Skip to content

Commit 38a28f4

Browse files
authored
Optimize GenericExpressionVisitor (#371)
1 parent f3518bb commit 38a28f4

File tree

3 files changed

+47
-60
lines changed

3 files changed

+47
-60
lines changed

Orm/Xtensive.Orm/Orm/Linq/Expressions/ConstructorExpression.cs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ internal sealed class ConstructorExpression : ParameterizedExpression
3030

3131
public override Expression BindParameter(ParameterExpression parameter, Dictionary<Expression, Expression> processedExpressions)
3232
{
33-
Func<Expression, Expression> genericBinder =
34-
e => GenericExpressionVisitor<IMappedExpression>.Process(e, mapped => mapped.BindParameter(parameter, processedExpressions));
33+
GenericExpressionVisitor<IMappedExpression> genericVisitor = new(mapped => mapped.BindParameter(parameter, processedExpressions));
34+
var genericBinder = genericVisitor.Process;
3535
return new ConstructorExpression(
3636
Type,
3737
Bindings.ToDictionary(kvp => kvp.Key, kvp => genericBinder(kvp.Value)),
@@ -42,8 +42,8 @@ public override Expression BindParameter(ParameterExpression parameter, Dictiona
4242

4343
public override Expression RemoveOuterParameter(Dictionary<Expression, Expression> processedExpressions)
4444
{
45-
Func<Expression, Expression> genericRemover =
46-
e => GenericExpressionVisitor<IMappedExpression>.Process(e, mapped => mapped.RemoveOuterParameter(processedExpressions));
45+
GenericExpressionVisitor<IMappedExpression> genericVisitor = new(mapped => mapped.RemoveOuterParameter(processedExpressions));
46+
var genericRemover = genericVisitor.Process;
4747
var result = new ConstructorExpression(
4848
Type,
4949
Bindings.ToDictionary(kvp => kvp.Key, kvp => genericRemover(kvp.Value)),
@@ -61,10 +61,10 @@ public override Expression Remap(ColNum offset, Dictionary<Expression, Expressio
6161
return mapped.Remap(offset, new Dictionary<Expression, Expression>());
6262
return (Expression) mapped;
6363
};
64-
var newBindings = Bindings.ToDictionary(kvp => kvp.Key, kvp => GenericExpressionVisitor<IMappedExpression>.Process(kvp.Value, remapper));
65-
var newConstructorArguments = ConstructorArguments
66-
.Select(arg => GenericExpressionVisitor<IMappedExpression>.Process(arg, remapper)).ToArray();
67-
var newNativeBindings = NativeBindings.ToDictionary(kvp => kvp.Key, kvp => GenericExpressionVisitor<IMappedExpression>.Process(kvp.Value, remapper));
64+
GenericExpressionVisitor<IMappedExpression> genericVisitor = new(remapper);
65+
var newBindings = Bindings.ToDictionary(kvp => kvp.Key, kvp => genericVisitor.Process(kvp.Value));
66+
var newConstructorArguments = ConstructorArguments.Select(genericVisitor.Process).ToArray();
67+
var newNativeBindings = NativeBindings.ToDictionary(kvp => kvp.Key, kvp => genericVisitor.Process(kvp.Value));
6868
var result = new ConstructorExpression(
6969
Type,
7070
newBindings,
@@ -82,9 +82,10 @@ public override Expression Remap(ColumnMap map, Dictionary<Expression, Expressio
8282
return mapped.Remap(map, new Dictionary<Expression, Expression>());
8383
return (Expression) mapped;
8484
};
85-
var newBindings = Bindings.ToDictionary(kvp => kvp.Key, kvp => GenericExpressionVisitor<IMappedExpression>.Process(kvp.Value, remapper));
86-
var newConstructorArguments = ConstructorArguments.Select(arg => GenericExpressionVisitor<IMappedExpression>.Process(arg, remapper)).ToArray();
87-
var newNativeBindings = NativeBindings.ToDictionary(kvp => kvp.Key, kvp => GenericExpressionVisitor<IMappedExpression>.Process(kvp.Value, remapper));
85+
GenericExpressionVisitor<IMappedExpression> genericVisitor = new(remapper);
86+
var newBindings = Bindings.ToDictionary(kvp => kvp.Key, kvp => genericVisitor.Process(kvp.Value));
87+
var newConstructorArguments = ConstructorArguments.Select(genericVisitor.Process).ToArray();
88+
var newNativeBindings = NativeBindings.ToDictionary(kvp => kvp.Key, kvp => genericVisitor.Process(kvp.Value));
8889
return new ConstructorExpression(Type, newBindings, newNativeBindings, Constructor, newConstructorArguments);
8990
}
9091

@@ -99,4 +100,4 @@ public ConstructorExpression(Type type, Dictionary<MemberInfo, Expression> bindi
99100
Constructor = constructor;
100101
}
101102
}
102-
}
103+
}

Orm/Xtensive.Orm/Orm/Linq/Expressions/SubQueryExpression.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,7 @@ public override SubQueryExpression Remap(ColumnMap map, Dictionary<Expression, E
8383

8484
// Remap Field parametrized parameters
8585
var item = GenericExpressionVisitor<IMappedExpression>.Process(ProjectionExpression.ItemProjector.Item, mapped => {
86-
var parametrizedExpression = mapped as ParameterizedExpression;
87-
if (parametrizedExpression!=null && parametrizedExpression.OuterParameter==OuterParameter)
86+
if (mapped is ParameterizedExpression parametrizedExpression && parametrizedExpression.OuterParameter==OuterParameter)
8887
return mapped.Remap(map, new Dictionary<Expression, Expression>());
8988
return (Expression) mapped;
9089
});
@@ -133,4 +132,4 @@ public SubQueryExpression(Type type, ParameterExpression parameterExpression, bo
133132
ApplyParameter = applyParameter;
134133
}
135134
}
136-
}
135+
}

Orm/Xtensive.Orm/Orm/Linq/Expressions/Visitors/GenericExpressionVisitor.cs

Lines changed: 32 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,59 +4,46 @@
44
// Created by: Alexis Kochetov
55
// Created: 2009.05.21
66

7-
using System;
87
using System.Linq.Expressions;
98
using ExpressionVisitor = Xtensive.Linq.ExpressionVisitor;
109

11-
namespace Xtensive.Orm.Linq.Expressions.Visitors
12-
{
13-
internal sealed class GenericExpressionVisitor<T> : ExpressionVisitor
14-
where T : class
15-
{
16-
private readonly Func<T, Expression> genericProcessor;
10+
namespace Xtensive.Orm.Linq.Expressions.Visitors;
1711

18-
public static Expression Process(Expression target, Func<T, Expression> genericProcessor)
19-
{
20-
var visitor = new GenericExpressionVisitor<T>(genericProcessor);
21-
22-
if (RemapScope.CurrentContext!=null)
23-
return visitor.Visit(target);
12+
internal sealed class GenericExpressionVisitor<T>(Func<T, Expression> genericProcessor) : ExpressionVisitor
13+
where T : class
14+
{
15+
public static Expression Process(Expression target, Func<T, Expression> genericProcessor) =>
16+
new GenericExpressionVisitor<T>(genericProcessor).Process(target);
2417

25-
using (new RemapScope())
26-
return visitor.Visit(target);
27-
}
18+
public Expression Process(Expression target)
19+
{
20+
if (RemapScope.CurrentContext!=null)
21+
return Visit(target);
2822

29-
protected override Expression VisitUnknown(Expression e)
30-
{
31-
var mapped = e as T;
32-
if (mapped!=null)
33-
return VisitGenericExpression(mapped);
34-
35-
var extendedExpression = e as ExtendedExpression;
36-
if (extendedExpression != null && extendedExpression.ExtendedType == ExtendedExpressionType.Marker) {
37-
var marker = (MarkerExpression) e;
38-
var result = Visit(marker.Target);
39-
if (result == marker.Target)
40-
return result;
41-
return new MarkerExpression(result, marker.MarkerType);
42-
}
43-
44-
return base.VisitUnknown(e);
45-
}
23+
using (new RemapScope())
24+
return Visit(target);
25+
}
4626

47-
private Expression VisitGenericExpression(T generic)
48-
{
49-
if (genericProcessor!=null)
50-
return genericProcessor.Invoke(generic);
51-
throw new NotSupportedException(Strings.ExUnableToUseBaseImplementationOfVisitGenericExpressionWithoutSpecifyingGenericProcessorDelegate);
27+
protected override Expression VisitUnknown(Expression e)
28+
{
29+
if (e is T mapped)
30+
return VisitGenericExpression(mapped);
31+
32+
if (e is ExtendedExpression extendedExpression && extendedExpression.ExtendedType == ExtendedExpressionType.Marker) {
33+
var marker = (MarkerExpression) e;
34+
var result = Visit(marker.Target);
35+
if (result == marker.Target)
36+
return result;
37+
return new MarkerExpression(result, marker.MarkerType);
5238
}
5339

40+
return base.VisitUnknown(e);
41+
}
5442

55-
// Constructors
56-
57-
private GenericExpressionVisitor(Func<T, Expression> mappingProcessor)
58-
{
59-
genericProcessor = mappingProcessor;
60-
}
43+
private Expression VisitGenericExpression(T generic)
44+
{
45+
if (genericProcessor!=null)
46+
return genericProcessor.Invoke(generic);
47+
throw new NotSupportedException(Strings.ExUnableToUseBaseImplementationOfVisitGenericExpressionWithoutSpecifyingGenericProcessorDelegate);
6148
}
62-
}
49+
}

0 commit comments

Comments
 (0)