// UNDONE: Rename to CreateBoundAnonymousFunction public EXPRBOUNDLAMBDA CreateAnonymousMethod(AggregateType delegateType) { Debug.Assert(delegateType == null || delegateType.isDelegateType()); EXPRBOUNDLAMBDA rval = new EXPRBOUNDLAMBDA(); rval.kind = ExpressionKind.EK_BOUNDLAMBDA; rval.type = delegateType; rval.flags = 0; Debug.Assert(rval != null); return(rval); }
protected EXPR DestroyWraps(EXPRBOUNDLAMBDA anonmeth, EXPR sequence) { for (Symbol sym = anonmeth.ArgumentScope(); sym != null; sym = sym.nextChild) { if (!sym.IsLocalVariableSymbol()) { continue; } LocalVariableSymbol local = sym.AsLocalVariableSymbol(); if (local.isThis) { continue; } Debug.Assert(local.wrap != null); Debug.Assert(anonmeth.OptionalBody != null); EXPR freeWrap = GetExprFactory().CreateWrap(anonmeth.OptionalBody.OptionalScopeSymbol, local.wrap); sequence = GetExprFactory().CreateReverseSequence(sequence, freeWrap); } return sequence; }
protected EXPR CreateWraps(EXPRBOUNDLAMBDA anonmeth) { EXPR sequence = null; for (Symbol sym = anonmeth.ArgumentScope().firstChild; sym != null; sym = sym.nextChild) { if (!sym.IsLocalVariableSymbol()) { continue; } LocalVariableSymbol local = sym.AsLocalVariableSymbol(); if (local.isThis) { continue; } Debug.Assert(anonmeth.OptionalBody != null); EXPR create = GenerateParameter(local.name.Text, local.GetType()); local.wrap = GetExprFactory().CreateWrapNoAutoFree(anonmeth.OptionalBody.OptionalScopeSymbol, create); EXPR save = GetExprFactory().CreateSave(local.wrap); if (sequence == null) { sequence = save; } else { sequence = GetExprFactory().CreateSequence(sequence, save); } } return sequence; }
protected EXPR RewriteLambdaParameters(EXPRBOUNDLAMBDA anonmeth) { Debug.Assert(anonmeth != null); // new ParameterExpression[2] {Parameter(typeof(type1), name1), Parameter(typeof(type2), name2)} EXPR paramArrayInitializerArgs = null; EXPR paramArrayInitializerArgsTail = paramArrayInitializerArgs; for (Symbol sym = anonmeth.ArgumentScope(); sym != null; sym = sym.nextChild) { if (!sym.IsLocalVariableSymbol()) { continue; } LocalVariableSymbol local = sym.AsLocalVariableSymbol(); if (local.isThis) { continue; } GetExprFactory().AppendItemToList(local.wrap, ref paramArrayInitializerArgs, ref paramArrayInitializerArgsTail); } return GenerateParamsArray(paramArrayInitializerArgs, PredefinedType.PT_PARAMETEREXPRESSION); }
protected EXPR RewriteLambdaBody(EXPRBOUNDLAMBDA anonmeth) { Debug.Assert(anonmeth != null); Debug.Assert(anonmeth.OptionalBody != null); Debug.Assert(anonmeth.OptionalBody.GetOptionalStatements() != null); // There ought to be no way to get an empty statement block successfully converted into an expression tree. Debug.Assert(anonmeth.OptionalBody.GetOptionalStatements().GetOptionalNextStatement() == null); EXPRBLOCK body = anonmeth.OptionalBody; // The most likely case: if (body.GetOptionalStatements().isRETURN()) { Debug.Assert(body.GetOptionalStatements().asRETURN().GetOptionalObject() != null); return Visit(body.GetOptionalStatements().asRETURN().GetOptionalObject()); } // This can only if it is a void delegate and this is a void expression, such as a call to a void method // or something like Expression<Action<Foo>> e = (Foo f) => f.MyEvent += MyDelegate; throw Error.InternalCompilerError(); }
///////////////////////////////////////////////////////////////////////////////// // Expression types. protected override EXPR VisitBOUNDLAMBDA(EXPRBOUNDLAMBDA anonmeth) { Debug.Assert(anonmeth != null); EXPRBOUNDLAMBDA prevAnonMeth = currentAnonMeth; currentAnonMeth = anonmeth; MethodSymbol lambdaMethod = GetPreDefMethod(PREDEFMETH.PM_EXPRESSION_LAMBDA); CType delegateType = anonmeth.DelegateType(); TypeArray lambdaTypeParams = GetSymbolLoader().getBSymmgr().AllocParams(1, new CType[] { delegateType }); AggregateType expressionType = GetSymbolLoader().GetOptPredefTypeErr(PredefinedType.PT_EXPRESSION, true); MethWithInst mwi = new MethWithInst(lambdaMethod, expressionType, lambdaTypeParams); EXPR createParameters = CreateWraps(anonmeth); EXPR body = RewriteLambdaBody(anonmeth); EXPR parameters = RewriteLambdaParameters(anonmeth); EXPR args = GetExprFactory().CreateList(body, parameters); CType typeRet = GetSymbolLoader().GetTypeManager().SubstType(mwi.Meth().RetType, mwi.GetType(), mwi.TypeArgs); EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(null, mwi); EXPR callLambda = GetExprFactory().CreateCall(0, typeRet, args, pMemGroup, mwi); callLambda.asCALL().PredefinedMethod = PREDEFMETH.PM_EXPRESSION_LAMBDA; currentAnonMeth = prevAnonMeth; if (createParameters != null) { callLambda = GetExprFactory().CreateSequence(createParameters, callLambda); } EXPR expr = DestroyWraps(anonmeth, callLambda); // If we are already inside an expression tree rewrite and this is an expression tree lambda // then it needs to be quoted. if (currentAnonMeth != null) { expr = GenerateCall(PREDEFMETH.PM_EXPRESSION_QUOTE, expr); } return expr; }
protected virtual EXPR VisitBOUNDLAMBDA(EXPRBOUNDLAMBDA pExpr) { return VisitEXPR(pExpr); }
protected virtual EXPR VisitBOUNDLAMBDA(EXPRBOUNDLAMBDA pExpr) { return(VisitEXPR(pExpr)); }
public EXPRBOUNDLAMBDA CreateAnonymousMethod(AggregateType delegateType) { Debug.Assert(delegateType == null || delegateType.isDelegateType()); EXPRBOUNDLAMBDA rval = new EXPRBOUNDLAMBDA(); rval.kind = ExpressionKind.EK_BOUNDLAMBDA; rval.type = delegateType; rval.flags = 0; Debug.Assert(rval != null); return (rval); }