Inheritance: NamespaceOrAggregateSymbol
示例#1
0
        internal static AggregateSymbol InitializePredefinedType(AggregateSymbol sym, PredefinedType pt)
        {
            sym.SetPredefined(true);
            sym.SetPredefType(pt);
            sym.SetSkipUDOps(pt <= PredefinedType.PT_ENUM && pt != PredefinedType.PT_INTPTR && pt != PredefinedType.PT_UINTPTR && pt != PredefinedType.PT_TYPE);

            return sym;
        }
示例#2
0
 public MethodSymbol LookupInvokeMeth(AggregateSymbol pAggDel)
 {
     Debug.Assert(pAggDel.AggKind() == AggKindEnum.Delegate);
     for (Symbol pSym = LookupAggMember(GetNameManager().GetPredefName(PredefinedName.PN_INVOKE), pAggDel, symbmask_t.MASK_ALL);
          pSym != null;
          pSym = LookupNextSym(pSym, pAggDel, symbmask_t.MASK_ALL))
     {
         if (pSym.IsMethodSymbol() && pSym.AsMethodSymbol().isInvoke())
         {
             return pSym.AsMethodSymbol();
         }
     }
     return null;
 }
示例#3
0
        // Aggregate
        public AggregateType CreateAggregateType(
            Name name,
            AggregateSymbol parent,
            TypeArray typeArgsThis,
            AggregateType outerType)
        {
            AggregateType type = new AggregateType();

            type.outerType = outerType;
            type.SetOwningAggregate(parent);
            type.SetTypeArgsThis(typeArgsThis);
            type.SetName(name);

            type.SetTypeKind(TypeKind.TK_AggregateType);
            return type;
        }
示例#4
0
        public AggregateDeclaration CreateAggregateDecl(AggregateSymbol agg, Declaration declOuter)
        {
            Debug.Assert(agg != null);
            //Debug.Assert(declOuter == null || declOuter.Bag() == agg.Parent);

            // DECLSYMs are not parented like named symbols.
            AggregateDeclaration sym = newBasicSym(SYMKIND.SK_AggregateDeclaration, agg.name, null).AsAggregateDeclaration();

            if (declOuter != null)
            {
                declOuter.AddToChildList(sym);
            }
            agg.AddDecl(sym);

            Debug.Assert(sym != null);
            return (sym);
        }
        private MethodSymbol LoadMethod(
                        AggregateSymbol type,
                        int[] signature,
                        int cMethodTyVars,
                        Name methodName,
                        ACCESS methodAccess,
                        bool isStatic,
                        bool isVirtual
                        )
        {
            Debug.Assert(signature != null);
            Debug.Assert(cMethodTyVars >= 0);
            Debug.Assert(methodName != null);

            if (type == null)
            {
                return null;
            }
            TypeArray classTyVars = type.GetTypeVarsAll();

            int index = 0;
            CType returnType = LoadTypeFromSignature(signature, ref index, classTyVars);
            if (returnType == null)
            {
                return null;
            }
            TypeArray argumentTypes = LoadTypeArrayFromSignature(signature, ref index, classTyVars);
            if (argumentTypes == null)
            {
                return null;
            }
            TypeArray standardMethodTyVars = GetTypeManager().GetStdMethTyVarArray(cMethodTyVars);

            MethodSymbol ret = LookupMethodWhileLoading(type, cMethodTyVars, methodName, methodAccess, isStatic, isVirtual, returnType, argumentTypes);

            if (ret == null)
            {
                RuntimeBinderSymbolTable.AddPredefinedMethodToSymbolTable(type, methodName);
                ret = LookupMethodWhileLoading(type, cMethodTyVars, methodName, methodAccess, isStatic, isVirtual, returnType, argumentTypes);
            }
            return ret;
        }
        private MethodSymbol FindDelegateConstructor(AggregateSymbol delegateType)
        {
            Debug.Assert(delegateType != null && delegateType.IsDelegate());

            MethodSymbol ctor = FindDelegateConstructor(delegateType, s_DelegateCtorSignature1);
            if (ctor == null)
            {
                ctor = FindDelegateConstructor(delegateType, s_DelegateCtorSignature2);
            }

            return ctor;
        }
            private bool bindImplicitConversionBetweenSimpleTypes(AggregateType aggTypeSrc)
            {
                AggregateSymbol aggSrc = aggTypeSrc.getAggregate();

                Debug.Assert(aggSrc.getThisType().isSimpleType());
                Debug.Assert(_typeDest.isSimpleType());

                Debug.Assert(aggSrc.IsPredefined() && _typeDest.isPredefined());
                PredefinedType ptSrc  = aggSrc.GetPredefType();
                PredefinedType ptDest = _typeDest.getPredefType();
                ConvKind       convertKind;
                bool           fConstShrinkCast = false;

                Debug.Assert((int)ptSrc < NUM_SIMPLE_TYPES && (int)ptDest < NUM_SIMPLE_TYPES);

                // 13.1.7 Implicit constant expression conversions
                //
                // An implicit constant expression conversion permits the following conversions:
                // *   A constant-expression (14.16) of type int can be converted to type sbyte,  byte,  short,
                //     ushort,  uint, or ulong, provided the value of the constant-expression is within the range
                //     of the destination type.
                // *   A constant-expression of type long can be converted to type ulong, provided the value of
                //     the constant-expression is not negative.
                // Note: Don't use GetConst here since the conversion only applies to bona-fide compile time constants.
                if (_exprSrc != null && _exprSrc.isCONSTANT_OK() &&
                    ((ptSrc == PredefinedType.PT_INT && ptDest != PredefinedType.PT_BOOL && ptDest != PredefinedType.PT_CHAR) ||
                     (ptSrc == PredefinedType.PT_LONG && ptDest == PredefinedType.PT_ULONG)) &&
                    isConstantInRange(_exprSrc.asCONSTANT(), _typeDest))
                {
                    // Special case (CLR 6.1.6): if integral constant is in range, the conversion is a legal implicit conversion.
                    convertKind      = ConvKind.Implicit;
                    fConstShrinkCast = _needsExprDest && (GetConvKind(ptSrc, ptDest) != ConvKind.Implicit);
                }
                else if (ptSrc == ptDest)
                {
                    // Special case: precision limiting casts to float or double
                    Debug.Assert(ptSrc == PredefinedType.PT_FLOAT || ptSrc == PredefinedType.PT_DOUBLE);
                    Debug.Assert(0 != (_flags & CONVERTTYPE.ISEXPLICIT));
                    convertKind = ConvKind.Implicit;
                }
                else
                {
                    convertKind = GetConvKind(ptSrc, ptDest);
                    Debug.Assert(convertKind != ConvKind.Identity);
                    // identity conversion should have been handled at first.
                }

                if (convertKind != ConvKind.Implicit)
                {
                    return(false);
                }

                // An implicit conversion exists. Do the conversion.
                if (_exprSrc.GetConst() != null)
                {
                    // Fold the constant cast if possible.
                    ConstCastResult result = _binder.bindConstantCast(_exprSrc, _exprTypeDest, _needsExprDest, out _exprDest, false);
                    if (result == ConstCastResult.Success)
                    {
                        return(true);  // else, don't fold and use a regular cast, below.
                    }
                }

                if (isUserDefinedConversion(ptSrc, ptDest))
                {
                    if (!_needsExprDest)
                    {
                        return(true);
                    }
                    // 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 NOUDC flag here.
                    return(_binder.bindUserDefinedConversion(_exprSrc, aggTypeSrc, _typeDest, _needsExprDest, out _exprDest, true));
                }
                if (_needsExprDest)
                {
                    _binder.bindSimpleCast(_exprSrc, _exprTypeDest, out _exprDest);
                }
                return(true);
            }
示例#8
0
        private AggregateSymbol FindPredefinedTypeCore(Name name, NamespaceOrAggregateSymbol bag, KAID aid, AggKindEnum aggKind, int arity,
                out AggregateSymbol paggAmbig, out AggregateSymbol paggBad)
        {
            AggregateSymbol aggFound = null;
            paggAmbig = null;
            paggBad = null;

            for (AggregateSymbol aggCur = _pBSymmgr.LookupGlobalSymCore(name, bag, symbmask_t.MASK_AggregateSymbol).AsAggregateSymbol();
                 aggCur != null;
                 aggCur = BSYMMGR.LookupNextSym(aggCur, bag, symbmask_t.MASK_AggregateSymbol).AsAggregateSymbol())
            {
                if (!aggCur.InAlias(aid) || aggCur.GetTypeVarsAll().size != arity)
                {
                    continue;
                }
                if (aggCur.AggKind() != aggKind)
                {
                    if (paggBad == null)
                    {
                        paggBad = aggCur;
                    }
                    continue;
                }
                if (aggFound != null)
                {
                    Debug.Assert(paggAmbig == null);
                    paggAmbig = aggCur;
                    break;
                }
                aggFound = aggCur;
                if (paggAmbig == null)
                {
                    break;
                }
            }

            return aggFound;
        }
示例#9
0
        public TypeParameterSymbol CreateClassTypeParameter(Name pName, AggregateSymbol pParent, int index, int indexTotal)
        {
            TypeParameterSymbol pResult = newBasicSym(SYMKIND.SK_TypeParameterSymbol, pName, pParent).AsTypeParameterSymbol();
            pResult.SetIndexInOwnParameters(index);
            pResult.SetIndexInTotalParameters(indexTotal);

            pResult.SetIsMethodTypeParameter(false);
            pResult.SetAccess(ACCESS.ACC_PRIVATE); // Always private - not accessible anywhere except their own type.

            return pResult;
        }
