1using System.Diagnostics;
2using System.Linq.Expressions;
3using System.Reflection;
8internal class ProjectionAnalysisVisitor : ExpressionVisitor
10 private readonly LookupTable _l;
11 private readonly ParameterExpression _param;
13 public HashSet<PropertyInfo> Accesses {
get; } =
new();
14 public bool Escapes {
get;
private set; } =
false;
16 public ProjectionAnalysisVisitor(
MappingContext ctx, ParameterExpression param)
18 _l =
new LookupTable(ctx);
22 protected override Expression VisitMember(MemberExpression node)
25 if (node.Expression == _param &&
26 node.Member is PropertyInfo prop &&
27 _l.HasField(prop, node.Expression))
33 return base.VisitMember(node);
36 protected override Expression VisitMethodCall(MethodCallExpression node)
39 return base.VisitMethodCall(node);
42 protected override Expression VisitParameter(ParameterExpression node)
50 return base.VisitParameter(node);
54internal class ProjectionRewriteVisitor : ExpressionVisitor
56 private readonly ParameterExpression _param;
57 private readonly PropertyInfo[] _props;
58 private readonly Expression[] _fieldAccesses;
60 public ProjectionRewriteVisitor(
61 ParameterExpression doc,
63 ParameterExpression projected)
65 var accesses =
new Expression[props.Length];
67 for (var i = 0; i < props.Length; i++)
69 accesses[i] = Expression.Convert(
70 Expression.ArrayIndex(projected, Expression.Constant(i)),
71 props[i].PropertyType);
76 _fieldAccesses = accesses;
79 protected override Expression VisitMember(MemberExpression node)
81 if (node.Expression == _param)
83 var prop = node.Member as PropertyInfo;
85 Debug.Assert(prop is not
null);
87 for (var i = 0; idx < 0 && i < _props.Length; i++)
89 if (_props[i] == prop)
95 Debug.Assert(idx >= 0);
97 return _fieldAccesses[idx];
100 return base.VisitMember(node);
A class representing the mapping context to be used during serialization and deserialization.