<PackageReference Include="NUnit" Version="4.1.0" />

ConstraintBuilder

public sealed class ConstraintBuilder : IResolveConstraint
ConstraintBuilder maintains the stacks that are used in processing a ConstraintExpression. An OperatorStack is used to hold operators that are waiting for their operands to be reorganized. a ConstraintStack holds input constraints as well as the results of each operator applied.
using System; using System.Collections.Generic; using System.Runtime.CompilerServices; namespace NUnit.Framework.Constraints { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] public sealed class ConstraintBuilder : IResolveConstraint { [System.Runtime.CompilerServices.Nullable(0)] private sealed class OperatorStack { private readonly Stack<ConstraintOperator> _stack = new Stack<ConstraintOperator>(); public bool Empty => _stack.Count == 0; public ConstraintOperator Top => _stack.Peek(); public void Push(ConstraintOperator op) { _stack.Push(op); } public ConstraintOperator Pop() { return _stack.Pop(); } } [System.Runtime.CompilerServices.Nullable(0)] public sealed class ConstraintStack { private readonly Stack<IConstraint> _stack = new Stack<IConstraint>(); private readonly ConstraintBuilder _builder; public bool Empty => _stack.Count == 0; public ConstraintStack(ConstraintBuilder builder) { _builder = builder; } public void Push(IConstraint constraint) { _stack.Push(constraint); constraint.Builder = _builder; } public IConstraint Pop() { IConstraint constraint = _stack.Pop(); constraint.Builder = null; return constraint; } } private readonly OperatorStack _ops; private readonly ConstraintStack _constraints; [System.Runtime.CompilerServices.Nullable(2)] private object _lastPushed; private bool IsResolvable { get { if (!(_lastPushed is Constraint)) return _lastPushed is SelfResolvingOperator; return true; } } public ConstraintBuilder() { _ops = new OperatorStack(); _constraints = new ConstraintStack(this); } public void Append(ConstraintOperator op) { op.LeftContext = _lastPushed; if (_lastPushed is ConstraintOperator) SetTopOperatorRightContext(op); ReduceOperatorStack(op.LeftPrecedence); _ops.Push(op); _lastPushed = op; } public void Append(Constraint constraint) { if (_lastPushed is ConstraintOperator) SetTopOperatorRightContext(constraint); _constraints.Push(constraint); _lastPushed = constraint; constraint.Builder = this; } private void SetTopOperatorRightContext(object rightContext) { int leftPrecedence = _ops.Top.LeftPrecedence; _ops.Top.RightContext = rightContext; if (_ops.Top.LeftPrecedence > leftPrecedence) { ConstraintOperator constraintOperator = _ops.Pop(); ReduceOperatorStack(constraintOperator.LeftPrecedence); _ops.Push(constraintOperator); } } private void ReduceOperatorStack(int targetPrecedence) { while (!_ops.Empty && _ops.Top.RightPrecedence < targetPrecedence) { _ops.Pop().Reduce(_constraints); } } public IConstraint Resolve() { if (!IsResolvable) throw new InvalidOperationException("A partial expression may not be resolved"); while (!_ops.Empty) { ConstraintOperator constraintOperator = _ops.Pop(); constraintOperator.Reduce(_constraints); } return _constraints.Pop(); } } }