示例#10
0
        /////////////////////////////////////////////////////////////////////////////////

        private CType GetConstructedType(Type type, AggregateSymbol agg)
        {
            // We've found the one we want, so return it.
            if (type.GetTypeInfo().IsGenericType)
            {
                // If we're a generic type, then we need to add the type arguments.
                List<CType> types = new List<CType>();

                foreach (Type argument in type.GetGenericArguments())
                {
                    types.Add(GetCTypeFromType(argument));
                }

                TypeArray typeArray = _bsymmgr.AllocParams(types.ToArray());
                AggregateType aggType = _typeManager.GetAggregate(agg, typeArray);
                return aggType;
            }
            CType ctype = agg.getThisType();
            return ctype;
        }
示例#11
0
 public void InsertAggregate(
     AggregateSymbol aggregate, AggregateType outer, TypeArray args, AggregateType pAggregate)
 {
     Debug.Assert(LookupAggregate(aggregate, outer, args) == null);
     _aggregateTable.Add(MakeKey(aggregate, MakeKey(outer, args)), pAggregate);
 }
示例#12
0
            public CMethodIterator(Name name, TypeArray containingTypes, CType qualifyingType, AggregateSymbol context, int arity, EXPRFLAG flags, symbmask_t mask, ArgInfos nonTrailingNamedArguments)
            {
                Debug.Assert(name != null);
                Debug.Assert(containingTypes != null);
                Debug.Assert(containingTypes.Count != 0);

                _name                      = name;
                _containingTypes           = containingTypes;
                _qualifyingType            = qualifyingType;
                _context                   = context;
                _arity                     = arity;
                _flags                     = flags;
                _mask                      = mask;
                _nonTrailingNamedArguments = nonTrailingNamedArguments;
            }
示例#13
0
        //
        // SymbolLoader forwarders (end)
        /////////////////////////////////////////////////////////////////////////////////

        //
        // Utility methods
        //
        private ACCESSERROR CheckAccessCore(Symbol symCheck, AggregateType atsCheck, Symbol symWhere, CType typeThru)
        {
            Debug.Assert(symCheck != null);
            Debug.Assert(atsCheck == null || symCheck.parent == atsCheck.getAggregate());
            Debug.Assert(typeThru == null ||
                         typeThru is AggregateType ||
                         typeThru is TypeParameterType ||
                         typeThru is ArrayType ||
                         typeThru is NullableType ||
                         typeThru is ErrorType);

            switch (symCheck.GetAccess())
            {
            default:
                throw Error.InternalCompilerError();
            //return ACCESSERROR.ACCESSERROR_NOACCESS;

            case ACCESS.ACC_UNKNOWN:
                return(ACCESSERROR.ACCESSERROR_NOACCESS);

            case ACCESS.ACC_PUBLIC:
                return(ACCESSERROR.ACCESSERROR_NOERROR);

            case ACCESS.ACC_PRIVATE:
            case ACCESS.ACC_PROTECTED:
                if (symWhere == null)
                {
                    return(ACCESSERROR.ACCESSERROR_NOACCESS);
                }
                break;

            case ACCESS.ACC_INTERNAL:
            case ACCESS.ACC_INTERNALPROTECTED:       // Check internal, then protected.

                if (symWhere == null)
                {
                    return(ACCESSERROR.ACCESSERROR_NOACCESS);
                }
                if (symWhere.SameAssemOrFriend(symCheck))
                {
                    return(ACCESSERROR.ACCESSERROR_NOERROR);
                }
                if (symCheck.GetAccess() == ACCESS.ACC_INTERNAL)
                {
                    return(ACCESSERROR.ACCESSERROR_NOACCESS);
                }
                break;
            }

            // Find the inner-most enclosing AggregateSymbol.
            AggregateSymbol aggWhere = null;

            for (Symbol symT = symWhere; symT != null; symT = symT.parent)
            {
                if (symT is AggregateSymbol aggSym)
                {
                    aggWhere = aggSym;
                    break;
                }
                if (symT is AggregateDeclaration aggDec)
                {
                    aggWhere = aggDec.Agg();
                    break;
                }
            }

            if (aggWhere == null)
            {
                return(ACCESSERROR.ACCESSERROR_NOACCESS);
            }

            // Should always have atsCheck for private and protected access check.
            // We currently don't need it since access doesn't respect instantiation.
            // We just use symWhere.parent as AggregateSymbol instead.
            AggregateSymbol aggCheck = symCheck.parent as AggregateSymbol;

            // First check for private access.
            for (AggregateSymbol agg = aggWhere; agg != null; agg = agg.GetOuterAgg())
            {
                if (agg == aggCheck)
                {
                    return(ACCESSERROR.ACCESSERROR_NOERROR);
                }
            }

            if (symCheck.GetAccess() == ACCESS.ACC_PRIVATE)
            {
                return(ACCESSERROR.ACCESSERROR_NOACCESS);
            }

            // Handle the protected case - which is the only real complicated one.
            Debug.Assert(symCheck.GetAccess() == ACCESS.ACC_PROTECTED || symCheck.GetAccess() == ACCESS.ACC_INTERNALPROTECTED);

            // Check if symCheck is in aggWhere or a base of aggWhere,
            // or in an outer agg of aggWhere or a base of an outer agg of aggWhere.

            AggregateType atsThru = null;

            if (typeThru != null && !symCheck.isStatic)
            {
                atsThru = SymbolLoader.GetAggTypeSym(typeThru);
            }

            // Look for aggCheck among the base classes of aggWhere and outer aggs.
            bool found = false;

            for (AggregateSymbol agg = aggWhere; agg != null; agg = agg.GetOuterAgg())
            {
                Debug.Assert(agg != aggCheck); // We checked for this above.

                // Look for aggCheck among the base classes of agg.
                if (agg.FindBaseAgg(aggCheck))
                {
                    found = true;
                    // aggCheck is a base class of agg. Check atsThru.
                    // For non-static protected access to be legal, atsThru must be an instantiation of
                    // agg or a CType derived from an instantiation of agg. In this case
                    // all that matters is that agg is in the base AggregateSymbol chain of atsThru. The
                    // actual AGGTYPESYMs involved don't matter.
                    if (atsThru == null || atsThru.getAggregate().FindBaseAgg(agg))
                    {
                        return(ACCESSERROR.ACCESSERROR_NOERROR);
                    }
                }
            }

            // the CType in which the method is being called has no relationship with the
            // CType on which the method is defined surely this is NOACCESS and not NOACCESSTHRU
            if (found == false)
            {
                return(ACCESSERROR.ACCESSERROR_NOACCESS);
            }

            return((atsThru == null) ? ACCESSERROR.ACCESSERROR_NOACCESS : ACCESSERROR.ACCESSERROR_NOACCESSTHRU);
        }
示例#14
0
 public Symbol LookupAggMember(Name name, AggregateSymbol agg, symbmask_t mask)
 {
     return(getBSymmgr().LookupAggMember(name, agg, mask));
 }
示例#15
0
        private AggregateSymbol GetOptPredefAgg(PredefinedType pt, bool fEnsureState)
        {
            AggregateSymbol agg = GetTypeManager().GetOptPredefAgg(pt);

            return(agg);
        }
示例#16
0
        protected Symbol newBasicSym(
            SYMKIND kind,
            Name name,
            ParentSymbol parent)
        {
            // The parser creates names with PN_MISSING when attempting to recover from errors
            // To prevent spurious errors, we create SYMs with a different name (PN_MISSINGSYM)
            // so that they are never found when doing lookup.
            if (name == m_pMissingNameNode)
            {
                name = m_pMissingNameSym;
            }

            Symbol sym;

            switch (kind)
            {
            case SYMKIND.SK_NamespaceSymbol:
                sym      = new NamespaceSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_NamespaceDeclaration:
                sym      = new NamespaceDeclaration();
                sym.name = name;
                break;

            case SYMKIND.SK_AssemblyQualifiedNamespaceSymbol:
                sym      = new AssemblyQualifiedNamespaceSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_AggregateSymbol:
                sym      = new AggregateSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_AggregateDeclaration:
                sym      = new AggregateDeclaration();
                sym.name = name;
                break;

            case SYMKIND.SK_TypeParameterSymbol:
                sym      = new TypeParameterSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_FieldSymbol:
                sym      = new FieldSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_LocalVariableSymbol:
                sym      = new LocalVariableSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_MethodSymbol:
                sym      = new MethodSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_PropertySymbol:
                sym      = new PropertySymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_EventSymbol:
                sym      = new EventSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_TransparentIdentifierMemberSymbol:
                sym      = new TransparentIdentifierMemberSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_Scope:
                sym      = new Scope();
                sym.name = name;
                break;

            case SYMKIND.SK_LabelSymbol:
                sym      = new LabelSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_GlobalAttributeDeclaration:
                sym      = new GlobalAttributeDeclaration();
                sym.name = name;
                break;

            case SYMKIND.SK_UnresolvedAggregateSymbol:
                sym      = new UnresolvedAggregateSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_InterfaceImplementationMethodSymbol:
                sym      = new InterfaceImplementationMethodSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_IndexerSymbol:
                sym      = new IndexerSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_ParentSymbol:
                sym      = new ParentSymbol();
                sym.name = name;
                break;

            case SYMKIND.SK_IteratorFinallyMethodSymbol:
                sym      = new IteratorFinallyMethodSymbol();
                sym.name = name;
                break;

            default:
                throw Error.InternalCompilerError();
            }

            sym.setKind(kind);

            if (parent != null)
            {
                // Set the parent element of the child symbol.
                parent.AddToChildList(sym);
                m_pSymTable.InsertChild(parent, sym);
            }

            return(sym);
        }
