1 // --------------------------------------------------------------------------- 2 // Copyright (C) 2005 Microsoft Corporation All Rights Reserved 3 // --------------------------------------------------------------------------- 4 5 #define CODE_ANALYSIS 6 using System.CodeDom; 7 using System.Collections.Generic; 8 using System.Diagnostics; 9 using System.Diagnostics.CodeAnalysis; 10 using System.Globalization; 11 using System.Reflection; 12 using System.Workflow.ComponentModel; 13 using System.Workflow.ComponentModel.Compiler; 14 using System.Workflow.Activities.Common; 15 16 namespace System.Workflow.Activities.Rules 17 { 18 #region Literal Class 19 /// <summary> 20 /// Represents a typed literal value and is the base class for all type specific literal classes 21 /// </summary> 22 internal abstract class Literal 23 { 24 #region Properties 25 /// <summary> 26 /// A delegate for literal factory methods 27 /// </summary> LiteralMaker(object literalValue)28 private delegate Literal LiteralMaker(object literalValue); 29 30 /// <summary> 31 /// Collection of literal factory methods indexed by type 32 /// </summary> 33 static private Dictionary<Type, LiteralMaker> types = CreateMakersDictionary(); 34 35 /// <summary> 36 /// The type of the literal 37 /// </summary> 38 protected internal Type m_type; 39 40 /// <summary> 41 /// Get the boxed literal 42 /// </summary> 43 internal abstract object Value { get; } 44 45 /// <summary> 46 /// Group types by similar characteristics so we can check if comparisons succeed 47 /// </summary> 48 [Flags()] 49 enum TypeFlags 50 { 51 SignedNumbers = 0x01, 52 UnsignedNumbers = 0x02, 53 ULong = 0x04, 54 Float = 0x08, 55 Decimal = 0x10, 56 String = 0x20, 57 Bool = 0x40 58 }; 59 60 /// <summary> 61 /// Collection of TypeFlags for the supported value types indexed by type 62 /// </summary> 63 private static Dictionary<Type, TypeFlags> supportedTypes = CreateTypesDictionary(); 64 CreateMakersDictionary()65 private static Dictionary<Type, LiteralMaker> CreateMakersDictionary() 66 { 67 // Create the literal class factory delegates 68 Dictionary<Type, LiteralMaker> dictionary = new Dictionary<Type, LiteralMaker>(32); 69 dictionary.Add(typeof(byte), new LiteralMaker(Literal.MakeByte)); 70 dictionary.Add(typeof(sbyte), new LiteralMaker(Literal.MakeSByte)); 71 dictionary.Add(typeof(short), new LiteralMaker(Literal.MakeShort)); 72 dictionary.Add(typeof(int), new LiteralMaker(Literal.MakeInt)); 73 dictionary.Add(typeof(long), new LiteralMaker(Literal.MakeLong)); 74 dictionary.Add(typeof(ushort), new LiteralMaker(Literal.MakeUShort)); 75 dictionary.Add(typeof(uint), new LiteralMaker(Literal.MakeUInt)); 76 dictionary.Add(typeof(ulong), new LiteralMaker(Literal.MakeULong)); 77 dictionary.Add(typeof(float), new LiteralMaker(Literal.MakeFloat)); 78 dictionary.Add(typeof(double), new LiteralMaker(Literal.MakeDouble)); 79 dictionary.Add(typeof(char), new LiteralMaker(Literal.MakeChar)); 80 dictionary.Add(typeof(string), new LiteralMaker(Literal.MakeString)); 81 dictionary.Add(typeof(decimal), new LiteralMaker(Literal.MakeDecimal)); 82 dictionary.Add(typeof(bool), new LiteralMaker(Literal.MakeBool)); 83 dictionary.Add(typeof(byte?), new LiteralMaker(Literal.MakeByte)); 84 dictionary.Add(typeof(sbyte?), new LiteralMaker(Literal.MakeSByte)); 85 dictionary.Add(typeof(short?), new LiteralMaker(Literal.MakeShort)); 86 dictionary.Add(typeof(int?), new LiteralMaker(Literal.MakeInt)); 87 dictionary.Add(typeof(long?), new LiteralMaker(Literal.MakeLong)); 88 dictionary.Add(typeof(ushort?), new LiteralMaker(Literal.MakeUShort)); 89 dictionary.Add(typeof(uint?), new LiteralMaker(Literal.MakeUInt)); 90 dictionary.Add(typeof(ulong?), new LiteralMaker(Literal.MakeULong)); 91 dictionary.Add(typeof(float?), new LiteralMaker(Literal.MakeFloat)); 92 dictionary.Add(typeof(double?), new LiteralMaker(Literal.MakeDouble)); 93 dictionary.Add(typeof(char?), new LiteralMaker(Literal.MakeChar)); 94 dictionary.Add(typeof(decimal?), new LiteralMaker(Literal.MakeDecimal)); 95 dictionary.Add(typeof(bool?), new LiteralMaker(Literal.MakeBool)); 96 return dictionary; 97 } 98 CreateTypesDictionary()99 private static Dictionary<Type, TypeFlags> CreateTypesDictionary() 100 { 101 // Create the literal class factory delegates 102 Dictionary<Type, TypeFlags> dictionary = new Dictionary<Type, TypeFlags>(32); 103 dictionary.Add(typeof(byte), TypeFlags.UnsignedNumbers); 104 dictionary.Add(typeof(byte?), TypeFlags.UnsignedNumbers); 105 dictionary.Add(typeof(sbyte), TypeFlags.SignedNumbers); 106 dictionary.Add(typeof(sbyte?), TypeFlags.SignedNumbers); 107 dictionary.Add(typeof(short), TypeFlags.SignedNumbers); 108 dictionary.Add(typeof(short?), TypeFlags.SignedNumbers); 109 dictionary.Add(typeof(int), TypeFlags.SignedNumbers); 110 dictionary.Add(typeof(int?), TypeFlags.SignedNumbers); 111 dictionary.Add(typeof(long), TypeFlags.SignedNumbers); 112 dictionary.Add(typeof(long?), TypeFlags.SignedNumbers); 113 dictionary.Add(typeof(ushort), TypeFlags.UnsignedNumbers); 114 dictionary.Add(typeof(ushort?), TypeFlags.UnsignedNumbers); 115 dictionary.Add(typeof(uint), TypeFlags.UnsignedNumbers); 116 dictionary.Add(typeof(uint?), TypeFlags.UnsignedNumbers); 117 dictionary.Add(typeof(ulong), TypeFlags.ULong); 118 dictionary.Add(typeof(ulong?), TypeFlags.ULong); 119 dictionary.Add(typeof(float), TypeFlags.Float); 120 dictionary.Add(typeof(float?), TypeFlags.Float); 121 dictionary.Add(typeof(double), TypeFlags.Float); 122 dictionary.Add(typeof(double?), TypeFlags.Float); 123 dictionary.Add(typeof(char), TypeFlags.UnsignedNumbers); 124 dictionary.Add(typeof(char?), TypeFlags.UnsignedNumbers); 125 dictionary.Add(typeof(string), TypeFlags.String); 126 dictionary.Add(typeof(decimal), TypeFlags.Decimal); 127 dictionary.Add(typeof(decimal?), TypeFlags.Decimal); 128 dictionary.Add(typeof(bool), TypeFlags.Bool); 129 dictionary.Add(typeof(bool?), TypeFlags.Bool); 130 return dictionary; 131 } 132 #endregion 133 134 #region Factory Methods MakeLiteral(Type literalType, object literalValue)135 internal static Literal MakeLiteral(Type literalType, object literalValue) 136 { 137 if (literalValue == null) 138 return new NullLiteral(literalType); 139 140 LiteralMaker f; 141 if (types.TryGetValue(literalType, out f)) 142 { 143 try 144 { 145 return f(literalValue); 146 } 147 catch (InvalidCastException e) 148 { 149 throw new RuleEvaluationIncompatibleTypesException( 150 string.Format(CultureInfo.CurrentCulture, 151 Messages.InvalidCast, 152 RuleDecompiler.DecompileType(literalValue.GetType()), 153 RuleDecompiler.DecompileType(literalType)), 154 literalType, 155 CodeBinaryOperatorType.Assign, 156 literalValue.GetType(), 157 e); 158 } 159 } 160 return null; 161 } 162 163 /// <summary> 164 /// Factory function for a boolean type 165 /// </summary> 166 /// <param name="literalValue"></param> 167 /// <param name="readOnly"></param> MakeBool(object literalValue)168 private static Literal MakeBool(object literalValue) 169 { 170 return new BoolLiteral((bool)literalValue); 171 } 172 173 /// <summary> 174 /// Factory function for a byte type 175 /// </summary> 176 /// <param name="literalValue"></param> 177 /// <param name="readOnly"></param> MakeByte(object literalValue)178 private static Literal MakeByte(object literalValue) 179 { 180 return new ByteLiteral((byte)literalValue); 181 } 182 183 /// <summary> 184 /// Factory function for a sbyte type 185 /// </summary> 186 /// <param name="literalValue"></param> 187 /// <param name="readOnly"></param> MakeSByte(object literalValue)188 private static Literal MakeSByte(object literalValue) 189 { 190 return new SByteLiteral((sbyte)literalValue); 191 } 192 193 /// <summary> 194 /// Factory function for a char type 195 /// </summary> 196 /// <param name="literalValue"></param> 197 /// <param name="readOnly"></param> MakeChar(object literalValue)198 private static Literal MakeChar(object literalValue) 199 { 200 return new CharLiteral((char)literalValue); 201 } 202 203 /// <summary> 204 /// Factory function for a decimal type 205 /// </summary> 206 /// <param name="literalValue"></param> 207 /// <param name="readOnly"></param> MakeDecimal(object literalValue)208 private static Literal MakeDecimal(object literalValue) 209 { 210 return new DecimalLiteral((decimal)literalValue); 211 } 212 213 /// <summary> 214 /// Factory function for an Int16 type 215 /// </summary> 216 /// <param name="literalValue"></param> 217 /// <param name="readOnly"></param> MakeShort(object literalValue)218 private static Literal MakeShort(object literalValue) 219 { 220 return new ShortLiteral((short)literalValue); 221 } 222 223 /// <summary> 224 /// Factory function for an Int32 type 225 /// </summary> 226 /// <param name="literalValue"></param> 227 /// <param name="readOnly"></param> MakeInt(object literalValue)228 private static Literal MakeInt(object literalValue) 229 { 230 return new IntLiteral((int)literalValue); 231 } 232 233 /// <summary> 234 /// Factory function for an Int64 type 235 /// </summary> 236 /// <param name="literalValue"></param> 237 /// <param name="readOnly"></param> MakeLong(object literalValue)238 private static Literal MakeLong(object literalValue) 239 { 240 return new LongLiteral((long)literalValue); 241 } 242 243 /// <summary> 244 /// Factory function for an UInt16 type 245 /// </summary> 246 /// <param name="literalValue"></param> 247 /// <param name="readOnly"></param> MakeUShort(object literalValue)248 private static Literal MakeUShort(object literalValue) 249 { 250 return new UShortLiteral((ushort)literalValue); 251 } 252 253 /// <summary> 254 /// Factory function for an UInt32 type 255 /// </summary> 256 /// <param name="literalValue"></param> 257 /// <param name="readOnly"></param> MakeUInt(object literalValue)258 private static Literal MakeUInt(object literalValue) 259 { 260 return new UIntLiteral((uint)literalValue); 261 } 262 263 /// <summary> 264 /// Factory function for an UInt64 type 265 /// </summary> 266 /// <param name="literalValue"></param> 267 /// <param name="readOnly"></param> MakeULong(object literalValue)268 private static Literal MakeULong(object literalValue) 269 { 270 return new ULongLiteral((ulong)literalValue); 271 } 272 273 /// <summary> 274 /// Factory function for a float type 275 /// </summary> 276 /// <param name="literalValue"></param> 277 /// <param name="readOnly"></param> MakeFloat(object literalValue)278 private static Literal MakeFloat(object literalValue) 279 { 280 return new FloatLiteral((float)literalValue); 281 } 282 283 /// <summary> 284 /// Factory function for a double type 285 /// </summary> 286 /// <param name="literalValue"></param> 287 /// <param name="readOnly"></param> MakeDouble(object literalValue)288 private static Literal MakeDouble(object literalValue) 289 { 290 return new DoubleLiteral((double)literalValue); 291 } 292 293 /// <summary> 294 /// Factory function for a string type 295 /// </summary> 296 /// <param name="literalValue"></param> 297 /// <param name="readOnly"></param> MakeString(object literalValue)298 private static Literal MakeString(object literalValue) 299 { 300 return new StringLiteral((string)literalValue); 301 } 302 #endregion 303 304 #region Default Operators 305 internal static class DefaultOperators 306 { Addition(int x, int y)307 public static int Addition(int x, int y) { return x + y; } Addition(uint x, uint y)308 public static uint Addition(uint x, uint y) { return x + y; } Addition(long x, long y)309 public static long Addition(long x, long y) { return x + y; } Addition(ulong x, ulong y)310 public static ulong Addition(ulong x, ulong y) { return x + y; } Addition(float x, float y)311 public static float Addition(float x, float y) { return x + y; } Addition(double x, double y)312 public static double Addition(double x, double y) { return x + y; } Addition(decimal x, decimal y)313 public static decimal Addition(decimal x, decimal y) { return x + y; } Addition(string x, string y)314 public static string Addition(string x, string y) { return x + y; } Addition(string x, object y)315 public static string Addition(string x, object y) { return x + y; } Addition(object x, string y)316 public static string Addition(object x, string y) { return x + y; } 317 Subtraction(int x, int y)318 public static int Subtraction(int x, int y) { return x - y; } Subtraction(uint x, uint y)319 public static uint Subtraction(uint x, uint y) { return x - y; } Subtraction(long x, long y)320 public static long Subtraction(long x, long y) { return x - y; } Subtraction(ulong x, ulong y)321 public static ulong Subtraction(ulong x, ulong y) { return x - y; } Subtraction(float x, float y)322 public static float Subtraction(float x, float y) { return x - y; } Subtraction(double x, double y)323 public static double Subtraction(double x, double y) { return x - y; } Subtraction(decimal x, decimal y)324 public static decimal Subtraction(decimal x, decimal y) { return x - y; } 325 Multiply(int x, int y)326 public static int Multiply(int x, int y) { return x * y; } Multiply(uint x, uint y)327 public static uint Multiply(uint x, uint y) { return x * y; } Multiply(long x, long y)328 public static long Multiply(long x, long y) { return x * y; } Multiply(ulong x, ulong y)329 public static ulong Multiply(ulong x, ulong y) { return x * y; } Multiply(float x, float y)330 public static float Multiply(float x, float y) { return x * y; } Multiply(double x, double y)331 public static double Multiply(double x, double y) { return x * y; } Multiply(decimal x, decimal y)332 public static decimal Multiply(decimal x, decimal y) { return x * y; } 333 Division(int x, int y)334 public static int Division(int x, int y) { return x / y; } Division(uint x, uint y)335 public static uint Division(uint x, uint y) { return x / y; } Division(long x, long y)336 public static long Division(long x, long y) { return x / y; } Division(ulong x, ulong y)337 public static ulong Division(ulong x, ulong y) { return x / y; } Division(float x, float y)338 public static float Division(float x, float y) { return x / y; } Division(double x, double y)339 public static double Division(double x, double y) { return x / y; } Division(decimal x, decimal y)340 public static decimal Division(decimal x, decimal y) { return x / y; } 341 Modulus(int x, int y)342 public static int Modulus(int x, int y) { return x % y; } Modulus(uint x, uint y)343 public static uint Modulus(uint x, uint y) { return x % y; } Modulus(long x, long y)344 public static long Modulus(long x, long y) { return x % y; } Modulus(ulong x, ulong y)345 public static ulong Modulus(ulong x, ulong y) { return x % y; } Modulus(float x, float y)346 public static float Modulus(float x, float y) { return x % y; } Modulus(double x, double y)347 public static double Modulus(double x, double y) { return x % y; } Modulus(decimal x, decimal y)348 public static decimal Modulus(decimal x, decimal y) { return x % y; } 349 BitwiseAnd(int x, int y)350 public static int BitwiseAnd(int x, int y) { return x & y; } BitwiseAnd(uint x, uint y)351 public static uint BitwiseAnd(uint x, uint y) { return x & y; } BitwiseAnd(long x, long y)352 public static long BitwiseAnd(long x, long y) { return x & y; } BitwiseAnd(ulong x, ulong y)353 public static ulong BitwiseAnd(ulong x, ulong y) { return x & y; } BitwiseAnd(bool x, bool y)354 public static bool BitwiseAnd(bool x, bool y) { return x & y; } 355 BitwiseOr(int x, int y)356 public static int BitwiseOr(int x, int y) { return x | y; } BitwiseOr(uint x, uint y)357 public static uint BitwiseOr(uint x, uint y) { return x | y; } BitwiseOr(long x, long y)358 public static long BitwiseOr(long x, long y) { return x | y; } BitwiseOr(ulong x, ulong y)359 public static ulong BitwiseOr(ulong x, ulong y) { return x | y; } BitwiseOr(bool x, bool y)360 public static bool BitwiseOr(bool x, bool y) { return x | y; } 361 Equality(int x, int y)362 public static bool Equality(int x, int y) { return x == y; } Equality(uint x, uint y)363 public static bool Equality(uint x, uint y) { return x == y; } Equality(long x, long y)364 public static bool Equality(long x, long y) { return x == y; } Equality(ulong x, ulong y)365 public static bool Equality(ulong x, ulong y) { return x == y; } Equality(float x, float y)366 public static bool Equality(float x, float y) { return x == y; } Equality(double x, double y)367 public static bool Equality(double x, double y) { return x == y; } Equality(decimal x, decimal y)368 public static bool Equality(decimal x, decimal y) { return x == y; } Equality(bool x, bool y)369 public static bool Equality(bool x, bool y) { return x == y; } Equality(string x, string y)370 public static bool Equality(string x, string y) { return x == y; } 371 // mark object == object since it has special rules ObjectEquality(object x, object y)372 public static bool ObjectEquality(object x, object y) { return x == y; } 373 GreaterThan(int x, int y)374 public static bool GreaterThan(int x, int y) { return x > y; } GreaterThan(uint x, uint y)375 public static bool GreaterThan(uint x, uint y) { return x > y; } GreaterThan(long x, long y)376 public static bool GreaterThan(long x, long y) { return x > y; } GreaterThan(ulong x, ulong y)377 public static bool GreaterThan(ulong x, ulong y) { return x > y; } GreaterThan(float x, float y)378 public static bool GreaterThan(float x, float y) { return x > y; } GreaterThan(double x, double y)379 public static bool GreaterThan(double x, double y) { return x > y; } GreaterThan(decimal x, decimal y)380 public static bool GreaterThan(decimal x, decimal y) { return x > y; } 381 GreaterThanOrEqual(int x, int y)382 public static bool GreaterThanOrEqual(int x, int y) { return x >= y; } GreaterThanOrEqual(uint x, uint y)383 public static bool GreaterThanOrEqual(uint x, uint y) { return x >= y; } GreaterThanOrEqual(long x, long y)384 public static bool GreaterThanOrEqual(long x, long y) { return x >= y; } GreaterThanOrEqual(ulong x, ulong y)385 public static bool GreaterThanOrEqual(ulong x, ulong y) { return x >= y; } GreaterThanOrEqual(float x, float y)386 public static bool GreaterThanOrEqual(float x, float y) { return x >= y; } GreaterThanOrEqual(double x, double y)387 public static bool GreaterThanOrEqual(double x, double y) { return x >= y; } GreaterThanOrEqual(decimal x, decimal y)388 public static bool GreaterThanOrEqual(decimal x, decimal y) { return x >= y; } 389 LessThan(int x, int y)390 public static bool LessThan(int x, int y) { return x < y; } LessThan(uint x, uint y)391 public static bool LessThan(uint x, uint y) { return x < y; } LessThan(long x, long y)392 public static bool LessThan(long x, long y) { return x < y; } LessThan(ulong x, ulong y)393 public static bool LessThan(ulong x, ulong y) { return x < y; } LessThan(float x, float y)394 public static bool LessThan(float x, float y) { return x < y; } LessThan(double x, double y)395 public static bool LessThan(double x, double y) { return x < y; } LessThan(decimal x, decimal y)396 public static bool LessThan(decimal x, decimal y) { return x < y; } 397 LessThanOrEqual(int x, int y)398 public static bool LessThanOrEqual(int x, int y) { return x <= y; } LessThanOrEqual(uint x, uint y)399 public static bool LessThanOrEqual(uint x, uint y) { return x <= y; } LessThanOrEqual(long x, long y)400 public static bool LessThanOrEqual(long x, long y) { return x <= y; } LessThanOrEqual(ulong x, ulong y)401 public static bool LessThanOrEqual(ulong x, ulong y) { return x <= y; } LessThanOrEqual(float x, float y)402 public static bool LessThanOrEqual(float x, float y) { return x <= y; } LessThanOrEqual(double x, double y)403 public static bool LessThanOrEqual(double x, double y) { return x <= y; } LessThanOrEqual(decimal x, decimal y)404 public static bool LessThanOrEqual(decimal x, decimal y) { return x <= y; } 405 } 406 #endregion 407 408 #region Type Checking Methods 409 410 [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] AllowedComparison( Type lhs, CodeExpression lhsExpression, Type rhs, CodeExpression rhsExpression, CodeBinaryOperatorType comparison, RuleValidation validator, out ValidationError error)411 internal static RuleBinaryExpressionInfo AllowedComparison( 412 Type lhs, 413 CodeExpression lhsExpression, 414 Type rhs, 415 CodeExpression rhsExpression, 416 CodeBinaryOperatorType comparison, 417 RuleValidation validator, 418 out ValidationError error) 419 { 420 // note that null values come in as a NullLiteral type 421 TypeFlags lhsFlags, rhsFlags; 422 423 // are the types supported? 424 if ((supportedTypes.TryGetValue(lhs, out lhsFlags)) && (supportedTypes.TryGetValue(rhs, out rhsFlags))) 425 { 426 // both sides supported 427 if (lhsFlags == rhsFlags) 428 { 429 // both sides the same type, so it's allowed 430 // only allow equality on booleans 431 if ((lhsFlags == TypeFlags.Bool) && (comparison != CodeBinaryOperatorType.ValueEquality)) 432 { 433 string message = string.Format(CultureInfo.CurrentCulture, Messages.RelationalOpBadTypes, comparison.ToString(), 434 RuleDecompiler.DecompileType(lhs), 435 RuleDecompiler.DecompileType(rhs)); 436 error = new ValidationError(message, ErrorNumbers.Error_OperandTypesIncompatible); 437 return null; 438 } 439 error = null; 440 return new RuleBinaryExpressionInfo(lhs, rhs, typeof(bool)); 441 } 442 443 // if not the same, only certain combinations allowed 444 switch (lhsFlags | rhsFlags) 445 { 446 case TypeFlags.Decimal | TypeFlags.SignedNumbers: 447 case TypeFlags.Decimal | TypeFlags.UnsignedNumbers: 448 case TypeFlags.Decimal | TypeFlags.ULong: 449 case TypeFlags.Float | TypeFlags.SignedNumbers: 450 case TypeFlags.Float | TypeFlags.UnsignedNumbers: 451 case TypeFlags.Float | TypeFlags.ULong: 452 case TypeFlags.ULong | TypeFlags.UnsignedNumbers: 453 case TypeFlags.SignedNumbers | TypeFlags.UnsignedNumbers: 454 error = null; 455 return new RuleBinaryExpressionInfo(lhs, rhs, typeof(bool)); 456 } 457 string message2 = string.Format(CultureInfo.CurrentCulture, Messages.RelationalOpBadTypes, comparison.ToString(), 458 (lhs == typeof(NullLiteral)) ? Messages.NullValue : RuleDecompiler.DecompileType(lhs), 459 (rhs == typeof(NullLiteral)) ? Messages.NullValue : RuleDecompiler.DecompileType(rhs)); 460 error = new ValidationError(message2, ErrorNumbers.Error_OperandTypesIncompatible); 461 return null; 462 } 463 else 464 { 465 // see if they override the operator 466 MethodInfo operatorOverride = MapOperatorToMethod(comparison, lhs, lhsExpression, rhs, rhsExpression, validator, out error); 467 if (operatorOverride != null) 468 return new RuleBinaryExpressionInfo(lhs, rhs, operatorOverride); 469 470 // unable to evaluate, so return false 471 return null; 472 } 473 } 474 475 internal enum OperatorGrouping 476 { 477 Arithmetic, 478 Equality, 479 Relational 480 } 481 482 internal static MethodInfo ObjectEquality = typeof(DefaultOperators).GetMethod("ObjectEquality"); 483 484 [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")] 485 [SuppressMessage("Microsoft.Performance", "CA1803:AvoidCostlyCallsWherePossible")] 486 [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")] // bogus since the casts are in different case statements MapOperatorToMethod( CodeBinaryOperatorType op, Type lhs, CodeExpression lhsExpression, Type rhs, CodeExpression rhsExpression, RuleValidation validator, out ValidationError error)487 internal static MethodInfo MapOperatorToMethod( 488 CodeBinaryOperatorType op, 489 Type lhs, 490 CodeExpression lhsExpression, 491 Type rhs, 492 CodeExpression rhsExpression, 493 RuleValidation validator, 494 out ValidationError error) 495 { 496 // determine what the method name should be 497 string methodName; 498 string message; 499 OperatorGrouping group; 500 501 switch (op) 502 { 503 case CodeBinaryOperatorType.ValueEquality: 504 methodName = "op_Equality"; 505 group = OperatorGrouping.Equality; 506 break; 507 case CodeBinaryOperatorType.GreaterThan: 508 methodName = "op_GreaterThan"; 509 group = OperatorGrouping.Relational; 510 break; 511 case CodeBinaryOperatorType.GreaterThanOrEqual: 512 methodName = "op_GreaterThanOrEqual"; 513 group = OperatorGrouping.Relational; 514 break; 515 case CodeBinaryOperatorType.LessThan: 516 methodName = "op_LessThan"; 517 group = OperatorGrouping.Relational; 518 break; 519 case CodeBinaryOperatorType.LessThanOrEqual: 520 methodName = "op_LessThanOrEqual"; 521 group = OperatorGrouping.Relational; 522 break; 523 case CodeBinaryOperatorType.Add: 524 methodName = "op_Addition"; 525 group = OperatorGrouping.Arithmetic; 526 break; 527 case CodeBinaryOperatorType.Subtract: 528 methodName = "op_Subtraction"; 529 group = OperatorGrouping.Arithmetic; 530 break; 531 case CodeBinaryOperatorType.Multiply: 532 methodName = "op_Multiply"; 533 group = OperatorGrouping.Arithmetic; 534 break; 535 case CodeBinaryOperatorType.Divide: 536 methodName = "op_Division"; 537 group = OperatorGrouping.Arithmetic; 538 break; 539 case CodeBinaryOperatorType.Modulus: 540 methodName = "op_Modulus"; 541 group = OperatorGrouping.Arithmetic; 542 break; 543 case CodeBinaryOperatorType.BitwiseAnd: 544 methodName = "op_BitwiseAnd"; 545 group = OperatorGrouping.Arithmetic; 546 break; 547 case CodeBinaryOperatorType.BitwiseOr: 548 methodName = "op_BitwiseOr"; 549 group = OperatorGrouping.Arithmetic; 550 break; 551 default: 552 Debug.Assert(false, "Operator " + op.ToString() + " not implemented"); 553 message = string.Format(CultureInfo.CurrentCulture, Messages.BinaryOpNotSupported, op.ToString()); 554 error = new ValidationError(message, ErrorNumbers.Error_CodeExpressionNotHandled); 555 return null; 556 } 557 558 // NOTE: types maybe NullLiteral, which signifies the constant "null" 559 List<MethodInfo> candidates = new List<MethodInfo>(); 560 bool lhsNullable = ConditionHelper.IsNullableValueType(lhs); 561 bool rhsNullable = ConditionHelper.IsNullableValueType(rhs); 562 Type lhsType0 = (lhsNullable) ? Nullable.GetUnderlyingType(lhs) : lhs; 563 Type rhsType0 = (rhsNullable) ? Nullable.GetUnderlyingType(rhs) : rhs; 564 565 // special cases for enums 566 if (lhsType0.IsEnum) 567 { 568 // only 3 cases (U = underlying type of E): 569 // E = E + U 570 // U = E - E 571 // E = E - U 572 // plus the standard comparisons (E == E, E > E, etc.) 573 // need to also allow E == 0 574 Type underlyingType; 575 switch (op) 576 { 577 case CodeBinaryOperatorType.Add: 578 underlyingType = EnumHelper.GetUnderlyingType(lhsType0); 579 if ((underlyingType != null) && 580 (RuleValidation.TypesAreAssignable(rhsType0, underlyingType, rhsExpression, out error))) 581 { 582 error = null; 583 return new EnumOperationMethodInfo(lhs, op, rhs, false); 584 } 585 break; 586 case CodeBinaryOperatorType.Subtract: 587 underlyingType = EnumHelper.GetUnderlyingType(lhsType0); 588 if (underlyingType != null) 589 { 590 if (lhsType0 == rhsType0) 591 { 592 // E - E 593 error = null; 594 return new EnumOperationMethodInfo(lhs, op, rhs, false); 595 } 596 else if (DecimalIntegerLiteralZero(rhs, rhsExpression as CodePrimitiveExpression)) 597 { 598 // E - 0, can convert 0 to E 599 error = null; 600 return new EnumOperationMethodInfo(lhs, op, rhs, true); 601 } 602 else if (RuleValidation.TypesAreAssignable(rhsType0, underlyingType, rhsExpression, out error)) 603 { 604 // expression not passed to TypesAreAssignable, so not looking for constants (since 0 is all we care about) 605 error = null; 606 return new EnumOperationMethodInfo(lhs, op, rhs, false); 607 } 608 } 609 break; 610 case CodeBinaryOperatorType.ValueEquality: 611 case CodeBinaryOperatorType.LessThan: 612 case CodeBinaryOperatorType.LessThanOrEqual: 613 case CodeBinaryOperatorType.GreaterThan: 614 case CodeBinaryOperatorType.GreaterThanOrEqual: 615 if (lhsType0 == rhsType0) 616 { 617 error = null; 618 return new EnumOperationMethodInfo(lhs, op, rhs, false); 619 } 620 else if (lhsNullable && (rhs == typeof(NullLiteral))) 621 { 622 // handle enum? op null 623 // treat the rhs as the same nullable enum 624 error = null; 625 return new EnumOperationMethodInfo(lhs, op, lhs, false); 626 } 627 else if (DecimalIntegerLiteralZero(rhs, rhsExpression as CodePrimitiveExpression)) 628 { 629 error = null; 630 return new EnumOperationMethodInfo(lhs, op, rhs, true); 631 } 632 break; 633 } 634 // can't do it, sorry 635 // but check if there is a user-defined operator that works 636 } 637 else if (rhsType0.IsEnum) 638 { 639 // lhs != enum, so only 2 cases (U = underlying type of E): 640 // E = U + E 641 // E = U - E 642 // comparisons are E == E, etc., so if the lhs is not an enum, too bad 643 // although we need to check for 0 == E 644 Type underlyingType; 645 switch (op) 646 { 647 case CodeBinaryOperatorType.Add: 648 underlyingType = EnumHelper.GetUnderlyingType(rhsType0); 649 if ((underlyingType != null) && 650 (RuleValidation.TypesAreAssignable(lhsType0, underlyingType, lhsExpression, out error))) 651 { 652 error = null; 653 return new EnumOperationMethodInfo(lhs, op, rhs, false); 654 } 655 break; 656 657 case CodeBinaryOperatorType.Subtract: 658 underlyingType = EnumHelper.GetUnderlyingType(rhsType0); 659 if (underlyingType != null) 660 { 661 CodePrimitiveExpression primitive = lhsExpression as CodePrimitiveExpression; 662 if (DecimalIntegerLiteralZero(lhs, primitive)) 663 { 664 // 0 - E, can convert 0 to E 665 error = null; 666 return new EnumOperationMethodInfo(lhs, op, rhs, true); 667 } 668 else if (RuleValidation.TypesAreAssignable(lhsType0, underlyingType, lhsExpression, out error)) 669 { 670 // expression not passed to TypesAreAssignable, so not looking for constants (since 0 is all we care about) 671 error = null; 672 return new EnumOperationMethodInfo(lhs, op, rhs, false); 673 } 674 } 675 break; 676 677 case CodeBinaryOperatorType.ValueEquality: 678 case CodeBinaryOperatorType.LessThan: 679 case CodeBinaryOperatorType.LessThanOrEqual: 680 case CodeBinaryOperatorType.GreaterThan: 681 case CodeBinaryOperatorType.GreaterThanOrEqual: 682 if (rhsNullable && (lhs == typeof(NullLiteral))) 683 { 684 // handle null op enum? 685 // treat the lhs as the same nullable enum type 686 error = null; 687 return new EnumOperationMethodInfo(rhs, op, rhs, false); 688 } 689 else if (DecimalIntegerLiteralZero(lhs, lhsExpression as CodePrimitiveExpression)) 690 { 691 error = null; 692 return new EnumOperationMethodInfo(lhs, op, rhs, true); 693 } 694 break; 695 } 696 697 // can't do it, sorry 698 // but check if there is a user-defined operator that works 699 } 700 701 // enum specific operations already handled, see if one side (or both) define operators 702 AddOperatorOverloads(lhsType0, methodName, lhs, rhs, candidates); 703 AddOperatorOverloads(rhsType0, methodName, lhs, rhs, candidates); 704 if (lhsNullable || rhsNullable || (lhs == typeof(NullLiteral)) || (rhs == typeof(NullLiteral))) 705 { 706 // need to add in lifted methods 707 AddLiftedOperators(lhsType0, methodName, group, lhsType0, rhsType0, candidates); 708 AddLiftedOperators(rhsType0, methodName, group, lhsType0, rhsType0, candidates); 709 } 710 711 if (candidates.Count == 0) 712 { 713 // no overrides, so get the default list 714 methodName = methodName.Substring(3); // strip off the op_ 715 foreach (MethodInfo mi in typeof(DefaultOperators).GetMethods()) 716 { 717 if (mi.Name == methodName) 718 { 719 ParameterInfo[] parameters = mi.GetParameters(); 720 Type parm1 = parameters[0].ParameterType; 721 Type parm2 = parameters[1].ParameterType; 722 if (RuleValidation.ImplicitConversion(lhs, parm1) && 723 RuleValidation.ImplicitConversion(rhs, parm2)) 724 { 725 candidates.Add(mi); 726 } 727 } 728 } 729 730 // if no candidates and ==, can we use object == object? 731 if ((candidates.Count == 0) && ("Equality" == methodName)) 732 { 733 // C# 7.9.6 734 // references must be compatible 735 // no boxing 736 // value types can't be compared 737 if ((!lhs.IsValueType) && (!rhs.IsValueType)) 738 { 739 // they are not classes, so references need to be compatible 740 // also check for null (which is NullLiteral type) -- null is compatible with any object type 741 if ((lhs == typeof(NullLiteral)) || (rhs == typeof(NullLiteral)) || 742 (lhs.IsAssignableFrom(rhs)) || (rhs.IsAssignableFrom(lhs))) 743 { 744 candidates.Add(ObjectEquality); 745 } 746 } 747 } 748 749 // if no candidates and nullable, add lifted operators 750 if ((candidates.Count == 0) && ((lhsNullable || rhsNullable || (lhs == typeof(NullLiteral)) || (rhs == typeof(NullLiteral))))) 751 { 752 foreach (MethodInfo mi in typeof(DefaultOperators).GetMethods()) 753 { 754 if (mi.Name == methodName) 755 { 756 ParameterInfo[] parameters = mi.GetParameters(); 757 MethodInfo liftedMethod = EvaluateLiftedMethod(mi, parameters, group, lhsType0, rhsType0); 758 if (liftedMethod != null) 759 candidates.Add(liftedMethod); 760 } 761 } 762 } 763 } 764 if (candidates.Count == 1) 765 { 766 // only 1, so it is it 767 error = null; 768 return candidates[0]; 769 } 770 else if (candidates.Count == 0) 771 { 772 // nothing matched 773 message = string.Format(CultureInfo.CurrentCulture, 774 (group == OperatorGrouping.Arithmetic) ? Messages.ArithOpBadTypes : Messages.RelationalOpBadTypes, 775 op.ToString(), 776 (lhs == typeof(NullLiteral)) ? Messages.NullValue : RuleDecompiler.DecompileType(lhs), 777 (rhs == typeof(NullLiteral)) ? Messages.NullValue : RuleDecompiler.DecompileType(rhs)); 778 error = new ValidationError(message, ErrorNumbers.Error_OperandTypesIncompatible); 779 return null; 780 } 781 else 782 { 783 // more than 1, so pick the best one 784 MethodInfo bestFit = validator.FindBestCandidate(null, candidates, lhs, rhs); 785 if (bestFit != null) 786 { 787 error = null; 788 return bestFit; 789 } 790 // must be ambiguous. Since there are at least 2 choices, show only the first 2 791 message = string.Format(CultureInfo.CurrentCulture, 792 Messages.AmbiguousOperator, 793 op.ToString(), 794 RuleDecompiler.DecompileMethod(candidates[0]), 795 RuleDecompiler.DecompileMethod(candidates[1])); 796 error = new ValidationError(message, ErrorNumbers.Error_OperandTypesIncompatible); 797 return null; 798 } 799 } 800 DecimalIntegerLiteralZero(Type type, CodePrimitiveExpression expression)801 private static bool DecimalIntegerLiteralZero(Type type, CodePrimitiveExpression expression) 802 { 803 if (expression != null) 804 { 805 if (type == typeof(int)) 806 return expression.Value.Equals(0); 807 else if (type == typeof(uint)) 808 return expression.Value.Equals(0U); 809 else if (type == typeof(long)) 810 return expression.Value.Equals(0L); 811 else if (type == typeof(ulong)) 812 return expression.Value.Equals(0UL); 813 } 814 return false; 815 } 816 AddOperatorOverloads(Type type, string methodName, Type arg1, Type arg2, List<MethodInfo> candidates)817 private static void AddOperatorOverloads(Type type, string methodName, Type arg1, Type arg2, List<MethodInfo> candidates) 818 { 819 // append the list of methods that match the name specified 820 int numAdded = 0; 821 MethodInfo[] possible = type.GetMethods(BindingFlags.Static | BindingFlags.Public); 822 foreach (MethodInfo mi in possible) 823 { 824 ParameterInfo[] parameters = mi.GetParameters(); 825 if ((mi.Name == methodName) && (parameters.Length == 2)) 826 { 827 if (EvaluateMethod(parameters, arg1, arg2)) 828 { 829 ++numAdded; 830 if (!candidates.Contains(mi)) 831 candidates.Add(mi); 832 } 833 } 834 } 835 if ((numAdded > 0) || (type == typeof(object))) 836 return; 837 838 // no matches, check direct base class (if there is one) 839 type = type.BaseType; 840 if (type != null) 841 { 842 possible = type.GetMethods(BindingFlags.Static | BindingFlags.Public); 843 foreach (MethodInfo mi in possible) 844 { 845 ParameterInfo[] parameters = mi.GetParameters(); 846 if ((mi.Name == methodName) && (parameters.Length == 2)) 847 { 848 if (EvaluateMethod(parameters, arg1, arg2)) 849 { 850 if (!candidates.Contains(mi)) 851 candidates.Add(mi); 852 } 853 } 854 } 855 } 856 } 857 AddLiftedOperators(Type type, string methodName, OperatorGrouping group, Type arg1, Type arg2, List<MethodInfo> candidates)858 private static void AddLiftedOperators(Type type, string methodName, OperatorGrouping group, Type arg1, Type arg2, List<MethodInfo> candidates) 859 { 860 // append the list of lifted methods that match the name specified 861 int numAdded = 0; 862 MethodInfo[] possible = type.GetMethods(BindingFlags.Static | BindingFlags.Public); 863 foreach (MethodInfo mi in possible) 864 { 865 ParameterInfo[] parameters = mi.GetParameters(); 866 if ((mi.Name == methodName) && (parameters.Length == 2)) 867 { 868 MethodInfo liftedMethod = EvaluateLiftedMethod(mi, parameters, group, arg1, arg2); 869 if (liftedMethod != null) 870 { 871 ++numAdded; 872 if (!candidates.Contains(liftedMethod)) 873 candidates.Add(liftedMethod); 874 } 875 } 876 } 877 if ((numAdded > 0) || (type == typeof(object))) 878 return; 879 880 // no matches, check direct base class (if there is one) 881 type = type.BaseType; 882 if (type != null) 883 { 884 possible = type.GetMethods(BindingFlags.Static | BindingFlags.Public); 885 foreach (MethodInfo mi in possible) 886 { 887 ParameterInfo[] parameters = mi.GetParameters(); 888 if ((mi.Name == methodName) && (parameters.Length == 2)) 889 { 890 MethodInfo liftedMethod = EvaluateLiftedMethod(mi, parameters, group, arg1, arg2); 891 if ((liftedMethod != null) && !candidates.Contains(liftedMethod)) 892 candidates.Add(liftedMethod); 893 } 894 } 895 } 896 } 897 EvaluateMethod(ParameterInfo[] parameters, Type arg1, Type arg2)898 private static bool EvaluateMethod(ParameterInfo[] parameters, Type arg1, Type arg2) 899 { 900 Type parm1 = parameters[0].ParameterType; 901 Type parm2 = parameters[1].ParameterType; 902 return (RuleValidation.ImplicitConversion(arg1, parm1) && 903 RuleValidation.ImplicitConversion(arg2, parm2)); 904 } 905 EvaluateLiftedMethod(MethodInfo mi, ParameterInfo[] parameters, OperatorGrouping group, Type arg1, Type arg2)906 private static MethodInfo EvaluateLiftedMethod(MethodInfo mi, ParameterInfo[] parameters, OperatorGrouping group, Type arg1, Type arg2) 907 { 908 Type parm1 = parameters[0].ParameterType; 909 Type parm2 = parameters[1].ParameterType; 910 if (ConditionHelper.IsNonNullableValueType(parm1) && ConditionHelper.IsNonNullableValueType(parm2)) 911 { 912 // lift the parameters for testing conversions, if possible 913 parm1 = typeof(Nullable<>).MakeGenericType(parm1); 914 parm2 = typeof(Nullable<>).MakeGenericType(parm2); 915 switch (group) 916 { 917 case OperatorGrouping.Equality: // for == != 918 if (mi.ReturnType == typeof(bool) && 919 RuleValidation.ImplicitConversion(arg1, parm1) && 920 RuleValidation.ImplicitConversion(arg2, parm2)) 921 { 922 return new LiftedEqualityOperatorMethodInfo(mi); 923 } 924 break; 925 case OperatorGrouping.Relational: // for < > <= >= 926 if (mi.ReturnType == typeof(bool) && 927 RuleValidation.ImplicitConversion(arg1, parm1) && 928 RuleValidation.ImplicitConversion(arg2, parm2)) 929 { 930 return new LiftedRelationalOperatorMethodInfo(mi); 931 } 932 break; 933 case OperatorGrouping.Arithmetic: // for + - * / % & ^ 934 if (ConditionHelper.IsNonNullableValueType(mi.ReturnType) && 935 RuleValidation.ImplicitConversion(arg1, parm1) && 936 RuleValidation.ImplicitConversion(arg2, parm2)) 937 { 938 return new LiftedArithmeticOperatorMethodInfo(mi); 939 } 940 break; 941 } 942 } 943 return null; 944 } 945 #endregion 946 947 #region Value Type Dispatch Methods 948 949 /// <summary> 950 /// Relational equal operator 951 /// Value-equality if we can do it, otherwise reference-equality 952 /// </summary> 953 /// <param name="rhs"></param> 954 /// <returns></returns> Equal(Literal rhs)955 internal abstract bool Equal(Literal rhs); Equal(byte literalValue)956 internal virtual bool Equal(byte literalValue) 957 { 958 return false; 959 } Equal(sbyte literalValue)960 internal virtual bool Equal(sbyte literalValue) 961 { 962 return false; 963 } Equal(short literalValue)964 internal virtual bool Equal(short literalValue) 965 { 966 return false; 967 } Equal(int literalValue)968 internal virtual bool Equal(int literalValue) 969 { 970 return false; 971 } Equal(long literalValue)972 internal virtual bool Equal(long literalValue) 973 { 974 return false; 975 } Equal(ushort literalValue)976 internal virtual bool Equal(ushort literalValue) 977 { 978 return false; 979 } Equal(uint literalValue)980 internal virtual bool Equal(uint literalValue) 981 { 982 return false; 983 } Equal(ulong literalValue)984 internal virtual bool Equal(ulong literalValue) 985 { 986 return false; 987 } Equal(float literalValue)988 internal virtual bool Equal(float literalValue) 989 { 990 return false; 991 } Equal(double literalValue)992 internal virtual bool Equal(double literalValue) 993 { 994 return false; 995 } Equal(char literalValue)996 internal virtual bool Equal(char literalValue) 997 { 998 return false; 999 } Equal(string literalValue)1000 internal virtual bool Equal(string literalValue) 1001 { 1002 return false; 1003 } Equal(decimal literalValue)1004 internal virtual bool Equal(decimal literalValue) 1005 { 1006 return false; 1007 } Equal(bool literalValue)1008 internal virtual bool Equal(bool literalValue) 1009 { 1010 return false; 1011 } 1012 1013 /// <summary> 1014 /// Relational less than operator 1015 /// </summary> 1016 /// <param name="rhs"></param> 1017 /// <returns></returns> LessThan(Literal rhs)1018 internal abstract bool LessThan(Literal rhs); LessThan()1019 internal virtual bool LessThan() 1020 { 1021 return false; 1022 } LessThan(byte literalValue)1023 internal virtual bool LessThan(byte literalValue) 1024 { 1025 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1026 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThan, m_type); 1027 } LessThan(char literalValue)1028 internal virtual bool LessThan(char literalValue) 1029 { 1030 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1031 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThan, m_type); 1032 } LessThan(sbyte literalValue)1033 internal virtual bool LessThan(sbyte literalValue) 1034 { 1035 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1036 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThan, m_type); 1037 } LessThan(short literalValue)1038 internal virtual bool LessThan(short literalValue) 1039 { 1040 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1041 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThan, m_type); 1042 } LessThan(int literalValue)1043 internal virtual bool LessThan(int literalValue) 1044 { 1045 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1046 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThan, m_type); 1047 } LessThan(long literalValue)1048 internal virtual bool LessThan(long literalValue) 1049 { 1050 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1051 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThan, m_type); 1052 } LessThan(ushort literalValue)1053 internal virtual bool LessThan(ushort literalValue) 1054 { 1055 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1056 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThan, m_type); 1057 } LessThan(uint literalValue)1058 internal virtual bool LessThan(uint literalValue) 1059 { 1060 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1061 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThan, m_type); 1062 } LessThan(ulong literalValue)1063 internal virtual bool LessThan(ulong literalValue) 1064 { 1065 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1066 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThan, m_type); 1067 } LessThan(float literalValue)1068 internal virtual bool LessThan(float literalValue) 1069 { 1070 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1071 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThan, m_type); 1072 } LessThan(double literalValue)1073 internal virtual bool LessThan(double literalValue) 1074 { 1075 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1076 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThan, m_type); 1077 } LessThan(string literalValue)1078 internal virtual bool LessThan(string literalValue) 1079 { 1080 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1081 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThan, m_type); 1082 } LessThan(decimal literalValue)1083 internal virtual bool LessThan(decimal literalValue) 1084 { 1085 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1086 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThan, m_type); 1087 } LessThan(bool literalValue)1088 internal virtual bool LessThan(bool literalValue) 1089 { 1090 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1091 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThan, m_type); 1092 } 1093 1094 /// <summary> 1095 /// Relational greater than operator 1096 /// </summary> 1097 /// <param name="rhs"></param> 1098 /// <returns></returns> GreaterThan(Literal rhs)1099 internal abstract bool GreaterThan(Literal rhs); GreaterThan()1100 internal virtual bool GreaterThan() 1101 { 1102 return false; 1103 } GreaterThan(byte literalValue)1104 internal virtual bool GreaterThan(byte literalValue) 1105 { 1106 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1107 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThan, m_type); 1108 } GreaterThan(char literalValue)1109 internal virtual bool GreaterThan(char literalValue) 1110 { 1111 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1112 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThan, m_type); 1113 } GreaterThan(sbyte literalValue)1114 internal virtual bool GreaterThan(sbyte literalValue) 1115 { 1116 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1117 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThan, m_type); 1118 } GreaterThan(short literalValue)1119 internal virtual bool GreaterThan(short literalValue) 1120 { 1121 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1122 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThan, m_type); 1123 } GreaterThan(int literalValue)1124 internal virtual bool GreaterThan(int literalValue) 1125 { 1126 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1127 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThan, m_type); 1128 } GreaterThan(long literalValue)1129 internal virtual bool GreaterThan(long literalValue) 1130 { 1131 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1132 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThan, m_type); 1133 } GreaterThan(ushort literalValue)1134 internal virtual bool GreaterThan(ushort literalValue) 1135 { 1136 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1137 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThan, m_type); 1138 } GreaterThan(uint literalValue)1139 internal virtual bool GreaterThan(uint literalValue) 1140 { 1141 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1142 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThan, m_type); 1143 } GreaterThan(ulong literalValue)1144 internal virtual bool GreaterThan(ulong literalValue) 1145 { 1146 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1147 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThan, m_type); 1148 } GreaterThan(float literalValue)1149 internal virtual bool GreaterThan(float literalValue) 1150 { 1151 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1152 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThan, m_type); 1153 } GreaterThan(double literalValue)1154 internal virtual bool GreaterThan(double literalValue) 1155 { 1156 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1157 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThan, m_type); 1158 } GreaterThan(string literalValue)1159 internal virtual bool GreaterThan(string literalValue) 1160 { 1161 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1162 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThan, m_type); 1163 } GreaterThan(decimal literalValue)1164 internal virtual bool GreaterThan(decimal literalValue) 1165 { 1166 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1167 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThan, m_type); 1168 } GreaterThan(bool literalValue)1169 internal virtual bool GreaterThan(bool literalValue) 1170 { 1171 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1172 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThan, m_type); 1173 } 1174 1175 /// <summary> 1176 /// Relational less than or equal to operator 1177 /// </summary> 1178 /// <param name="rhs"></param> 1179 /// <returns></returns> LessThanOrEqual(Literal rhs)1180 internal abstract bool LessThanOrEqual(Literal rhs); LessThanOrEqual()1181 internal virtual bool LessThanOrEqual() 1182 { 1183 return false; 1184 } LessThanOrEqual(byte literalValue)1185 internal virtual bool LessThanOrEqual(byte literalValue) 1186 { 1187 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1188 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThanOrEqual, m_type); 1189 } LessThanOrEqual(char literalValue)1190 internal virtual bool LessThanOrEqual(char literalValue) 1191 { 1192 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1193 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThanOrEqual, m_type); 1194 } LessThanOrEqual(sbyte literalValue)1195 internal virtual bool LessThanOrEqual(sbyte literalValue) 1196 { 1197 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1198 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThanOrEqual, m_type); 1199 } LessThanOrEqual(short literalValue)1200 internal virtual bool LessThanOrEqual(short literalValue) 1201 { 1202 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1203 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThanOrEqual, m_type); 1204 } LessThanOrEqual(int literalValue)1205 internal virtual bool LessThanOrEqual(int literalValue) 1206 { 1207 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1208 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThanOrEqual, m_type); 1209 } LessThanOrEqual(long literalValue)1210 internal virtual bool LessThanOrEqual(long literalValue) 1211 { 1212 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1213 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThanOrEqual, m_type); 1214 } LessThanOrEqual(ushort literalValue)1215 internal virtual bool LessThanOrEqual(ushort literalValue) 1216 { 1217 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1218 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThanOrEqual, m_type); 1219 } LessThanOrEqual(uint literalValue)1220 internal virtual bool LessThanOrEqual(uint literalValue) 1221 { 1222 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1223 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThanOrEqual, m_type); 1224 } LessThanOrEqual(ulong literalValue)1225 internal virtual bool LessThanOrEqual(ulong literalValue) 1226 { 1227 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1228 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThanOrEqual, m_type); 1229 } LessThanOrEqual(float literalValue)1230 internal virtual bool LessThanOrEqual(float literalValue) 1231 { 1232 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1233 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThanOrEqual, m_type); 1234 } LessThanOrEqual(double literalValue)1235 internal virtual bool LessThanOrEqual(double literalValue) 1236 { 1237 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1238 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThanOrEqual, m_type); 1239 } LessThanOrEqual(string literalValue)1240 internal virtual bool LessThanOrEqual(string literalValue) 1241 { 1242 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1243 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThanOrEqual, m_type); 1244 } LessThanOrEqual(decimal literalValue)1245 internal virtual bool LessThanOrEqual(decimal literalValue) 1246 { 1247 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1248 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThanOrEqual, m_type); 1249 } LessThanOrEqual(bool literalValue)1250 internal virtual bool LessThanOrEqual(bool literalValue) 1251 { 1252 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1253 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.LessThanOrEqual, m_type); 1254 } 1255 1256 /// <summary> 1257 /// Relational greater than or equal to operator 1258 /// </summary> 1259 /// <param name="rhs"></param> 1260 /// <returns></returns> GreaterThanOrEqual(Literal rhs)1261 internal abstract bool GreaterThanOrEqual(Literal rhs); GreaterThanOrEqual()1262 internal virtual bool GreaterThanOrEqual() 1263 { 1264 return false; 1265 } GreaterThanOrEqual(byte literalValue)1266 internal virtual bool GreaterThanOrEqual(byte literalValue) 1267 { 1268 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1269 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThanOrEqual, m_type); 1270 } GreaterThanOrEqual(char literalValue)1271 internal virtual bool GreaterThanOrEqual(char literalValue) 1272 { 1273 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1274 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThanOrEqual, m_type); 1275 } GreaterThanOrEqual(sbyte literalValue)1276 internal virtual bool GreaterThanOrEqual(sbyte literalValue) 1277 { 1278 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1279 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThanOrEqual, m_type); 1280 } GreaterThanOrEqual(short literalValue)1281 internal virtual bool GreaterThanOrEqual(short literalValue) 1282 { 1283 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1284 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThanOrEqual, m_type); 1285 } GreaterThanOrEqual(int literalValue)1286 internal virtual bool GreaterThanOrEqual(int literalValue) 1287 { 1288 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1289 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThanOrEqual, m_type); 1290 } GreaterThanOrEqual(long literalValue)1291 internal virtual bool GreaterThanOrEqual(long literalValue) 1292 { 1293 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1294 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThanOrEqual, m_type); 1295 } GreaterThanOrEqual(ushort literalValue)1296 internal virtual bool GreaterThanOrEqual(ushort literalValue) 1297 { 1298 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1299 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThanOrEqual, m_type); 1300 } GreaterThanOrEqual(uint literalValue)1301 internal virtual bool GreaterThanOrEqual(uint literalValue) 1302 { 1303 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1304 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThanOrEqual, m_type); 1305 } GreaterThanOrEqual(ulong literalValue)1306 internal virtual bool GreaterThanOrEqual(ulong literalValue) 1307 { 1308 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1309 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThanOrEqual, m_type); 1310 } GreaterThanOrEqual(float literalValue)1311 internal virtual bool GreaterThanOrEqual(float literalValue) 1312 { 1313 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1314 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThanOrEqual, m_type); 1315 } GreaterThanOrEqual(double literalValue)1316 internal virtual bool GreaterThanOrEqual(double literalValue) 1317 { 1318 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1319 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThanOrEqual, m_type); 1320 } GreaterThanOrEqual(string literalValue)1321 internal virtual bool GreaterThanOrEqual(string literalValue) 1322 { 1323 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1324 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThanOrEqual, m_type); 1325 } GreaterThanOrEqual(decimal literalValue)1326 internal virtual bool GreaterThanOrEqual(decimal literalValue) 1327 { 1328 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1329 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThanOrEqual, m_type); 1330 } GreaterThanOrEqual(bool literalValue)1331 internal virtual bool GreaterThanOrEqual(bool literalValue) 1332 { 1333 string message = string.Format(CultureInfo.CurrentCulture, Messages.IncompatibleComparisonTypes, literalValue.GetType(), m_type); 1334 throw new RuleEvaluationIncompatibleTypesException(message, literalValue.GetType(), CodeBinaryOperatorType.GreaterThanOrEqual, m_type); 1335 } 1336 #endregion 1337 } 1338 #endregion 1339 1340 #region Null Literal Class 1341 /// <summary> 1342 /// Represents an null literal 1343 /// </summary> 1344 internal class NullLiteral : Literal 1345 { 1346 // NOTE (from MSDN page on IComparable.CompareTo Method): 1347 // By definition, any object compares greater than a null reference 1348 // But C# (24.3.1) doesn't -- if either side is null, result is false 1349 NullLiteral(Type type)1350 internal NullLiteral(Type type) 1351 { 1352 m_type = type; 1353 } 1354 1355 internal override object Value 1356 { 1357 get { return null; } 1358 } 1359 Equal(Literal rhs)1360 internal override bool Equal(Literal rhs) 1361 { 1362 return rhs.Value == null; 1363 } 1364 LessThan(Literal rhs)1365 internal override bool LessThan(Literal rhs) 1366 { 1367 return rhs.GreaterThan(); 1368 } LessThan(byte literalValue)1369 internal override bool LessThan(byte literalValue) 1370 { 1371 return false; 1372 } LessThan(char literalValue)1373 internal override bool LessThan(char literalValue) 1374 { 1375 return false; 1376 } LessThan(sbyte literalValue)1377 internal override bool LessThan(sbyte literalValue) 1378 { 1379 return false; 1380 } LessThan(short literalValue)1381 internal override bool LessThan(short literalValue) 1382 { 1383 return false; 1384 } LessThan(int literalValue)1385 internal override bool LessThan(int literalValue) 1386 { 1387 return false; 1388 } LessThan(long literalValue)1389 internal override bool LessThan(long literalValue) 1390 { 1391 return false; 1392 } LessThan(ushort literalValue)1393 internal override bool LessThan(ushort literalValue) 1394 { 1395 return false; 1396 } LessThan(uint literalValue)1397 internal override bool LessThan(uint literalValue) 1398 { 1399 return false; 1400 } LessThan(ulong literalValue)1401 internal override bool LessThan(ulong literalValue) 1402 { 1403 return false; 1404 } LessThan(float literalValue)1405 internal override bool LessThan(float literalValue) 1406 { 1407 return false; 1408 } LessThan(double literalValue)1409 internal override bool LessThan(double literalValue) 1410 { 1411 return false; 1412 } LessThan(string literalValue)1413 internal override bool LessThan(string literalValue) 1414 { 1415 // for strings, maintain compatibility with v1 1416 return true; 1417 } LessThan(decimal literalValue)1418 internal override bool LessThan(decimal literalValue) 1419 { 1420 return false; 1421 } 1422 GreaterThan(Literal rhs)1423 internal override bool GreaterThan(Literal rhs) 1424 { 1425 return rhs.LessThan(); 1426 } GreaterThan(byte literalValue)1427 internal override bool GreaterThan(byte literalValue) 1428 { 1429 return false; 1430 } GreaterThan(char literalValue)1431 internal override bool GreaterThan(char literalValue) 1432 { 1433 return false; 1434 } GreaterThan(sbyte literalValue)1435 internal override bool GreaterThan(sbyte literalValue) 1436 { 1437 return false; 1438 } GreaterThan(short literalValue)1439 internal override bool GreaterThan(short literalValue) 1440 { 1441 return false; 1442 } GreaterThan(int literalValue)1443 internal override bool GreaterThan(int literalValue) 1444 { 1445 return false; 1446 } GreaterThan(long literalValue)1447 internal override bool GreaterThan(long literalValue) 1448 { 1449 return false; 1450 } GreaterThan(ushort literalValue)1451 internal override bool GreaterThan(ushort literalValue) 1452 { 1453 return false; 1454 } GreaterThan(uint literalValue)1455 internal override bool GreaterThan(uint literalValue) 1456 { 1457 return false; 1458 } GreaterThan(ulong literalValue)1459 internal override bool GreaterThan(ulong literalValue) 1460 { 1461 return false; 1462 } GreaterThan(float literalValue)1463 internal override bool GreaterThan(float literalValue) 1464 { 1465 return false; 1466 } GreaterThan(double literalValue)1467 internal override bool GreaterThan(double literalValue) 1468 { 1469 return false; 1470 } GreaterThan(string literalValue)1471 internal override bool GreaterThan(string literalValue) 1472 { 1473 return false; 1474 } GreaterThan(decimal literalValue)1475 internal override bool GreaterThan(decimal literalValue) 1476 { 1477 return false; 1478 } 1479 1480 /// <summary> 1481 /// Relational less than or equal to operator 1482 /// </summary> 1483 /// <param name="rhs"></param> 1484 /// <returns></returns> LessThanOrEqual(Literal rhs)1485 internal override bool LessThanOrEqual(Literal rhs) 1486 { 1487 return rhs.GreaterThanOrEqual(); 1488 } LessThanOrEqual()1489 internal override bool LessThanOrEqual() 1490 { 1491 return (m_type == typeof(string)); // null == null for strings only 1492 } LessThanOrEqual(byte literalValue)1493 internal override bool LessThanOrEqual(byte literalValue) 1494 { 1495 return false; 1496 } LessThanOrEqual(char literalValue)1497 internal override bool LessThanOrEqual(char literalValue) 1498 { 1499 return false; 1500 } LessThanOrEqual(sbyte literalValue)1501 internal override bool LessThanOrEqual(sbyte literalValue) 1502 { 1503 return false; 1504 } LessThanOrEqual(short literalValue)1505 internal override bool LessThanOrEqual(short literalValue) 1506 { 1507 return false; 1508 } LessThanOrEqual(int literalValue)1509 internal override bool LessThanOrEqual(int literalValue) 1510 { 1511 return false; 1512 } LessThanOrEqual(long literalValue)1513 internal override bool LessThanOrEqual(long literalValue) 1514 { 1515 return false; 1516 } LessThanOrEqual(ushort literalValue)1517 internal override bool LessThanOrEqual(ushort literalValue) 1518 { 1519 return false; 1520 } LessThanOrEqual(uint literalValue)1521 internal override bool LessThanOrEqual(uint literalValue) 1522 { 1523 return false; 1524 } LessThanOrEqual(ulong literalValue)1525 internal override bool LessThanOrEqual(ulong literalValue) 1526 { 1527 return false; 1528 } LessThanOrEqual(float literalValue)1529 internal override bool LessThanOrEqual(float literalValue) 1530 { 1531 return false; 1532 } LessThanOrEqual(double literalValue)1533 internal override bool LessThanOrEqual(double literalValue) 1534 { 1535 return false; 1536 } LessThanOrEqual(string literalValue)1537 internal override bool LessThanOrEqual(string literalValue) 1538 { 1539 // for strings, maintain compatibility with v1 1540 return true; 1541 } LessThanOrEqual(decimal literalValue)1542 internal override bool LessThanOrEqual(decimal literalValue) 1543 { 1544 return false; 1545 } 1546 GreaterThanOrEqual(Literal rhs)1547 internal override bool GreaterThanOrEqual(Literal rhs) 1548 { 1549 return rhs.LessThanOrEqual(); 1550 } GreaterThanOrEqual()1551 internal override bool GreaterThanOrEqual() 1552 { 1553 return (m_type == typeof(string)); // null == null for strings only 1554 } GreaterThanOrEqual(byte literalValue)1555 internal override bool GreaterThanOrEqual(byte literalValue) 1556 { 1557 return false; 1558 } GreaterThanOrEqual(char literalValue)1559 internal override bool GreaterThanOrEqual(char literalValue) 1560 { 1561 return false; 1562 } GreaterThanOrEqual(sbyte literalValue)1563 internal override bool GreaterThanOrEqual(sbyte literalValue) 1564 { 1565 return false; 1566 } GreaterThanOrEqual(short literalValue)1567 internal override bool GreaterThanOrEqual(short literalValue) 1568 { 1569 return false; 1570 } GreaterThanOrEqual(int literalValue)1571 internal override bool GreaterThanOrEqual(int literalValue) 1572 { 1573 return false; 1574 } GreaterThanOrEqual(long literalValue)1575 internal override bool GreaterThanOrEqual(long literalValue) 1576 { 1577 return false; 1578 } GreaterThanOrEqual(ushort literalValue)1579 internal override bool GreaterThanOrEqual(ushort literalValue) 1580 { 1581 return false; 1582 } GreaterThanOrEqual(uint literalValue)1583 internal override bool GreaterThanOrEqual(uint literalValue) 1584 { 1585 return false; 1586 } GreaterThanOrEqual(ulong literalValue)1587 internal override bool GreaterThanOrEqual(ulong literalValue) 1588 { 1589 return false; 1590 } GreaterThanOrEqual(float literalValue)1591 internal override bool GreaterThanOrEqual(float literalValue) 1592 { 1593 return false; 1594 } GreaterThanOrEqual(double literalValue)1595 internal override bool GreaterThanOrEqual(double literalValue) 1596 { 1597 return false; 1598 } GreaterThanOrEqual(string literalValue)1599 internal override bool GreaterThanOrEqual(string literalValue) 1600 { 1601 return false; 1602 } GreaterThanOrEqual(decimal literalValue)1603 internal override bool GreaterThanOrEqual(decimal literalValue) 1604 { 1605 return false; 1606 } 1607 } 1608 #endregion 1609 1610 #region Boolean Literal Class 1611 /// <summary> 1612 /// Represents a boolean literal 1613 /// </summary> 1614 internal class BoolLiteral : Literal 1615 { 1616 private bool m_value; 1617 1618 internal override object Value 1619 { 1620 get { return m_value; } 1621 } 1622 BoolLiteral(bool literalValue)1623 internal BoolLiteral(bool literalValue) 1624 { 1625 m_value = literalValue; 1626 m_type = typeof(bool); 1627 } 1628 Equal(Literal rhs)1629 internal override bool Equal(Literal rhs) 1630 { 1631 return rhs.Equal(m_value); 1632 } Equal(bool rhs)1633 internal override bool Equal(bool rhs) 1634 { 1635 return m_value == rhs; 1636 } 1637 LessThan(Literal rhs)1638 internal override bool LessThan(Literal rhs) 1639 { 1640 return rhs.GreaterThan(m_value); 1641 } 1642 GreaterThan(Literal rhs)1643 internal override bool GreaterThan(Literal rhs) 1644 { 1645 return rhs.LessThan(m_value); 1646 } 1647 LessThanOrEqual(Literal rhs)1648 internal override bool LessThanOrEqual(Literal rhs) 1649 { 1650 return rhs.GreaterThanOrEqual(m_value); 1651 } 1652 GreaterThanOrEqual(Literal rhs)1653 internal override bool GreaterThanOrEqual(Literal rhs) 1654 { 1655 return rhs.LessThanOrEqual(m_value); 1656 } 1657 } 1658 #endregion 1659 1660 #region Byte Literal Class 1661 /// <summary> 1662 /// Represents a byte literal 1663 /// </summary> 1664 internal class ByteLiteral : Literal 1665 { 1666 private byte m_value; 1667 1668 internal override object Value 1669 { 1670 get { return m_value; } 1671 } 1672 ByteLiteral(byte literalValue)1673 internal ByteLiteral(byte literalValue) 1674 { 1675 m_value = literalValue; 1676 m_type = typeof(byte); 1677 } 1678 Equal(Literal rhs)1679 internal override bool Equal(Literal rhs) 1680 { 1681 return rhs.Equal(m_value); 1682 } Equal(sbyte rhs)1683 internal override bool Equal(sbyte rhs) 1684 { 1685 return m_value == rhs; 1686 } Equal(byte rhs)1687 internal override bool Equal(byte rhs) 1688 { 1689 return m_value == rhs; 1690 } Equal(char rhs)1691 internal override bool Equal(char rhs) 1692 { 1693 return m_value == rhs; 1694 } Equal(short rhs)1695 internal override bool Equal(short rhs) 1696 { 1697 return m_value == rhs; 1698 } Equal(ushort rhs)1699 internal override bool Equal(ushort rhs) 1700 { 1701 return m_value == rhs; 1702 } Equal(int rhs)1703 internal override bool Equal(int rhs) 1704 { 1705 return m_value == rhs; 1706 } Equal(uint rhs)1707 internal override bool Equal(uint rhs) 1708 { 1709 return m_value == rhs; 1710 } Equal(long rhs)1711 internal override bool Equal(long rhs) 1712 { 1713 return m_value == rhs; 1714 } Equal(ulong rhs)1715 internal override bool Equal(ulong rhs) 1716 { 1717 return m_value == rhs; 1718 } Equal(float rhs)1719 internal override bool Equal(float rhs) 1720 { 1721 return m_value == rhs; 1722 } Equal(double rhs)1723 internal override bool Equal(double rhs) 1724 { 1725 return m_value == rhs; 1726 } Equal(decimal rhs)1727 internal override bool Equal(decimal rhs) 1728 { 1729 return m_value == rhs; 1730 } 1731 LessThan(Literal rhs)1732 internal override bool LessThan(Literal rhs) 1733 { 1734 return rhs.GreaterThan(m_value); 1735 } LessThan(sbyte rhs)1736 internal override bool LessThan(sbyte rhs) 1737 { 1738 return m_value < rhs; 1739 } LessThan(byte rhs)1740 internal override bool LessThan(byte rhs) 1741 { 1742 return m_value < rhs; 1743 } LessThan(char rhs)1744 internal override bool LessThan(char rhs) 1745 { 1746 return m_value < rhs; 1747 } LessThan(short rhs)1748 internal override bool LessThan(short rhs) 1749 { 1750 return m_value < rhs; 1751 } LessThan(ushort rhs)1752 internal override bool LessThan(ushort rhs) 1753 { 1754 return m_value < rhs; 1755 } LessThan(int rhs)1756 internal override bool LessThan(int rhs) 1757 { 1758 return m_value < rhs; 1759 } LessThan(uint rhs)1760 internal override bool LessThan(uint rhs) 1761 { 1762 return m_value < rhs; 1763 } LessThan(long rhs)1764 internal override bool LessThan(long rhs) 1765 { 1766 return m_value < rhs; 1767 } LessThan(ulong rhs)1768 internal override bool LessThan(ulong rhs) 1769 { 1770 return m_value < rhs; 1771 } LessThan(float rhs)1772 internal override bool LessThan(float rhs) 1773 { 1774 return m_value < rhs; 1775 } LessThan(double rhs)1776 internal override bool LessThan(double rhs) 1777 { 1778 return m_value < rhs; 1779 } LessThan(decimal rhs)1780 internal override bool LessThan(decimal rhs) 1781 { 1782 return m_value < rhs; 1783 } 1784 GreaterThan(Literal rhs)1785 internal override bool GreaterThan(Literal rhs) 1786 { 1787 return rhs.LessThan(m_value); 1788 } GreaterThan(sbyte rhs)1789 internal override bool GreaterThan(sbyte rhs) 1790 { 1791 return m_value > rhs; 1792 } GreaterThan(byte rhs)1793 internal override bool GreaterThan(byte rhs) 1794 { 1795 return m_value > rhs; 1796 } GreaterThan(char rhs)1797 internal override bool GreaterThan(char rhs) 1798 { 1799 return m_value > rhs; 1800 } GreaterThan(short rhs)1801 internal override bool GreaterThan(short rhs) 1802 { 1803 return m_value > rhs; 1804 } GreaterThan(ushort rhs)1805 internal override bool GreaterThan(ushort rhs) 1806 { 1807 return m_value > rhs; 1808 } GreaterThan(int rhs)1809 internal override bool GreaterThan(int rhs) 1810 { 1811 return m_value > rhs; 1812 } GreaterThan(uint rhs)1813 internal override bool GreaterThan(uint rhs) 1814 { 1815 return m_value > rhs; 1816 } GreaterThan(long rhs)1817 internal override bool GreaterThan(long rhs) 1818 { 1819 return m_value > rhs; 1820 } GreaterThan(ulong rhs)1821 internal override bool GreaterThan(ulong rhs) 1822 { 1823 return m_value > rhs; 1824 } GreaterThan(float rhs)1825 internal override bool GreaterThan(float rhs) 1826 { 1827 return m_value > rhs; 1828 } GreaterThan(double rhs)1829 internal override bool GreaterThan(double rhs) 1830 { 1831 return m_value > rhs; 1832 } GreaterThan(decimal rhs)1833 internal override bool GreaterThan(decimal rhs) 1834 { 1835 return m_value > rhs; 1836 } 1837 LessThanOrEqual(Literal rhs)1838 internal override bool LessThanOrEqual(Literal rhs) 1839 { 1840 return rhs.GreaterThanOrEqual(m_value); 1841 } LessThanOrEqual(sbyte rhs)1842 internal override bool LessThanOrEqual(sbyte rhs) 1843 { 1844 return m_value <= rhs; 1845 } LessThanOrEqual(byte rhs)1846 internal override bool LessThanOrEqual(byte rhs) 1847 { 1848 return m_value <= rhs; 1849 } LessThanOrEqual(short rhs)1850 internal override bool LessThanOrEqual(short rhs) 1851 { 1852 return m_value <= rhs; 1853 } LessThanOrEqual(char rhs)1854 internal override bool LessThanOrEqual(char rhs) 1855 { 1856 return m_value <= rhs; 1857 } LessThanOrEqual(ushort rhs)1858 internal override bool LessThanOrEqual(ushort rhs) 1859 { 1860 return m_value <= rhs; 1861 } LessThanOrEqual(int rhs)1862 internal override bool LessThanOrEqual(int rhs) 1863 { 1864 return m_value <= rhs; 1865 } LessThanOrEqual(uint rhs)1866 internal override bool LessThanOrEqual(uint rhs) 1867 { 1868 return m_value <= rhs; 1869 } LessThanOrEqual(long rhs)1870 internal override bool LessThanOrEqual(long rhs) 1871 { 1872 return m_value <= rhs; 1873 } LessThanOrEqual(ulong rhs)1874 internal override bool LessThanOrEqual(ulong rhs) 1875 { 1876 return m_value <= rhs; 1877 } LessThanOrEqual(float rhs)1878 internal override bool LessThanOrEqual(float rhs) 1879 { 1880 return m_value <= rhs; 1881 } LessThanOrEqual(double rhs)1882