Datei: NDODLL/NDOql/Expressions/OqlExpression.cs
Last Commit (28c8c45)
| 1 | using System; |
| 2 | using System.Collections.Generic; |
| 3 | using System.Text; |
| 4 | using System.Globalization; |
| 5 | |
| 6 | namespace NDOql.Expressions |
| 7 | { |
| 8 | ····internal interface IManageExpression |
| 9 | ····{ |
| 10 | ········void SetParent( OqlExpression exp ); |
| 11 | ····} |
| 12 | |
| 13 | ····/// <summary> |
| 14 | ····/// Base class for Oql expressions |
| 15 | ····/// </summary> |
| 16 | ····public class OqlExpression : IManageExpression |
| 17 | ····{ |
| 18 | ········int line; |
| 19 | ········int col; |
| 20 | ········ExpressionType expressionType; |
| 21 | ········string unaryOp; |
| 22 | ········string op; |
| 23 | ········OqlExpression parent = null; |
| 24 | ········List<OqlExpression> children = new List<OqlExpression>(); |
| 25 | ········object value; |
| 26 | ········Dictionary<string, object> annotations = new Dictionary<string, object>(); |
| 27 | |
| 28 | ········/// <summary> |
| 29 | ········/// Sets an annotation for a certain experession node |
| 30 | ········/// </summary> |
| 31 | ········/// <param name="key"></param> |
| 32 | ········/// <param name="value"></param> |
| 33 | ········public void SetAnnotation(string key, object value) |
| 34 | ········{ |
| 35 | ············annotations[key] = value; |
| 36 | ········} |
| 37 | |
| 38 | ········/// <summary> |
| 39 | ········/// Gets an annotation for a node |
| 40 | ········/// </summary> |
| 41 | ········/// <typeparam name="T"></typeparam> |
| 42 | ········/// <param name="key"></param> |
| 43 | ········/// <returns></returns> |
| 44 | ········public T GetAnnotation<T>( string key ) |
| 45 | ········{ |
| 46 | ············if (!annotations.ContainsKey( key )) |
| 47 | ················return default(T); |
| 48 | |
| 49 | ············return (T)annotations[key]; |
| 50 | ········} |
| 51 | |
| 52 | ········/// <summary> |
| 53 | ········/// Gets or sets the line number where the expression appears |
| 54 | ········/// </summary> |
| 55 | ········public int Line |
| 56 | ········{ |
| 57 | ············get { return line; } |
| 58 | ············set { line = value; } |
| 59 | ········} |
| 60 | ········/// <summary> |
| 61 | ········/// Gets or sets the column in the line where the expression appears |
| 62 | ········/// </summary> |
| 63 | ········public int Column |
| 64 | ········{ |
| 65 | ············get { return col; } |
| 66 | ············set { col = value; } |
| 67 | ········} |
| 68 | |
| 69 | ········/// <summary> |
| 70 | ········/// Gets or sets the expression type |
| 71 | ········/// </summary> |
| 72 | ········public ExpressionType ExpressionType |
| 73 | ········{ |
| 74 | ············get { return expressionType; } |
| 75 | ············set { expressionType = value; } |
| 76 | ········} |
| 77 | |
| 78 | ········void ThrowUnaryException() |
| 79 | ········{ |
| 80 | ············throw new OqlExpressionException("Unary Operator doesn't fit to the type of the expression in '" + this.ToString() + "'. Line " + this.line + ", Col " + this.col); |
| 81 | ········} |
| 82 | |
| 83 | ········/// <summary> |
| 84 | ········/// Gets or sets an unary operator, if one exists |
| 85 | ········/// </summary> |
| 86 | ········public string UnaryOp |
| 87 | ········{ |
| 88 | ············get { return unaryOp; } |
| 89 | ············set |
| 90 | ············{ |
| 91 | ················unaryOp = value; |
| 92 | ················if (unaryOp == "NOT") |
| 93 | ················{ |
| 94 | ····················if (this.expressionType != ExpressionType.Boolean |
| 95 | ························&& this.expressionType != ExpressionType.Unknown) |
| 96 | ························ThrowUnaryException(); |
| 97 | ················} |
| 98 | ················else if (unaryOp == "~" || unaryOp == "-" || unaryOp == "+") |
| 99 | ················{ |
| 100 | ····················if (this.expressionType != ExpressionType.Number |
| 101 | ························&& this.expressionType != ExpressionType.Unknown) |
| 102 | ························ThrowUnaryException(); |
| 103 | ················} |
| 104 | ············} |
| 105 | ········} |
| 106 | |
| 107 | ········/// <summary> |
| 108 | ········/// Gets or sets an operator |
| 109 | ········/// </summary> |
| 110 | ········public string Operator |
| 111 | ········{ |
| 112 | ············get { return op; } |
| 113 | ············set { op = value; } |
| 114 | ········} |
| 115 | |
| 116 | ········bool hasBrackets; |
| 117 | ········/// <summary> |
| 118 | ········/// Gets or sets a value, which determines, if an expression should be bracketed |
| 119 | ········/// </summary> |
| 120 | ········public bool HasBrackets |
| 121 | ········{ |
| 122 | ············get { return hasBrackets; } |
| 123 | ············set { hasBrackets = value; } |
| 124 | ········} |
| 125 | |
| 126 | ········/// <summary> |
| 127 | ········/// Gets the child expressions |
| 128 | ········/// </summary> |
| 129 | ········public List<OqlExpression> Children |
| 130 | ········{ |
| 131 | ············get { return children; } |
| 132 | ········} |
| 133 | |
| 134 | ········/// <summary> |
| 135 | ········/// Gets the parent expression |
| 136 | ········/// </summary> |
| 137 | ········public OqlExpression Parent |
| 138 | ········{ |
| 139 | ············get { return this.parent; } |
| 140 | ········} |
| 141 | |
| 142 | ········/// <summary> |
| 143 | ········/// </summary> |
| 144 | ········/// <param name="exp"></param> |
| 145 | ········/// <remarks> |
| 146 | ········/// Since there occurs a lot of shuffling around the children during the parse process |
| 147 | ········/// we itererate through the tree after parsing and set the parent there. |
| 148 | ········/// </remarks> |
| 149 | ········void IManageExpression.SetParent( OqlExpression exp ) |
| 150 | ········{ |
| 151 | ············this.parent = exp; |
| 152 | ········} |
| 153 | |
| 154 | ········/// <summary> |
| 155 | ········/// Gets the value of the expression |
| 156 | ········/// </summary> |
| 157 | ········public object Value |
| 158 | ········{ |
| 159 | ············get { return this.value; } |
| 160 | ············set { this.value = value; } |
| 161 | ········} |
| 162 | |
| 163 | ········/// <summary> |
| 164 | ········/// Constructor |
| 165 | ········/// </summary> |
| 166 | ········/// <param name="line"></param> |
| 167 | ········/// <param name="col"></param> |
| 168 | ········public OqlExpression(int line, int col) |
| 169 | ········{ |
| 170 | ············this.line = line; |
| 171 | ············this.col = col; |
| 172 | ········} |
| 173 | |
| 174 | ········/// <summary> |
| 175 | ········/// Determines, if an expression is a leaf in the tree. |
| 176 | ········/// </summary> |
| 177 | ········public virtual bool IsTerminating |
| 178 | ········{ |
| 179 | ············get { return this.children.Count == 0; } |
| 180 | ········} |
| 181 | |
| 182 | ········/// <summary> |
| 183 | ········/// Reduces an expression |
| 184 | ········/// </summary> |
| 185 | ········/// <returns></returns> |
| 186 | public OqlExpression Simplify( ) |
| 187 | ········{ |
| 188 | ············System.Diagnostics.Debug.Assert(this.children.Count != 0 || this.value != null); |
| 189 | ············if (this.children.Count > 1 || this.IsTerminating) |
| 190 | ················return this; |
| 191 | ············if (unaryOp != null) |
| 192 | ············{ |
| 193 | ················if (this.children[0].unaryOp == null && !this.children[0].hasBrackets) |
| 194 | ················{ |
| 195 | ····················this.children[0].unaryOp = this.unaryOp; |
| 196 | ····················return this.children[0]; |
| 197 | ················} |
| 198 | ················else |
| 199 | ················{ |
| 200 | ····················return this; |
| 201 | ················} |
| 202 | ············} |
| 203 | ············return this.children[0]; |
| 204 | ········} |
| 205 | |
| 206 | ········/// <summary> |
| 207 | ········/// Adds a child expressoin |
| 208 | ········/// </summary> |
| 209 | ········/// <param name="exp"></param> |
| 210 | ········public virtual void Add(OqlExpression exp) |
| 211 | ········{············ |
| 212 | ············this.children.Add(exp); |
| 213 | ········} |
| 214 | |
| 215 | ········/// <summary> |
| 216 | ········/// Adds a child expression and an operator |
| 217 | ········/// </summary> |
| 218 | ········/// <param name="exp"></param> |
| 219 | ········/// <param name="op"></param> |
| 220 | ········public virtual void Add(OqlExpression exp, string op) |
| 221 | ········{ |
| 222 | ············System.Diagnostics.Debug.Assert(this.children.Count > 0); |
| 223 | ············if (this.Children.Count < 2) |
| 224 | ············{ |
| 225 | ················this.children.Add(exp); |
| 226 | ················this.op = op; |
| 227 | ············} |
| 228 | ············else if (this.op == op) |
| 229 | ············{ |
| 230 | ················this.children.Add(exp); |
| 231 | ············} |
| 232 | ············else |
| 233 | ············{ |
| 234 | ················OqlExpression left = this.Clone(); |
| 235 | ················this.children.Clear(); |
| 236 | ················this.children.Add(left); |
| 237 | ················this.op = op; |
| 238 | ················this.children.Add(exp); |
| 239 | ············} |
| 240 | ········} |
| 241 | |
| 242 | ········/// <summary> |
| 243 | ········/// Gets all siblings of an expression |
| 244 | ········/// </summary> |
| 245 | ········public List<OqlExpression> Siblings |
| 246 | ········{ |
| 247 | ············get |
| 248 | ············{ |
| 249 | ················List<OqlExpression> result = new List<OqlExpression>(); |
| 250 | ················if ( this.parent != null ) |
| 251 | ················{ |
| 252 | ····················foreach ( OqlExpression child in parent.children ) |
| 253 | ····················{ |
| 254 | ························if ( Object.ReferenceEquals( child, this ) ) |
| 255 | ····························continue; |
| 256 | |
| 257 | ························result.Add( child ); |
| 258 | ····················} |
| 259 | ················} |
| 260 | ················return result; |
| 261 | ············} |
| 262 | ········} |
| 263 | |
| 264 | ········/// <summary> |
| 265 | ········/// Gets the next sibling starting from the current expression |
| 266 | ········/// </summary> |
| 267 | ········public OqlExpression NextSibling |
| 268 | ········{ |
| 269 | ············get |
| 270 | ············{ |
| 271 | ················if (this.parent != null) |
| 272 | ················{ |
| 273 | ····················bool foundMyself = false; |
| 274 | ····················foreach (OqlExpression child in parent.children) |
| 275 | ····················{ |
| 276 | ························if (foundMyself) |
| 277 | ····························return child; |
| 278 | ························if (Object.ReferenceEquals(child, this)) |
| 279 | ····························foundMyself = true; |
| 280 | |
| 281 | ····················} |
| 282 | ················} |
| 283 | ················return null; |
| 284 | ············} |
| 285 | ········} |
| 286 | |
| 287 | ········/// <summary> |
| 288 | ········/// Clones the expression |
| 289 | ········/// </summary> |
| 290 | ········/// <returns></returns> |
| 291 | ········protected virtual OqlExpression Clone() |
| 292 | ········{ |
| 293 | ············OqlExpression exp = new OqlExpression(this.line, this.col); |
| 294 | ············exp.children = children; |
| 295 | ············exp.op = op; |
| 296 | ············exp.unaryOp = unaryOp; |
| 297 | ············exp.value = value; |
| 298 | ············return exp; |
| 299 | ········} |
| 300 | |
| 301 | ········//public List<object> Serialize() |
| 302 | ········//{ |
| 303 | ········//····List<object> list = new List<object>(); |
| 304 | ········//····Serialize(list); |
| 305 | ········//} |
| 306 | |
| 307 | ········//private void Serialize(List<object> list) |
| 308 | ········//{ |
| 309 | ········//····if (this.IsTerminating) |
| 310 | ········//····{ |
| 311 | ········//········list.Add(this); |
| 312 | ········//····} |
| 313 | ········//····else |
| 314 | ········//····{ |
| 315 | ········//········if (this.hasBrackets) |
| 316 | ········//············list.Add("("); |
| 317 | ········//········if (this.unaryOp != null) |
| 318 | ········//············list.Add(this.unaryOp); |
| 319 | ········//····} |
| 320 | |
| 321 | ········//} |
| 322 | |
| 323 | ········///<inheritdoc/> |
| 324 | ········public override string ToString() |
| 325 | ········{ |
| 326 | ············StringBuilder sb = new StringBuilder(); |
| 327 | |
| 328 | ············if (hasBrackets) |
| 329 | ················sb.Append('('); |
| 330 | ············if (unaryOp != null) |
| 331 | ············{ |
| 332 | ················sb.Append(unaryOp); |
| 333 | ················sb.Append(' '); |
| 334 | ············} |
| 335 | ············if (ExpressionType == Expressions.ExpressionType.Raw && value != null) |
| 336 | ············{ |
| 337 | ················sb.Append( this.value.ToString() ); |
| 338 | ················if (!IsTerminating) |
| 339 | ····················sb.Append( ' ' ); |
| 340 | ············} |
| 341 | ············else if (this.IsTerminating) |
| 342 | ············{ |
| 343 | ················if (this.value is Double) |
| 344 | ····················sb.Append(((Double)this.value).ToString(CultureInfo.InvariantCulture)); |
| 345 | ················else |
| 346 | ····················if (value != null) |
| 347 | ····················sb.Append(this.value.ToString()); |
| 348 | ············} |
| 349 | ············if (!this.IsTerminating) |
| 350 | ············{ |
| 351 | ················string op1 = op; |
| 352 | ················for (int i = 0; i < children.Count; i++) |
| 353 | ················{ |
| 354 | ····················OqlExpression child = this.children[i]; |
| 355 | ····················sb.Append(child.ToString()); |
| 356 | ····················if (i < children.Count - 1) |
| 357 | ····················{ |
| 358 | ························if (!String.IsNullOrEmpty(op)) |
| 359 | ························{ |
| 360 | ····························if (op != ",") |
| 361 | ································sb.Append(' '); |
| 362 | ····························sb.Append(op1); |
| 363 | ····························if (op1 == "BETWEEN") |
| 364 | ····························{ |
| 365 | ································op1 = "AND"; |
| 366 | ····························} |
| 367 | ····························sb.Append(' '); |
| 368 | ························} |
| 369 | ························else |
| 370 | ························{ |
| 371 | ····························sb.Append(' '); |
| 372 | ························} |
| 373 | ····················} |
| 374 | ················} |
| 375 | ············} |
| 376 | ············if (hasBrackets) |
| 377 | ················sb.Append(')'); |
| 378 | ············ |
| 379 | ············return sb.ToString(); |
| 380 | ········} |
| 381 | |
| 382 | ········/// <summary> |
| 383 | ········/// Visits all expressions of the tree and returns the expressions to which the predicate applies |
| 384 | ········/// </summary> |
| 385 | ········/// <param name="predicate"></param> |
| 386 | ········/// <returns></returns> |
| 387 | ········public IEnumerable<OqlExpression> GetAll(Func<OqlExpression, bool>predicate) |
| 388 | ········{ |
| 389 | ············if (predicate(this)) |
| 390 | ················yield return this; |
| 391 | ············foreach (var child in children) |
| 392 | ············{ |
| 393 | ················foreach (var exp in child.GetAll( predicate )) |
| 394 | ················{ |
| 395 | ····················yield return exp; |
| 396 | ················} |
| 397 | ············} |
| 398 | ········} |
| 399 | ···· |
| 400 | ········/// <summary> |
| 401 | ········/// Constructs a deep clone of the expression |
| 402 | ········/// </summary> |
| 403 | ········public virtual OqlExpression DeepClone |
| 404 | ········{ |
| 405 | ············get |
| 406 | ············{ |
| 407 | ················OqlExpression clone = new OqlExpression( this.line, this.col ); |
| 408 | ················clone.expressionType = this.expressionType; |
| 409 | ················clone.hasBrackets = this.hasBrackets; |
| 410 | ················clone.op = this.op; |
| 411 | ················clone.unaryOp = this.unaryOp; |
| 412 | ················clone.value = this.value; |
| 413 | ················clone.annotations = annotations; |
| 414 | ················foreach(var child in children) |
| 415 | ················{ |
| 416 | ····················OqlExpression childClone = child.DeepClone; |
| 417 | ····················((IManageExpression)childClone).SetParent( clone ); |
| 418 | ····················clone.Add( childClone ); |
| 419 | ················} |
| 420 | ················return clone; |
| 421 | ············} |
| 422 | ········} |
| 423 | ····} |
| 424 | } |
| 425 |
New Commit (b47b95e)
| 1 | using System; |
| 2 | using System.Collections.Generic; |
| 3 | using System.Text; |
| 4 | using System.Globalization; |
| 5 | |
| 6 | namespace NDOql.Expressions |
| 7 | { |
| 8 | ····internal interface IManageExpression |
| 9 | ····{ |
| 10 | ········void SetParent( OqlExpression exp ); |
| 11 | ····} |
| 12 | |
| 13 | ····/// <summary> |
| 14 | ····/// Base class for Oql expressions |
| 15 | ····/// </summary> |
| 16 | ····public class OqlExpression : IManageExpression |
| 17 | ····{ |
| 18 | ········int line; |
| 19 | ········int col; |
| 20 | ········ExpressionType expressionType; |
| 21 | ········string unaryOp; |
| 22 | ········string op; |
| 23 | ········OqlExpression parent = null; |
| 24 | ········List<OqlExpression> children = new List<OqlExpression>(); |
| 25 | ········object value; |
| 26 | ········Dictionary<string, object> annotations = new Dictionary<string, object>(); |
| 27 | |
| 28 | ········/// <summary> |
| 29 | ········/// Sets an annotation for a certain experession node |
| 30 | ········/// </summary> |
| 31 | ········/// <param name="key"></param> |
| 32 | ········/// <param name="value"></param> |
| 33 | ········public void SetAnnotation(string key, object value) |
| 34 | ········{ |
| 35 | ············annotations[key] = value; |
| 36 | ········} |
| 37 | |
| 38 | ········/// <summary> |
| 39 | ········/// Gets an annotation for a node |
| 40 | ········/// </summary> |
| 41 | ········/// <typeparam name="T"></typeparam> |
| 42 | ········/// <param name="key"></param> |
| 43 | ········/// <returns></returns> |
| 44 | ········public T GetAnnotation<T>( string key ) |
| 45 | ········{ |
| 46 | ············if (!annotations.ContainsKey( key )) |
| 47 | ················return default(T); |
| 48 | |
| 49 | ············return (T)annotations[key]; |
| 50 | ········} |
| 51 | |
| 52 | ········/// <summary> |
| 53 | ········/// Gets or sets the line number where the expression appears |
| 54 | ········/// </summary> |
| 55 | ········public int Line |
| 56 | ········{ |
| 57 | ············get { return line; } |
| 58 | ············set { line = value; } |
| 59 | ········} |
| 60 | ········/// <summary> |
| 61 | ········/// Gets or sets the column in the line where the expression appears |
| 62 | ········/// </summary> |
| 63 | ········public int Column |
| 64 | ········{ |
| 65 | ············get { return col; } |
| 66 | ············set { col = value; } |
| 67 | ········} |
| 68 | |
| 69 | ········/// <summary> |
| 70 | ········/// Gets or sets the expression type |
| 71 | ········/// </summary> |
| 72 | ········public ExpressionType ExpressionType |
| 73 | ········{ |
| 74 | ············get { return expressionType; } |
| 75 | ············set { expressionType = value; } |
| 76 | ········} |
| 77 | |
| 78 | ········void ThrowUnaryException() |
| 79 | ········{ |
| 80 | ············throw new OqlExpressionException("Unary Operator doesn't fit to the type of the expression in '" + this.ToString() + "'. Line " + this.line + ", Col " + this.col); |
| 81 | ········} |
| 82 | |
| 83 | ········/// <summary> |
| 84 | ········/// Gets or sets an unary operator, if one exists |
| 85 | ········/// </summary> |
| 86 | ········public string UnaryOp |
| 87 | ········{ |
| 88 | ············get { return unaryOp; } |
| 89 | ············set |
| 90 | ············{ |
| 91 | ················unaryOp = value; |
| 92 | ················if (unaryOp == "NOT") |
| 93 | ················{ |
| 94 | ····················if (this.expressionType != ExpressionType.Boolean |
| 95 | ························&& this.expressionType != ExpressionType.Unknown) |
| 96 | ························ThrowUnaryException(); |
| 97 | ················} |
| 98 | ················else if (unaryOp == "~" || unaryOp == "-" || unaryOp == "+") |
| 99 | ················{ |
| 100 | ····················if (this.expressionType != ExpressionType.Number |
| 101 | ························&& this.expressionType != ExpressionType.Unknown) |
| 102 | ························ThrowUnaryException(); |
| 103 | ················} |
| 104 | ············} |
| 105 | ········} |
| 106 | |
| 107 | ········/// <summary> |
| 108 | ········/// Gets or sets an operator |
| 109 | ········/// </summary> |
| 110 | ········public string Operator |
| 111 | ········{ |
| 112 | ············get { return op; } |
| 113 | ············set { op = value; } |
| 114 | ········} |
| 115 | |
| 116 | ········bool hasBrackets; |
| 117 | ········/// <summary> |
| 118 | ········/// Gets or sets a value, which determines, if an expression should be bracketed |
| 119 | ········/// </summary> |
| 120 | ········public bool HasBrackets |
| 121 | ········{ |
| 122 | ············get { return hasBrackets; } |
| 123 | ············set { hasBrackets = value; } |
| 124 | ········} |
| 125 | |
| 126 | ········/// <summary> |
| 127 | ········/// Gets the child expressions |
| 128 | ········/// </summary> |
| 129 | ········public List<OqlExpression> Children |
| 130 | ········{ |
| 131 | ············get { return children; } |
| 132 | ········} |
| 133 | |
| 134 | ········/// <summary> |
| 135 | ········/// Gets the parent expression |
| 136 | ········/// </summary> |
| 137 | ········public OqlExpression Parent |
| 138 | ········{ |
| 139 | ············get { return this.parent; } |
| 140 | ········} |
| 141 | |
| 142 | ········/// <summary> |
| 143 | ········/// </summary> |
| 144 | ········/// <param name="exp"></param> |
| 145 | ········/// <remarks> |
| 146 | ········/// Since there occurs a lot of shuffling around the children during the parse process |
| 147 | ········/// we itererate through the tree after parsing and set the parent there. |
| 148 | ········/// </remarks> |
| 149 | ········void IManageExpression.SetParent( OqlExpression exp ) |
| 150 | ········{ |
| 151 | ············this.parent = exp; |
| 152 | ········} |
| 153 | |
| 154 | ········/// <summary> |
| 155 | ········/// Gets the value of the expression |
| 156 | ········/// </summary> |
| 157 | ········public object Value |
| 158 | ········{ |
| 159 | ············get { return this.value; } |
| 160 | ············set { this.value = value; } |
| 161 | ········} |
| 162 | |
| 163 | ········/// <summary> |
| 164 | ········/// Constructor |
| 165 | ········/// </summary> |
| 166 | ········/// <param name="line"></param> |
| 167 | ········/// <param name="col"></param> |
| 168 | ········public OqlExpression(int line, int col) |
| 169 | ········{ |
| 170 | ············this.line = line; |
| 171 | ············this.col = col; |
| 172 | ········} |
| 173 | |
| 174 | ········/// <summary> |
| 175 | ········/// Determines, if an expression is a leaf in the tree. |
| 176 | ········/// </summary> |
| 177 | ········public virtual bool IsTerminating |
| 178 | ········{ |
| 179 | ············get { return this.children.Count == 0; } |
| 180 | ········} |
| 181 | |
| 182 | ········/// <summary> |
| 183 | ········/// Reduces an expression |
| 184 | ········/// </summary> |
| 185 | ········/// <returns></returns> |
| 186 | public virtual OqlExpression Simplify( ) |
| 187 | ········{ |
| 188 | ············System.Diagnostics.Debug.Assert(this.children.Count != 0 || this.value != null); |
| 189 | ············if (this.children.Count > 1 || this.IsTerminating) |
| 190 | ················return this; |
| 191 | ············if (unaryOp != null) |
| 192 | ············{ |
| 193 | ················if (this.children[0].unaryOp == null && !this.children[0].hasBrackets) |
| 194 | ················{ |
| 195 | ····················this.children[0].unaryOp = this.unaryOp; |
| 196 | ····················return this.children[0]; |
| 197 | ················} |
| 198 | ················else |
| 199 | ················{ |
| 200 | ····················return this; |
| 201 | ················} |
| 202 | ············} |
| 203 | ············return this.children[0]; |
| 204 | ········} |
| 205 | |
| 206 | ········/// <summary> |
| 207 | ········/// Adds a child expressoin |
| 208 | ········/// </summary> |
| 209 | ········/// <param name="exp"></param> |
| 210 | ········public virtual void Add(OqlExpression exp) |
| 211 | ········{············ |
| 212 | ············this.children.Add(exp); |
| 213 | ········} |
| 214 | |
| 215 | ········/// <summary> |
| 216 | ········/// Adds a child expression and an operator |
| 217 | ········/// </summary> |
| 218 | ········/// <param name="exp"></param> |
| 219 | ········/// <param name="op"></param> |
| 220 | ········public virtual void Add(OqlExpression exp, string op) |
| 221 | ········{ |
| 222 | ············System.Diagnostics.Debug.Assert(this.children.Count > 0); |
| 223 | ············if (this.Children.Count < 2) |
| 224 | ············{ |
| 225 | ················this.children.Add(exp); |
| 226 | ················this.op = op; |
| 227 | ············} |
| 228 | ············else if (this.op == op) |
| 229 | ············{ |
| 230 | ················this.children.Add(exp); |
| 231 | ············} |
| 232 | ············else |
| 233 | ············{ |
| 234 | ················OqlExpression left = this.Clone(); |
| 235 | ················this.children.Clear(); |
| 236 | ················this.children.Add(left); |
| 237 | ················this.op = op; |
| 238 | ················this.children.Add(exp); |
| 239 | ············} |
| 240 | ········} |
| 241 | |
| 242 | ········/// <summary> |
| 243 | ········/// Gets all siblings of an expression |
| 244 | ········/// </summary> |
| 245 | ········public List<OqlExpression> Siblings |
| 246 | ········{ |
| 247 | ············get |
| 248 | ············{ |
| 249 | ················List<OqlExpression> result = new List<OqlExpression>(); |
| 250 | ················if ( this.parent != null ) |
| 251 | ················{ |
| 252 | ····················foreach ( OqlExpression child in parent.children ) |
| 253 | ····················{ |
| 254 | ························if ( Object.ReferenceEquals( child, this ) ) |
| 255 | ····························continue; |
| 256 | |
| 257 | ························result.Add( child ); |
| 258 | ····················} |
| 259 | ················} |
| 260 | ················return result; |
| 261 | ············} |
| 262 | ········} |
| 263 | |
| 264 | ········/// <summary> |
| 265 | ········/// Gets the next sibling starting from the current expression |
| 266 | ········/// </summary> |
| 267 | ········public OqlExpression NextSibling |
| 268 | ········{ |
| 269 | ············get |
| 270 | ············{ |
| 271 | ················if (this.parent != null) |
| 272 | ················{ |
| 273 | ····················bool foundMyself = false; |
| 274 | ····················foreach (OqlExpression child in parent.children) |
| 275 | ····················{ |
| 276 | ························if (foundMyself) |
| 277 | ····························return child; |
| 278 | ························if (Object.ReferenceEquals(child, this)) |
| 279 | ····························foundMyself = true; |
| 280 | |
| 281 | ····················} |
| 282 | ················} |
| 283 | ················return null; |
| 284 | ············} |
| 285 | ········} |
| 286 | |
| 287 | ········/// <summary> |
| 288 | ········/// Clones the expression |
| 289 | ········/// </summary> |
| 290 | ········/// <returns></returns> |
| 291 | ········protected virtual OqlExpression Clone() |
| 292 | ········{ |
| 293 | ············OqlExpression exp = new OqlExpression(this.line, this.col); |
| 294 | ············exp.children = children; |
| 295 | ············exp.op = op; |
| 296 | ············exp.unaryOp = unaryOp; |
| 297 | ············exp.value = value; |
| 298 | ············return exp; |
| 299 | ········} |
| 300 | |
| 301 | ········//public List<object> Serialize() |
| 302 | ········//{ |
| 303 | ········//····List<object> list = new List<object>(); |
| 304 | ········//····Serialize(list); |
| 305 | ········//} |
| 306 | |
| 307 | ········//private void Serialize(List<object> list) |
| 308 | ········//{ |
| 309 | ········//····if (this.IsTerminating) |
| 310 | ········//····{ |
| 311 | ········//········list.Add(this); |
| 312 | ········//····} |
| 313 | ········//····else |
| 314 | ········//····{ |
| 315 | ········//········if (this.hasBrackets) |
| 316 | ········//············list.Add("("); |
| 317 | ········//········if (this.unaryOp != null) |
| 318 | ········//············list.Add(this.unaryOp); |
| 319 | ········//····} |
| 320 | |
| 321 | ········//} |
| 322 | |
| 323 | ········///<inheritdoc/> |
| 324 | ········public override string ToString() |
| 325 | ········{ |
| 326 | ············StringBuilder sb = new StringBuilder(); |
| 327 | |
| 328 | ············if (hasBrackets) |
| 329 | ················sb.Append('('); |
| 330 | ············if (unaryOp != null) |
| 331 | ············{ |
| 332 | ················sb.Append(unaryOp); |
| 333 | ················sb.Append(' '); |
| 334 | ············} |
| 335 | ············if (ExpressionType == Expressions.ExpressionType.Raw && value != null) |
| 336 | ············{ |
| 337 | ················sb.Append( this.value.ToString() ); |
| 338 | ················if (!IsTerminating) |
| 339 | ····················sb.Append( ' ' ); |
| 340 | ············} |
| 341 | ············else if (this.IsTerminating) |
| 342 | ············{ |
| 343 | ················if (this.value is Double) |
| 344 | ····················sb.Append(((Double)this.value).ToString(CultureInfo.InvariantCulture)); |
| 345 | ················else |
| 346 | ····················if (value != null) |
| 347 | ····················sb.Append(this.value.ToString()); |
| 348 | ············} |
| 349 | ············if (!this.IsTerminating) |
| 350 | ············{ |
| 351 | ················string op1 = op; |
| 352 | ················for (int i = 0; i < children.Count; i++) |
| 353 | ················{ |
| 354 | ····················OqlExpression child = this.children[i]; |
| 355 | ····················sb.Append(child.ToString()); |
| 356 | ····················if (i < children.Count - 1) |
| 357 | ····················{ |
| 358 | ························if (!String.IsNullOrEmpty(op)) |
| 359 | ························{ |
| 360 | ····························if (op != ",") |
| 361 | ································sb.Append(' '); |
| 362 | ····························sb.Append(op1); |
| 363 | ····························if (op1 == "BETWEEN") |
| 364 | ····························{ |
| 365 | ································op1 = "AND"; |
| 366 | ····························} |
| 367 | ····························sb.Append(' '); |
| 368 | ························} |
| 369 | ························else |
| 370 | ························{ |
| 371 | ····························sb.Append(' '); |
| 372 | ························} |
| 373 | ····················} |
| 374 | ················} |
| 375 | ············} |
| 376 | ············if (hasBrackets) |
| 377 | ················sb.Append(')'); |
| 378 | ············ |
| 379 | ············return sb.ToString(); |
| 380 | ········} |
| 381 | |
| 382 | ········/// <summary> |
| 383 | ········/// Visits all expressions of the tree and returns the expressions to which the predicate applies |
| 384 | ········/// </summary> |
| 385 | ········/// <param name="predicate"></param> |
| 386 | ········/// <returns></returns> |
| 387 | ········public IEnumerable<OqlExpression> GetAll(Func<OqlExpression, bool>predicate) |
| 388 | ········{ |
| 389 | ············if (predicate(this)) |
| 390 | ················yield return this; |
| 391 | ············foreach (var child in children) |
| 392 | ············{ |
| 393 | ················foreach (var exp in child.GetAll( predicate )) |
| 394 | ················{ |
| 395 | ····················yield return exp; |
| 396 | ················} |
| 397 | ············} |
| 398 | ········} |
| 399 | ···· |
| 400 | ········/// <summary> |
| 401 | ········/// Constructs a deep clone of the expression |
| 402 | ········/// </summary> |
| 403 | ········public virtual OqlExpression DeepClone |
| 404 | ········{ |
| 405 | ············get |
| 406 | ············{ |
| 407 | ················OqlExpression clone = new OqlExpression( this.line, this.col ); |
| 408 | ················clone.expressionType = this.expressionType; |
| 409 | ················clone.hasBrackets = this.hasBrackets; |
| 410 | ················clone.op = this.op; |
| 411 | ················clone.unaryOp = this.unaryOp; |
| 412 | ················clone.value = this.value; |
| 413 | ················clone.annotations = annotations; |
| 414 | ················foreach(var child in children) |
| 415 | ················{ |
| 416 | ····················OqlExpression childClone = child.DeepClone; |
| 417 | ····················((IManageExpression)childClone).SetParent( clone ); |
| 418 | ····················clone.Add( childClone ); |
| 419 | ················} |
| 420 | ················return clone; |
| 421 | ············} |
| 422 | ········} |
| 423 | ····} |
| 424 | } |
| 425 |