//------------------------------------------------------------ // 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); }
//------------------------------------------------------------ // FUNCBREC.EnsureNubHasValue // /// <summary> /// Make sure the HasValue property of System.Nullable<T> 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); }
//------------------------------------------------------------ // PropWithType.Set (1) // /// <summary></summary> /// <param name="prop"></param> /// <param name="ats"></param> //------------------------------------------------------------ internal void Set(PROPSYM prop, AGGTYPESYM ats) { base.Set(prop, ats); }
//------------------------------------------------------------ // PropWithType Constructor (2) // /// <summary></summary> /// <param name="prop"></param> /// <param name="ats"></param> //------------------------------------------------------------ internal PropWithType(PROPSYM prop, AGGTYPESYM ats) { Set(prop, ats); }
//------------------------------------------------------------ // 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)); }