/// <summary> /// Rewrites the given expression into a CPS-based expression using the specified initial CPS rewrite state. /// </summary> /// <param name="expression">Expression to rewrite to a CPS-based expression.</param> /// <param name="initialState">Initial CPS rewrite state.</param> /// <param name="inline">Indicates whether or not to inline invocations when possible. This optimization may defeat evaluation order for specific subclasses, so it can be disabled.</param> /// <returns>Rewritten expression in CPS style.</returns> protected Expression RewriteCore(Expression expression, TContinuationState initialState, bool inline) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } var res = new Impl(this, initialState).Visit(expression); if (inline) { res = BetaReducer.Reduce(res); } res = new LambdaParameterRenamer().Visit(res); return(res); }
public static void GetConvertAndPredicate <TLeaf, TTarget>(Expression <Func <TLeaf, TTarget> > convert, Expression <Func <TLeaf, bool> > predicate, out Expression <Func <ExpressionTree, TTarget> > convertLambda, out Func <ExpressionTreeBase, TTarget> convertFunction, out Expression <Func <ExpressionTree, bool> > predicateLambda, out Func <ExpressionTreeBase, bool> predicateFunction) where TLeaf : Expression { var expressionProperty = (PropertyInfo)ReflectionHelpers.InfoOf((ExpressionTree et) => et.Expression); var convertParameter = Expression.Parameter(typeof(ExpressionTree), convert.Parameters[0].Name); var convertLambdaRaw = Expression.Lambda <Func <ExpressionTree, TTarget> >( Expression.Invoke( convert, Expression.Convert( Expression.Property( convertParameter, expressionProperty ), typeof(TLeaf) ) ), convertParameter ); convertLambda = (Expression <Func <ExpressionTree, TTarget> >)BetaReducer.Reduce(convertLambdaRaw, BetaReductionNodeTypes.Unrestricted, BetaReductionRestrictions.None); var convertFunctionStrong = convertLambda.Compile(); convertFunction = new Func <ExpressionTreeBase, TTarget>(etb => { return(convertFunctionStrong((ExpressionTree)etb)); }); var predicateParameter = Expression.Parameter(typeof(ExpressionTree), predicate.Parameters[0].Name); var predicateLambdaRaw = Expression.Lambda <Func <ExpressionTree, bool> >( Expression.AndAlso( Expression.TypeIs( Expression.Property( predicateParameter, expressionProperty ), typeof(TLeaf) ), Expression.Invoke( predicate, Expression.Convert( Expression.Property( predicateParameter, expressionProperty ), typeof(TLeaf) ) ) ), predicateParameter ); predicateLambda = (Expression <Func <ExpressionTree, bool> >)BetaReducer.Reduce(predicateLambdaRaw, BetaReductionNodeTypes.Unrestricted, BetaReductionRestrictions.None); var predicateFunctionStrong = predicateLambda.Compile(); predicateFunction = new Func <ExpressionTreeBase, bool>(etb => { return(etb is ExpressionTree et && predicateFunctionStrong(et)); }); }