示例#17
0
        /***************************************************************************************************
        *   Determine whether there is an explicit or implicit reference conversion (or identity conversion)
        *   from typeSrc to typeDst. This is when:
        *
        *  13.2.3 Explicit reference conversions
        *
        *  The explicit reference conversions are:
        *   From object to any reference-type.
        *   From any class-type S to any class-type T, provided S is a base class of T.
        *   From any class-type S to any interface-type T, provided S is not sealed and provided S does not implement T.
        *   From any interface-type S to any class-type T, provided T is not sealed or provided T implements S.
        *   From any interface-type S to any interface-type T, provided S is not derived from T.
        *   From an array-type S with an element type SE to an array-type T with an element type TE, provided all of the following are true:
        *   o   S and T differ only in element type. (In other words, S and T have the same number of dimensions.)
        *   o   An explicit reference conversion exists from SE to TE.
        *   From System.Array and the interfaces it implements, to any array-type.
        *   From System.Delegate and the interfaces it implements, to any delegate-type.
        *   From a one-dimensional array-type S[] to System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyList<T> and their base interfaces, provided there is an explicit reference conversion from S to T.
        *   From a generic delegate type S to generic delegate type  T, provided all of the follow are true:
        *   o Both types are constructed generic types of the same generic delegate type, D<X1,... Xk>.That is,
        *     S is D<S1,... Sk> and T is D<T1,... Tk>.
        *   o S is not compatible with or identical to T.
        *   o If type parameter Xi is declared to be invariant then Si must be identical to Ti.
        *   o If type parameter Xi is declared to be covariant ("out") then Si must be convertible
        *     to Ti via an identify conversion,  implicit reference conversion, or explicit reference conversion.
        *   o If type parameter Xi is declared to be contravariant ("in") then either Si must be identical to Ti,
        *      or Si and Ti must both be reference types.
        *   From System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyList<T> and their base interfaces to a one-dimensional array-type S[], provided there is an implicit or explicit reference conversion from S[] to System.Collections.Generic.IList<T> or System.Collections.Generic.IReadOnlyList<T>. This is precisely when either S and T are the same type or there is an implicit or explicit reference conversion from S to T.
        *
        *  For a type-parameter T that is known to be a reference type (§25.7), the following explicit reference conversions exist:
        *   From the effective base class C of T to T and from any base class of C to T.
        *   From any interface-type to T.
        *   From T to any interface-type I provided there isn’t already an implicit reference conversion from T to I.
        *   From a type-parameter U to T provided that T depends on U (§25.7). [Note: Since T is known to be a reference type, within the scope of T, the run-time type of U will always be a reference type, even if U is not known to be a reference type at compile-time. end note]
        *
        * Both src and dst are reference types and there is a builtin explicit conversion from
        *     src to dst.
        * Or src is a reference type and dst is a base type of src (in which case the conversion is
        *     implicit as well).
        * Or dst is a reference type and src is a base type of dst.
        *
        *   The latter two cases can happen with type variables even though the other type variable is not
        *   a reference type.
        ***************************************************************************************************/
        public static bool FExpRefConv(SymbolLoader loader, CType typeSrc, CType typeDst)
        {
            Debug.Assert(typeSrc != null);
            Debug.Assert(typeDst != null);
            if (typeSrc.IsRefType() && typeDst.IsRefType())
            {
                // is there an implicit reference conversion in either direction?
                // this handles the bulk of the cases ...
                if (loader.HasIdentityOrImplicitReferenceConversion(typeSrc, typeDst) ||
                    loader.HasIdentityOrImplicitReferenceConversion(typeDst, typeSrc))
                {
                    return(true);
                }

                // For a type-parameter T that is known to be a reference type (§25.7), the following explicit reference conversions exist:
                // •    From any interface-type to T.
                // •    From T to any interface-type I provided there isn’t already an implicit reference conversion from T to I.
                if (typeSrc.isInterfaceType() && typeDst.IsTypeParameterType())
                {
                    return(true);
                }
                if (typeSrc.IsTypeParameterType() && typeDst.isInterfaceType())
                {
                    return(true);
                }

                // * From any class-type S to any interface-type T, provided S is not sealed
                // * From any interface-type S to any class-type T, provided T is not sealed
                // * From any interface-type S to any interface-type T, provided S is not derived from T.
                if (typeSrc.IsAggregateType() && typeDst.IsAggregateType())
                {
                    AggregateSymbol aggSrc  = typeSrc.AsAggregateType().getAggregate();
                    AggregateSymbol aggDest = typeDst.AsAggregateType().getAggregate();

                    if ((aggSrc.IsClass() && !aggSrc.IsSealed() && aggDest.IsInterface()) ||
                        (aggSrc.IsInterface() && aggDest.IsClass() && !aggDest.IsSealed()) ||
                        (aggSrc.IsInterface() && aggDest.IsInterface()))
                    {
                        return(true);
                    }
                }

                // *    From an array-type S with an element type SE to an array-type T with an element type TE, provided all of the following are true:
                //     o    S and T differ only in element type. (In other words, S and T have the same number of dimensions.)
                //     o    An explicit reference conversion exists from SE to TE.
                if (typeSrc.IsArrayType() && typeDst.IsArrayType())
                {
                    return(typeSrc.AsArrayType().rank == typeDst.AsArrayType().rank&& FExpRefConv(loader, typeSrc.AsArrayType().GetElementType(), typeDst.AsArrayType().GetElementType()));
                }

                // *    From a one-dimensional array-type S[] to System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyList<T>
                //      and their base interfaces, provided there is an explicit reference conversion from S to T.
                if (typeSrc.IsArrayType())
                {
                    if (typeSrc.AsArrayType().rank != 1 ||
                        !typeDst.isInterfaceType() || typeDst.AsAggregateType().GetTypeArgsAll().Size != 1)
                    {
                        return(false);
                    }

                    AggregateSymbol aggIList         = loader.GetOptPredefAgg(PredefinedType.PT_G_ILIST);
                    AggregateSymbol aggIReadOnlyList = loader.GetOptPredefAgg(PredefinedType.PT_G_IREADONLYLIST);

                    if ((aggIList == null ||
                         !loader.IsBaseAggregate(aggIList, typeDst.AsAggregateType().getAggregate())) &&
                        (aggIReadOnlyList == null ||
                         !loader.IsBaseAggregate(aggIReadOnlyList, typeDst.AsAggregateType().getAggregate())))
                    {
                        return(false);
                    }

                    return(FExpRefConv(loader, typeSrc.AsArrayType().GetElementType(), typeDst.AsAggregateType().GetTypeArgsAll().Item(0)));
                }

                if (typeDst.IsArrayType() && typeSrc.IsAggregateType())
                {
                    // * From System.Array and the interfaces it implements, to any array-type.
                    if (loader.HasIdentityOrImplicitReferenceConversion(loader.GetReqPredefType(PredefinedType.PT_ARRAY), typeSrc))
                    {
                        return(true);
                    }

                    // *    From System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyList<T> and their base interfaces to a
                    //      one-dimensional array-type S[], provided there is an implicit or explicit reference conversion from S[] to
                    //      System.Collections.Generic.IList<T> or System.Collections.Generic.IReadOnlyList<T>. This is precisely when either S and T
                    //      are the same type or there is an implicit or explicit reference conversion from S to T.
                    ArrayType     arrayDest  = typeDst.AsArrayType();
                    AggregateType aggtypeSrc = typeSrc.AsAggregateType();
                    if (arrayDest.rank != 1 || !typeSrc.isInterfaceType() ||
                        aggtypeSrc.GetTypeArgsAll().Size != 1)
                    {
                        return(false);
                    }

                    AggregateSymbol aggIList         = loader.GetOptPredefAgg(PredefinedType.PT_G_ILIST);
                    AggregateSymbol aggIReadOnlyList = loader.GetOptPredefAgg(PredefinedType.PT_G_IREADONLYLIST);

                    if ((aggIList == null ||
                         !loader.IsBaseAggregate(aggIList, aggtypeSrc.getAggregate())) &&
                        (aggIReadOnlyList == null ||
                         !loader.IsBaseAggregate(aggIReadOnlyList, aggtypeSrc.getAggregate())))
                    {
                        return(false);
                    }

                    CType typeArr = arrayDest.GetElementType();
                    CType typeLst = aggtypeSrc.GetTypeArgsAll().Item(0);

                    Debug.Assert(!typeArr.IsNeverSameType());
                    return(typeArr == typeLst || FExpRefConv(loader, typeArr, typeLst));
                }
                if (HasGenericDelegateExplicitReferenceConversion(loader, typeSrc, typeDst))
                {
                    return(true);
                }
            }
            else if (typeSrc.IsRefType())
            {
                // conversion of T . U, where T : class, U
                // .. these constraints implies where U : class
                return(loader.HasIdentityOrImplicitReferenceConversion(typeSrc, typeDst));
            }
            else if (typeDst.IsRefType())
            {
                // conversion of T . U, where U : class, T
                // .. these constraints implies where T : class
                return(loader.HasIdentityOrImplicitReferenceConversion(typeDst, typeSrc));
            }
            return(false);
        }
