using System.Linq.Expressions; using Connected.Expressions.Mappings; using ExpressionVisitor = Connected.Expressions.Visitors.ExpressionVisitor; namespace Connected.Expressions.Evaluation; internal sealed class ColumnNominator : ExpressionVisitor { private ColumnNominator() { Candidates = new HashSet(); } private HashSet Candidates { get; set; } private bool CannotBeEvaluated { get; set; } public static HashSet Nominate(Expression expression) { var nominator = new ColumnNominator(); nominator.Visit(expression); return nominator.Candidates; } protected override Expression? Visit(Expression? expression) { if (expression is not null) { var saveCannotBeEvaluated = CannotBeEvaluated; CannotBeEvaluated = false; base.Visit(expression); if (!CannotBeEvaluated) { if (MappingsCache.CanEvaluateLocally(expression)) Candidates.Add(expression); else CannotBeEvaluated = true; } CannotBeEvaluated |= saveCannotBeEvaluated; } return expression; } }