/***************************************************************************************************
* 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());
}