private bool FindNextMethod() { while (true) { CurrentSymbol = (CurrentSymbol == null ? SymbolLoader.LookupAggMember(_name, CurrentType.OwningAggregate, _mask) : CurrentSymbol.LookupNext(_mask)) as MethodOrPropertySymbol; // If we couldn't find a sym, we look up the type chain and get the next type. if (CurrentSymbol == null) { if (!FindNextTypeForInstanceMethods()) { return(false); } } else { // Note that we do not filter the current symbol for the user. They must do that themselves. // This is because for instance, BindGrpToArgs wants to filter on arguments before filtering // on bogosity. // If we're here, we're good to go. return(true); } } }
public EventSymbol getEvent(SymbolLoader symbolLoader) { Debug.Assert(this.isEvent == true); EventSymbol evt = symbolLoader.LookupAggMember(this.name, this.getClass(), symbmask_t.MASK_EventSymbol).AsEventSymbol(); return(evt); }
public EventSymbol getEvent(SymbolLoader symbolLoader) { Debug.Assert(this.isEvent == true); EventSymbol evt = symbolLoader.LookupAggMember(this.name, this.getClass(), symbmask_t.MASK_EventSymbol).AsEventSymbol(); return evt; }
private static MethodSymbol LookupMethodWhileLoading(AggregateSymbol type, int cMethodTyVars, Name methodName, ACCESS methodAccess, bool isStatic, bool isVirtual, CType returnType, TypeArray argumentTypes) { for (Symbol sym = SymbolLoader.LookupAggMember(methodName, type, symbmask_t.MASK_ALL); sym != null; sym = sym.LookupNext(symbmask_t.MASK_ALL)) { if (sym is MethodSymbol methsym) { if ((methsym.GetAccess() == methodAccess || methodAccess == ACCESS.ACC_UNKNOWN) && methsym.isStatic == isStatic && methsym.isVirtual == isVirtual && methsym.typeVars.Count == cMethodTyVars && TypeManager.SubstEqualTypes(methsym.RetType, returnType, null, methsym.typeVars, true) && TypeManager.SubstEqualTypeArrays(methsym.Params, argumentTypes, null, methsym.typeVars)) { return(methsym); } } } return(null); }
public EventSymbol getEvent() { Debug.Assert(isEvent); return(SymbolLoader.LookupAggMember(name, getClass(), symbmask_t.MASK_EventSymbol) as EventSymbol); }
private bool SearchSingleType(AggregateType typeCur, out bool pfHideByName) { bool fFoundSome = false; pfHideByName = false; // Make sure this type is accessible. It may not be due to private inheritance // or friend assemblies. bool fInaccess = !CSemanticChecker.CheckTypeAccess(typeCur, _symWhere); if (fInaccess && (_csym != 0 || _swtInaccess != null)) { return(false); } // Loop through symbols. Symbol symCur; for (symCur = SymbolLoader.LookupAggMember(_name, typeCur.OwningAggregate, symbmask_t.MASK_Member); symCur != null; symCur = symCur.LookupNext(symbmask_t.MASK_Member)) { Debug.Assert(!(symCur is AggregateSymbol)); // Check for arity. // For non-zero arity, only methods of the correct arity are considered. // For zero arity, don't filter out any methods since we do type argument // inferencing. // All others are only considered when arity is zero. if (_arity > 0 && (!(symCur is MethodSymbol curMeth) || curMeth.typeVars.Count != _arity)) { if (!_swtBadArity) { _swtBadArity.Set(symCur, typeCur); } continue; } // Check for user callability. if (symCur.IsOverride() && !symCur.IsHideByName()) { continue; } MethodOrPropertySymbol methProp = symCur as MethodOrPropertySymbol; MethodSymbol meth = symCur as MethodSymbol; if (methProp != null && (_flags & MemLookFlags.UserCallable) != 0 && !methProp.isUserCallable()) { // If its an indexed property method symbol, let it through. // This is too liberal, but maintained for compatibility. if (meth == null || !meth.isPropertyAccessor() || (!symCur.name.Text.StartsWith("set_", StringComparison.Ordinal) || meth.Params.Count <= 1) && (!symCur.name.Text.StartsWith("get_", StringComparison.Ordinal) || meth.Params.Count <= 0)) { if (!_swtInaccess) { _swtInaccess.Set(symCur, typeCur); } continue; } } if (fInaccess || !CSemanticChecker.CheckAccess(symCur, typeCur, _symWhere, _typeQual)) { // Not accessible so get the next sym. if (!_swtInaccess) { _swtInaccess.Set(symCur, typeCur); } if (fInaccess) { return(false); } continue; } PropertySymbol prop = symCur as PropertySymbol; // Make sure that whether we're seeing a ctor, operator, or indexer is consistent with the flags. if (((_flags & MemLookFlags.Ctor) == 0) != (meth == null || !meth.IsConstructor()) || ((_flags & MemLookFlags.Operator) == 0) != (meth == null || !meth.isOperator) || ((_flags & MemLookFlags.Indexer) == 0) != !(prop is IndexerSymbol)) { if (!_swtBad) { _swtBad.Set(symCur, typeCur); } continue; } // We can't call CheckBogus on methods or indexers because if the method has the wrong // number of parameters people don't think they should have to /r the assemblies containing // the parameter types and they complain about the resulting CS0012 errors. if (!(symCur is MethodSymbol) && (_flags & MemLookFlags.Indexer) == 0 && CSemanticChecker.CheckBogus(symCur)) { // A bogus member - we can't use these, so only record them for error reporting. if (!_swtBogus) { _swtBogus.Set(symCur, typeCur); } continue; } // if we are in a calling context then we should only find a property if it is delegate valued if ((_flags & MemLookFlags.MustBeInvocable) != 0) { if ((symCur is FieldSymbol field && !IsDelegateType(field.GetType(), typeCur) && !IsDynamicMember(symCur)) || (prop != null && !IsDelegateType(prop.RetType, typeCur) && !IsDynamicMember(symCur))) { if (!_swtBad) { _swtBad.Set(symCur, typeCur); } continue; } } if (methProp != null) { MethPropWithType mwpInsert = new MethPropWithType(methProp, typeCur); _methPropWithTypeList.Add(mwpInsert); } // We have a visible symbol. fFoundSome = true; if (_swtFirst) { if (!typeCur.IsInterfaceType) { // Non-interface case. Debug.Assert(_fMulti || typeCur == _prgtype[0]); if (!_fMulti) { if (_swtFirst.Sym is FieldSymbol && symCur is EventSymbol // The isEvent bit is only set on symbols which come from source... // This is not a problem for the compiler because the field is only // accessible in the scope in which it is declared, // but in the EE we ignore accessibility... && _swtFirst.Field().isEvent ) { // m_swtFirst is just the field behind the event symCur so ignore symCur. continue; } else if (_swtFirst.Sym is FieldSymbol && symCur is EventSymbol) { // symCur is the matching event. continue; } goto LAmbig; } if (_swtFirst.Sym.getKind() != symCur.getKind()) { if (typeCur == _prgtype[0]) { goto LAmbig; } // This one is hidden by the first one. This one also hides any more in base types. pfHideByName = true; continue; } } // Interface case. // m_fMulti : n n n y y y y y // same-kind : * * * y n n n n // fDiffHidden: * * * * y n n n // meth : * * * * * y n * can n happen? just in case, we better handle it.... // hack : n * y * * y * n // meth-2 : * n y * * * * * // res : A A S R H H A A else if (!_fMulti) { // Give method groups priority. if (!(symCur is MethodSymbol)) { goto LAmbig; } // Erase previous results so we'll record this method as the first. _prgtype = new List <AggregateType>(); _csym = 0; _swtFirst.Clear(); _swtAmbig.Clear(); } else if (_swtFirst.Sym.getKind() != symCur.getKind()) { if (!typeCur.DiffHidden) { // Give method groups priority. if (!(_swtFirst.Sym is MethodSymbol)) { goto LAmbig; } } // This one is hidden by another. This one also hides any more in base types. pfHideByName = true; continue; } } RecordType(typeCur, symCur); if (methProp != null && methProp.isHideByName) { pfHideByName = true; } // We've found a symbol in this type but need to make sure there aren't any conflicting // syms here, so keep searching the type. } Debug.Assert(!fInaccess || !fFoundSome); return(fFoundSome); LAmbig: // Ambiguous! if (!_swtAmbig) { _swtAmbig.Set(symCur, typeCur); } pfHideByName = true; return(true); }
///////////////////////////////////////////////////////////////////////////////// public static MethodOrPropertySymbol FindMostDerivedMethod( SymbolLoader symbolLoader, MethodOrPropertySymbol pMethProp, CType pType) { MethodSymbol method; bool bIsIndexer = false; if (pMethProp.IsMethodSymbol()) { method = pMethProp.AsMethodSymbol(); } else { PropertySymbol prop = pMethProp.AsPropertySymbol(); method = prop.methGet != null ? prop.methGet : prop.methSet; if (method == null) { return null; } bIsIndexer = prop.isIndexer(); } if (!method.isVirtual) { return method; } if (pType == null) { // This must be a static call. return method; } // Now get the slot method. if (method.swtSlot != null && method.swtSlot.Meth() != null) { method = method.swtSlot.Meth(); } if (!pType.IsAggregateType()) { // Not something that can have overrides anyway. return method; } for (AggregateSymbol pAggregate = pType.AsAggregateType().GetOwningAggregate(); pAggregate != null && pAggregate.GetBaseAgg() != null; pAggregate = pAggregate.GetBaseAgg()) { for (MethodOrPropertySymbol meth = symbolLoader.LookupAggMember(method.name, pAggregate, symbmask_t.MASK_MethodSymbol | symbmask_t.MASK_PropertySymbol).AsMethodOrPropertySymbol(); meth != null; meth = symbolLoader.LookupNextSym(meth, pAggregate, symbmask_t.MASK_MethodSymbol | symbmask_t.MASK_PropertySymbol).AsMethodOrPropertySymbol()) { if (!meth.isOverride) { continue; } if (meth.swtSlot.Sym != null && meth.swtSlot.Sym == method) { if (bIsIndexer) { Debug.Assert(meth.IsMethodSymbol()); return meth.AsMethodSymbol().getProperty(); } else { return meth; } } } } // If we get here, it means we can have two cases: one is that we have // a delegate. This is because the delegate invoke method is virtual and is // an override, but we wont have the slots set up correctly, and will // not find the base type in the inheritance hierarchy. The second is that // we're calling off of the base itself. Debug.Assert(method.parent.IsAggregateSymbol()); return method; }
///////////////////////////////////////////////////////////////////////////////// private static EXPR GenerateOptionalArgument( SymbolLoader symbolLoader, ExprFactory exprFactory, MethodOrPropertySymbol methprop, CType type, int index) { CType pParamType = type; CType pRawParamType = type.IsNullableType() ? type.AsNullableType().GetUnderlyingType() : type; EXPR optionalArgument = null; if (methprop.HasDefaultParameterValue(index)) { CType pConstValType = methprop.GetDefaultParameterValueConstValType(index); CONSTVAL cv = methprop.GetDefaultParameterValue(index); if (pConstValType.isPredefType(PredefinedType.PT_DATETIME) && (pRawParamType.isPredefType(PredefinedType.PT_DATETIME) || pRawParamType.isPredefType(PredefinedType.PT_OBJECT) || pRawParamType.isPredefType(PredefinedType.PT_VALUE))) { // This is the specific case where we want to create a DateTime // but the constval that stores it is a long. AggregateType dateTimeType = symbolLoader.GetReqPredefType(PredefinedType.PT_DATETIME); optionalArgument = exprFactory.CreateConstant(dateTimeType, new CONSTVAL(DateTime.FromBinary(cv.longVal))); } else if (pConstValType.isSimpleOrEnumOrString()) { // In this case, the constval is a simple type (all the numerics, including // decimal), or an enum or a string. This covers all the substantial values, // and everything else that can be encoded is just null or default(something). // For enum parameters, we create a constant of the enum type. For everything // else, we create the appropriate constant. if (pRawParamType.isEnumType() && pConstValType == pRawParamType.underlyingType()) { optionalArgument = exprFactory.CreateConstant(pRawParamType, cv); } else { optionalArgument = exprFactory.CreateConstant(pConstValType, cv); } } else if ((pParamType.IsRefType() || pParamType.IsNullableType()) && cv.IsNullRef()) { // We have an "= null" default value with a reference type or a nullable type. optionalArgument = exprFactory.CreateNull(); } else { // We have a default value that is encoded as a nullref, and that nullref is // interpreted as default(something). For instance, the pParamType could be // a type parameter type or a non-simple value type. optionalArgument = exprFactory.CreateZeroInit(pParamType); } } else { // There was no default parameter specified, so generally use default(T), // except for some cases when the parameter type in metatdata is object. if (pParamType.isPredefType(PredefinedType.PT_OBJECT)) { if (methprop.MarshalAsObject(index)) { // For [opt] parameters of type object, if we have marshal(iunknown), // marshal(idispatch), or marshal(interface), then we emit a null. optionalArgument = exprFactory.CreateNull(); } else { // Otherwise, we generate Type.Missing AggregateSymbol agg = symbolLoader.GetOptPredefAgg(PredefinedType.PT_MISSING); Name name = symbolLoader.GetNameManager().GetPredefinedName(PredefinedName.PN_CAP_VALUE); FieldSymbol field = symbolLoader.LookupAggMember(name, agg, symbmask_t.MASK_FieldSymbol).AsFieldSymbol(); FieldWithType fwt = new FieldWithType(field, agg.getThisType()); EXPRFIELD exprField = exprFactory.CreateField(0, agg.getThisType(), null, 0, fwt, null); if (agg.getThisType() != type) { optionalArgument = exprFactory.CreateCast(0, type, exprField); } else { optionalArgument = exprField; } } } else { // Every type aside from object that doesn't have a default value gets // its default value. optionalArgument = exprFactory.CreateZeroInit(pParamType); } } Debug.Assert(optionalArgument != null); optionalArgument.IsOptionalArgument = true; return optionalArgument; }
//////////////////////////////////////////////////////////////////////////////// // For a base call we need to remap from the virtual to the specific override // to invoke. This is also used to map a virtual on pObject (like ToString) to // the specific override when the pObject is a simple type (int, bool, char, // etc). In these cases it is safe to assume that any override won't later be // removed.... We start searching from "typeObj" up the superclass hierarchy // until we find a method with an exact signature match. public static void RemapToOverride(SymbolLoader symbolLoader, SymWithType pswt, CType typeObj) { // For a property/indexer we remap the accessors, not the property/indexer. // Since every event has both accessors we remap the event instead of the accessors. Debug.Assert(pswt && (pswt.Sym.IsMethodSymbol() || pswt.Sym.IsEventSymbol() || pswt.Sym.IsMethodOrPropertySymbol())); Debug.Assert(typeObj != null); // Don't remap static or interface methods. if (typeObj.IsNullableType()) { typeObj = typeObj.AsNullableType().GetAts(symbolLoader.GetErrorContext()); if (typeObj == null) { VSFAIL("Why did GetAts return null?"); return; } } // Don't remap non-virtual members if (!typeObj.IsAggregateType() || typeObj.isInterfaceType() || !pswt.Sym.IsVirtual()) { return; } symbmask_t mask = pswt.Sym.mask(); AggregateType atsObj = typeObj.AsAggregateType(); // Search for an override version of the method. while (atsObj != null && atsObj.getAggregate() != pswt.Sym.parent) { for (Symbol symT = symbolLoader.LookupAggMember(pswt.Sym.name, atsObj.getAggregate(), mask); symT != null; symT = symbolLoader.LookupNextSym(symT, atsObj.getAggregate(), mask)) { if (symT.IsOverride() && (symT.SymBaseVirtual() == pswt.Sym || symT.SymBaseVirtual() == pswt.Sym.SymBaseVirtual())) { pswt.Set(symT, atsObj); return; } } atsObj = atsObj.GetBaseClass(); } }