<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />

MemberLookup

class MemberLookup
using Microsoft.CSharp.RuntimeBinder.Errors; using Microsoft.CSharp.RuntimeBinder.Syntax; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; namespace Microsoft.CSharp.RuntimeBinder.Semantics { internal class MemberLookup { private CSemanticChecker _pSemanticChecker; private SymbolLoader _pSymbolLoader; private CType _typeSrc; private EXPR _obj; private CType _typeQual; private ParentSymbol _symWhere; private Name _name; private int _arity; private MemLookFlags _flags; private CMemberLookupResults _results; private List<AggregateType> _rgtypeStart; private List<AggregateType> _prgtype; private int _csym; private SymWithType _swtFirst; private List<MethPropWithType> _methPropWithTypeList; private SymWithType _swtAmbig; private SymWithType _swtInaccess; private SymWithType _swtBad; private SymWithType _swtBogus; private SymWithType _swtBadArity; private SymWithType _swtAmbigWarn; private SymWithType _swtOverride; private bool _fMulti; private void RecordType(AggregateType type, Symbol sym) { if (!_prgtype.Contains(type)) _prgtype.Add(type); _csym++; if (_swtFirst == (SymWithType)null) { _swtFirst.Set(sym, type); _fMulti = (sym.IsMethodSymbol() || (sym.IsPropertySymbol() && sym.AsPropertySymbol().isIndexer())); } } private bool SearchSingleType(AggregateType typeCur, out bool pfHideByName) { bool result = false; pfHideByName = false; bool flag = !GetSemanticChecker().CheckTypeAccess(typeCur, _symWhere); if (flag && (_csym != 0 || _swtInaccess != (SymWithType)null)) return false; Symbol symbol = null; for (symbol = GetSymbolLoader().LookupAggMember(_name, typeCur.getAggregate(), symbmask_t.MASK_ALL); symbol != null; symbol = GetSymbolLoader().LookupNextSym(symbol, typeCur.getAggregate(), symbmask_t.MASK_ALL)) { switch (symbol.getKind()) { case SYMKIND.SK_MethodSymbol: if (_arity > 0 && symbol.AsMethodSymbol().typeVars.size != _arity) { if (!(bool)_swtBadArity) _swtBadArity.Set(symbol, typeCur); break; } goto IL_0161; case SYMKIND.SK_AggregateSymbol: if (symbol.AsAggregateSymbol().GetTypeVars().size != _arity) { if (!(bool)_swtBadArity) _swtBadArity.Set(symbol, typeCur); break; } goto IL_0161; case SYMKIND.SK_TypeParameterSymbol: if ((_flags & MemLookFlags.TypeVarsAllowed) == MemLookFlags.None) break; if (_arity > 0) { if (!(bool)_swtBadArity) _swtBadArity.Set(symbol, typeCur); break; } goto IL_0161; default: { if (_arity > 0) { if (!(bool)_swtBadArity) _swtBadArity.Set(symbol, typeCur); break; } goto IL_0161; } IL_054f: RecordType(typeCur, symbol); if (symbol.IsMethodOrPropertySymbol() && symbol.AsMethodOrPropertySymbol().isHideByName) pfHideByName = true; break; IL_058c: if (!(bool)_swtAmbig) _swtAmbig.Set(symbol, typeCur); pfHideByName = true; return true; IL_0161: if (symbol.IsOverride() && !symbol.IsHideByName()) { if (!(bool)_swtOverride) _swtOverride.Set(symbol, typeCur); break; } if ((_flags & MemLookFlags.UserCallable) != 0 && symbol.IsMethodOrPropertySymbol() && !symbol.AsMethodOrPropertySymbol().isUserCallable()) { bool flag2 = false; if (symbol.IsMethodSymbol() && symbol.AsMethodSymbol().isPropertyAccessor() && ((symbol.name.Text.StartsWith("set_", StringComparison.Ordinal) && symbol.AsMethodSymbol().Params.size > 1) || (symbol.name.Text.StartsWith("get_", StringComparison.Ordinal) && symbol.AsMethodSymbol().Params.size > 0))) flag2 = true; if (!flag2) { if (!(bool)_swtInaccess) _swtInaccess.Set(symbol, typeCur); break; } } if (flag || !GetSemanticChecker().CheckAccess(symbol, typeCur, _symWhere, _typeQual)) { if (!(bool)_swtInaccess) _swtInaccess.Set(symbol, typeCur); if (flag) return false; break; } if ((_flags & MemLookFlags.Ctor) == MemLookFlags.None != (!symbol.IsMethodSymbol() || !symbol.AsMethodSymbol().IsConstructor()) || (_flags & MemLookFlags.Operator) == MemLookFlags.None != (!symbol.IsMethodSymbol() || !symbol.AsMethodSymbol().isOperator) || (_flags & MemLookFlags.Indexer) == MemLookFlags.None != (!symbol.IsPropertySymbol() || !symbol.AsPropertySymbol().isIndexer())) { if (!(bool)_swtBad) _swtBad.Set(symbol, typeCur); break; } if (!symbol.IsMethodSymbol() && (_flags & MemLookFlags.Indexer) == MemLookFlags.None && GetSemanticChecker().CheckBogus(symbol)) { if (!(bool)_swtBogus) _swtBogus.Set(symbol, typeCur); break; } if ((_flags & MemLookFlags.MustBeInvocable) != 0 && ((symbol.IsFieldSymbol() && !IsDelegateType(symbol.AsFieldSymbol().GetType(), typeCur) && !IsDynamicMember(symbol)) || (symbol.IsPropertySymbol() && !IsDelegateType(symbol.AsPropertySymbol().RetType, typeCur) && !IsDynamicMember(symbol)))) { if (!(bool)_swtBad) _swtBad.Set(symbol, typeCur); break; } if (symbol.IsMethodOrPropertySymbol()) { MethPropWithType item = new MethPropWithType(symbol.AsMethodOrPropertySymbol(), typeCur); _methPropWithTypeList.Add(item); } result = true; if ((bool)_swtFirst) { if (!typeCur.isInterfaceType()) { if (!_fMulti) { if ((_swtFirst.Sym.IsFieldSymbol() && symbol.IsEventSymbol() && _swtFirst.Field().isEvent) || (_swtFirst.Sym.IsFieldSymbol() && symbol.IsEventSymbol())) break; } else { if (_swtFirst.Sym.getKind() == symbol.getKind()) goto IL_054f; if (typeCur != _prgtype[0]) { pfHideByName = true; break; } } goto IL_058c; } if (!_fMulti) { if (!symbol.IsMethodSymbol()) goto IL_058c; _swtAmbigWarn = _swtFirst; _prgtype = new List<AggregateType>(); _csym = 0; _swtFirst.Clear(); _swtAmbig.Clear(); } else if (_swtFirst.Sym.getKind() != symbol.getKind()) { if (!typeCur.fDiffHidden) { if (!_swtFirst.Sym.IsMethodSymbol()) goto IL_058c; if (!(bool)_swtAmbigWarn) _swtAmbigWarn.Set(symbol, typeCur); } pfHideByName = true; break; } } goto IL_054f; } } return result; } private bool IsDynamicMember(Symbol sym) { DynamicAttribute dynamicAttribute = null; if (sym.IsFieldSymbol()) { if (!sym.AsFieldSymbol().getType().isPredefType(PredefinedType.PT_OBJECT)) return false; Attribute[] array = CustomAttributeExtensions.GetCustomAttributes(sym.AsFieldSymbol().AssociatedFieldInfo, typeof(DynamicAttribute), false).ToArray(); if (array.Length == 1) dynamicAttribute = (array[0] as DynamicAttribute); } else { if (!sym.AsPropertySymbol().getType().isPredefType(PredefinedType.PT_OBJECT)) return false; Attribute[] array2 = CustomAttributeExtensions.GetCustomAttributes(sym.AsPropertySymbol().AssociatedPropertyInfo, typeof(DynamicAttribute), false).ToArray(); if (array2.Length == 1) dynamicAttribute = (array2[0] as DynamicAttribute); } if (dynamicAttribute == null) return false; if (dynamicAttribute.TransformFlags.Count != 0) { if (dynamicAttribute.TransformFlags.Count == 1) return dynamicAttribute.TransformFlags[0]; return false; } return true; } private bool LookupInClass(AggregateType typeStart, ref AggregateType ptypeEnd) { AggregateType aggregateType = ptypeEnd; AggregateType aggregateType2 = typeStart; while (aggregateType2 != aggregateType && aggregateType2 != null) { bool pfHideByName = false; SearchSingleType(aggregateType2, out pfHideByName); _flags &= (MemLookFlags)3221225471; if ((bool)_swtFirst && !_fMulti) return false; if (pfHideByName) { ptypeEnd = null; return true; } if ((_flags & MemLookFlags.Ctor) != 0) return false; aggregateType2 = aggregateType2.GetBaseClass(); } return true; } private bool LookupInInterfaces(AggregateType typeStart, TypeArray types) { if (typeStart != null) { typeStart.fAllHidden = false; typeStart.fDiffHidden = (_swtFirst != (SymWithType)null); } for (int i = 0; i < types.size; i++) { AggregateType aggregateType = types.Item(i).AsAggregateType(); aggregateType.fAllHidden = false; aggregateType.fDiffHidden = _swtFirst; } bool flag = false; AggregateType aggregateType2 = typeStart; int num = 0; if (aggregateType2 == null) aggregateType2 = types.Item(num++).AsAggregateType(); while (true) { bool pfHideByName = false; if (!aggregateType2.fAllHidden && SearchSingleType(aggregateType2, out pfHideByName)) { pfHideByName |= !_fMulti; TypeArray ifacesAll = aggregateType2.GetIfacesAll(); for (int j = 0; j < ifacesAll.size; j++) { AggregateType aggregateType3 = ifacesAll.Item(j).AsAggregateType(); if (pfHideByName) aggregateType3.fAllHidden = true; aggregateType3.fDiffHidden = true; } if (pfHideByName) flag = true; } _flags &= (MemLookFlags)3221225471; if (num >= types.size) break; aggregateType2 = types.Item(num++).AsAggregateType(); } return !flag; } private SymbolLoader GetSymbolLoader() { return _pSymbolLoader; } private CSemanticChecker GetSemanticChecker() { return _pSemanticChecker; } private ErrorHandling GetErrorContext() { return GetSymbolLoader().GetErrorContext(); } private void ReportBogus(SymWithType swt) { switch (swt.Sym.getKind()) { case SYMKIND.SK_PropertySymbol: if (swt.Prop().useMethInstead) { MethodSymbol methGet = swt.Prop().methGet; MethodSymbol methSet = swt.Prop().methSet; ReportBogusForEventsAndProperties(swt, methGet, methSet); return; } break; case SYMKIND.SK_MethodSymbol: if (swt.Meth().name == GetSymbolLoader().GetNameManager().GetPredefName(PredefinedName.PN_INVOKE) && swt.Meth().getClass().IsDelegate()) swt.Set(swt.Meth().getClass(), swt.GetType()); break; } GetErrorContext().ErrorRef(ErrorCode.ERR_BindToBogus, swt); } private void ReportBogusForEventsAndProperties(SymWithType swt, MethodSymbol meth1, MethodSymbol meth2) { if (meth1 != null && meth2 != null) GetErrorContext().Error(ErrorCode.ERR_BindToBogusProp2, swt.Sym.name, new SymWithType(meth1, swt.GetType()), new SymWithType(meth2, swt.GetType()), new ErrArgRefOnly(swt.Sym)); else { if (meth1 == null && meth2 == null) throw Error.InternalCompilerError(); GetErrorContext().Error(ErrorCode.ERR_BindToBogusProp1, swt.Sym.name, new SymWithType((meth1 != null) ? meth1 : meth2, swt.GetType()), new ErrArgRefOnly(swt.Sym)); } } private bool IsDelegateType(CType pSrcType, AggregateType pAggType) { CType cType = GetSymbolLoader().GetTypeManager().SubstType(pSrcType, pAggType, pAggType.GetTypeArgsAll()); return cType.isDelegateType(); } public MemberLookup() { _methPropWithTypeList = new List<MethPropWithType>(); _rgtypeStart = new List<AggregateType>(); _swtFirst = new SymWithType(); _swtAmbig = new SymWithType(); _swtInaccess = new SymWithType(); _swtBad = new SymWithType(); _swtBogus = new SymWithType(); _swtBadArity = new SymWithType(); _swtAmbigWarn = new SymWithType(); _swtOverride = new SymWithType(); } public bool Lookup(CSemanticChecker checker, CType typeSrc, EXPR obj, ParentSymbol symWhere, Name name, int arity, MemLookFlags flags) { _prgtype = _rgtypeStart; _pSemanticChecker = checker; _pSymbolLoader = checker.GetSymbolLoader(); _typeSrc = typeSrc; _obj = ((obj != null && !obj.isCLASS()) ? obj : null); _symWhere = symWhere; _name = name; _arity = arity; _flags = flags; if ((_flags & MemLookFlags.BaseCall) != 0) _typeQual = null; else if ((_flags & MemLookFlags.Ctor) != 0) { _typeQual = _typeSrc; } else if (obj != null) { _typeQual = obj.type; } else { _typeQual = null; } AggregateType aggregateType = null; AggregateType aggregateType2 = null; TypeArray typeArray = BSYMMGR.EmptyTypeArray(); AggregateType ptypeEnd = null; if (typeSrc.IsTypeParameterType()) { _flags &= (MemLookFlags)3221225471; typeArray = typeSrc.AsTypeParameterType().GetInterfaceBounds(); aggregateType = typeSrc.AsTypeParameterType().GetEffectiveBaseClass(); if (typeArray.size > 0 && aggregateType.isPredefType(PredefinedType.PT_OBJECT)) aggregateType = null; } else if (!typeSrc.isInterfaceType()) { aggregateType = typeSrc.AsAggregateType(); if (aggregateType.IsWindowsRuntimeType()) typeArray = aggregateType.GetWinRTCollectionIfacesAll(GetSymbolLoader()); } else { aggregateType2 = typeSrc.AsAggregateType(); typeArray = aggregateType2.GetIfacesAll(); } if (aggregateType2 != null || typeArray.size > 0) ptypeEnd = GetSymbolLoader().GetReqPredefType(PredefinedType.PT_OBJECT); if ((aggregateType == null || LookupInClass(aggregateType, ref ptypeEnd)) && (aggregateType2 != null || typeArray.size > 0) && LookupInInterfaces(aggregateType2, typeArray) && ptypeEnd != null) { AggregateType ptypeEnd2 = null; LookupInClass(ptypeEnd, ref ptypeEnd2); } _results = new CMemberLookupResults(GetAllTypes(), _name); return !FError(); } public CMemberLookupResults GetResults() { return _results; } public bool FError() { if ((bool)_swtFirst) return _swtAmbig; return true; } public Symbol SymFirst() { return _swtFirst.Sym; } public SymWithType SwtFirst() { return _swtFirst; } public SymWithType SwtInaccessible() { return _swtInaccess; } public EXPR GetObject() { return _obj; } public CType GetSourceType() { return _typeSrc; } public MemLookFlags GetFlags() { return _flags; } public TypeArray GetAllTypes() { return GetSymbolLoader().getBSymmgr().AllocParams(_prgtype.Count, _prgtype.ToArray()); } public void ReportErrors() { if ((bool)_swtFirst) GetErrorContext().ErrorRef(ErrorCode.ERR_AmbigMember, _swtFirst, _swtAmbig); else if ((bool)_swtInaccess) { if (!_swtInaccess.Sym.isUserCallable() && (_flags & MemLookFlags.UserCallable) != 0) GetErrorContext().Error(ErrorCode.ERR_CantCallSpecialMethod, _swtInaccess); else GetSemanticChecker().ReportAccessError(_swtInaccess, _symWhere, _typeQual); } else if ((_flags & MemLookFlags.Ctor) != 0) { if (_arity > 0) GetErrorContext().Error(ErrorCode.ERR_BadCtorArgCount, _typeSrc.getAggregate(), _arity); else GetErrorContext().Error(ErrorCode.ERR_NoConstructors, _typeSrc.getAggregate()); } else if ((_flags & MemLookFlags.Operator) != 0) { GetErrorContext().Error(ErrorCode.ERR_NoSuchMember, _typeSrc, _name); } else if ((_flags & MemLookFlags.Indexer) != 0) { GetErrorContext().Error(ErrorCode.ERR_BadIndexLHS, _typeSrc); } else if ((bool)_swtBad) { GetErrorContext().Error(((_flags & MemLookFlags.MustBeInvocable) != 0) ? ErrorCode.ERR_NonInvocableMemberCalled : ErrorCode.ERR_CantCallSpecialMethod, _swtBad); } else if ((bool)_swtBogus) { ReportBogus(_swtBogus); } else if ((bool)_swtBadArity) { switch (_swtBadArity.Sym.getKind()) { case SYMKIND.SK_MethodSymbol: { int size = _swtBadArity.Sym.AsMethodSymbol().typeVars.size; GetErrorContext().ErrorRef((size > 0) ? ErrorCode.ERR_BadArity : ErrorCode.ERR_HasNoTypeVars, _swtBadArity, new ErrArgSymKind(_swtBadArity.Sym), size); break; } case SYMKIND.SK_AggregateSymbol: { int size = _swtBadArity.Sym.AsAggregateSymbol().GetTypeVars().size; GetErrorContext().ErrorRef((size > 0) ? ErrorCode.ERR_BadArity : ErrorCode.ERR_HasNoTypeVars, _swtBadArity, new ErrArgSymKind(_swtBadArity.Sym), size); break; } default: ExpressionBinder.ReportTypeArgsNotAllowedError(GetSymbolLoader(), _arity, _swtBadArity, new ErrArgSymKind(_swtBadArity.Sym)); break; } } else if (((int)_flags & -2147483648) != 0) { GetErrorContext().Error(ErrorCode.ERR_NoSuchMemberOrExtension, _typeSrc, _name); } else { GetErrorContext().Error(ErrorCode.ERR_NoSuchMember, _typeSrc, _name); } } } }