Esempio n. 1
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);
        }
Esempio n. 2
0
        //------------------------------------------------------------
        // FUNCBREC.BindNubGetValOrDef
        //
        /// <summary>
        /// Create an expr for exprSrc.GetValueOrDefault()
        /// where exprSrc->type is a NUBSYM.
        /// </summary>
        /// <param name="treeNode"></param>
        /// <param name="srcExpr"></param>
        /// <returns></returns>
        //------------------------------------------------------------
        private EXPR BindNubGetValOrDef(BASENODE treeNode, EXPR srcExpr)
        {
            DebugUtil.Assert(srcExpr != null && srcExpr.TypeSym.IsNUBSYM);

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

            // If srcExpr is null, just return the appropriate default value.
            if (srcExpr.GetConst() != null)
            {
                return(AddSideEffects(treeNode, NewExprZero(treeNode, baseTypeSym), srcExpr, true, true));
            }

            // 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);
            }

            AGGTYPESYM aggTypeSym = (srcExpr.TypeSym as NUBSYM).GetAggTypeSym();

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

            METHSYM methSym = EnsureNubGetValOrDef(treeNode);

            if (methSym == null)
            {
                return(NewError(treeNode, baseTypeSym));
            }

            CheckFieldUse(srcExpr, true);

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

            resExpr.MethodWithInst.Set(methSym, aggTypeSym, BSYMMGR.EmptyTypeArray);
            resExpr.ArgumentsExpr = null;
            resExpr.ObjectExpr    = srcExpr;

            return(resExpr);
        }
Esempio n. 3
0
        //------------------------------------------------------------
        // MemberLookup.LookupExtensionMethodInInterfaces
        //
        /// <summary></summary>
        /// <param name="startAggTypeSym"></param>
        /// <returns></returns>
        //------------------------------------------------------------
        private bool LookupExtensionMethodInInterfaces(AGGTYPESYM startAggTypeSym)
        {
            //DebugUtil.Assert(this.firstSymWithType == null || this.isMulti);
            //DebugUtil.Assert(startAggTypeSym != null);
            if (startAggTypeSym == null)
            {
                return(false);
            }
            if (this.firstSymWithType != null && this.firstSymWithType.IsNotNull)
            {
                return(false);
            }

            //DebugUtil.Assert(startAggTypeSym == null || startAggTypeSym.IsInterfaceType());
            //DebugUtil.Assert(startAggTypeSym != null || interfaceTypeArray.Count > 0);
            //DebugUtil.Assert((this.flags &
            //    (MemLookFlagsEnum.Ctor | MemLookFlagsEnum.Operator | MemLookFlagsEnum.BaseCall))
            //    == 0);

            TypeArray interfaceTypeArray = startAggTypeSym.GetIfacesAll();

            if (interfaceTypeArray == null || interfaceTypeArray.Count == 0)
            {
                return(false);
            }

            // Clear all the hidden flags. Anything found in a class hides any other
            // kind of member in all the interfaces.
            if (startAggTypeSym != null)
            {
                startAggTypeSym.AllHidden  = false;
                startAggTypeSym.DiffHidden = (this.firstSymWithType != null);
            }

            for (int i = 0; i < interfaceTypeArray.Count; ++i)
            {
                AGGTYPESYM type = interfaceTypeArray[i] as AGGTYPESYM;
                DebugUtil.Assert(type.IsInterfaceType());

                type.AllHidden  = false;
                type.DiffHidden = (this.firstSymWithType != null);
            }

            if (startAggTypeSym != null)
            {
                Compiler.EnsureState(startAggTypeSym, AggStateEnum.Prepared);
            }
            if (interfaceTypeArray != null)
            {
                Compiler.EnsureState(interfaceTypeArray, AggStateEnum.Prepared);
            }

            //--------------------------------------------------------
            // Loop through the interfaces.
            //--------------------------------------------------------
            bool       hideObject = false;
            int        index      = 0;
            AGGTYPESYM currentSym = interfaceTypeArray[index++] as AGGTYPESYM;

            DebugUtil.Assert(currentSym != null);

            for (; ;)
            {
                DebugUtil.Assert(currentSym != null && currentSym.IsInterfaceType());
                bool hideByName = false;

                if (!currentSym.AllHidden && SearchSingleType(currentSym, out hideByName))
                {
                    SYM fsym = this.firstSymWithType.Sym;
                    DebugUtil.Assert(fsym != null);

                    if (fsym.Kind == SYMKIND.METHSYM &&
                        (fsym as METHSYM).IsInstanceExtensionMethod)
                    {
                        hideByName |= !this.isMulti;

                        // Mark base interfaces appropriately.
                        TypeArray interfaceArray = currentSym.GetIfacesAll();
                        for (int i = 0; i < interfaceArray.Count; ++i)
                        {
                            AGGTYPESYM sym = interfaceArray[i] as AGGTYPESYM;
                            DebugUtil.Assert(sym.IsInterfaceType());

                            if (hideByName)
                            {
                                sym.AllHidden = true;
                            }
                            sym.DiffHidden = true;
                        }

                        // If we hide all base types, that includes object!
                        if (hideByName)
                        {
                            hideObject = true;
                        }
                    }
                }
                this.flags &= ~MemLookFlagsEnum.TypeVarsAllowed;

                if (index >= interfaceTypeArray.Count)
                {
                    return(!hideObject);
                }

                // Substitution has already been done.
                currentSym = interfaceTypeArray[index++] as AGGTYPESYM;
            }
        }
