public bool Lookup(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); _prgtype = _rgtypeStart; // Save the inputs for error handling, etc. _typeSrc = typeSrc; _symWhere = symWhere; _name = name; _arity = arity; _flags = flags; _typeQual = (_flags & MemLookFlags.Ctor) != 0 ? _typeSrc : obj?.Type; // Determine what to search. AggregateType typeCls1; AggregateType typeIface; TypeArray ifaces; if (typeSrc.IsInterfaceType) { Debug.Assert((_flags & (MemLookFlags.Ctor | MemLookFlags.NewObj | MemLookFlags.Operator | MemLookFlags.BaseCall)) == 0); typeCls1 = null; typeIface = (AggregateType)typeSrc; ifaces = typeIface.IfacesAll; } else { typeCls1 = (AggregateType)typeSrc; typeIface = null; ifaces = TypeArray.Empty; } AggregateType typeCls2 = typeIface != null || ifaces.Count > 0 ? SymbolLoader.GetPredefindType(PredefinedType.PT_OBJECT) : null; // 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()); }
private AggCastResult bindExplicitConversionFromEnumToDecimal(AggregateType aggTypeDest) { Debug.Assert(_typeSrc != null); Debug.Assert(aggTypeDest != null); Debug.Assert(aggTypeDest.IsPredefType(PredefinedType.PT_DECIMAL)); Debug.Assert(_typeSrc.IsEnumType); AggregateType underlyingType = _typeSrc.UnderlyingEnumType; // Need to first cast the source expr to its underlying type. Expr exprCast; if (_exprSrc == null) { exprCast = null; } else { _binder.bindSimpleCast(_exprSrc, underlyingType, out exprCast); } // There is always an implicit conversion from any integral type to decimal. if (exprCast.GetConst() != null) { // Fold the constant cast if possible. ConstCastResult result = _binder.bindConstantCast(exprCast, _typeDest, _needsExprDest, out _exprDest, true); if (result == ConstCastResult.Success) { return(AggCastResult.Success); // else, don't fold and use a regular cast, below. } if (result == ConstCastResult.CheckFailure && 0 == (_flags & CONVERTTYPE.CHECKOVERFLOW)) { return(AggCastResult.Abort); } } // Conversions from integral types to decimal are always bound as a user-defined conversion. if (_needsExprDest) { // According the language, this is a standard conversion, but it is implemented // through a user-defined conversion. Because it's a standard conversion, we don't // test the CONVERTTYPE.NOUDC flag here. bool ok = _binder.bindUserDefinedConversion(exprCast, underlyingType, aggTypeDest, _needsExprDest, out _exprDest, false); Debug.Assert(ok); } return(AggCastResult.Success); }
/*************************************************************************************************** * 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((_flags & (MemLookFlags.Ctor | MemLookFlags.NewObj | MemLookFlags.Operator | MemLookFlags.BaseCall)) == 0); typeIface = (AggregateType)typeSrc; ifaces = typeIface.IfacesAll; } 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()); }