Fauna v10 .NET/C# Driver 1.0.0
 
Loading...
Searching...
No Matches
ProjectionVisitors.cs
Go to the documentation of this file.
1using System.Diagnostics;
2using System.Linq.Expressions;
3using System.Reflection;
4using Fauna.Mapping;
5
6namespace Fauna.Linq;
7
8internal class ProjectionAnalysisVisitor : ExpressionVisitor
9{
10 private readonly LookupTable _l;
11 private readonly ParameterExpression _param;
12
13 public HashSet<PropertyInfo> Accesses { get; } = new();
14 public bool Escapes { get; private set; } = false;
15
16 public ProjectionAnalysisVisitor(MappingContext ctx, ParameterExpression param)
17 {
18 _l = new LookupTable(ctx);
19 _param = param;
20 }
21
22 protected override Expression VisitMember(MemberExpression node)
23 {
24 // FIXME handle chaining
25 if (node.Expression == _param &&
26 node.Member is PropertyInfo prop &&
27 _l.HasField(prop, node.Expression))
28 {
29 Accesses.Add(prop);
30 return node;
31 }
32
33 return base.VisitMember(node);
34 }
35
36 protected override Expression VisitMethodCall(MethodCallExpression node)
37 {
38 // FIXME(matt) handle these by checking arg FQL purity
39 return base.VisitMethodCall(node);
40 }
41
42 protected override Expression VisitParameter(ParameterExpression node)
43 {
44 if (node == _param)
45 {
46 Escapes = true;
47 return node;
48 }
49
50 return base.VisitParameter(node);
51 }
52}
53
54internal class ProjectionRewriteVisitor : ExpressionVisitor
55{
56 private readonly ParameterExpression _param;
57 private readonly PropertyInfo[] _props;
58 private readonly Expression[] _fieldAccesses;
59
60 public ProjectionRewriteVisitor(
61 ParameterExpression doc,
62 PropertyInfo[] props,
63 ParameterExpression projected)
64 {
65 var accesses = new Expression[props.Length];
66
67 for (var i = 0; i < props.Length; i++)
68 {
69 accesses[i] = Expression.Convert(
70 Expression.ArrayIndex(projected, Expression.Constant(i)),
71 props[i].PropertyType);
72 }
73
74 _param = doc;
75 _props = props;
76 _fieldAccesses = accesses;
77 }
78
79 protected override Expression VisitMember(MemberExpression node)
80 {
81 if (node.Expression == _param)
82 {
83 var prop = node.Member as PropertyInfo;
84 var idx = -1;
85 Debug.Assert(prop is not null);
86
87 for (var i = 0; idx < 0 && i < _props.Length; i++)
88 {
89 if (_props[i] == prop)
90 {
91 idx = i;
92 }
93 }
94
95 Debug.Assert(idx >= 0);
96
97 return _fieldAccesses[idx];
98 }
99
100 return base.VisitMember(node);
101 }
102}
A class representing the mapping context to be used during serialization and deserialization.