/// <summary> /// Builds an expression for the given <paramref name="target"/>. /// </summary> /// <param name="target">The target whose expression is to be built.</param> /// <param name="context">The compilation context.</param> /// <param name="compiler">The expression compiler to be used to build any other expressions for targets /// which might be required by the <paramref name="target" />. Note that unlike on the interface, where this /// parameter is optional, this will always be provided</param> protected override Expression Build(ExpressionTarget target, IExpressionCompileContext context, IExpressionCompiler compiler) { // reasonably simple - get the underlying expression, push it through the ExpressionTranslator to perform any parameter augmentations // or conversion to other targets (like ResolvedTarget, CconstructorTarget etc) and then push the result through a // TargetExpressionRewriter to compile any newly created targets into their respective expressions and into the resulting // expression. var translator = new ExpressionTranslator(context); var translated = translator.Visit(target.ExpressionFactory != null ? target.ExpressionFactory(context) : target.Expression); // the translator does lots of things - including identifying common code constructs which have rich target equivalents - such as // the NewExpression being the same as the ConstructorTarget. When it creates a target in place of an expression, it wrap it // inside a TargetExpression - so these then have to be compiled again via the TargetExpressionRewriter. var targetRewriter = new TargetExpressionRewriter(compiler, context); return(targetRewriter.Visit(translated)); }