//------------------------------------------------------------ // FUNCBREC.BindNubNew // /// <summary> /// Create an expr for new T?(exprSrc) where T is exprSrc->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); }
//------------------------------------------------------------ // 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); }
//------------------------------------------------------------ // FUNCBREC.BindExtensionMethod // /// <summary></summary> /// <param name="callExpr"></param> /// <returns></returns> //------------------------------------------------------------ internal EXPR BindExtensionMethod(EXPRCALL instanceCallExpr) { DebugUtil.Assert( instanceCallExpr != null && instanceCallExpr.MethodWithInst != null && instanceCallExpr.MethodWithInst.MethSym != null); MethWithInst instanceMwi = instanceCallExpr.MethodWithInst; METHSYM instanceMethSym = instanceMwi.MethSym; METHSYM staticMethSym = instanceMethSym.StaticExtensionMethodSym; if (staticMethSym == null) { return(instanceCallExpr); } MethWithInst staticMwi = new MethWithInst( staticMethSym, staticMethSym.ParentAggSym.GetThisType(), // non-generic type. instanceMwi.TypeArguments); EXPR topArgExpr = instanceCallExpr.ObjectExpr; EXPR lastArgExpr = topArgExpr; if (instanceCallExpr.ArgumentsExpr != null) { NewList(instanceCallExpr.ArgumentsExpr, ref topArgExpr, ref lastArgExpr); } EXPRCALL staticCallExpr = NewExpr( treeNode, EXPRKIND.CALL, instanceCallExpr.TypeSym) as EXPRCALL; staticCallExpr.MethodWithInst = staticMwi; staticCallExpr.ArgumentsExpr = topArgExpr; staticCallExpr.ObjectExpr = null; return(staticCallExpr); }