forked from aspnet/AspNetWebStack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHoistingExpressionVisitor.cs
More file actions
38 lines (31 loc) · 1.63 KB
/
Copy pathHoistingExpressionVisitor.cs
File metadata and controls
38 lines (31 loc) · 1.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Linq.Expressions;
namespace System.Web.Mvc.ExpressionUtil
{
// This is a visitor which rewrites constant expressions as parameter lookups. It's meant
// to produce an expression which can be cached safely.
internal sealed class HoistingExpressionVisitor<TIn, TOut> : ExpressionVisitor
{
private static readonly ParameterExpression _hoistedConstantsParamExpr = Expression.Parameter(typeof(List<object>), "hoistedConstants");
private int _numConstantsProcessed;
// factory will create instance
private HoistingExpressionVisitor()
{
}
public static Expression<Hoisted<TIn, TOut>> Hoist(Expression<Func<TIn, TOut>> expr)
{
// rewrite Expression<Func<TIn, TOut>> as Expression<Hoisted<TIn, TOut>>
var visitor = new HoistingExpressionVisitor<TIn, TOut>();
var rewrittenBodyExpr = visitor.Visit(expr.Body);
var rewrittenLambdaExpr = Expression.Lambda<Hoisted<TIn, TOut>>(rewrittenBodyExpr, expr.Parameters[0], _hoistedConstantsParamExpr);
return rewrittenLambdaExpr;
}
protected override Expression VisitConstant(ConstantExpression node)
{
// rewrite the constant expression as (TConst)hoistedConstants[i];
return Expression.Convert(Expression.Property(_hoistedConstantsParamExpr, "Item", Expression.Constant(_numConstantsProcessed++)), node.Type);
}
}
}