コード例 #1
0
ファイル: ReflectionUtil.cs プロジェクト: lesterbogran/uncs
        //------------------------------------------------------------
        // NestedTypeResolver.ResolveType
        //
        /// <summary>
        /// Find the class specified in args and create its Type.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        //------------------------------------------------------------
        internal Assembly ResolveType(object sender, ResolveEventArgs args)
        {
            if (args == null || String.IsNullOrEmpty(args.Name))
            {
                return(null);
            }

            string[]  names     = args.Name.Split('.');
            AGGSYM    aggSym    = null;
            AGGSYM    parentSym = this.EnclosingAggSym;
            Exception excp      = null;

            for (int i = 0; i < names.Length; ++i)
            {
                aggSym = compiler.LookupGlobalSym(names[i], parentSym, SYMBMASK.AGGSYM) as AGGSYM;
                if (aggSym == null)
                {
                    return(null);
                }
                parentSym = aggSym;
            }

            aggSym.CreateType(out excp);
            OUTFILESYM outfileSym = aggSym.GetOutputFile();

            if (outfileSym != null && outfileSym.AssemblyBuilderEx != null)
            {
                return(outfileSym.AssemblyBuilderEx.AssemblyBuilder);
            }
            return(null);
        }
コード例 #2
0
ファイル: Nullable.cs プロジェクト: lesterbogran/uncs
        //------------------------------------------------------------
        // FUNCBREC.EnsureNubHasValue
        //
        /// <summary>
        /// Make sure the HasValue property of System.Nullable&lt;T&gt; is appropriate (and return it).
        /// </summary>
        /// <param name="treeNode"></param>
        /// <returns></returns>
        //------------------------------------------------------------
        private PROPSYM EnsureNubHasValue(BASENODE treeNode)
        {
            PROPSYM propSym = Compiler.MainSymbolManager.NullableHasValuePropertySym;

            if (propSym == null)
            {
                AGGSYM nubAggSym = Compiler.GetOptPredefAggErr(PREDEFTYPE.G_OPTIONAL, true);
                if (nubAggSym == null)
                {
                    return(null);
                }
                string name = Compiler.NameManager.GetPredefinedName(PREDEFNAME.HASVALUE);

                SYM sym = Compiler.MainSymbolManager.LookupAggMember(
                    name, nubAggSym, SYMBMASK.PROPSYM);
                propSym = sym as PROPSYM;
                if (propSym == null ||
                    propSym.IsStatic ||
                    propSym.Access != ACCESS.PUBLIC ||
                    propSym.ParameterTypes.Count > 0 ||
                    !propSym.ReturnTypeSym.IsPredefType(PREDEFTYPE.BOOL) ||
                    propSym.GetMethodSym == null)
                {
                    Compiler.Error(treeNode, CSCERRID.ERR_MissingPredefinedMember,
                                   new ErrArg(nubAggSym), new ErrArg(name));
                    return(null);
                }
                Compiler.MainSymbolManager.NullableHasValuePropertySym = propSym;
            }

            return(propSym);
        }
コード例 #3
0
ファイル: FileIter.cs プロジェクト: lesterbogran/uncs
        //------------------------------------------------------------
        // AggIterator
        //------------------------------------------------------------
        internal AGGSYM Reset(INFILESYM infile)
        {
            DebugUtil.Assert(infile.RootNsDeclSym != null);

            aggCur = GetFirstInListNsDecl(infile.RootNsDeclSym.FirstChildSym);
            return(aggCur);
        }
