Exemplo n.º 1
0
        //------------------------------------------------------------
        // FUNCBREC.BindNubValue
        //
        /// <summary>
        /// Create an expr for exprSrc.Value where exprSrc->type is a NUBSYM.
        /// </summary>
        /// <param name="treeNode"></param>
        /// <param name="srcExpr"></param>
        /// <returns></returns>
        //------------------------------------------------------------
        private EXPR BindNubValue(BASENODE treeNode, EXPR srcExpr)
        {
            DebugUtil.Assert(srcExpr != null && srcExpr.TypeSym.IsNUBSYM);

            // For new T?(x), the answer is x.
            if (IsNubCtor(srcExpr))
            {
                DebugUtil.Assert(
                    (srcExpr as EXPRCALL).ArgumentsExpr != null &&
                    (srcExpr as EXPRCALL).ArgumentsExpr.Kind != EXPRKIND.LIST);
                return((srcExpr as EXPRCALL).ArgumentsExpr);
            }

            TYPESYM    baseTypeSym = (srcExpr.TypeSym as NUBSYM).BaseTypeSym;
            AGGTYPESYM ats         = (srcExpr.TypeSym as NUBSYM).GetAggTypeSym();

            if (ats == null)
            {
                return(NewError(treeNode, baseTypeSym));
            }
            compiler.EnsureState(ats, AggStateEnum.Prepared);

            PROPSYM propertySym = compiler.MainSymbolManager.NullableValuePropertySym;

            if (propertySym == null)
            {
                string name = compiler.NameManager.GetPredefinedName(PREDEFNAME.CAP_VALUE);

                propertySym = compiler.MainSymbolManager.LookupAggMember(
                    name,
                    ats.GetAggregate(),
                    SYMBMASK.PROPSYM) as PROPSYM;
                if (propertySym == null ||
                    propertySym.IsStatic ||
                    propertySym.Access != ACCESS.PUBLIC ||
                    propertySym.ParameterTypes.Count > 0 ||
                    !propertySym.ReturnTypeSym.IsTYVARSYM ||
                    propertySym.GetMethodSym == null)
                {
                    compiler.Error(
                        treeNode,
                        CSCERRID.ERR_MissingPredefinedMember,
                        new ErrArg(ats),
                        new ErrArg(name));
                    return(NewError(treeNode, baseTypeSym));
                }
                compiler.MainSymbolManager.NullableValuePropertySym = propertySym;
            }

            CheckFieldUse(srcExpr, true);

            EXPRPROP propertyExpr = NewExpr(treeNode, EXPRKIND.PROP, baseTypeSym) as EXPRPROP;

            propertyExpr.SlotPropWithType.Set(propertySym, ats);
            propertyExpr.GetMethodWithType.Set(propertySym.GetMethodSym, ats);
            propertyExpr.ArgumentsExpr = null;
            propertyExpr.ObjectExpr    = srcExpr;

            return(propertyExpr);
        }
Exemplo n.º 2
0
        //------------------------------------------------------------
        // SymWithType.Set (1)
        //
        /// <summary>
        /// <para>If sym is null, ats is set null.</para>
        /// <para>If sym is not null, sym and ats should have the same parent.</para>
        /// </summary>
        /// <param name="sym"></param>
        /// <param name="ats"></param>
        //------------------------------------------------------------
        internal void Set(SYM sym, AGGTYPESYM ats)
        {
            if (sym == null)
            {
                ats = null;
            }
            DebugUtil.Assert(ats == null || sym.ParentSym == ats.GetAggregate());

            if (ats != null && sym.ParentSym != ats.GetAggregate())
            {
                return;
            }

            this.Sym        = sym;
            this.AggTypeSym = ats;
        }
Exemplo n.º 3
0
        //------------------------------------------------------------
        // FUNCBREC.GetActionInvokeMethod
        //
        /// <summary></summary>
        /// <param name="arity"></param>
        /// <returns></returns>
        //------------------------------------------------------------
        internal METHSYM GetActionInvokeMethod(int arity)
        {
            if (arity < 0 || arity >= systemActionDelegateCount)
            {
                return(null);
            }
            InitSystemActionInvokeMethodSyms();

            METHSYM invokeSym = systemActionInvokeMethodSyms[arity];

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

            AGGTYPESYM actionAts = GetActionTypeSym(arity);

            if (actionAts == null)
            {
                return(null);
            }

            invokeSym = Compiler.MainSymbolManager.LookupAggMember(
                "Invoke",
                actionAts.GetAggregate(),
                SYMBMASK.METHSYM) as METHSYM;

            systemActionInvokeMethodSyms[arity] = invokeSym;
            return(invokeSym);
        }
