[NUI] Rebase develnui (DevelNUI only patches --> master) (#3910)
[platform/core/csapi/tizenfx.git] / test / Tizen.NUI.Devel.Tests.Ubuntu / nunit.framework / Constraints / ConstraintBuilder.cs
1 // ***********************************************************************
2 // Copyright (c) 2007 Charlie Poole
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
11 // 
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 // 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 // ***********************************************************************
23 #define PORTABLE
24 #define TIZEN
25 #define NUNIT_FRAMEWORK
26 #define NUNITLITE
27 #define NET_4_5
28 #define PARALLEL
29 using System;
30 using System.Collections.Generic;
31
32 namespace NUnit.Framework.Constraints
33 {
34     /// <summary>
35     /// ConstraintBuilder maintains the stacks that are used in
36     /// processing a ConstraintExpression. An OperatorStack
37     /// is used to hold operators that are waiting for their
38     /// operands to be reorganized. a ConstraintStack holds 
39     /// input constraints as well as the results of each
40     /// operator applied.
41     /// </summary>
42     public class ConstraintBuilder : IResolveConstraint
43     {
44         #region Nested Operator Stack Class
45
46         /// <summary>
47         /// OperatorStack is a type-safe stack for holding ConstraintOperators
48         /// </summary>
49         public class OperatorStack
50         {
51             private readonly Stack<ConstraintOperator> stack = new Stack<ConstraintOperator>();
52
53             /// <summary>
54             /// Initializes a new instance of the <see cref="OperatorStack"/> class.
55             /// </summary>
56             /// <param name="builder">The ConstraintBuilder using this stack.</param>
57             public OperatorStack(ConstraintBuilder builder)
58             {
59             }
60
61             /// <summary>
62             /// Gets a value indicating whether this <see cref="OperatorStack"/> is empty.
63             /// </summary>
64             /// <value><c>true</c> if empty; otherwise, <c>false</c>.</value>
65             public bool Empty
66             {
67                 get { return stack.Count == 0; }
68             }
69
70             /// <summary>
71             /// Gets the topmost operator without modifying the stack.
72             /// </summary>
73             public ConstraintOperator Top
74             {
75                 get { return stack.Peek(); }
76             }
77
78             /// <summary>
79             /// Pushes the specified operator onto the stack.
80             /// </summary>
81             /// <param name="op">The operator to put onto the stack.</param>
82             public void Push(ConstraintOperator op)
83             {
84                 stack.Push(op);
85             }
86
87             /// <summary>
88             /// Pops the topmost operator from the stack.
89             /// </summary>
90             /// <returns>The topmost operator on the stack</returns>
91             public ConstraintOperator Pop()
92             {
93                 return stack.Pop();
94             }
95         }
96
97         #endregion
98
99         #region Nested Constraint Stack Class
100
101         /// <summary>
102         /// ConstraintStack is a type-safe stack for holding Constraints
103         /// </summary>
104         public class ConstraintStack
105         {
106             private readonly Stack<IConstraint> stack = new Stack<IConstraint>();
107             private readonly ConstraintBuilder builder;
108
109             /// <summary>
110             /// Initializes a new instance of the <see cref="ConstraintStack"/> class.
111             /// </summary>
112             /// <param name="builder">The ConstraintBuilder using this stack.</param>
113             public ConstraintStack(ConstraintBuilder builder)
114             {
115                 this.builder = builder;
116             }
117
118             /// <summary>
119             /// Gets a value indicating whether this <see cref="ConstraintStack"/> is empty.
120             /// </summary>
121             /// <value><c>true</c> if empty; otherwise, <c>false</c>.</value>
122             public bool Empty
123             {
124                 get { return stack.Count == 0; }
125             }
126
127             /// <summary>
128             /// Pushes the specified constraint. As a side effect,
129             /// the constraint's Builder field is set to the 
130             /// ConstraintBuilder owning this stack.
131             /// </summary>
132             /// <param name="constraint">The constraint to put onto the stack</param>
133             public void Push(IConstraint constraint)
134             {
135                 stack.Push(constraint);
136                 constraint.Builder = this.builder;
137             }
138
139             /// <summary>
140             /// Pops this topmost constraint from the stack.
141             /// As a side effect, the constraint's Builder
142             /// field is set to null.
143             /// </summary>
144             /// <returns>The topmost contraint on the stack</returns>
145             public IConstraint Pop()
146             {
147                 IConstraint constraint = stack.Pop();
148                 constraint.Builder = null;
149                 return constraint;
150             }
151         }
152
153         #endregion
154
155         #region Instance Fields
156
157         private readonly OperatorStack ops;
158
159         private readonly ConstraintStack constraints;
160
161         private object lastPushed;
162
163         #endregion
164
165         #region Constructor
166
167         /// <summary>
168         /// Initializes a new instance of the <see cref="ConstraintBuilder"/> class.
169         /// </summary>
170         public ConstraintBuilder()
171         {
172             this.ops = new OperatorStack(this);
173             this.constraints = new ConstraintStack(this);
174         }
175
176         #endregion
177
178         #region Public Methods
179
180         /// <summary>
181         /// Appends the specified operator to the expression by first
182         /// reducing the operator stack and then pushing the new
183         /// operator on the stack.
184         /// </summary>
185         /// <param name="op">The operator to push.</param>
186         public void Append(ConstraintOperator op)
187         {
188             op.LeftContext = lastPushed;
189             if (lastPushed is ConstraintOperator)
190                 SetTopOperatorRightContext(op);
191
192             // Reduce any lower precedence operators
193             ReduceOperatorStack(op.LeftPrecedence);
194             
195             ops.Push(op);
196             lastPushed = op;
197         }
198
199         /// <summary>
200         /// Appends the specified constraint to the expression by pushing
201         /// it on the constraint stack.
202         /// </summary>
203         /// <param name="constraint">The constraint to push.</param>
204         public void Append(Constraint constraint)
205         {
206             if (lastPushed is ConstraintOperator)
207                 SetTopOperatorRightContext(constraint);
208
209             constraints.Push(constraint);
210             lastPushed = constraint;
211             constraint.Builder = this;
212         }
213
214         /// <summary>
215         /// Sets the top operator right context.
216         /// </summary>
217         /// <param name="rightContext">The right context.</param>
218         private void SetTopOperatorRightContext(object rightContext)
219         {
220             // Some operators change their precedence based on
221             // the right context - save current precedence.
222             int oldPrecedence = ops.Top.LeftPrecedence;
223
224             ops.Top.RightContext = rightContext;
225
226             // If the precedence increased, we may be able to
227             // reduce the region of the stack below the operator
228             if (ops.Top.LeftPrecedence > oldPrecedence)
229             {
230                 ConstraintOperator changedOp = ops.Pop();
231                 ReduceOperatorStack(changedOp.LeftPrecedence);
232                 ops.Push(changedOp);
233             }
234         }
235
236         /// <summary>
237         /// Reduces the operator stack until the topmost item
238         /// precedence is greater than or equal to the target precedence.
239         /// </summary>
240         /// <param name="targetPrecedence">The target precedence.</param>
241         private void ReduceOperatorStack(int targetPrecedence)
242         {
243             while (!ops.Empty && ops.Top.RightPrecedence < targetPrecedence)
244                 ops.Pop().Reduce(constraints);
245         }
246
247         #endregion
248
249         #region IResolveConstraint Implementation
250
251         /// <summary>
252         /// Resolves this instance, returning a Constraint. If the Builder
253         /// is not currently in a resolvable state, an exception is thrown.
254         /// </summary>
255         /// <returns>The resolved constraint</returns>
256         public IConstraint Resolve()
257         {
258             if (!IsResolvable)
259                 throw new InvalidOperationException("A partial expression may not be resolved");
260
261             while (!ops.Empty)
262             {
263                 ConstraintOperator op = ops.Pop();
264                 op.Reduce(constraints);
265             }
266
267             return constraints.Pop();
268         }
269
270         #endregion
271
272         #region Helper Methods
273
274         /// <summary>
275         /// Gets a value indicating whether this instance is resolvable.
276         /// </summary>
277         /// <value>
278         ///     <c>true</c> if this instance is resolvable; otherwise, <c>false</c>.
279         /// </value>
280         private bool IsResolvable
281         {
282             get { return lastPushed is Constraint || lastPushed is SelfResolvingOperator; }
283         }
284
285         #endregion
286     }
287 }