コード例 #4
0
        //------------------------------------------------------------
        // SecurityUtil.EmitSecurityAttributes (1) Type
        //
        /// <summary></summary>
        /// <param name="methodSym"></param>
        /// <param name="permissionSets"></param>
        //------------------------------------------------------------
        internal static bool EmitSecurityAttributes(
            AGGSYM aggSym,
            Dictionary <SecurityAction, PermissionSet> permissionSets,
            out Exception excp)
        {
            excp = null;
            bool rval = true;

            if (aggSym == null ||
                aggSym.TypeBuilder == null)
            {
                return(false);
            }
            if (permissionSets == null || permissionSets.Count == 0)
            {
                return(true);
            }

            foreach (KeyValuePair <SecurityAction, PermissionSet> kv in permissionSets)
            {
                switch (kv.Key)
                {
                case SecurityAction.Assert:
                case SecurityAction.Demand:
                case SecurityAction.Deny:
                case SecurityAction.InheritanceDemand:
                case SecurityAction.LinkDemand:
                case SecurityAction.PermitOnly:
                default:
                    try
                    {
                        aggSym.TypeBuilder.AddDeclarativeSecurity(kv.Key, kv.Value);
                    }
                    catch (ArgumentException ex)
                    {
                        if (excp == null)
                        {
                            excp = ex;
                        }
                        rval = false;
                    }
                    catch (InvalidOperationException ex)
                    {
                        if (excp == null)
                        {
                            excp = ex;
                        }
                        rval = false;
                    }
                    break;

                case SecurityAction.RequestMinimum:
                case SecurityAction.RequestOptional:
                case SecurityAction.RequestRefuse:
                    break;
                }
            }
            return(rval);
        }
コード例 #5
0
        //------------------------------------------------------------
        // CLSDREC.CreateBackField
        //
        /// <summary></summary>
        /// <param name="aggSym"></param>
        /// <param name="propName"></param>
        //------------------------------------------------------------
        private MEMBVARSYM CreateBackField(
            PROPERTYNODE propNode,
            string propName,
            TYPESYM propTypeSym,
            AGGSYM aggSym,
            AGGDECLSYM aggDeclSym)
        {
            DebugUtil.Assert(aggSym.IsClass || aggSym.IsStruct);
            string backFieldName = GenerateBackFieldName(propName);

            NODEFLAGS propFlags = propNode.Flags;

            MEMBVARSYM backFieldSym = Compiler.MainSymbolManager.CreateMembVar(
                backFieldName,
                aggSym,
                aggDeclSym);

            backFieldSym.TypeSym       = propTypeSym;
            backFieldSym.ParseTreeNode = null;
            backFieldSym.IsAssigned    = true;

            NODEFLAGS allowableFlags =
                aggSym.AllowableMemberAccess() |
                NODEFLAGS.MOD_UNSAFE |
                NODEFLAGS.MOD_NEW |
                NODEFLAGS.MOD_STATIC;

            backFieldSym.IsUnsafe = (aggDeclSym.IsUnsafe || (propFlags & NODEFLAGS.MOD_UNSAFE) != 0);

            if ((propFlags & NODEFLAGS.MOD_ABSTRACT) != 0)
            {
                DebugUtil.Assert((allowableFlags & NODEFLAGS.MOD_ABSTRACT) == 0);
                Compiler.ErrorRef(null, CSCERRID.ERR_AbstractField, new ErrArgRef(backFieldSym));
                //flags &= ~NODEFLAGS.MOD_ABSTRACT;
            }

            backFieldSym.Access = ACCESS.PRIVATE;   // GetAccessFromFlags(aggSym, allowableFlags, flags);

            if ((propFlags & NODEFLAGS.MOD_STATIC) != 0)
            {
                backFieldSym.IsStatic = true;
            }

            CheckForProtectedInSealed(backFieldSym);

            // Check that the field type is as accessible as the field itself.
            CheckConstituentVisibility(backFieldSym, propTypeSym, CSCERRID.ERR_BadVisFieldType);

            return(backFieldSym);
        }