Exemplo n.º 4
0
        //------------------------------------------------------------
        // FUNCBREC.BindNubNew
        //
        /// <summary>
        /// Create an expr for new T?(exprSrc) where T is exprSrc-&gt;type.
        /// </summary>
        /// <param name="treeNode"></param>
        /// <param name="srcExpr"></param>
        /// <returns></returns>
        //------------------------------------------------------------
        private EXPR BindNubNew(BASENODE treeNode, EXPR srcExpr)
        {
            DebugUtil.Assert(srcExpr != null);

            // Create a NUBSYM instance whose base bype is represented by srcExpr.TypeSym.
            NUBSYM nubSym = Compiler.MainSymbolManager.GetNubType(srcExpr.TypeSym);

            // Get a TYPESYM instance representing Nullable<> for nubSym.
            AGGTYPESYM aggTypeSym = nubSym.GetAggTypeSym();

            if (aggTypeSym == null)
            {
                return(NewError(treeNode, nubSym));
            }
            Compiler.EnsureState(aggTypeSym, AggStateEnum.Prepared);

            METHSYM methSym = Compiler.MainSymbolManager.NullableCtorMethodSym;

            if (methSym == null)
            {
                string name = Compiler.NameManager.GetPredefinedName(PREDEFNAME.CTOR);

                for (SYM sym = Compiler.MainSymbolManager.LookupAggMember(name, aggTypeSym.GetAggregate(), SYMBMASK.ALL);
                     ;
                     sym = sym.NextSameNameSym)
                {
                    if (sym == null)
                    {
                        Compiler.Error(treeNode, CSCERRID.ERR_MissingPredefinedMember,
                                       new ErrArg(aggTypeSym), new ErrArg(name));
                        return(NewError(treeNode, nubSym));
                    }
                    if (sym.IsMETHSYM)
                    {
                        methSym = sym as METHSYM;
                        if (methSym.ParameterTypes.Count == 1 && methSym.ParameterTypes[0].IsTYVARSYM &&
                            methSym.Access == ACCESS.PUBLIC)
                        {
                            break;
                        }
                    }
                }
                Compiler.MainSymbolManager.NullableCtorMethodSym = methSym;
            }

            EXPRCALL resExpr = NewExpr(treeNode, EXPRKIND.CALL, nubSym) as EXPRCALL;

            resExpr.MethodWithInst.Set(methSym, aggTypeSym, BSYMMGR.EmptyTypeArray);
            resExpr.ArgumentsExpr = srcExpr;
            resExpr.ObjectExpr    = null;
            resExpr.Flags        |= EXPRFLAG.NEWOBJCALL | EXPRFLAG.CANTBENULL;

            return(resExpr);
        }
Exemplo n.º 5
0
        //------------------------------------------------------------
        // 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;
        }
Exemplo n.º 6
0
        //------------------------------------------------------------
        // MethPropWithInst.Set (1)
        //
        /// <summary></summary>
        /// <param name="mps"></param>
        /// <param name="ats"></param>
        /// <param name="TypeArguments"></param>
        //------------------------------------------------------------
        internal void Set(METHPROPSYM mps, AGGTYPESYM ats, TypeArray TypeArguments)
        {
            if (mps == null)
            {
                ats           = null;
                TypeArguments = null;
            }

            DebugUtil.Assert(
                ats == null ||
                mps != null && mps.ClassSym == ats.GetAggregate());
            DebugUtil.Assert(
                TypeArguments == null ||
                TypeArguments.Count == 0 ||
                mps != null && mps.IsMETHSYM);
            DebugUtil.Assert(
                TypeArguments == null ||
                !mps.IsMETHSYM ||
                (mps as METHSYM).TypeVariables.Count == TypeArguments.Count);

            this.Sym           = mps;
            this.AggTypeSym    = ats;
            this.TypeArguments = TypeArguments;
        }
Exemplo n.º 7
0
        //------------------------------------------------------------
        // 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);
        }
Exemplo n.º 8
0
        //------------------------------------------------------------
        // 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);
        }