44
55namespace TagExpressions ;
66
7- // Abstract base class implementing the interface
7+ /// <summary>
8+ /// Provides an abstract base for tag expressions that can be evaluated against a set of input tags.
9+ /// </summary>
810public abstract class TagExpression : ITagExpression
911{
10- // Public API
12+ /// <summary>
13+ /// Evaluates the tag expression against the provided input tags.
14+ /// </summary>
15+ /// <param name="inputs">A collection of input tags to evaluate against.</param>
16+ /// <returns><c>true</c> if the expression matches the inputs; otherwise, <c>false</c>.</returns>
1117 public bool Evaluate ( IEnumerable < string > inputs )
1218 {
1319 var inputSet = new HashSet < string > ( inputs ) ;
1420 return EvaluateInternal ( inputSet ) ;
1521 }
1622
23+ /// <summary>
24+ /// Returns the string representation of the tag expression.
25+ /// </summary>
26+ /// <returns>A string that represents the tag expression.</returns>
1727 public abstract override string ToString ( ) ;
1828
19- // Internal recursive evaluation method
29+ /// <summary>
30+ /// Recursively evaluates the tag expression against the provided set of input tags.
31+ /// </summary>
32+ /// <param name="inputs">A set of input tags.</param>
33+ /// <returns><c>true</c> if the expression matches the inputs; otherwise, <c>false</c>.</returns>
2034 internal abstract bool EvaluateInternal ( HashSet < string > inputs ) ;
2135}
2236
2337/// <summary>
2438/// Represents an expression that always evaluates to <see langword="true"/>.
2539/// </summary>
26- /// <remarks>This expression is used as a fallback condition when the expression input is empty.
27- /// By convention, an empty tag expression is considered equivalent to <see langword="true"/> regardless of input.</remarks>
40+ /// <remarks>
41+ /// This expression is used as a fallback condition when the expression input is empty.
42+ /// By convention, an empty tag expression is considered equivalent to <see langword="true"/> regardless of input.
43+ /// </remarks>
2844public class NullExpression : TagExpression
2945{
46+ /// <inheritdoc/>
3047 public override string ToString ( ) => "true" ;
48+ /// <inheritdoc/>
3149 internal override bool EvaluateInternal ( HashSet < string > inputs ) => true ;
3250}
3351
34- // Leaf node representing literals (variables)
52+ /// <summary>
53+ /// Represents a leaf node for a tag expression, corresponding to a literal tag name.
54+ /// </summary>
3555public class LiteralNode : TagExpression
3656{
57+ /// <summary>
58+ /// Gets the name of the literal tag.
59+ /// </summary>
3760 public string Name { get ; }
61+
62+ /// <summary>
63+ /// Initializes a new instance of the <see cref="LiteralNode"/> class.
64+ /// </summary>
65+ /// <param name="name">The name of the tag.</param>
3866 public LiteralNode ( string name ) => Name = name ;
3967
68+ /// <inheritdoc/>
4069 public override string ToString ( )
4170 {
4271 var sb = new StringBuilder ( ) ;
@@ -49,44 +78,75 @@ public override string ToString()
4978 return sb . ToString ( ) ;
5079 }
5180
81+ /// <inheritdoc/>
5282 internal override bool EvaluateInternal ( HashSet < string > inputs ) => inputs . Contains ( Name ) ;
5383}
5484
55- // Unary NOT node
85+ /// <summary>
86+ /// Represents a unary NOT operation in a tag expression.
87+ /// </summary>
5688public class NotNode : TagExpression
5789{
90+ /// <summary>
91+ /// Gets the operand of the NOT operation.
92+ /// </summary>
5893 public ITagExpression Operand { get ; }
94+
95+ /// <summary>
96+ /// Initializes a new instance of the <see cref="NotNode"/> class.
97+ /// </summary>
98+ /// <param name="operand">The operand expression to negate.</param>
5999 public NotNode ( ITagExpression operand ) => Operand = operand ;
60100
101+ /// <inheritdoc/>
61102 public override string ToString ( )
62103 {
63104 string operandStr = Operand is not BinaryOpNode ? $ "( { Operand } )" : Operand . ToString ( ) ;
64105 return $ "not { operandStr } ";
65106 }
66107
67- internal override bool EvaluateInternal ( HashSet < string > inputs ) => ! ( ( ( TagExpression ) Operand ) . EvaluateInternal ( inputs ) ) ;
108+ /// <inheritdoc/>
109+ internal override bool EvaluateInternal ( HashSet < string > inputs ) => ! ( ( ( TagExpression ) Operand ) . EvaluateInternal ( inputs ) ) ;
68110}
69111
70- // Binary operator node for AND / OR
112+ /// <summary>
113+ /// Represents a binary operator node for AND and OR operations in a tag expression.
114+ /// </summary>
71115public class BinaryOpNode : TagExpression
72116{
117+ /// <summary>
118+ /// Gets the left operand of the binary operation.
119+ /// </summary>
73120 public ITagExpression Left { get ; }
121+ /// <summary>
122+ /// Gets the right operand of the binary operation.
123+ /// </summary>
74124 public ITagExpression Right { get ; }
75- public string Op { get ; } // "AND" or "OR"
76-
125+ /// <summary>
126+ /// Gets the operator for the binary operation ("AND" or "OR").
127+ /// </summary>
128+ public string Op { get ; }
129+
130+ /// <summary>
131+ /// Initializes a new instance of the <see cref="BinaryOpNode"/> class.
132+ /// </summary>
133+ /// <param name="op">The operator ("AND" or "OR").</param>
134+ /// <param name="left">The left operand.</param>
135+ /// <param name="right">The right operand.</param>
77136 public BinaryOpNode ( string op , ITagExpression left , ITagExpression right )
78137 {
79138 Op = op ;
80139 Left = left ;
81140 Right = right ;
82141 }
83142
143+ /// <inheritdoc/>
84144 public override string ToString ( )
85145 {
86146 string leftStr = Left is BinaryOpNode leftBin && Precedence ( leftBin . Op ) < Precedence ( Op )
87- ? $ "( { Left } )" : Left . ToString ( ) ;
147+ ? $ "( { Left } )" : Left . ToString ( ) ;
88148 string rightStr = Right is BinaryOpNode rightBin && Precedence ( rightBin . Op ) < Precedence ( Op )
89- ? $ "( { Right } )" : Right . ToString ( ) ;
149+ ? $ "( { Right } )" : Right . ToString ( ) ;
90150 return $ "( { leftStr } { Op } { rightStr } )";
91151 }
92152
@@ -95,6 +155,7 @@ private int Precedence(string op) =>
95155 op == "and" ? 2 :
96156 op == "or" ? 1 : 0 ;
97157
158+ /// <inheritdoc/>
98159 internal override bool EvaluateInternal ( HashSet < string > inputs )
99160 {
100161 bool leftVal = ( ( TagExpression ) Left ) . EvaluateInternal ( inputs ) ;
0 commit comments