コード例 #6
0
ファイル: FileIter.cs プロジェクト: lesterbogran/uncs
        //------------------------------------------------------------
        // AggIterator.GetNext
        //------------------------------------------------------------
        static protected AGGSYM GetNext(AGGSYM agg)
        {
            if (agg == null)
            {
                return(null);
            }

            // Children first. We process nested AGGs with the outer AGG.
            AGGSYM aggNext = GetFirstInListAgg(agg.FirstChildSym);

            if (aggNext != null)
            {
                return(aggNext);
            }

            // Check siblings. If none found move up a level. Once agg's parent is a NS
            // the processing is different (following this loop).
            for (; agg.ParentBagSym.IsAGGSYM; agg = agg.ParentBagSym as AGGSYM)
            {
                aggNext = GetFirstInListAgg(agg.NextSym);
                if (aggNext != null)
                {
                    return(aggNext);
                }
            }

            // Agg's parent is a NS. Switch to searching DECLs.
            // ASSERT(agg && agg.Parent().IsNSSYM);
            if (agg == null || !agg.ParentBagSym.IsNSSYM)
            {
                return(null);
            }
            for (DECLSYM decl = agg.FirstDeclSym; decl != null; decl = decl.ParentDeclSym)
            {
                aggNext = GetFirstInListNsDecl(decl.NextSym);
                if (aggNext != null)
                {
                    return(aggNext);
                }
            }
            return(null);
        }
コード例 #7
0
ファイル: ExtensionMethods.cs プロジェクト: lesterbogran/uncs
        //------------------------------------------------------------
        // CLSDREC.DefineExtensionMethodCore
        //
        /// <summary></summary>
        /// <param name="methodSym"></param>
        //------------------------------------------------------------
        internal void DefineExtensionMethodCore(METHSYM methodSym)
        {
            DebugUtil.Assert(methodSym != null);

            DebugUtil.Assert(methodSym.ParameterTypes.Count > 0);
            TypeArray  paramTypes = methodSym.ParameterTypes;
            AGGTYPESYM ats        = paramTypes[0] as AGGTYPESYM;

            if (ats == null)
            {
                return;
            }
            AGGSYM targetAggSym = ats.GetAggregate();

            METHSYM instanceMethSym = Compiler.MainSymbolManager.CreateGlobalSym(
                SYMKIND.METHSYM,
                methodSym.Name,
                targetAggSym) as METHSYM;

            instanceMethSym.ContainingAggDeclSym = targetAggSym.FirstDeclSym;
            instanceMethSym.IsUnsafe             = methodSym.IsUnsafe;

            instanceMethSym.TypeVariables = methodSym.TypeVariables;

            TypeArray instParamTypes = new TypeArray();

            for (int i = 1; i < paramTypes.Count; ++i)
            {
                instParamTypes.Add(paramTypes[i]);
            }
            instanceMethSym.ParameterTypes
                = Compiler.MainSymbolManager.AllocParams(instParamTypes);
            instanceMethSym.ReturnTypeSym = methodSym.ReturnTypeSym;
            instanceMethSym.Access        = methodSym.Access;
            instanceMethSym.IsStatic      = false;

            instanceMethSym.IsParameterArray = methodSym.IsParameterArray;
            instanceMethSym.IsVarargs        = methodSym.IsVarargs;

            instanceMethSym.StaticExtensionMethodSym = methodSym;
        }
コード例 #8
0
ファイル: Nullable.cs プロジェクト: lesterbogran/uncs
        //------------------------------------------------------------
        // FUNCBREC.EnsureNubGetValOrDef
        //
        /// <summary>
        /// Make sure the HasValue property of System.Nullable&lt;T&gt; is appropriate (and return it).
        /// </summary>
        /// <param name="treeNode"></param>
        /// <returns></returns>
        //------------------------------------------------------------
        private METHSYM EnsureNubGetValOrDef(BASENODE treeNode)
        {
            METHSYM methSym = Compiler.MainSymbolManager.NullableGetValOrDefMethodSym;

            if (methSym == null)
            {
                AGGSYM nubAggSym = Compiler.GetOptPredefAggErr(PREDEFTYPE.G_OPTIONAL, true);
                if (nubAggSym == null)
                {
                    return(null);
                }
                string name = Compiler.NameManager.GetPredefinedName(PREDEFNAME.GET_VALUE_OR_DEF);

                for (SYM sym = Compiler.MainSymbolManager.LookupAggMember(name, nubAggSym, SYMBMASK.ALL);
                     ;
                     sym = sym.NextSameNameSym)
                {
                    if (sym == null)
                    {
                        Compiler.Error(treeNode, CSCERRID.ERR_MissingPredefinedMember,
                                       new ErrArg(nubAggSym), new ErrArg(name));
                        return(null);
                    }
                    if (sym.IsMETHSYM)
                    {
                        methSym = sym as METHSYM;
                        if (methSym.ParameterTypes.Count == 0 &&
                            methSym.ParameterTypes.Count == 0 &&
                            methSym.ReturnTypeSym.IsTYVARSYM &&
                            !methSym.IsStatic &&
                            methSym.Access == ACCESS.PUBLIC)
                        {
                            break;
                        }
                    }
                }
                Compiler.MainSymbolManager.NullableGetValOrDefMethodSym = methSym;
            }

            return(methSym);
        }