示例#18
0
        public bool computeManagedType(SymbolLoader symbolLoader)
        {
            if (IsVoidType())
            {
                return(false);
            }

            switch (fundType())
            {
            case FUNDTYPE.FT_NONE:
            case FUNDTYPE.FT_REF:
            case FUNDTYPE.FT_VAR:
                return(true);

            case FUNDTYPE.FT_STRUCT:
                if (IsNullableType())
                {
                    return(true);
                }
                else
                {
                    AggregateSymbol aggT = getAggregate();

                    // See if we already know.
                    if (aggT.IsKnownManagedStructStatus())
                    {
                        return(aggT.IsManagedStruct());
                    }

                    // Generics are always managed.
                    if (aggT.GetTypeVarsAll().Count > 0)
                    {
                        aggT.SetManagedStruct(true);
                        return(true);
                    }

                    // If the struct layout has an error, don't recurse its children.
                    if (aggT.IsLayoutError())
                    {
                        aggT.SetUnmanagedStruct(true);
                        return(false);
                    }

                    // at this point we can only determine the managed status
                    // if we have members defined, otherwise we don't know the result
                    if (symbolLoader != null)
                    {
                        for (Symbol ps = aggT.firstChild; ps != null; ps = ps.nextChild)
                        {
                            if (ps.IsFieldSymbol() && !ps.AsFieldSymbol().isStatic)
                            {
                                CType type = ps.AsFieldSymbol().GetType();
                                if (type.computeManagedType(symbolLoader))
                                {
                                    aggT.SetManagedStruct(true);
                                    return(true);
                                }
                            }
                        }

                        aggT.SetUnmanagedStruct(true);
                    }

                    return(false);
                }

            default:
                return(false);
            }
        }
示例#19
0
        /////////////////////////////////////////////////////////////////////////////////

        private void SetInterfacesOnAggregate(AggregateSymbol aggregate, Type type)
        {
            Type[] interfaces;

            if (type.GetTypeInfo().IsGenericType)
            {
                type = type.GetTypeInfo().GetGenericTypeDefinition();
            }
            interfaces = type.GetTypeInfo().ImplementedInterfaces.ToArray();

            // We wont be able to find the difference between Ifaces and 
            // IfacesAll anymore - at runtime, the class implements all of its
            // Ifaces and IfacesAll, so theres no way to differentiate.
            //
            // This actually doesn't matter though - for conversions and methodcalls,
            // we don't really care where they've come from as long as we know the overall
            // set of IfacesAll.

            aggregate.SetIfaces(_bsymmgr.AllocParams(interfaces.Length, GetCTypeArrayFromTypes(interfaces)));
            aggregate.SetIfacesAll(aggregate.GetIfaces());
        }
示例#20
0
        private EventSymbol AddEventToSymbolTable(EventInfo eventInfo, AggregateSymbol aggregate, FieldSymbol addedField)
        {
            EventSymbol ev = _symbolTable.LookupSym(
                GetName(eventInfo.Name),
                aggregate,
                symbmask_t.MASK_EventSymbol) as EventSymbol;
            if (ev != null)
            {
                Debug.Assert(ev.AssociatedEventInfo == eventInfo);
                return ev;
            }

            ev = _symFactory.CreateEvent(GetName(eventInfo.Name), aggregate, null);
            ev.AssociatedEventInfo = eventInfo;

            // EventSymbol
            ACCESS access = ACCESS.ACC_PRIVATE;
            if (eventInfo.AddMethod != null)
            {
                ev.methAdd = AddMethodToSymbolTable(eventInfo.AddMethod, aggregate, MethodKindEnum.EventAccessor);
                ev.methAdd.SetEvent(ev);
                ev.isOverride = ev.methAdd.IsOverride();

                access = ev.methAdd.GetAccess();
            }
            if (eventInfo.RemoveMethod != null)
            {
                ev.methRemove = AddMethodToSymbolTable(eventInfo.RemoveMethod, aggregate, MethodKindEnum.EventAccessor);
                ev.methRemove.SetEvent(ev);
                ev.isOverride = ev.methRemove.IsOverride();

                access = ev.methRemove.GetAccess();
            }
            Debug.Assert(ev.methAdd != null || ev.methRemove != null);
            ev.isStatic = false;
            ev.type = GetCTypeFromType(eventInfo.EventHandlerType);

            // Symbol
            ev.SetAccess(access);

            Type eventRegistrationTokenType = EventRegistrationTokenType;
            if ((object)eventRegistrationTokenType != null && (object)WindowsRuntimeMarshalType != null &&
                ev.methAdd.RetType.AssociatedSystemType == eventRegistrationTokenType &&
                ev.methRemove.Params.Item(0).AssociatedSystemType == eventRegistrationTokenType)
            {
                ev.IsWindowsRuntimeEvent = true;
            }

            // If we imported a field on the same aggregate, with the same name, and it also
            // has the same type, then that field is the backing field for this event, and
            // we mark it as such. This is used for the CSharpIsEventBinder.
            // In the case of a WindowsRuntime event, the field will be of type
            // EventRegistrationTokenTable<delegateType>.
            Type eventRegistrationTokenTableType;
            if (addedField != null && addedField.GetType() != null &&
                (addedField.GetType() == ev.type ||
                (
                    addedField.GetType().AssociatedSystemType.IsConstructedGenericType &&
                    (object)(eventRegistrationTokenTableType = EventRegistrationTokenTableType) != null &&
                    addedField.GetType().AssociatedSystemType.GetGenericTypeDefinition() == eventRegistrationTokenTableType &&
                    addedField.GetType().AssociatedSystemType.GenericTypeArguments[0] == ev.type.AssociatedSystemType)
                ))
            {
                addedField.isEvent = true;
            }

            return ev;
        }
            private AggCastResult bindExplicitConversionBetweenSimpleTypes(AggregateType aggTypeDest)
            {
                // 13.2.1
                //
                // Because the explicit conversions include all implicit and explicit numeric conversions,
                // it is always possible to convert from any numeric-type to any other numeric-type using
                // a cast expression (14.6.6).

                Debug.Assert(_typeSrc != null);
                Debug.Assert(aggTypeDest != null);

                if (!_typeSrc.isSimpleType() || !aggTypeDest.isSimpleType())
                {
                    return(AggCastResult.Failure);
                }

                AggregateSymbol aggDest = aggTypeDest.getAggregate();

                Debug.Assert(_typeSrc.isPredefined() && aggDest.IsPredefined());

                PredefinedType ptSrc  = _typeSrc.getPredefType();
                PredefinedType ptDest = aggDest.GetPredefType();

                Debug.Assert((int)ptSrc < NUM_SIMPLE_TYPES && (int)ptDest < NUM_SIMPLE_TYPES);

                ConvKind convertKind = GetConvKind(ptSrc, ptDest);

                // Identity and implicit conversions should already have been handled.
                Debug.Assert(convertKind != ConvKind.Implicit);
                Debug.Assert(convertKind != ConvKind.Identity);

                if (convertKind != ConvKind.Explicit)
                {
                    return(AggCastResult.Failure);
                }

                if (_exprSrc.GetConst() != null)
                {
                    // Fold the constant cast if possible.
                    ConstCastResult result = _binder.bindConstantCast(_exprSrc, _exprTypeDest, _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);
                    }
                }

                bool bConversionOk = true;

                if (_needsExprDest)
                {
                    // Explicit conversions involving decimals are bound as user-defined conversions.
                    if (isUserDefinedConversion(ptSrc, ptDest))
                    {
                        // 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.
                        bConversionOk = _binder.bindUserDefinedConversion(_exprSrc, _typeSrc, aggTypeDest, _needsExprDest, out _exprDest, false);
                    }
                    else
                    {
                        _binder.bindSimpleCast(_exprSrc, _exprTypeDest, out _exprDest, (_flags & CONVERTTYPE.CHECKOVERFLOW) != 0 ? EXPRFLAG.EXF_CHECKOVERFLOW : 0);
                    }
                }
                return(bConversionOk ? AggCastResult.Success : AggCastResult.Failure);
            }
