2using System.Diagnostics;
 
    3using System.Linq.Expressions;
 
    4using 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);