コード例 #9
0
ファイル: ExtensionMethods.cs プロジェクト: lesterbogran/uncs
        //------------------------------------------------------------
        // CLSDREC.DefineExtensionMethod
        //
        /// <summary></summary>
        /// <param name="methodNode"></param>
        /// <param name="methodSym"></param>
        //------------------------------------------------------------
        internal void DefineExtensionMethod(METHODNODE methodNode, METHSYM methodSym)
        {
            DebugUtil.Assert(
                methodNode != null && methodNode.IsExtensionMethod &&
                methodSym != null);

            //--------------------------------------------------------
            //
            //--------------------------------------------------------
            AGGSYM parentAggSym = methodSym.ParentAggSym;

            DebugUtil.Assert(parentAggSym != null);

            if (!methodSym.IsStatic)
            {
                Compiler.Error(
                    methodNode,
                    CSCERRID.ERR_NonStaticExtensionMethod);
                return;
            }
            if (!parentAggSym.IsStatic ||
                (parentAggSym.AllTypeVariables != null &&
                 parentAggSym.AllTypeVariables.Count > 0))
            {
                Compiler.Error(
                    methodNode,
                    CSCERRID.ERR_ExtensionMethodInImproperClass);
                return;
            }
            if (parentAggSym.IsNested)
            {
                Compiler.Error(
                    methodNode,
                    CSCERRID.ERR_ExtensionMethodInNestedClass,
                    new ErrArg(parentAggSym.Name));
                return;
            }

            DefineExtensionMethodCore(methodSym);
        }
