Beispiel #1
0
        /***************************************************************************************************
        *   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());
        }
Beispiel #2
0
        /////////////////////////////////////////////////////////////////////////////////

        private EXPRMEMGRP CreateMemberGroupEXPR(
            string Name,
            IList<Type> typeArguments,
            EXPR callingObject,
            SYMKIND kind)
        {
            Name name = SymbolTable.GetName(Name, _semanticChecker.GetNameManager());
            AggregateType callingType;

            if (callingObject.type.IsArrayType())
            {
                callingType = _semanticChecker.GetSymbolLoader().GetReqPredefType(PredefinedType.PT_ARRAY);
            }
            else if (callingObject.type.IsNullableType())
            {
                callingType = callingObject.type.AsNullableType().GetAts(_semanticChecker.GetSymbolLoader().GetErrorContext());
            }
            else if (callingObject.type.IsAggregateType())
            {
                callingType = callingObject.type.AsAggregateType();
            }
            else
            {
                callingType = null;
                Debug.Assert(false, "MemberGroup on non-array, non-aggregate");
            }

            List<CType> callingTypes = new List<CType>();

            // The C# binder expects that only the base virtual method is inserted
            // into the list of candidates, and only the type containing the base
            // virtual method is inserted into the list of types. However, since we
            // don't want to do all the logic, we're just going to insert every type
            // that has a member of the given name, and allow the C# binder to filter
            // out all overrides.
            //
            // Find that set of types now.
            symbmask_t mask = symbmask_t.MASK_MethodSymbol;
            switch (kind)
            {
                case SYMKIND.SK_PropertySymbol:
                case SYMKIND.SK_IndexerSymbol:
                    mask = symbmask_t.MASK_PropertySymbol;
                    break;
                case SYMKIND.SK_MethodSymbol:
                    mask = symbmask_t.MASK_MethodSymbol;
                    break;
                default:
                    Debug.Assert(false, "Unhandled kind");
                    break;
            }

            // If we have a constructor, only find its type.
            bool bIsConstructor = name == SymbolLoader.GetNameManager().GetPredefinedName(PredefinedName.PN_CTOR);
            for (AggregateType t = callingType; t != null; t = t.GetBaseClass())
            {
                if (_symbolTable.AggregateContainsMethod(t.GetOwningAggregate(), Name, mask))
                {
                    callingTypes.Add(t);
                }

                // If we have a constructor, run the loop once for the constructor's type, and thats it.
                if (bIsConstructor)
                {
                    break;
                }
            }

            // If this is a WinRT type we have to add all collection interfaces that have this method 
            // as well so that overload resolution can find them.
            if (callingType.IsWindowsRuntimeType())
            {
                TypeArray collectioniFaces = callingType.GetWinRTCollectionIfacesAll(SymbolLoader);

                for (int i = 0; i < collectioniFaces.size; i++)
                {
                    CType t = collectioniFaces.Item(i);
                    // Collection interfaces will be aggregates.
                    Debug.Assert(t.IsAggregateType());

                    if (_symbolTable.AggregateContainsMethod(t.AsAggregateType().GetOwningAggregate(), Name, mask))
                    {
                        callingTypes.Add(t);
                    }
                }
            }

            EXPRFLAG flags = EXPRFLAG.EXF_USERCALLABLE;
            // If its a delegate, mark that on the memgroup.
            if (Name == SpecialNames.Invoke && callingObject.type.isDelegateType())
            {
                flags |= EXPRFLAG.EXF_DELEGATE;
            }

            // For a constructor, we need to seed the memgroup with the constructor flag.
            if (Name == SpecialNames.Constructor)
            {
                flags |= EXPRFLAG.EXF_CTOR;
            }

            // If we have an indexer, mark that.
            if (Name == SpecialNames.Indexer)
            {
                flags |= EXPRFLAG.EXF_INDEXER;
            }

            TypeArray typeArgumentsAsTypeArray = BSYMMGR.EmptyTypeArray();
            if (typeArguments != null && typeArguments.Count > 0)
            {
                typeArgumentsAsTypeArray = _semanticChecker.getBSymmgr().AllocParams(
                    _symbolTable.GetCTypeArrayFromTypes(typeArguments));
            }
            EXPRMEMGRP memgroup = _exprFactory.CreateMemGroup(// Tree
                flags, name, typeArgumentsAsTypeArray, kind, callingType, null, null, new CMemberLookupResults(
                    _semanticChecker.getBSymmgr().AllocParams(callingTypes.Count, callingTypes.ToArray()),
                    name));
            if (callingObject.isCLASS())
            {
                memgroup.SetOptionalLHS(callingObject);
            }
            else
            {
                memgroup.SetOptionalObject(callingObject);
            }
            return memgroup;
        }
Beispiel #3
0
        /////////////////////////////////////////////////////////////////////////////////

        private EXPR CreateProperty(
            SymWithType swt,
            EXPR callingObject,
            BindingFlag flags)
        {
            // For a property, we simply create the EXPRPROP for the thing, call the
            // expression tree rewriter, rewrite it, and send it on its way.

            PropertySymbol property = swt.Prop();
            AggregateType propertyType = swt.GetType();
            PropWithType pwt = new PropWithType(property, propertyType);
            EXPRMEMGRP pMemGroup = CreateMemberGroupEXPR(property.name.Text, null, callingObject, SYMKIND.SK_PropertySymbol);

            return _binder.BindToProperty(// For a static property instance, don't set the object.
                    callingObject.isCLASS() ? null : callingObject, pwt, flags, null, null, pMemGroup);
        }
Beispiel #4
0
        /////////////////////////////////////////////////////////////////////////////////

        private EXPR CreateField(
            SymWithType swt,
            EXPR callingObject)
        {
            // For a field, simply create the EXPRFIELD and our caller takes care of the rest.

            FieldSymbol fieldSymbol = swt.Field();
            CType returnType = fieldSymbol.GetType();
            AggregateType fieldType = swt.GetType();
            FieldWithType fwt = new FieldWithType(fieldSymbol, fieldType);

            EXPR field = _binder.BindToField(callingObject.isCLASS() ? null : callingObject, fwt, 0);
            return field;
        }
Beispiel #5
0
        /***************************************************************************************************
            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();
        }