示例#22
0
        /////////////////////////////////////////////////////////////////////////////////

        private TypeParameterType AddTypeParameterToSymbolTable(
                AggregateSymbol agg,
                MethodSymbol meth,
                Type t,
                bool bIsAggregate)
        {
            Debug.Assert((agg != null && bIsAggregate) || (meth != null && !bIsAggregate));

            TypeParameterSymbol typeParam;
            if (bIsAggregate)
            {
                typeParam = _symFactory.CreateClassTypeParameter(
                    GetName(t),
                    agg,
                    t.GenericParameterPosition,
                    t.GenericParameterPosition);
            }
            else
            {
                typeParam = _symFactory.CreateMethodTypeParameter(
                    GetName(t),
                    meth,
                    t.GenericParameterPosition,
                    t.GenericParameterPosition);
            }

            if ((t.GetTypeInfo().GenericParameterAttributes & GenericParameterAttributes.Covariant) != 0)
            {
                typeParam.Covariant = true;
            }
            if ((t.GetTypeInfo().GenericParameterAttributes & GenericParameterAttributes.Contravariant) != 0)
            {
                typeParam.Contravariant = true;
            }

            SpecCons cons = SpecCons.None;

            if ((t.GetTypeInfo().GenericParameterAttributes & GenericParameterAttributes.DefaultConstructorConstraint) != 0)
            {
                cons |= SpecCons.New;
            }
            if ((t.GetTypeInfo().GenericParameterAttributes & GenericParameterAttributes.ReferenceTypeConstraint) != 0)
            {
                cons |= SpecCons.Ref;
            }
            if ((t.GetTypeInfo().GenericParameterAttributes & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0)
            {
                cons |= SpecCons.Val;
            }

            typeParam.SetConstraints(cons);
            typeParam.SetAccess(ACCESS.ACC_PUBLIC);
            TypeParameterType typeParamType = _typeManager.GetTypeParameter(typeParam);

            return typeParamType;
        }
示例#23
0
 public static string GetNiceName(AggregateSymbol type) =>
 type.IsPredefined() ? GetNiceName(type.GetPredefType()) : null;
示例#24
0
        private AggregateSymbol FindPredefinedTypeCore(Name name, NamespaceOrAggregateSymbol bag, KAID aid, AggKindEnum aggKind, int arity,
                                                       out AggregateSymbol paggAmbig, out AggregateSymbol paggBad)
        {
            AggregateSymbol aggFound = null;

            paggAmbig = null;
            paggBad   = null;

            for (AggregateSymbol aggCur = _pBSymmgr.LookupGlobalSymCore(name, bag, symbmask_t.MASK_AggregateSymbol).AsAggregateSymbol();
                 aggCur != null;
                 aggCur = BSYMMGR.LookupNextSym(aggCur, bag, symbmask_t.MASK_AggregateSymbol).AsAggregateSymbol())
            {
                if (!aggCur.InAlias(aid) || aggCur.GetTypeVarsAll().size != arity)
                {
                    continue;
                }
                if (aggCur.AggKind() != aggKind)
                {
                    if (paggBad == null)
                    {
                        paggBad = aggCur;
                    }
                    continue;
                }
                if (aggFound != null)
                {
                    Debug.Assert(paggAmbig == null);
                    paggAmbig = aggCur;
                    break;
                }
                aggFound = aggCur;
                if (paggAmbig == null)
                {
                    break;
                }
            }

            return(aggFound);
        }
示例#25
0
 public static Symbol LookupAggMember(Name name, AggregateSymbol agg, symbmask_t mask) => SymbolStore.LookupSym(name, agg, mask);
示例#26
0
 public Symbol LookupAggMember(Name name, AggregateSymbol agg, symbmask_t mask)
 {
     return(tableGlobal.LookupSym(name, agg, mask));
 }
        /*
         * returns the inputfile where a symbol was declared.
         *
         * returns null for namespaces because they can be declared
         * in multiple files.
         */
        public InputFile getInputFile()
        {
            switch (kind)
            {
            case SYMKIND.SK_NamespaceSymbol:
            case SYMKIND.SK_AssemblyQualifiedNamespaceSymbol:
                // namespaces don't have input files
                // call with a NamespaceDeclaration instead
                Debug.Assert(false);
                return(null);

            case SYMKIND.SK_NamespaceDeclaration:
                return(null);

            case SYMKIND.SK_AggregateSymbol:
            {
#if !CSEE
                AggregateSymbol AggregateSymbol = this.AsAggregateSymbol();
                if (!AggregateSymbol.IsSource())
                {
                    return(AggregateSymbol.DeclOnly().getInputFile());
                }

                // Because an AggregateSymbol that isn't metadata can be defined across multiple
                // files, getInputFile isn't a reasonable operation.
                Debug.Assert(false);
                return(null);
#endif
            }

            /*
             * case SK_AggregateType:
             *  return ((Symbol)this.AsAggregateType().getAggregate()).getInputFile();
             */

            case SYMKIND.SK_AggregateDeclaration:
                return(this.AsAggregateDeclaration().getInputFile());

            /*
             * case SK_TypeParameterType:
             *  if (this.AsTypeParameterType().GetOwningSymbol().IsAggregateSymbol())
             *  {
             *      ASSERT(0);
             *      return null;
             *  }
             *  else
             *  {
             *      ASSERT(this.AsTypeParameterType().GetOwningSymbol().IsMethodSymbol());
             *      return AsTypeParameterType().GetOwningSymbol().AsMethodSymbol().getInputFile();
             *  }
             */
            case SYMKIND.SK_TypeParameterSymbol:
                if (this.parent.IsAggregateSymbol())
                {
                    // Because an AggregateSymbol that isn't metadata can be defined across multiple
                    // files, getInputFile isn't a reasonable operation.
                    Debug.Assert(false);
                    return(null);
                }
                else if (this.parent.IsMethodSymbol())
                {
                    return(this.parent.AsMethodSymbol().getInputFile());
                }
                Debug.Assert(false);
                break;

            case SYMKIND.SK_FieldSymbol:
                return(this.AsFieldSymbol().containingDeclaration().getInputFile());

            case SYMKIND.SK_MethodSymbol:
                return(this.AsMethodSymbol().containingDeclaration().getInputFile());

            case SYMKIND.SK_PropertySymbol:
                return(this.AsPropertySymbol().containingDeclaration().getInputFile());

            case SYMKIND.SK_EventSymbol:
                return(this.AsEventSymbol().containingDeclaration().getInputFile());

            /*
             * case SK_PointerType:
             * case SK_NullableType:
             * case SK_ArrayType:
             * case SK_PinnedType:
             * case SK_ParameterModifierType:
             * case SK_OptionalModifierType:
             *  return AsType().GetBaseOrParameterOrElementType().getInputFile();
             */

            case SYMKIND.SK_GlobalAttributeDeclaration:
                return(parent.getInputFile());

            /*
             * case SK_NullType:
             * case SK_VoidType:
             *  return null;
             */

            default:
                Debug.Assert(false);
                break;
            }

            return(null);
        }
示例#28
0
 public static string GetNiceName(AggregateSymbol type)
 {
     if (type.IsPredefined())
         return GetNiceName(type.GetPredefType());
     else
         return null;
 }
示例#29
0
        private bool TryVarianceAdjustmentToGetAccessibleType(CSemanticChecker semanticChecker, BindingContext bindingContext, AggregateType typeSrc, out CType typeDst)
        {
            Debug.Assert(typeSrc != null);
            Debug.Assert(typeSrc.isInterfaceType() || typeSrc.isDelegateType());

            typeDst = null;

            AggregateSymbol aggSym      = typeSrc.GetOwningAggregate();
            AggregateType   aggOpenType = aggSym.getThisType();

            if (!semanticChecker.CheckTypeAccess(aggOpenType, bindingContext.ContextForMemberLookup))
            {
                // if the aggregate symbol itself is not accessible, then forget it, there is no
                // variance that will help us arrive at an accessible type.
                return(false);
            }

            TypeArray typeArgs   = typeSrc.GetTypeArgsThis();
            TypeArray typeParams = aggOpenType.GetTypeArgsThis();

            CType[] newTypeArgsTemp = new CType[typeArgs.Count];

            for (int i = 0; i < typeArgs.Count; i++)
            {
                if (semanticChecker.CheckTypeAccess(typeArgs[i], bindingContext.ContextForMemberLookup))
                {
                    // we have an accessible argument, this position is not a problem.
                    newTypeArgsTemp[i] = typeArgs[i];
                    continue;
                }

                if (!typeArgs[i].IsRefType() || !((TypeParameterType)typeParams[i]).Covariant)
                {
                    // This guy is inaccessible, and we are not going to be able to vary him, so we need to fail.
                    return(false);
                }

                CType intermediateTypeArg;
                if (GetBestAccessibleType(semanticChecker, bindingContext, typeArgs[i], out intermediateTypeArg))
                {
                    // now we either have a value type (which must be accessible due to the above
                    // check, OR we have an inaccessible type (which must be a ref type). In either
                    // case, the recursion worked out and we are OK to vary this argument.
                    newTypeArgsTemp[i] = intermediateTypeArg;
                    continue;
                }
                else
                {
                    Debug.Assert(false, "GetBestAccessibleType unexpectedly failed on a type that was used as a type parameter");
                    return(false);
                }
            }

            TypeArray newTypeArgs      = semanticChecker.getBSymmgr().AllocParams(typeArgs.Count, newTypeArgsTemp);
            CType     intermediateType = this.GetAggregate(aggSym, typeSrc.outerType, newTypeArgs);

            // All type arguments were varied successfully, which means now we must be accessible. But we could
            // have violated constraints. Let's check that out.

            if (!TypeBind.CheckConstraints(semanticChecker, null /*ErrorHandling*/, intermediateType, CheckConstraintsFlags.NoErrors))
            {
                return(false);
            }

            typeDst = intermediateType;
            Debug.Assert(semanticChecker.CheckTypeAccess(typeDst, bindingContext.ContextForMemberLookup));
            return(true);
        }
示例#30
0
        // delegate specific helpers
        private MethodSymbol FindDelegateConstructor(AggregateSymbol delegateType, int[] signature)
        {
            Debug.Assert(delegateType != null && delegateType.IsDelegate());
            Debug.Assert(signature != null);

            return LoadMethod(
                                delegateType,
                                signature,
                                0,                          // meth ty vars
                                GetPredefName(PredefinedName.PN_CTOR),
                                ACCESS.ACC_PUBLIC,
                                false,                      // MethodCallingConventionEnum.Static
                                false);                     // MethodCallingConventionEnum.Virtual
        }
示例#31
0
        public AggregateType GetAggregate(AggregateSymbol agg, AggregateType atsOuter, TypeArray typeArgs)
        {
            Debug.Assert(agg.GetTypeManager() == this);
            Debug.Assert(atsOuter == null || atsOuter.getAggregate() == agg.Parent, "");

            if (typeArgs == null)
            {
                typeArgs = BSYMMGR.EmptyTypeArray();
            }

            Debug.Assert(agg.GetTypeVars().Count == typeArgs.Count);

            Name name = _BSymmgr.GetNameFromPtrs(typeArgs, atsOuter);

            Debug.Assert(name != null);

            AggregateType pAggregate = _typeTable.LookupAggregate(name, agg);

            if (pAggregate == null)
            {
                pAggregate = _typeFactory.CreateAggregateType(
                    name,
                    agg,
                    typeArgs,
                    atsOuter
                    );

                Debug.Assert(!pAggregate.fConstraintsChecked && !pAggregate.fConstraintError);

                pAggregate.SetErrors(false);
                _typeTable.InsertAggregate(name, agg, pAggregate);

                // If we have a generic type definition, then we need to set the
                // base class to be our current base type, and use that to calculate
                // our agg type and its base, then set it to be the generic version of the
                // base type. This is because:
                //
                // Suppose we have Foo<T> : IFoo<T>
                //
                // Initially, the BaseType will be IFoo<Foo.T>, which gives us the substitution
                // that we want to use for our agg type's base type. However, in the Symbol chain,
                // we want the base type to be IFoo<IFoo.T>. Thats why we need to do this little trick.
                //
                // If we don't have a generic type definition, then we just need to set our base
                // class. This is so that if we have a base type that's generic, we'll be
                // getting the correctly instantiated base type.

                var baseType = pAggregate.AssociatedSystemType?.BaseType;
                if (baseType != null)
                {
                    // Store the old base class.

                    AggregateType oldBaseType = agg.GetBaseClass();
                    agg.SetBaseClass(_symbolTable.GetCTypeFromType(baseType) as AggregateType);
                    pAggregate.GetBaseClass(); // Get the base type for the new agg type we're making.

                    agg.SetBaseClass(oldBaseType);
                }
            }
            else
            {
                Debug.Assert(!pAggregate.HasErrors());
            }

            Debug.Assert(pAggregate.getAggregate() == agg);
            Debug.Assert(pAggregate.GetTypeArgsThis() != null && pAggregate.GetTypeArgsAll() != null);
            Debug.Assert(pAggregate.GetTypeArgsThis() == typeArgs);

            return(pAggregate);
        }
示例#32
0
        public MethodSymbol FindDelegateConstructor(AggregateSymbol delegateType, bool fReportErrors)
        {
            MethodSymbol ctor = FindDelegateConstructor(delegateType);
            if (ctor == null && fReportErrors)
            {
                GetErrorContext().Error(ErrorCode.ERR_BadDelegateConstructor, delegateType);
            }

            return ctor;
            throw Error.InternalCompilerError();
        }
示例#33
0
        /////////////////////////////////////////////////////////////////////////////////

        private PropertySymbol AddPropertyToSymbolTable(PropertyInfo property, AggregateSymbol aggregate)
        {
            Name name;
            bool isIndexer = property.GetIndexParameters() != null && property.GetIndexParameters().Length != 0;

            if (isIndexer)
            {
                name = GetName(SpecialNames.Indexer);
            }
            else
            {
                name = GetName(property.Name);
            }
            PropertySymbol prop = _symbolTable.LookupSym(
                name,
                aggregate,
                symbmask_t.MASK_PropertySymbol) as PropertySymbol;

            // If we already had one, see if it matches.
            if (prop != null)
            {
                PropertySymbol prevProp = null;

                // We'll have multiple properties with the same name if we have indexers.
                // In that case, we need to look at every indexer to see if we find one with
                // the matching associated sym that we want.
                while (prop != null)
                {
                    if (prop.AssociatedPropertyInfo.IsEquivalentTo(property))
                    {
                        return prop;
                    }

                    prevProp = prop;
                    prop = _semanticChecker.SymbolLoader.LookupNextSym(prop, prop.parent, symbmask_t.MASK_PropertySymbol).AsPropertySymbol();
                }

                prop = prevProp;
                if (isIndexer)
                {
                    // We have an indexer for a different property info, so 
                    // create a new symbol for it.
                    prop = null;
                }
            }

            // If we already had a property but its associated info doesn't match,
            // then we repurpose the property that we've found. This can happen
            // in the case of generic instantiations. 
            //
            // Note that this is a bit of a hack - the best way to fix this is 
            // by not depending on the instantiated properties at all, but rather depending
            // on their non-instantiated generic form, which can be gotten from the
            // parent's generic type definition's member. From there, we'll also need to 
            // keep track of the instantiation as we move along, so that when we need the
            // associated property, we can instantiate it correctly.
            //
            // This seems far too heavyweight - since we know we will never bind to more
            // than one property per payload, lets just blast it each time.
            if (prop == null)
            {
                if (isIndexer)
                {
                    prop = _semanticChecker.GetSymbolLoader().GetGlobalMiscSymFactory().CreateIndexer(name, aggregate, GetName(property.Name), null);
                    prop.Params = CreateParameterArray(null, property.GetIndexParameters());
                }
                else
                {
                    prop = _symFactory.CreateProperty(GetName(property.Name), aggregate, null);
                    prop.Params = BSYMMGR.EmptyTypeArray();
                }
            }
            prop.AssociatedPropertyInfo = property;

            prop.isStatic = property.GetGetMethod(true) != null ? property.GetGetMethod(true).IsStatic : property.GetSetMethod(true).IsStatic;
            prop.isParamArray = DoesMethodHaveParameterArray(property.GetIndexParameters());
            prop.swtSlot = null;
            prop.RetType = GetCTypeFromType(property.PropertyType);
            prop.isOperator = isIndexer;

            // Determine if its an override. We should always have an accessor, unless
            // the metadata was bogus.
            if (property.GetMethod != null || property.SetMethod != null)
            {
                MethodInfo accessor = property.GetMethod ?? property.SetMethod; // Must have at least one.
                prop.isOverride = accessor.IsVirtual && accessor.IsHideBySig && accessor.GetRuntimeBaseDefinition() != accessor;
                prop.isHideByName = !accessor.IsHideBySig;
            }

            SetParameterDataForMethProp(prop, property.GetIndexParameters());

            // Get and set.
            MethodInfo methGet = property.GetMethod;
            MethodInfo methSet = property.SetMethod;
            ACCESS access = ACCESS.ACC_PRIVATE;
            if (methGet != null)
            {
                prop.methGet = AddMethodToSymbolTable(methGet, aggregate, MethodKindEnum.PropAccessor);

                // If we have an indexed property, leave the method as a method we can call,
                // and mark the property as bogus.
                if (isIndexer || prop.methGet.Params.size == 0)
                {
                    prop.methGet.SetProperty(prop);
                }
                else
                {
                    prop.setBogus(true);
                    prop.methGet.SetMethKind(MethodKindEnum.Actual);
                }

                if (prop.methGet.GetAccess() > access)
                {
                    access = prop.methGet.GetAccess();
                }
            }
            if (methSet != null)
            {
                prop.methSet = AddMethodToSymbolTable(methSet, aggregate, MethodKindEnum.PropAccessor);

                // If we have an indexed property, leave the method as a method we can call,
                // and mark the property as bogus.
                if (isIndexer || prop.methSet.Params.size == 1)
                {
                    prop.methSet.SetProperty(prop);
                }
                else
                {
                    prop.setBogus(true);
                    prop.methSet.SetMethKind(MethodKindEnum.Actual);
                }

                if (prop.methSet.GetAccess() > access)
                {
                    access = prop.methSet.GetAccess();
                }
            }

            // The access of the property is the least restrictive access of its getter/setter.
            prop.SetAccess(access);

            return prop;
        }
示例#34
0
 private MethodSymbol LookupMethodWhileLoading(AggregateSymbol type, int cMethodTyVars, Name methodName, ACCESS methodAccess, bool isStatic, bool isVirtual, CType returnType, TypeArray argumentTypes)
 {
     for (Symbol sym = GetSymbolLoader().LookupAggMember(methodName, type, symbmask_t.MASK_ALL);
          sym != null;
          sym = GetSymbolLoader().LookupNextSym(sym, type, symbmask_t.MASK_ALL))
     {
         if (sym.IsMethodSymbol())
         {
             MethodSymbol methsym = sym.AsMethodSymbol();
             if ((methsym.GetAccess() == methodAccess || methodAccess == ACCESS.ACC_UNKNOWN) &&
                 methsym.isStatic == isStatic &&
                 methsym.isVirtual == isVirtual &&
                 methsym.typeVars.size == cMethodTyVars &&
                 GetTypeManager().SubstEqualTypes(methsym.RetType, returnType, null, methsym.typeVars, SubstTypeFlags.DenormMeth) &&
                 GetTypeManager().SubstEqualTypeArrays(methsym.Params, argumentTypes, (TypeArray)null,
                     methsym.typeVars, SubstTypeFlags.DenormMeth) &&
                 !methsym.getBogus())
             {
                 return methsym;
             }
         }
     }
     return null;
 }
示例#35
0
        /////////////////////////////////////////////////////////////////////////////////

        private MethodSymbol AddMethodToSymbolTable(MemberInfo member, AggregateSymbol callingAggregate, MethodKindEnum kind)
        {
            MethodInfo method = member as MethodInfo;
            ConstructorInfo ctor = member as ConstructorInfo;

            Debug.Assert(method != null || ctor != null);
#if UNSUPPORTEDAPI
            Debug.Assert(member.DeclaringType == member.ReflectedType);
#endif
            // If we are trying to add an actual method via MethodKindEnum.Actual, and 
            // the memberinfo is a special name, and its not static, then return null. 
            // We'll re-add the thing later with some other method kind.
            //
            // This will happen for things like indexers and properties. The ones that have
            // special names that we DO want to allow adding are things like operators, which
            // are static and will not be added again later.

            if (kind == MethodKindEnum.Actual && // MethKindEnum.Actual
                (method == null || // Not a ConstructorInfo
                    (!method.IsStatic && method.IsSpecialName))) // Not static and is a special name
            {
                return null;
            }

            MethodSymbol methodSymbol = FindMatchingMethod(member, callingAggregate);
            if (methodSymbol != null)
            {
                return methodSymbol;
            }

            ParameterInfo[] parameters = method != null ? method.GetParameters() : ctor.GetParameters();
            // First create the method.
            methodSymbol = _symFactory.CreateMethod(GetName(member.Name), callingAggregate, null);
            methodSymbol.AssociatedMemberInfo = member;
            methodSymbol.SetMethKind(kind);
            if (kind == MethodKindEnum.ExplicitConv || kind == MethodKindEnum.ImplicitConv)
            {
                callingAggregate.SetHasConversion();
                methodSymbol.SetConvNext(callingAggregate.GetFirstUDConversion());
                callingAggregate.SetFirstUDConversion(methodSymbol);
            }
            ACCESS access;
            if (method != null)
            {
                if (method.IsPublic)
                {
                    access = ACCESS.ACC_PUBLIC;
                }
                else if (method.IsPrivate)
                {
                    access = ACCESS.ACC_PRIVATE;
                }
                else if (method.IsFamily)
                {
                    access = ACCESS.ACC_PROTECTED;
                }
                else if (method.IsAssembly || method.IsFamilyAndAssembly)
                {
                    access = ACCESS.ACC_INTERNAL;
                }
                else
                {
                    Debug.Assert(method.IsFamilyOrAssembly);
                    access = ACCESS.ACC_INTERNALPROTECTED;
                }
            }
            else
            {
                Debug.Assert(ctor != null);
                if (ctor.IsPublic)
                {
                    access = ACCESS.ACC_PUBLIC;
                }
                else if (ctor.IsPrivate)
                {
                    access = ACCESS.ACC_PRIVATE;
                }
                else if (ctor.IsFamily)
                {
                    access = ACCESS.ACC_PROTECTED;
                }
                else if (ctor.IsAssembly || ctor.IsFamilyAndAssembly)
                {
                    access = ACCESS.ACC_INTERNAL;
                }
                else
                {
                    Debug.Assert(ctor.IsFamilyOrAssembly);
                    access = ACCESS.ACC_INTERNALPROTECTED;
                }
            }
            methodSymbol.SetAccess(access);

            methodSymbol.isExtension = false; // We don't support extension methods.
            methodSymbol.isExternal = false;

            if (method != null)
            {
                methodSymbol.typeVars = GetMethodTypeParameters(method, methodSymbol);
                methodSymbol.isVirtual = method.IsVirtual;
                methodSymbol.isAbstract = method.IsAbstract;
                methodSymbol.isStatic = method.IsStatic;
                methodSymbol.isOverride = method.IsVirtual && method.IsHideBySig && method.GetRuntimeBaseDefinition() != method;
                methodSymbol.isOperator = IsOperator(method);
                methodSymbol.swtSlot = GetSlotForOverride(method);
                methodSymbol.isVarargs = (method.CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs;
                methodSymbol.RetType = GetCTypeFromType(method.ReturnType);
            }
            else
            {
                methodSymbol.typeVars = BSYMMGR.EmptyTypeArray();
                methodSymbol.isVirtual = ctor.IsVirtual;
                methodSymbol.isAbstract = ctor.IsAbstract;
                methodSymbol.isStatic = ctor.IsStatic;
                methodSymbol.isOverride = false;
                methodSymbol.isOperator = false;
                methodSymbol.swtSlot = null;
                methodSymbol.isVarargs = false;
                methodSymbol.RetType = _typeManager.GetVoid();
            }
            methodSymbol.modOptCount = GetCountOfModOpts(parameters);

            methodSymbol.useMethInstead = false;
            methodSymbol.isParamArray = DoesMethodHaveParameterArray(parameters);
            methodSymbol.isHideByName = false;

            methodSymbol.errExpImpl = null;
            methodSymbol.Params = CreateParameterArray(methodSymbol.AssociatedMemberInfo, parameters);
            methodSymbol.declaration = null;

            SetParameterDataForMethProp(methodSymbol, parameters);

            return methodSymbol;
        }
示例#36
0
        /////////////////////////////////////////////////////////////////////////////////

        private FieldSymbol AddFieldToSymbolTable(FieldInfo fieldInfo, AggregateSymbol aggregate)
        {
            FieldSymbol field = _symbolTable.LookupSym(
                GetName(fieldInfo.Name),
                aggregate,
                symbmask_t.MASK_FieldSymbol) as FieldSymbol;
            if (field != null)
            {
                return field;
            }

            field = _symFactory.CreateMemberVar(GetName(fieldInfo.Name), aggregate, null, 0);
            field.AssociatedFieldInfo = fieldInfo;

            field.isStatic = fieldInfo.IsStatic;
            ACCESS access;
            if (fieldInfo.IsPublic)
            {
                access = ACCESS.ACC_PUBLIC;
            }
            else if (fieldInfo.IsPrivate)
            {
                access = ACCESS.ACC_PRIVATE;
            }
            else if (fieldInfo.IsFamily)
            {
                access = ACCESS.ACC_PROTECTED;
            }
            else if (fieldInfo.IsAssembly || fieldInfo.IsFamilyAndAssembly)
            {
                access = ACCESS.ACC_INTERNAL;
            }
            else
            {
                Debug.Assert(fieldInfo.IsFamilyOrAssembly);
                access = ACCESS.ACC_INTERNALPROTECTED;
            }
            field.SetAccess(access);
            field.isReadOnly = fieldInfo.IsInitOnly;
            field.isEvent = false;
            field.isAssigned = true;
            field.SetType(GetCTypeFromType(fieldInfo.FieldType));

            return field;
        }
示例#37
0
        /////////////////////////////////////////////////////////////////////////////////

        private TypeArray GetAggregateTypeParameters(Type type, AggregateSymbol agg)
        {
            if (type.GetTypeInfo().IsGenericType)
            {
                Type genericDefinition = type.GetTypeInfo().GetGenericTypeDefinition();
                Type[] genericArguments = genericDefinition.GetGenericArguments();
                List<CType> ctypes = new List<CType>();
                int outerParameters = agg.isNested() ? agg.GetOuterAgg().GetTypeVarsAll().size : 0;

                for (int i = 0; i < genericArguments.Length; i++)
                {
                    // Suppose we have the following:
                    //
                    // class A<A1, A2, ..., An> 
                    // {
                    //     class B<B1, B2, ..., Bm>
                    //     {
                    //     }
                    // }
                    //
                    // B will have m+n generic arguments - { A1, A2, ..., An, B1, B2, ..., Bn }.
                    // As we enumerate these, we need to skip type parameters whose GenericParameterPosition
                    // is less than n, since the first n type parameters are { A1, A2, ..., An }. 

                    Type t = genericArguments[i];

                    if (t.GenericParameterPosition < outerParameters)
                    {
                        continue;
                    }

                    CType ctype = null;
                    if (t.IsGenericParameter && t.DeclaringType == genericDefinition)
                    {
                        ctype = LoadClassTypeParameter(agg, t);
                    }
                    else
                    {
                        ctype = GetCTypeFromType(t);
                    }

                    // We check to make sure we own the type parameter - this is because we're
                    // currently calculating TypeArgsThis, NOT TypeArgsAll.
                    if (ctype.AsTypeParameterType().GetOwningSymbol() == agg)
                    {
                        ctypes.Add(ctype);
                    }
                }
                return _bsymmgr.AllocParams(ctypes.Count, ctypes.ToArray());
            }
            return BSYMMGR.EmptyTypeArray();
        }
示例#38
0
        /////////////////////////////////////////////////////////////////////////////////

        internal void AddPredefinedPropertyToSymbolTable(AggregateSymbol type, Name property)
        {
            AggregateType aggtype = type.getThisType();
            Type t = aggtype.AssociatedSystemType;

            var props = Enumerable.Where(t.GetRuntimeProperties(), x => x.Name == property.Text);

            foreach (PropertyInfo pi in props)
            {
                AddPropertyToSymbolTable(pi, type);
            }
        }
示例#39
0
 public AggregateType LookupAggregate(AggregateSymbol aggregate, AggregateType outer, TypeArray args)
 {
     _aggregateTable.TryGetValue(MakeKey(aggregate, MakeKey(outer, args)), out AggregateType result);
     return(result);
 }
示例#40
0
        /////////////////////////////////////////////////////////////////////////////////

        internal void AddPredefinedMethodToSymbolTable(AggregateSymbol type, Name methodName)
        {
            Type t = type.getThisType().AssociatedSystemType;

            // If we got here, it means we couldn't find it in our initial lookup. Means we haven't loaded it from reflection yet.
            // Lets go and do that now.
            // Check if we have constructors or not.
            if (methodName == _nameManager.GetPredefinedName(PredefinedName.PN_CTOR))
            {
                var ctors = Enumerable.Where(t.GetConstructors(), m => m.Name == methodName.Text);

                foreach (ConstructorInfo c in ctors)
                {
                    AddMethodToSymbolTable(
                        c,
                        type,
                        MethodKindEnum.Constructor);
                }
            }
            else
            {
                var methods = Enumerable.Where(t.GetRuntimeMethods(), m => m.Name == methodName.Text && m.DeclaringType == t);

                foreach (MethodInfo m in methods)
                {
                    AddMethodToSymbolTable(
                        m,
                        type,
                        m.Name == SpecialNames.Invoke ? MethodKindEnum.Invoke : MethodKindEnum.Actual);
                }
            }
        }
示例#41
0
        public AggregateType GetAggregate(AggregateSymbol agg, AggregateType atsOuter, TypeArray typeArgs)
        {
            Debug.Assert(agg.GetTypeManager() == this);
            Debug.Assert(atsOuter == null || atsOuter.getAggregate() == agg.Parent, "");

            if (typeArgs == null)
            {
                typeArgs = BSYMMGR.EmptyTypeArray();
            }

            Debug.Assert(agg.GetTypeVars().Size == typeArgs.Size);

            Name name = _BSymmgr.GetNameFromPtrs(typeArgs, atsOuter);
            Debug.Assert(name != null);

            AggregateType pAggregate = _typeTable.LookupAggregate(name, agg);
            if (pAggregate == null)
            {
                pAggregate = _typeFactory.CreateAggregateType(
                          name,
                          agg,
                          typeArgs,
                          atsOuter
                      );

                Debug.Assert(!pAggregate.fConstraintsChecked && !pAggregate.fConstraintError);

                pAggregate.SetErrors(pAggregate.GetTypeArgsAll().HasErrors());
#if CSEE

                SpecializedSymbolCreationEE* pSymCreate = static_cast<SpecializedSymbolCreationEE*>(m_BSymmgr.GetSymFactory().m_pSpecializedSymbolCreation);
                AggregateSymbolExtra* pExtra = pSymCreate.GetHashTable().GetElement(agg).AsAggregateSymbolExtra();
                pAggregate.typeRes = pAggregate;
                if (!pAggregate.IsUnresolved())
                {
                    pAggregate.tsRes = ktsImportMax;
                }
                pAggregate.fDirty = pExtra.IsDirty() || pAggregate.IsUnresolved();
                pAggregate.tsDirty = pExtra.GetLastComputedDirtyBit();
#endif // CSEE

                _typeTable.InsertAggregate(name, agg, pAggregate);

                // If we have a generic type definition, then we need to set the
                // base class to be our current base type, and use that to calculate 
                // our agg type and its base, then set it to be the generic version of the
                // base type. This is because:
                //
                // Suppose we have Foo<T> : IFoo<T>
                //
                // Initially, the BaseType will be IFoo<Foo.T>, which gives us the substitution
                // that we want to use for our agg type's base type. However, in the Symbol chain,
                // we want the base type to be IFoo<IFoo.T>. Thats why we need to do this little trick.
                //
                // If we don't have a generic type definition, then we just need to set our base
                // class. This is so that if we have a base type that's generic, we'll be
                // getting the correctly instantiated base type.

                if (pAggregate.AssociatedSystemType != null &&
                    pAggregate.AssociatedSystemType.GetTypeInfo().BaseType != null)
                {
                    // Store the old base class.

                    AggregateType oldBaseType = agg.GetBaseClass();
                    agg.SetBaseClass(_symbolTable.GetCTypeFromType(pAggregate.AssociatedSystemType.GetTypeInfo().BaseType).AsAggregateType());
                    pAggregate.GetBaseClass(); // Get the base type for the new agg type we're making.

                    agg.SetBaseClass(oldBaseType);
                }
            }
            else
            {
                Debug.Assert(pAggregate.HasErrors() == pAggregate.GetTypeArgsAll().HasErrors());
            }

            Debug.Assert(pAggregate.getAggregate() == agg);
            Debug.Assert(pAggregate.GetTypeArgsThis() != null && pAggregate.GetTypeArgsAll() != null);
            Debug.Assert(pAggregate.GetTypeArgsThis() == typeArgs);

            return pAggregate;
        }
示例#42
0
        /////////////////////////////////////////////////////////////////////////////////

        internal bool AggregateContainsMethod(AggregateSymbol agg, string szName, symbmask_t mask)
        {
            return _semanticChecker.SymbolLoader.LookupAggMember(GetName(szName), agg, mask) != null;
        }
示例#43
0
        public AggregateType GetAggregate(AggregateSymbol agg, TypeArray typeArgsAll)
        {
            Debug.Assert(typeArgsAll != null && typeArgsAll.Size == agg.GetTypeVarsAll().Size);

            if (typeArgsAll.size == 0)
                return agg.getThisType();

            AggregateSymbol aggOuter = agg.GetOuterAgg();

            if (aggOuter == null)
                return GetAggregate(agg, null, typeArgsAll);

            int cvarOuter = aggOuter.GetTypeVarsAll().Size;
            Debug.Assert(cvarOuter <= typeArgsAll.Size);

            TypeArray typeArgsOuter = _BSymmgr.AllocParams(cvarOuter, typeArgsAll, 0);
            TypeArray typeArgsInner = _BSymmgr.AllocParams(agg.GetTypeVars().Size, typeArgsAll, cvarOuter);
            AggregateType atsOuter = GetAggregate(aggOuter, typeArgsOuter);

            return GetAggregate(agg, atsOuter, typeArgsInner);
        }
示例#44
0
        /////////////////////////////////////////////////////////////////////////////////

        private TypeParameterType LoadClassTypeParameter(AggregateSymbol parent, Type t)
        {
            for (AggregateSymbol p = parent; p != null; p = p.parent.IsAggregateSymbol() ? p.parent.AsAggregateSymbol() : null)
            {
                for (TypeParameterSymbol typeParam = _bsymmgr.LookupAggMember(
                        GetName(t), p, symbmask_t.MASK_TypeParameterSymbol) as TypeParameterSymbol;
                    typeParam != null;
                    typeParam = BSYMMGR.LookupNextSym(typeParam, p, symbmask_t.MASK_TypeParameterSymbol) as TypeParameterSymbol)
                {
                    if (AreTypeParametersEquivalent(typeParam.GetTypeParameterType().AssociatedSystemType, t))
                    {
                        return typeParam.GetTypeParameterType();
                    }
                }
            }
            return AddTypeParameterToSymbolTable(parent, null, t, true);
        }
示例#45
0
        public AggregateType outerType;          // the outer type if this is a nested type

        public void SetOwningAggregate(AggregateSymbol agg)
        {
            _pOwningAggregate = agg;
        }
示例#46
0
        /////////////////////////////////////////////////////////////////////////////////

        private TypeParameterType ProcessMethodTypeParameter(MethodInfo methinfo, Type t, AggregateSymbol parent)
        {
            MethodSymbol meth = FindMatchingMethod(methinfo, parent);
            if (meth == null)
            {
                meth = AddMethodToSymbolTable(methinfo, parent, MethodKindEnum.Actual);

                // Because we return null from AddMethodToSymbolTable when we have a MethodKindEnum.Actual
                // and the method that we're trying to add is a special name, we need to assert that 
                // we indeed have added a method. This is because no special name should have a method
                // type parameter on it.
                Debug.Assert(meth != null);
            }
            return LoadMethodTypeParameter(meth, t);
        }
示例#47
0
 public bool FindBaseAgg(AggregateSymbol agg)
 {
     for (AggregateSymbol aggT = this; aggT != null; aggT = aggT.GetBaseAgg())
     {
         if (aggT == agg)
             return true;
     }
     return false;
 }
示例#48
0
        /////////////////////////////////////////////////////////////////////////////////

        private AggregateSymbol FindSymWithMatchingArity(AggregateSymbol aggregateSymbol, Type type)
        {
            for (AggregateSymbol agg = aggregateSymbol;
                agg != null;
                agg = BSYMMGR.LookupNextSym(agg, agg.Parent, symbmask_t.MASK_AggregateSymbol) as AggregateSymbol)
            {
                if (agg.GetTypeVarsAll().size == type.GetGenericArguments().Length)
                {
                    return agg;
                }
            }
            return null;
        }
示例#49
0
        private AggregateSymbol FindPredefinedType(ErrorHandling errorContext, string pszType, KAID aid, AggKindEnum aggKind, int arity, bool isRequired)
        {
            Debug.Assert(!string.IsNullOrEmpty(pszType)); // Shouldn't be the empty string!

            NamespaceOrAggregateSymbol bagCur = _pBSymmgr.GetRootNS();
            Name name = null;

            string[] nameParts = pszType.Split(s_nameSeparators);
            for (int i = 0, n = nameParts.Length; i < n; i++)
            {
                name = _pBSymmgr.GetNameManager().Add(nameParts[i]);

                if (i == n - 1)
                {
                    // This is the last component. Handle it special below.
                    break;
                }

                // first search for an outer type which is also predefined
                // this must be first because we always create a namespace for
                // outer names, even for nested types
                AggregateSymbol aggNext = _pBSymmgr.LookupGlobalSymCore(name, bagCur, symbmask_t.MASK_AggregateSymbol).AsAggregateSymbol();
                if (aggNext != null && aggNext.InAlias(aid) && aggNext.IsPredefined())
                {
                    bagCur = aggNext;
                }
                else
                {
                    // ... if no outer type, then search for namespaces
                    NamespaceSymbol nsNext     = _pBSymmgr.LookupGlobalSymCore(name, bagCur, symbmask_t.MASK_NamespaceSymbol).AsNamespaceSymbol();
                    bool            bIsInAlias = true;
                    if (nsNext == null)
                    {
                        bIsInAlias = false;
                    }
                    else
                    {
                        bIsInAlias = nsNext.InAlias(aid);
                    }
                    if (!bIsInAlias)
                    {
                        // Didn't find the namespace in this aid.
                        if (isRequired)
                        {
                            errorContext.Error(ErrorCode.ERR_PredefinedTypeNotFound, pszType);
                        }
                        return(null);
                    }
                    bagCur = nsNext;
                }
            }

            AggregateSymbol aggAmbig;
            AggregateSymbol aggBad;
            AggregateSymbol aggFound = FindPredefinedTypeCore(name, bagCur, aid, aggKind, arity, out aggAmbig, out aggBad);

            if (aggFound == null)
            {
                // Didn't find the AggregateSymbol.
                if (aggBad != null && (isRequired || aid == KAID.kaidGlobal && aggBad.IsSource()))
                {
                    errorContext.ErrorRef(ErrorCode.ERR_PredefinedTypeBadType, aggBad);
                }
                else if (isRequired)
                {
                    errorContext.Error(ErrorCode.ERR_PredefinedTypeNotFound, pszType);
                }
                return(null);
            }

            if (aggAmbig == null && aid != KAID.kaidGlobal)
            {
                // Look in kaidGlobal to make sure there isn't a conflicting one.
                AggregateSymbol tmp;
                AggregateSymbol agg2 = FindPredefinedTypeCore(name, bagCur, KAID.kaidGlobal, aggKind, arity, out aggAmbig, out tmp);
                Debug.Assert(agg2 != null);
                if (agg2 != aggFound)
                {
                    aggAmbig = agg2;
                }
            }

            return(aggFound);
        }