コード例 #10
0
        //------------------------------------------------------------
        // MetaDataHelper.GetAggregateFlags
        //
        /// <summary>
        /// <para>Determine the flags for a typedef definition in metadata</para>
        /// <para>Use System.Reflection.TypeAttribuetes in place of CorTypeAttr of sscli.</para>
        /// <para>CorTypeAttr has a member named "Forwarder" which TypeAttributes does not has.</para>
        /// </summary>
        /// <param name="aggSym"></param>
        /// <returns></returns>
        //------------------------------------------------------------
        internal static TypeAttributes GetAggregateFlags(AGGSYM aggSym)
        {
            TypeAttributes flags = 0;

            // Determine flags.

            // Set access flags.
            flags |= GetTypeAccessFlags(aggSym);

            // Set other flags
            switch (aggSym.AggKind)
            {
            case AggKindEnum.Class:
                if (aggSym.IsSealed)
                {
                    flags |= TypeAttributes.Sealed;
                }
                if (aggSym.IsAbstract)
                {
                    flags |= TypeAttributes.Abstract;
                }
                if (!aggSym.HasUserDefinedStaticCtor)
                {
                    flags |= TypeAttributes.BeforeFieldInit;
                }
                break;

            case AggKindEnum.Interface:
                flags |= TypeAttributes.Interface | TypeAttributes.Abstract;
                break;

            case AggKindEnum.Enum:
                DebugUtil.Assert(aggSym.IsSealed);
                flags |= TypeAttributes.Sealed;
                break;

            case AggKindEnum.Struct:
                DebugUtil.Assert(aggSym.IsSealed);
                flags |= TypeAttributes.Sealed;
                if (!aggSym.HasUserDefinedStaticCtor)
                {
                    flags |= TypeAttributes.BeforeFieldInit;
                }
                if (aggSym.IsFabricated)
                {
                    flags |= TypeAttributes.SequentialLayout;     // Fabricated structs are always sequential
                }
                break;

            case AggKindEnum.Delegate:
                DebugUtil.Assert(aggSym.IsSealed);
                flags |= TypeAttributes.Sealed;
                break;

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

            switch (aggSym.GetOutputFile().DefaultCharSet)
            {
            default:
                DebugUtil.VsFail("A new value was added to System.Runtime.InteropServices.CharSet that we need to handle");
                goto case 0;

            case (System.Runtime.InteropServices.CharSet) 0:        // Unset
            case System.Runtime.InteropServices.CharSet.None:       // 1:
                break;

            case System.Runtime.InteropServices.CharSet.Ansi:       // 2:
                flags |= TypeAttributes.AnsiClass;
                break;

            case System.Runtime.InteropServices.CharSet.Unicode:        // 3:
                flags |= TypeAttributes.UnicodeClass;
                break;

            case System.Runtime.InteropServices.CharSet.Auto:       // 4:
                flags |= TypeAttributes.AutoClass;
                break;
            }

            return(flags);
        }
コード例 #11
0
        //------------------------------------------------------------
        // MetaDataHelper.GetExplicitImplTypeName
        //
        /// <summary></summary>
        /// <param name="typeSym"></param>
        /// <param name="strBuilder"></param>
        //------------------------------------------------------------
        public void GetExplicitImplTypeName(TYPESYM typeSym, StringBuilder strBuilder)
        {
#if DEBUG
            if (!(typeSym != null))
            {
                ;
            }
#endif
            DebugUtil.Assert(typeSym != null);

            TYPESYM   nakedTypeSym = typeSym.GetNakedType(false);
            TypeArray typeArgs     = null;

            switch (nakedTypeSym.Kind)
            {
            default:
                DebugUtil.Assert(false, "Unhandled type in GetExplicitImplTypeName");
                return;

            case SYMKIND.TYVARSYM:
                strBuilder.Append(nakedTypeSym.Name);
                break;

            case SYMKIND.NUBSYM:
                nakedTypeSym = (nakedTypeSym as NUBSYM).GetAggTypeSym();
                if (nakedTypeSym == null)
                {
                    DebugUtil.Assert(false, "Why did GetAts return null?");
                    return;
                }
                // Fall through.
                goto case SYMKIND.AGGTYPESYM;

            case SYMKIND.AGGTYPESYM:
            {
                AGGTYPESYM outerAggTypeSym = (nakedTypeSym as AGGTYPESYM).OuterTypeSym;
                AGGSYM     aggSym          = nakedTypeSym.GetAggregate();

                if (outerAggTypeSym != null)
                {
                    GetExplicitImplTypeName(outerAggTypeSym, strBuilder);
                    strBuilder.Append('.');
                }
                else
                {
                    DebugUtil.Assert(aggSym.ParentBagSym != null && !aggSym.ParentBagSym.IsAGGSYM);
                    int cch = strBuilder.Length;
                    GetFullName(aggSym.ParentBagSym, strBuilder, aggSym);
                    if (cch < strBuilder.Length)
                    {
                        strBuilder.Append('.');
                    }
                }
                strBuilder.Append(aggSym.Name);

                typeArgs = (nakedTypeSym as AGGTYPESYM).TypeArguments;
            }
            break;

            case SYMKIND.ERRORSYM:
            {
                ERRORSYM errSym    = nakedTypeSym as ERRORSYM;
                SYM      parentSym = errSym.ParentSym;

                if (parentSym != null && parentSym.IsTYPESYM)
                {
                    GetExplicitImplTypeName(parentSym as TYPESYM, strBuilder);
                    strBuilder.Append('.');
                }
                else if (parentSym != null && parentSym.IsNSAIDSYM)
                {
                    parentSym = (parentSym as NSAIDSYM).NamespaceSym;
                    int cch = strBuilder.Length;
                    GetFullName(parentSym, strBuilder, errSym);
                    if (cch < strBuilder.Length)
                    {
                        strBuilder.Append('.');
                    }
                }
                strBuilder.Append(errSym.ErrorName);

                typeArgs = errSym.TypeArguments;
            }
            break;
            }

            if (typeArgs != null && typeArgs.Count > 0)
            {
                strBuilder.Append('<');
                for (int i = 0; i < typeArgs.Count; ++i)
                {
                    if (i > 0)
                    {
                        strBuilder.Append(',');
                    }
                    GetExplicitImplTypeName(typeArgs[i], strBuilder);
                }
                strBuilder.Append('>');
            }

            // Add ptr and array modifiers
            AddTypeModifiers(typeSym, strBuilder);
        }
コード例 #12
0
ファイル: ReflectionUtil.cs プロジェクト: lesterbogran/uncs
 internal NestedTypeResolver(COMPILER comp, AGGSYM sym)
 {
     this.compiler        = comp;
     this.EnclosingAggSym = sym;
 }
コード例 #13
0
ファイル: ReflectionUtil.cs プロジェクト: lesterbogran/uncs
        //------------------------------------------------------------
        // ReflectionUtil.IsTypeBuilderInstruction
        //
        /// <summary></summary>
        /// <param name="typeSym"></param>
        /// <returns></returns>
        //------------------------------------------------------------
        internal static bool IsTypeBuilderInstruction(TYPESYM typeSym)
        {
            if (typeSym == null)
            {
                return(false);
            }
            Type type  = null;
            int  count = 0;
            int  index = 0;

            switch (typeSym.Kind)
            {
            //----------------------------------------------------
            // AGGTYPESYM
            //----------------------------------------------------
            case SYMKIND.AGGTYPESYM:
                AGGTYPESYM ats = typeSym as AGGTYPESYM;
                DebugUtil.Assert(ats != null);
                if (ats.AllTypeArguments == null ||
                    ats.AllTypeArguments.Count == 0)
                {
                    return(false);
                }

                AGGSYM aggSym = ats.GetAggregate();
                DebugUtil.Assert(aggSym != null);
                if (aggSym.TypeBuilder != null)
                {
                    return(true);
                }
                TypeArray typeArgs = ats.AllTypeArguments;
                for (int i = 0; i < typeArgs.Count; ++i)
                {
                    if (IsTypeBuilderInstruction(typeArgs[i]))
                    {
                        return(true);
                    }
                }
                return(false);

            //----------------------------------------------------
            // ARRAYSYM
            //----------------------------------------------------
            case SYMKIND.ARRAYSYM:
                return(IsTypeBuilderInstruction(typeSym.ParentSym as TYPESYM));

            //----------------------------------------------------
            // VOIDSYM
            //----------------------------------------------------
            case SYMKIND.VOIDSYM:
                return(false);

            //----------------------------------------------------
            // PARAMMODSYM
            //----------------------------------------------------
            case SYMKIND.PARAMMODSYM:
                return(IsTypeBuilderInstruction(typeSym.ParentSym as TYPESYM));

            //----------------------------------------------------
            // TYVARSYM
            //----------------------------------------------------
            case SYMKIND.TYVARSYM:
                return(true);

            //----------------------------------------------------
            // PTRSYM
            //----------------------------------------------------
            case SYMKIND.PTRSYM:
                return(IsTypeBuilderInstruction((typeSym as PTRSYM).BaseTypeSym));

            //----------------------------------------------------
            // NUBSYM
            //----------------------------------------------------
            case SYMKIND.NUBSYM:
                return(IsTypeBuilderInstruction((typeSym as NUBSYM).BaseTypeSym));

            //----------------------------------------------------
            // otherwise
            //----------------------------------------------------
            case SYMKIND.NULLSYM:
            case SYMKIND.ERRORSYM:
                break;

            case SYMKIND.MODOPTTYPESYM:
                throw new NotImplementedException("SymbolUtil.MakeSystemType: MODOPTTYPESYM");

            case SYMKIND.ANONMETHSYM:
            case SYMKIND.METHGRPSYM:
            case SYMKIND.UNITSYM:
                break;

            default:
                break;
            }
            return(false);
        }
コード例 #14
0
ファイル: FileIter.cs プロジェクト: lesterbogran/uncs
 //------------------------------------------------------------
 // AggIterator.Next
 //------------------------------------------------------------
 internal AGGSYM Next()
 {
     aggCur = GetNext(aggCur);
     return(aggCur);
 }
コード例 #15
0
ファイル: Initializers.cs プロジェクト: lesterbogran/uncs
        //------------------------------------------------------------
        // FUNCBREC.HasIEnumerable (2)
        //
        /// <summary>
        /// Rewrite HasIEnumerable for collection initializer.
        /// Return the IEnumerable or IEnumerable&lt;T&gt; instance.
        /// </summary>
        /// <param name="collection"></param>
        /// <param name="tree"></param>
        /// <param name="badType"></param>
        /// <param name="badMember"></param>
        /// <returns></returns>
        //------------------------------------------------------------
        private AGGTYPESYM HasIEnumerable(
            TYPESYM collectionTypeSym/*,
                                      * BASENODE treeNode,
                                      * TYPESYM badTypeSym,
                                      * PREDEFNAME badMemberName*/
            )
        {
            AGGTYPESYM ifaceCandidateAts = null;
            // First try the generic interfaces
            AGGSYM gEnumAggSym
                = Compiler.GetOptPredefAgg(PREDEFTYPE.G_IENUMERABLE, true);
            TypeArray  allIfacesTypeArray = null;
            AGGTYPESYM baseAts            = null;

            // If generics don't exist or the type isn't an AGGTYPESYM
            // then we can't check the interfaces (and base-class interfaces)
            // for IEnumerable<T> so immediately try the non-generic IEnumerable
            if (gEnumAggSym == null)
            {
                goto NO_GENERIC;
            }

            if (collectionTypeSym.IsAGGTYPESYM)
            {
                if (collectionTypeSym.GetAggregate() == gEnumAggSym ||
                    collectionTypeSym.IsPredefType(PREDEFTYPE.IENUMERABLE))
                {
                    DebugUtil.Assert(false, "IEnumerable/ator types are bad!");
                    goto LERROR;
                }

                AGGTYPESYM tempAts = collectionTypeSym as AGGTYPESYM;
                allIfacesTypeArray = tempAts.GetIfacesAll();
                baseAts            = tempAts.GetBaseClass();
            }
            else if (collectionTypeSym.IsTYVARSYM)
            {
                // Note:
                // we'll search the interface list before the class constraint,
                // but it doesn't matter since we require a unique instantiation of IEnumerable<T>.

                // Note:
                // The pattern search will usually find the interface constraint
                // - but if the class constraint has a non-public or non-applicable
                // or non-method GetEnumerator,
                // the interfaces are hidden in which case we will find them here.

                TYVARSYM tempTvSym = collectionTypeSym as TYVARSYM;
                allIfacesTypeArray = tempTvSym.AllInterfaces;
                baseAts            = tempTvSym.BaseClassSym;
            }
            else
            {
                goto NO_GENERIC;
            }

            DebugUtil.Assert(allIfacesTypeArray != null);

            // If the type implements exactly one instantiation of
            // IEnumerable<T> then it's the one.
            //
            // If it implements none then try the non-generic interface.
            //
            // If it implements more than one, then it's an error.
            //
            // Search the direct and indirect interfaces via allIfacesTypeArray,
            // going up the base chain...
            // Work up the base chain
            for (; ;)
            {
                // Now work across all the interfaces
                for (int i = 0; i < allIfacesTypeArray.Count; ++i)
                {
                    AGGTYPESYM iface = allIfacesTypeArray[i] as AGGTYPESYM;
                    if (iface.GetAggregate() == gEnumAggSym)
                    {
                        if (ifaceCandidateAts == null)
                        {
                            // First implementation
                            ifaceCandidateAts = iface;
                        }
                        else if (iface != ifaceCandidateAts)
                        {
                            // If this really is a different instantiation report an error
                            Compiler.Error(
                                treeNode,
                                CSCERRID.ERR_MultipleIEnumOfT,
                                new ErrArgRef(collectionTypeSym),
                                new ErrArg(gEnumAggSym.GetThisType()));
                            return(null);
                        }
                    }
                }
                // Check the base class.
                if (baseAts == null)
                {
                    break;
                }
                allIfacesTypeArray = baseAts.GetIfacesAll();
                baseAts            = baseAts.GetBaseClass();
            }

            // Report the one and only generic interface
            if (ifaceCandidateAts != null)
            {
                DebugUtil.Assert(
                    CanConvert(collectionTypeSym, ifaceCandidateAts, ConvertTypeEnum.NOUDC));
                return(ifaceCandidateAts);
            }

NO_GENERIC:
            if (collectionTypeSym.IsPredefType(PREDEFTYPE.IENUMERABLE))
            {
                DebugUtil.VsFail("Why didn't IEnumerator match the pattern?");
                goto LERROR;
            }

            // No errors, no generic interfaces, try the non-generic interface
            ifaceCandidateAts = GetRequiredPredefinedType(PREDEFTYPE.IENUMERABLE);
            if (CanConvert(collectionTypeSym, ifaceCandidateAts, ConvertTypeEnum.NOUDC))
            {
                return(ifaceCandidateAts);
            }

LERROR:
            return(null);
        }
コード例 #16
0
ファイル: FncBindExt.cs プロジェクト: lesterbogran/uncs
        //------------------------------------------------------------
        // FUNCBREC.SetFncBrecExtFields
        //
        /// <summary></summary>
        /// <returns></returns>
        //------------------------------------------------------------
        private bool SetFncBrecExtFields()
        {
            if (systemNsSym == null)
            {
                systemNsSym = Compiler.LookupInBagAid(
                    "System",
                    Compiler.MainSymbolManager.RootNamespaceSym,
                    0,
                    0,
                    SYMBMASK.NSSYM) as NSSYM;
            }
            if (systemNsSym == null)
            {
                Compiler.Error(CSCERRID.ERR_SingleTypeNameNotFound, new ErrArg("System"));
                return(false);
            }

            if (reflectionNsSym == null)
            {
                reflectionNsSym = Compiler.LookupInBagAid(
                    "Reflection",
                    systemNsSym,
                    0,
                    0,
                    SYMBMASK.NSSYM) as NSSYM;
            }
            if (reflectionNsSym == null)
            {
                Compiler.Error(CSCERRID.ERR_SingleTypeNameNotFound, new ErrArg("Reflection"));
                return(false);
            }

            if (systemTypeAggTypeSym == null)
            {
                systemTypeAggSym = Compiler.LookupInBagAid(
                    "Type",
                    systemNsSym,
                    0,
                    0,
                    SYMBMASK.AGGSYM) as AGGSYM;
                systemTypeAggTypeSym = systemTypeAggSym.GetThisType();
            }
            if (systemTypeAggTypeSym == null)
            {
                Compiler.Error(CSCERRID.ERR_SingleTypeNameNotFound, new ErrArg("Type"));
                return(false);
            }
            if (systemTypeArraySym == null)
            {
                systemTypeArraySym = Compiler.MainSymbolManager.GetArray(
                    systemTypeAggTypeSym,
                    1,
                    systemTypeAggTypeSym.Type.MakeArrayType());
            }
            if (systemTypeArraySym == null)
            {
                Compiler.Error(CSCERRID.ERR_SingleTypeNameNotFound, new ErrArg("Type[]"));
                return(false);
            }

            return(true);
        }