private bool HasAnyBaseInterfaceConversion(CType pDerived, CType pBase) { if (!pBase.isInterfaceType()) { return(false); } if (!pDerived.IsAggregateType()) { return(false); } AggregateType atsDer = pDerived.AsAggregateType(); while (atsDer != null) { TypeArray ifacesAll = atsDer.GetIfacesAll(); for (int i = 0; i < ifacesAll.Count; i++) { if (HasInterfaceConversion(ifacesAll[i].AsAggregateType(), pBase.AsAggregateType())) { return(true); } } atsDer = atsDer.GetBaseClass(); } return(false); }
private bool IsBaseInterface(CType pDerived, CType pBase) { Debug.Assert(pDerived != null); Debug.Assert(pBase != null); if (!pBase.isInterfaceType()) { return(false); } if (!pDerived.IsAggregateType()) { return(false); } AggregateType atsDer = pDerived.AsAggregateType(); while (atsDer != null) { TypeArray ifacesAll = atsDer.GetIfacesAll(); for (int i = 0; i < ifacesAll.Count; i++) { if (AreTypesEqualForConversion(ifacesAll[i], pBase)) { return(true); } } atsDer = atsDer.GetBaseClass(); } return(false); }
private static IEnumerable <AggregateType> InterfaceAndBases(this AggregateType type) { Debug.Assert(type != null); yield return(type); foreach (AggregateType t in type.GetIfacesAll().Items) { yield return(t); } }
private static bool IsBaseInterface(AggregateType atsDer, AggregateType pBase) { Debug.Assert(atsDer != null); Debug.Assert(pBase != null); if (pBase.isInterfaceType()) { while (atsDer != null) { TypeArray ifacesAll = atsDer.GetIfacesAll(); for (int i = 0; i < ifacesAll.Count; i++) { if (AreTypesEqualForConversion(ifacesAll[i], pBase)) { return(true); } } atsDer = atsDer.GetBaseClass(); } } return(false); }
/*************************************************************************************************** * Lookup must be called before anything else can be called. * * typeSrc - Must be an AggregateType or TypeParameterType. * obj - the expression through which the member is being accessed. This is used for accessibility * of protected members and for constructing a MEMGRP from the results of the lookup. * It is legal for obj to be an EK_CLASS, in which case it may be used for accessibility, but * will not be used for MEMGRP construction. * symWhere - the symbol from with the name is being accessed (for checking accessibility). * name - the name to look for. * arity - the number of type args specified. Only members that support this arity are found. * Note that when arity is zero, all methods are considered since we do type argument * inferencing. * * flags - See MemLookFlags. * TypeVarsAllowed only applies to the most derived type (not base types). ***************************************************************************************************/ public bool Lookup(CSemanticChecker checker, CType typeSrc, EXPR obj, ParentSymbol symWhere, Name name, int arity, MemLookFlags flags) { Debug.Assert((flags & ~MemLookFlags.All) == 0); Debug.Assert(obj == null || obj.type != null); Debug.Assert(typeSrc.IsAggregateType() || typeSrc.IsTypeParameterType()); Debug.Assert(checker != null); _prgtype = _rgtypeStart; // Save the inputs for error handling, etc. _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 = (CType)obj.type; } else { _typeQual = null; } // Determine what to search. AggregateType typeCls1 = null; AggregateType typeIface = null; TypeArray ifaces = BSYMMGR.EmptyTypeArray(); AggregateType typeCls2 = null; if (typeSrc.IsTypeParameterType()) { Debug.Assert((_flags & (MemLookFlags.Ctor | MemLookFlags.NewObj | MemLookFlags.Operator | MemLookFlags.BaseCall | MemLookFlags.TypeVarsAllowed)) == 0); _flags &= ~MemLookFlags.TypeVarsAllowed; ifaces = typeSrc.AsTypeParameterType().GetInterfaceBounds(); typeCls1 = typeSrc.AsTypeParameterType().GetEffectiveBaseClass(); if (ifaces.size > 0 && typeCls1.isPredefType(PredefinedType.PT_OBJECT)) { typeCls1 = null; } } else if (!typeSrc.isInterfaceType()) { typeCls1 = typeSrc.AsAggregateType(); if (typeCls1.IsWindowsRuntimeType()) { ifaces = typeCls1.GetWinRTCollectionIfacesAll(GetSymbolLoader()); } } else { Debug.Assert(typeSrc.isInterfaceType()); Debug.Assert((_flags & (MemLookFlags.Ctor | MemLookFlags.NewObj | MemLookFlags.Operator | MemLookFlags.BaseCall)) == 0); typeIface = typeSrc.AsAggregateType(); ifaces = typeIface.GetIfacesAll(); } if (typeIface != null || ifaces.size > 0) { typeCls2 = GetSymbolLoader().GetReqPredefType(PredefinedType.PT_OBJECT); } // Search the class first (except possibly object). if (typeCls1 == null || LookupInClass(typeCls1, ref typeCls2)) { // Search the interfaces. if ((typeIface != null || ifaces.size > 0) && LookupInInterfaces(typeIface, ifaces) && typeCls2 != null) { // Search object last. Debug.Assert(typeCls2 != null && typeCls2.isPredefType(PredefinedType.PT_OBJECT)); AggregateType result = null; LookupInClass(typeCls2, ref result); } } // if we are requested with extension methods _results = new CMemberLookupResults(GetAllTypes(), _name); return(!FError()); }
/****************************************************************************** * Returns true if searching should continue to object. ******************************************************************************/ private bool LookupInInterfaces(AggregateType typeStart, TypeArray types) { Debug.Assert(!_swtFirst || _fMulti); Debug.Assert(typeStart == null || typeStart.isInterfaceType()); Debug.Assert(typeStart != null || types.size != 0); // Clear all the hidden flags. Anything found in a class hides any other // kind of member in all the interfaces. if (typeStart != null) { typeStart.fAllHidden = false; typeStart.fDiffHidden = (_swtFirst != null); } for (int i = 0; i < types.size; i++) { AggregateType type = types.Item(i).AsAggregateType(); Debug.Assert(type.isInterfaceType()); type.fAllHidden = false; type.fDiffHidden = !!_swtFirst; } bool fHideObject = false; AggregateType typeCur = typeStart; int itypeNext = 0; if (typeCur == null) { typeCur = types.Item(itypeNext++).AsAggregateType(); } Debug.Assert(typeCur != null); // Loop through the interfaces. for (; ;) { Debug.Assert(typeCur != null && typeCur.isInterfaceType()); bool fHideByName = false; if (!typeCur.fAllHidden && SearchSingleType(typeCur, out fHideByName)) { fHideByName |= !_fMulti; // Mark base interfaces appropriately. TypeArray ifaces = typeCur.GetIfacesAll(); for (int i = 0; i < ifaces.size; i++) { AggregateType type = ifaces.Item(i).AsAggregateType(); Debug.Assert(type.isInterfaceType()); if (fHideByName) { type.fAllHidden = true; } type.fDiffHidden = true; } // If we hide all base types, that includes object! if (fHideByName) { fHideObject = true; } } _flags &= ~MemLookFlags.TypeVarsAllowed; if (itypeNext >= types.size) { return(!fHideObject); } // Substitution has already been done. typeCur = types.Item(itypeNext++).AsAggregateType(); } }
/*************************************************************************************************** * Lookup must be called before anything else can be called. * * typeSrc - Must be an AggregateType or TypeParameterType. * obj - the expression through which the member is being accessed. This is used for accessibility * of protected members and for constructing a MEMGRP from the results of the lookup. * It is legal for obj to be an EK_CLASS, in which case it may be used for accessibility, but * will not be used for MEMGRP construction. * symWhere - the symbol from with the name is being accessed (for checking accessibility). * name - the name to look for. * arity - the number of type args specified. Only members that support this arity are found. * Note that when arity is zero, all methods are considered since we do type argument * inferencing. * * flags - See MemLookFlags. * TypeVarsAllowed only applies to the most derived type (not base types). ***************************************************************************************************/ public bool Lookup(CSemanticChecker checker, CType typeSrc, Expr obj, ParentSymbol symWhere, Name name, int arity, MemLookFlags flags) { Debug.Assert((flags & ~MemLookFlags.All) == 0); Debug.Assert(obj == null || obj.Type != null); Debug.Assert(typeSrc is AggregateType); Debug.Assert(checker != null); _prgtype = _rgtypeStart; // Save the inputs for error handling, etc. _pSemanticChecker = checker; _pSymbolLoader = checker.SymbolLoader; _typeSrc = typeSrc; _obj = obj is ExprClass ? null : obj; _symWhere = symWhere; _name = name; _arity = arity; _flags = flags; _typeQual = (_flags & MemLookFlags.Ctor) != 0 ? _typeSrc : obj?.Type; // Determine what to search. AggregateType typeCls1 = null; AggregateType typeIface = null; TypeArray ifaces = BSYMMGR.EmptyTypeArray(); AggregateType typeCls2 = null; if (!typeSrc.isInterfaceType()) { typeCls1 = (AggregateType)typeSrc; if (typeCls1.IsWindowsRuntimeType()) { ifaces = typeCls1.GetWinRTCollectionIfacesAll(GetSymbolLoader()); } } else { Debug.Assert(typeSrc.isInterfaceType()); Debug.Assert((_flags & (MemLookFlags.Ctor | MemLookFlags.NewObj | MemLookFlags.Operator | MemLookFlags.BaseCall)) == 0); typeIface = (AggregateType)typeSrc; ifaces = typeIface.GetIfacesAll(); } if (typeIface != null || ifaces.Count > 0) { typeCls2 = GetSymbolLoader().GetPredefindType(PredefinedType.PT_OBJECT); } // Search the class first (except possibly object). if (typeCls1 == null || LookupInClass(typeCls1, ref typeCls2)) { // Search the interfaces. if ((typeIface != null || ifaces.Count > 0) && LookupInInterfaces(typeIface, ifaces) && typeCls2 != null) { // Search object last. Debug.Assert(typeCls2 != null && typeCls2.isPredefType(PredefinedType.PT_OBJECT)); AggregateType result = null; LookupInClass(typeCls2, ref result); } } return(!FError()); }