Esempio n. 4
0
        //------------------------------------------------------------
        // FUNCBREC.BindNubHasValue
        //
        /// <summary>
        /// <para>Create an expr for exprSrc.HasValue where exprSrc->type is a NUBSYM.</para>
        /// <para>If fCheckTrue is false, invert the result.</para>
        /// <para>(In sscli, checkTrue has the default value true.)</para>
        /// </summary>
        /// <param name="treeNode"></param>
        /// <param name="srcExpr"></param>
        /// <param name="checkTrue"></param>
        /// <returns></returns>
        //------------------------------------------------------------
        private EXPR BindNubHasValue(
            BASENODE treeNode,
            EXPR srcExpr,
            bool checkTrue) // = true
        {
            DebugUtil.Assert(srcExpr != null && srcExpr.TypeSym.IsNUBSYM);

            TYPESYM boolTypeSym = GetRequiredPredefinedType(PREDEFTYPE.BOOL);

            // When srcExpr is a null, the result is false
            if (srcExpr.GetConst() != null)
            {
                return(AddSideEffects(
                           treeNode,
                           NewExprConstant(treeNode, boolTypeSym, new ConstValInit(!checkTrue)),
                           srcExpr,
                           true,
                           true));
            }

            // For new T?(x), the answer is true.
            if (IsNubCtor(srcExpr))
            {
                return(AddSideEffects(
                           treeNode,
                           NewExprConstant(treeNode, boolTypeSym, new ConstValInit(checkTrue)),
                           StripNubCtor(srcExpr),
                           true,
                           true));
            }

            AGGTYPESYM aggTypeSym = (srcExpr.TypeSym as NUBSYM).GetAggTypeSym();

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

            PROPSYM propSym = EnsureNubHasValue(treeNode);

            if (propSym == null)
            {
                return(NewError(treeNode, boolTypeSym));
            }

            CheckFieldUse(srcExpr, true);

            EXPRPROP resExpr = NewExpr(treeNode, EXPRKIND.PROP, boolTypeSym) as EXPRPROP;

            resExpr.SlotPropWithType.Set(propSym, aggTypeSym);
            resExpr.GetMethodWithType.Set(propSym.GetMethodSym, aggTypeSym);
            resExpr.ArgumentsExpr = null;
            resExpr.ObjectExpr    = srcExpr;

            if (checkTrue)
            {
                return(resExpr);
            }

            return(NewExprBinop(treeNode, EXPRKIND.LOGNOT, resExpr.TypeSym, resExpr, null));
        }