Advertisement
Guest User

Linq.Dynamic

a guest
Aug 21st, 2012
279
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 96.83 KB | None | 0 0
  1. //Copyright (C) Microsoft Corporation.  All rights reserved.
  2.  
  3. namespace System.Linq.Dynamic
  4. {
  5.  
  6.  
  7.     public static class DynamicQueryable
  8.     {
  9.  
  10.  
  11.         public static IQueryable<T> Where<T>(this IQueryable<T> source, string predicate, params object[] values)
  12.         {
  13.             return (IQueryable<T>)Where((IQueryable)source, predicate, values);
  14.         }
  15.  
  16.         public static IQueryable Where(this IQueryable source, string predicate, params object[] values)
  17.         {
  18.             if (source == null) throw new ArgumentNullException("source");
  19.             if (predicate == null) throw new ArgumentNullException("predicate");
  20.             System.Linq.Expressions.LambdaExpression lambda = DynamicExpression.ParseLambda(source.ElementType, typeof(bool), predicate, values);
  21.             return source.Provider.CreateQuery(
  22.                 System.Linq.Expressions.Expression.Call(
  23.                     typeof(Queryable), "Where",
  24.                     new Type[] { source.ElementType },
  25.                     source.Expression, System.Linq.Expressions.Expression.Quote(lambda)));
  26.         }
  27.  
  28.         public static IQueryable Select(this IQueryable source, string selector, params object[] values)
  29.         {
  30.             if (source == null) throw new ArgumentNullException("source");
  31.             if (selector == null) throw new ArgumentNullException("selector");
  32.             System.Linq.Expressions.LambdaExpression lambda = DynamicExpression.ParseLambda(source.ElementType, null, selector, values);
  33.             return source.Provider.CreateQuery(
  34.                 System.Linq.Expressions.Expression.Call(
  35.                     typeof(Queryable), "Select",
  36.                     new Type[] { source.ElementType, lambda.Body.Type },
  37.                     source.Expression, System.Linq.Expressions.Expression.Quote(lambda)));
  38.         }
  39.  
  40.         public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string ordering, params object[] values)
  41.         {
  42.             return (IQueryable<T>)OrderBy((IQueryable)source, ordering, values);
  43.         }
  44.  
  45.         public static IQueryable OrderBy(this IQueryable source, string ordering, params object[] values)
  46.         {
  47.             if (source == null) throw new ArgumentNullException("source");
  48.             if (ordering == null) throw new ArgumentNullException("ordering");
  49.  
  50.             if (object.ReferenceEquals(source.ElementType, typeof(System.Data.DataRow)))
  51.             {
  52.                 int iOrdinal = 0;
  53.                 string[] astrParts = ordering.Split(' ');
  54.  
  55.                 foreach (System.Data.DataRow row in source)
  56.                 {
  57.                     iOrdinal = row.Table.Columns[astrParts[0]].Ordinal;
  58.                     break;
  59.                 }
  60.  
  61.                 ordering = "ItemArray[" + iOrdinal + "]";
  62.                 for (int i = 1; i < astrParts.Length; ++i)
  63.                 {
  64.                     ordering += " " + astrParts[i];
  65.                 }
  66.  
  67.                 astrParts = null;
  68.             }
  69.  
  70.             System.Linq.Expressions.ParameterExpression[] parameters = new System.Linq.Expressions.ParameterExpression[] {
  71.                 System.Linq.Expressions.Expression.Parameter(source.ElementType, "") };
  72.             ExpressionParser parser = new ExpressionParser(parameters, ordering, values);
  73.             System.Collections.Generic.IEnumerable<DynamicOrdering> orderings = parser.ParseOrdering();
  74.             System.Linq.Expressions.Expression queryExpr = source.Expression;
  75.             string methodAsc = "OrderBy";
  76.             string methodDesc = "OrderByDescending";
  77.             foreach (DynamicOrdering o in orderings)
  78.             {
  79.                 queryExpr = System.Linq.Expressions.Expression.Call(
  80.                     typeof(Queryable), o.Ascending ? methodAsc : methodDesc,
  81.                     new Type[] { source.ElementType, o.Selector.Type },
  82.                     queryExpr, System.Linq.Expressions.Expression.Quote(System.Linq.Expressions.Expression.Lambda(o.Selector, parameters)));
  83.                 methodAsc = "ThenBy";
  84.                 methodDesc = "ThenByDescending";
  85.             }
  86.             return source.Provider.CreateQuery(queryExpr);
  87.         }
  88.  
  89.         public static IQueryable Take(this IQueryable source, int count)
  90.         {
  91.             if (source == null) throw new ArgumentNullException("source");
  92.             return source.Provider.CreateQuery(
  93.                 System.Linq.Expressions.Expression.Call(
  94.                     typeof(Queryable), "Take",
  95.                     new Type[] { source.ElementType },
  96.                     source.Expression, System.Linq.Expressions.Expression.Constant(count)));
  97.         }
  98.  
  99.         public static IQueryable Skip(this IQueryable source, int count)
  100.         {
  101.             if (source == null) throw new ArgumentNullException("source");
  102.             return source.Provider.CreateQuery(
  103.                 System.Linq.Expressions.Expression.Call(
  104.                     typeof(Queryable), "Skip",
  105.                     new Type[] { source.ElementType },
  106.                     source.Expression, System.Linq.Expressions.Expression.Constant(count)));
  107.         }
  108.  
  109.         public static IQueryable GroupBy(this IQueryable source, string keySelector, string elementSelector, params object[] values)
  110.         {
  111.             if (source == null) throw new ArgumentNullException("source");
  112.             if (keySelector == null) throw new ArgumentNullException("keySelector");
  113.             if (elementSelector == null) throw new ArgumentNullException("elementSelector");
  114.             System.Linq.Expressions.LambdaExpression keyLambda = DynamicExpression.ParseLambda(source.ElementType, null, keySelector, values);
  115.             System.Linq.Expressions.LambdaExpression elementLambda = DynamicExpression.ParseLambda(source.ElementType, null, elementSelector, values);
  116.             return source.Provider.CreateQuery(
  117.                 System.Linq.Expressions.Expression.Call(
  118.                     typeof(Queryable), "GroupBy",
  119.                     new Type[] { source.ElementType, keyLambda.Body.Type, elementLambda.Body.Type },
  120.                     source.Expression, System.Linq.Expressions.Expression.Quote(keyLambda), System.Linq.Expressions.Expression.Quote(elementLambda)));
  121.         }
  122.  
  123.         public static bool Any(this IQueryable source)
  124.         {
  125.             if (source == null) throw new ArgumentNullException("source");
  126.             return (bool)source.Provider.Execute(
  127.                 System.Linq.Expressions.Expression.Call(
  128.                     typeof(Queryable), "Any",
  129.                     new Type[] { source.ElementType }, source.Expression));
  130.         }
  131.  
  132.         public static int Count(this IQueryable source)
  133.         {
  134.             if (source == null) throw new ArgumentNullException("source");
  135.             return (int)source.Provider.Execute(
  136.                 System.Linq.Expressions.Expression.Call(
  137.                     typeof(Queryable), "Count",
  138.                     new Type[] { source.ElementType }, source.Expression));
  139.         }
  140.     }
  141.  
  142.     public abstract class DynamicClass
  143.     {
  144.         public override string ToString()
  145.         {
  146.             System.Reflection.PropertyInfo[] props = this.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
  147.             System.Text.StringBuilder sb = new System.Text.StringBuilder();
  148.             sb.Append("{");
  149.             for (int i = 0; i < props.Length; i++)
  150.             {
  151.                 if (i > 0) sb.Append(", ");
  152.                 sb.Append(props[i].Name);
  153.                 sb.Append("=");
  154.                 sb.Append(props[i].GetValue(this, null));
  155.             }
  156.             sb.Append("}");
  157.             return sb.ToString();
  158.         }
  159.     }
  160.  
  161.     public class DynamicProperty
  162.     {
  163.         string name;
  164.         Type type;
  165.  
  166.         public DynamicProperty(string name, Type type)
  167.         {
  168.             if (name == null) throw new ArgumentNullException("name");
  169.             if (type == null) throw new ArgumentNullException("type");
  170.             this.name = name;
  171.             this.type = type;
  172.         }
  173.  
  174.         public string Name
  175.         {
  176.             get { return name; }
  177.         }
  178.  
  179.         public Type Type
  180.         {
  181.             get { return type; }
  182.         }
  183.     }
  184.  
  185.     public static class DynamicExpression
  186.     {
  187.         public static System.Linq.Expressions.Expression Parse(Type resultType, string expression, params object[] values)
  188.         {
  189.             ExpressionParser parser = new ExpressionParser(null, expression, values);
  190.             return parser.Parse(resultType);
  191.         }
  192.  
  193.         public static System.Linq.Expressions.LambdaExpression ParseLambda(Type itType, Type resultType, string expression, params object[] values)
  194.         {
  195.             return ParseLambda(new System.Linq.Expressions.ParameterExpression[] { System.Linq.Expressions.Expression.Parameter(itType, "") }, resultType, expression, values);
  196.         }
  197.  
  198.         public static System.Linq.Expressions.LambdaExpression ParseLambda(System.Linq.Expressions.ParameterExpression[] parameters, Type resultType, string expression, params object[] values)
  199.         {
  200.             ExpressionParser parser = new ExpressionParser(parameters, expression, values);
  201.             return System.Linq.Expressions.Expression.Lambda(parser.Parse(resultType), parameters);
  202.         }
  203.  
  204.         public static System.Linq.Expressions.Expression<Func<T, S>> ParseLambda<T, S>(string expression, params object[] values)
  205.         {
  206.             return (System.Linq.Expressions.Expression<Func<T, S>>)ParseLambda(typeof(T), typeof(S), expression, values);
  207.         }
  208.  
  209.         public static Type CreateClass(params DynamicProperty[] properties)
  210.         {
  211.             return ClassFactory.Instance.GetDynamicClass(properties);
  212.         }
  213.  
  214.         public static Type CreateClass(System.Collections.Generic.IEnumerable<DynamicProperty> properties)
  215.         {
  216.             return ClassFactory.Instance.GetDynamicClass(properties);
  217.         }
  218.     }
  219.  
  220.     internal class DynamicOrdering
  221.     {
  222.         public System.Linq.Expressions.Expression Selector;
  223.         public bool Ascending;
  224.     }
  225.  
  226.     internal class Signature : IEquatable<Signature>
  227.     {
  228.         public DynamicProperty[] properties;
  229.         public int hashCode;
  230.  
  231.         public Signature(System.Collections.Generic.IEnumerable<DynamicProperty> properties)
  232.         {
  233.             this.properties = properties.ToArray();
  234.             hashCode = 0;
  235.             foreach (DynamicProperty p in properties)
  236.             {
  237.                 hashCode ^= p.Name.GetHashCode() ^ p.Type.GetHashCode();
  238.             }
  239.         }
  240.  
  241.         public override int GetHashCode()
  242.         {
  243.             return hashCode;
  244.         }
  245.  
  246.         public override bool Equals(object obj)
  247.         {
  248.             return obj is Signature ? Equals((Signature)obj) : false;
  249.         }
  250.  
  251.         public bool Equals(Signature other)
  252.         {
  253.             if (properties.Length != other.properties.Length) return false;
  254.             for (int i = 0; i < properties.Length; i++)
  255.             {
  256.                 if (properties[i].Name != other.properties[i].Name ||
  257.                     properties[i].Type != other.properties[i].Type) return false;
  258.             }
  259.             return true;
  260.         }
  261.     }
  262.  
  263.     internal class ClassFactory
  264.     {
  265.         public static readonly ClassFactory Instance = new ClassFactory();
  266.  
  267.         static ClassFactory() { }  // Trigger lazy initialization of static fields
  268.  
  269.         System.Reflection.Emit.ModuleBuilder module;
  270.         System.Collections.Generic.Dictionary<Signature, Type> classes;
  271.         int classCount;
  272.         System.Threading.ReaderWriterLock rwLock;
  273.  
  274.         private ClassFactory()
  275.         {
  276.             System.Reflection.AssemblyName name = new System.Reflection.AssemblyName("DynamicClasses");
  277.             System.Reflection.Emit.AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, System.Reflection.Emit.AssemblyBuilderAccess.Run);
  278. #if ENABLE_LINQ_PARTIAL_TRUST
  279.             new ReflectionPermission(PermissionState.Unrestricted).Assert();
  280. #endif
  281.             try
  282.             {
  283.                 module = assembly.DefineDynamicModule("Module");
  284.             }
  285.             finally
  286.             {
  287. #if ENABLE_LINQ_PARTIAL_TRUST
  288.                 PermissionSet.RevertAssert();
  289. #endif
  290.             }
  291.             classes = new System.Collections.Generic.Dictionary<Signature, Type>();
  292.             rwLock = new System.Threading.ReaderWriterLock();
  293.         }
  294.  
  295.         public Type GetDynamicClass(System.Collections.Generic.IEnumerable<DynamicProperty> properties)
  296.         {
  297.             rwLock.AcquireReaderLock(System.Threading.Timeout.Infinite);
  298.             try
  299.             {
  300.                 Signature signature = new Signature(properties);
  301.                 Type type;
  302.                 if (!classes.TryGetValue(signature, out type))
  303.                 {
  304.                     type = CreateDynamicClass(signature.properties);
  305.                     classes.Add(signature, type);
  306.                 }
  307.                 return type;
  308.             }
  309.             finally
  310.             {
  311.                 rwLock.ReleaseReaderLock();
  312.             }
  313.         }
  314.  
  315.         Type CreateDynamicClass(DynamicProperty[] properties)
  316.         {
  317.             System.Threading.LockCookie cookie = rwLock.UpgradeToWriterLock(System.Threading.Timeout.Infinite);
  318.             try
  319.             {
  320.                 string typeName = "DynamicClass" + (classCount + 1);
  321. #if ENABLE_LINQ_PARTIAL_TRUST
  322.                 new ReflectionPermission(PermissionState.Unrestricted).Assert();
  323. #endif
  324.                 try
  325.                 {
  326.                     System.Reflection.Emit.TypeBuilder tb = this.module.DefineType(typeName, System.Reflection.TypeAttributes.Class |
  327.                         System.Reflection.TypeAttributes.Public, typeof(DynamicClass));
  328.                     System.Reflection.FieldInfo[] fields = GenerateProperties(tb, properties);
  329.                     GenerateEquals(tb, fields);
  330.                     GenerateGetHashCode(tb, fields);
  331.                     Type result = tb.CreateType();
  332.                     classCount++;
  333.                     return result;
  334.                 }
  335.                 finally
  336.                 {
  337. #if ENABLE_LINQ_PARTIAL_TRUST
  338.                     PermissionSet.RevertAssert();
  339. #endif
  340.                 }
  341.             }
  342.             finally
  343.             {
  344.                 rwLock.DowngradeFromWriterLock(ref cookie);
  345.             }
  346.         }
  347.  
  348.         System.Reflection.FieldInfo[] GenerateProperties(System.Reflection.Emit.TypeBuilder tb, DynamicProperty[] properties)
  349.         {
  350.             System.Reflection.FieldInfo[] fields = new System.Reflection.Emit.FieldBuilder[properties.Length];
  351.             for (int i = 0; i < properties.Length; i++)
  352.             {
  353.                 DynamicProperty dp = properties[i];
  354.                 System.Reflection.Emit.FieldBuilder fb = tb.DefineField("_" + dp.Name, dp.Type, System.Reflection.FieldAttributes.Private);
  355.                 System.Reflection.Emit.PropertyBuilder pb = tb.DefineProperty(dp.Name, System.Reflection.PropertyAttributes.HasDefault, dp.Type, null);
  356.                 System.Reflection.Emit.MethodBuilder mbGet = tb.DefineMethod("get_" + dp.Name,
  357.                     System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.SpecialName | System.Reflection.MethodAttributes.HideBySig,
  358.                     dp.Type, Type.EmptyTypes);
  359.                 System.Reflection.Emit.ILGenerator genGet = mbGet.GetILGenerator();
  360.                 genGet.Emit(System.Reflection.Emit.OpCodes.Ldarg_0);
  361.                 genGet.Emit(System.Reflection.Emit.OpCodes.Ldfld, fb);
  362.                 genGet.Emit(System.Reflection.Emit.OpCodes.Ret);
  363.                 System.Reflection.Emit.MethodBuilder mbSet = tb.DefineMethod("set_" + dp.Name,
  364.                     System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.SpecialName | System.Reflection.MethodAttributes.HideBySig,
  365.                     null, new Type[] { dp.Type });
  366.                 System.Reflection.Emit.ILGenerator genSet = mbSet.GetILGenerator();
  367.                 genSet.Emit(System.Reflection.Emit.OpCodes.Ldarg_0);
  368.                 genSet.Emit(System.Reflection.Emit.OpCodes.Ldarg_1);
  369.                 genSet.Emit(System.Reflection.Emit.OpCodes.Stfld, fb);
  370.                 genSet.Emit(System.Reflection.Emit.OpCodes.Ret);
  371.                 pb.SetGetMethod(mbGet);
  372.                 pb.SetSetMethod(mbSet);
  373.                 fields[i] = fb;
  374.             }
  375.             return fields;
  376.         }
  377.  
  378.         void GenerateEquals(System.Reflection.Emit.TypeBuilder tb, System.Reflection.FieldInfo[] fields)
  379.         {
  380.             System.Reflection.Emit.MethodBuilder mb = tb.DefineMethod("Equals",
  381.                 System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.ReuseSlot |
  382.                 System.Reflection.MethodAttributes.Virtual | System.Reflection.MethodAttributes.HideBySig,
  383.                 typeof(bool), new Type[] { typeof(object) });
  384.             System.Reflection.Emit.ILGenerator gen = mb.GetILGenerator();
  385.             System.Reflection.Emit.LocalBuilder other = gen.DeclareLocal(tb);
  386.             System.Reflection.Emit.Label next = gen.DefineLabel();
  387.             gen.Emit(System.Reflection.Emit.OpCodes.Ldarg_1);
  388.             gen.Emit(System.Reflection.Emit.OpCodes.Isinst, tb);
  389.             gen.Emit(System.Reflection.Emit.OpCodes.Stloc, other);
  390.             gen.Emit(System.Reflection.Emit.OpCodes.Ldloc, other);
  391.             gen.Emit(System.Reflection.Emit.OpCodes.Brtrue_S, next);
  392.             gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0);
  393.             gen.Emit(System.Reflection.Emit.OpCodes.Ret);
  394.             gen.MarkLabel(next);
  395.             foreach (System.Reflection.FieldInfo field in fields)
  396.             {
  397.                 Type ft = field.FieldType;
  398.                 Type ct = typeof(System.Collections.Generic.EqualityComparer<>).MakeGenericType(ft);
  399.                 next = gen.DefineLabel();
  400.                 gen.EmitCall(System.Reflection.Emit.OpCodes.Call, ct.GetMethod("get_Default"), null);
  401.                 gen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0);
  402.                 gen.Emit(System.Reflection.Emit.OpCodes.Ldfld, field);
  403.                 gen.Emit(System.Reflection.Emit.OpCodes.Ldloc, other);
  404.                 gen.Emit(System.Reflection.Emit.OpCodes.Ldfld, field);
  405.                 gen.EmitCall(System.Reflection.Emit.OpCodes.Callvirt, ct.GetMethod("Equals", new Type[] { ft, ft }), null);
  406.                 gen.Emit(System.Reflection.Emit.OpCodes.Brtrue_S, next);
  407.                 gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0);
  408.                 gen.Emit(System.Reflection.Emit.OpCodes.Ret);
  409.                 gen.MarkLabel(next);
  410.             }
  411.             gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_1);
  412.             gen.Emit(System.Reflection.Emit.OpCodes.Ret);
  413.         }
  414.  
  415.         void GenerateGetHashCode(System.Reflection.Emit.TypeBuilder tb, System.Reflection.FieldInfo[] fields)
  416.         {
  417.             System.Reflection.Emit.MethodBuilder mb = tb.DefineMethod("GetHashCode",
  418.                 System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.ReuseSlot |
  419.                 System.Reflection.MethodAttributes.Virtual | System.Reflection.MethodAttributes.HideBySig,
  420.                 typeof(int), Type.EmptyTypes);
  421.             System.Reflection.Emit.ILGenerator gen = mb.GetILGenerator();
  422.             gen.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0);
  423.             foreach (System.Reflection.FieldInfo field in fields)
  424.             {
  425.                 Type ft = field.FieldType;
  426.                 Type ct = typeof(System.Collections.Generic.EqualityComparer<>).MakeGenericType(ft);
  427.                 gen.EmitCall(System.Reflection.Emit.OpCodes.Call, ct.GetMethod("get_Default"), null);
  428.                 gen.Emit(System.Reflection.Emit.OpCodes.Ldarg_0);
  429.                 gen.Emit(System.Reflection.Emit.OpCodes.Ldfld, field);
  430.                 gen.EmitCall(System.Reflection.Emit.OpCodes.Callvirt, ct.GetMethod("GetHashCode", new Type[] { ft }), null);
  431.                 gen.Emit(System.Reflection.Emit.OpCodes.Xor);
  432.             }
  433.             gen.Emit(System.Reflection.Emit.OpCodes.Ret);
  434.         }
  435.     }
  436.  
  437.     public sealed class ParseException : Exception
  438.     {
  439.         int position;
  440.  
  441.         public ParseException(string message, int position)
  442.             : base(message)
  443.         {
  444.             this.position = position;
  445.         }
  446.  
  447.         public int Position
  448.         {
  449.             get { return position; }
  450.         }
  451.  
  452.         public override string ToString()
  453.         {
  454.             return string.Format(Res.ParseExceptionFormat, Message, position);
  455.         }
  456.     }
  457.  
  458.     internal class ExpressionParser
  459.     {
  460.         struct Token
  461.         {
  462.             public TokenId id;
  463.             public string text;
  464.             public int pos;
  465.         }
  466.  
  467.         enum TokenId
  468.         {
  469.             Unknown,
  470.             End,
  471.             Identifier,
  472.             StringLiteral,
  473.             IntegerLiteral,
  474.             RealLiteral,
  475.             Exclamation,
  476.             Percent,
  477.             Amphersand,
  478.             OpenParen,
  479.             CloseParen,
  480.             Asterisk,
  481.             Plus,
  482.             Comma,
  483.             Minus,
  484.             Dot,
  485.             Slash,
  486.             Colon,
  487.             LessThan,
  488.             Equal,
  489.             GreaterThan,
  490.             Question,
  491.             OpenBracket,
  492.             CloseBracket,
  493.             Bar,
  494.             ExclamationEqual,
  495.             DoubleAmphersand,
  496.             LessThanEqual,
  497.             LessGreater,
  498.             DoubleEqual,
  499.             GreaterThanEqual,
  500.             DoubleBar
  501.         }
  502.  
  503.         interface ILogicalSignatures
  504.         {
  505.             void F(bool x, bool y);
  506.             void F(bool? x, bool? y);
  507.         }
  508.  
  509.         interface IArithmeticSignatures
  510.         {
  511.             void F(int x, int y);
  512.             void F(uint x, uint y);
  513.             void F(long x, long y);
  514.             void F(ulong x, ulong y);
  515.             void F(float x, float y);
  516.             void F(double x, double y);
  517.             void F(decimal x, decimal y);
  518.             void F(int? x, int? y);
  519.             void F(uint? x, uint? y);
  520.             void F(long? x, long? y);
  521.             void F(ulong? x, ulong? y);
  522.             void F(float? x, float? y);
  523.             void F(double? x, double? y);
  524.             void F(decimal? x, decimal? y);
  525.         }
  526.  
  527.         interface IRelationalSignatures : IArithmeticSignatures
  528.         {
  529.             void F(string x, string y);
  530.             void F(char x, char y);
  531.             void F(DateTime x, DateTime y);
  532.             void F(TimeSpan x, TimeSpan y);
  533.             void F(char? x, char? y);
  534.             void F(DateTime? x, DateTime? y);
  535.             void F(TimeSpan? x, TimeSpan? y);
  536.         }
  537.  
  538.         interface IEqualitySignatures : IRelationalSignatures
  539.         {
  540.             void F(bool x, bool y);
  541.             void F(bool? x, bool? y);
  542.         }
  543.  
  544.         interface IAddSignatures : IArithmeticSignatures
  545.         {
  546.             void F(DateTime x, TimeSpan y);
  547.             void F(TimeSpan x, TimeSpan y);
  548.             void F(DateTime? x, TimeSpan? y);
  549.             void F(TimeSpan? x, TimeSpan? y);
  550.         }
  551.  
  552.         interface ISubtractSignatures : IAddSignatures
  553.         {
  554.             void F(DateTime x, DateTime y);
  555.             void F(DateTime? x, DateTime? y);
  556.         }
  557.  
  558.         interface INegationSignatures
  559.         {
  560.             void F(int x);
  561.             void F(long x);
  562.             void F(float x);
  563.             void F(double x);
  564.             void F(decimal x);
  565.             void F(int? x);
  566.             void F(long? x);
  567.             void F(float? x);
  568.             void F(double? x);
  569.             void F(decimal? x);
  570.         }
  571.  
  572.         interface INotSignatures
  573.         {
  574.             void F(bool x);
  575.             void F(bool? x);
  576.         }
  577.  
  578.         interface IEnumerableSignatures
  579.         {
  580.             void Where(bool predicate);
  581.             void Any();
  582.             void Any(bool predicate);
  583.             void All(bool predicate);
  584.             void Count();
  585.             void Count(bool predicate);
  586.             void Min(object selector);
  587.             void Max(object selector);
  588.             void Sum(int selector);
  589.             void Sum(int? selector);
  590.             void Sum(long selector);
  591.             void Sum(long? selector);
  592.             void Sum(float selector);
  593.             void Sum(float? selector);
  594.             void Sum(double selector);
  595.             void Sum(double? selector);
  596.             void Sum(decimal selector);
  597.             void Sum(decimal? selector);
  598.             void Average(int selector);
  599.             void Average(int? selector);
  600.             void Average(long selector);
  601.             void Average(long? selector);
  602.             void Average(float selector);
  603.             void Average(float? selector);
  604.             void Average(double selector);
  605.             void Average(double? selector);
  606.             void Average(decimal selector);
  607.             void Average(decimal? selector);
  608.         }
  609.  
  610.         static readonly Type[] predefinedTypes = {
  611.             typeof(Object),
  612.             typeof(Boolean),
  613.             typeof(Char),
  614.             typeof(String),
  615.             typeof(SByte),
  616.             typeof(Byte),
  617.             typeof(Int16),
  618.             typeof(UInt16),
  619.             typeof(Int32),
  620.             typeof(UInt32),
  621.             typeof(Int64),
  622.             typeof(UInt64),
  623.             typeof(Single),
  624.             typeof(Double),
  625.             typeof(Decimal),
  626.             typeof(DateTime),
  627.             typeof(TimeSpan),
  628.             typeof(Guid),
  629.             typeof(Math),
  630.             typeof(Convert)
  631.         };
  632.  
  633.         static readonly System.Linq.Expressions.Expression trueLiteral = System.Linq.Expressions.Expression.Constant(true);
  634.         static readonly System.Linq.Expressions.Expression falseLiteral = System.Linq.Expressions.Expression.Constant(false);
  635.         static readonly System.Linq.Expressions.Expression nullLiteral = System.Linq.Expressions.Expression.Constant(null);
  636.  
  637.         static readonly string keywordIt = "it";
  638.         static readonly string keywordIif = "iif";
  639.         static readonly string keywordNew = "new";
  640.  
  641.         static System.Collections.Generic.Dictionary<string, object> keywords;
  642.  
  643.         System.Collections.Generic.Dictionary<string, object> symbols;
  644.         System.Collections.Generic.IDictionary<string, object> externals;
  645.         System.Collections.Generic.Dictionary<System.Linq.Expressions.Expression, string> literals;
  646.         System.Linq.Expressions.ParameterExpression it;
  647.         string text;
  648.         int textPos;
  649.         int textLen;
  650.         char ch;
  651.         Token token;
  652.  
  653.         public ExpressionParser(System.Linq.Expressions.ParameterExpression[] parameters, string expression, object[] values)
  654.         {
  655.             if (expression == null) throw new ArgumentNullException("expression");
  656.             if (keywords == null) keywords = CreateKeywords();
  657.             symbols = new System.Collections.Generic.Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
  658.             literals = new System.Collections.Generic.Dictionary<System.Linq.Expressions.Expression, string>();
  659.             if (parameters != null) ProcessParameters(parameters);
  660.             if (values != null) ProcessValues(values);
  661.             text = expression;
  662.             textLen = text.Length;
  663.             SetTextPos(0);
  664.             NextToken();
  665.         }
  666.  
  667.         void ProcessParameters(System.Linq.Expressions.ParameterExpression[] parameters)
  668.         {
  669.             foreach (System.Linq.Expressions.ParameterExpression pe in parameters)
  670.                 if (!String.IsNullOrEmpty(pe.Name))
  671.                     AddSymbol(pe.Name, pe);
  672.             if (parameters.Length == 1 && String.IsNullOrEmpty(parameters[0].Name))
  673.                 it = parameters[0];
  674.         }
  675.  
  676.         void ProcessValues(object[] values)
  677.         {
  678.             for (int i = 0; i < values.Length; i++)
  679.             {
  680.                 object value = values[i];
  681.                 if (i == values.Length - 1 && value is System.Collections.Generic.IDictionary<string, object>)
  682.                 {
  683.                     externals = (System.Collections.Generic.IDictionary<string, object>)value;
  684.                 }
  685.                 else
  686.                 {
  687.                     AddSymbol("@" + i.ToString(System.Globalization.CultureInfo.InvariantCulture), value);
  688.                 }
  689.             }
  690.         }
  691.  
  692.         void AddSymbol(string name, object value)
  693.         {
  694.             if (symbols.ContainsKey(name))
  695.                 throw ParseError(Res.DuplicateIdentifier, name);
  696.             symbols.Add(name, value);
  697.         }
  698.  
  699.         public System.Linq.Expressions.Expression Parse(Type resultType)
  700.         {
  701.             int exprPos = token.pos;
  702.             System.Linq.Expressions.Expression expr = ParseExpression();
  703.             if (resultType != null)
  704.                 if ((expr = PromoteExpression(expr, resultType, true)) == null)
  705.                     throw ParseError(exprPos, Res.ExpressionTypeMismatch, GetTypeName(resultType));
  706.             ValidateToken(TokenId.End, Res.SyntaxError);
  707.             return expr;
  708.         }
  709.  
  710. #pragma warning disable 0219
  711.         public System.Collections.Generic.IEnumerable<DynamicOrdering> ParseOrdering()
  712.         {
  713.             System.Collections.Generic.List<DynamicOrdering> orderings = new System.Collections.Generic.List<DynamicOrdering>();
  714.             while (true)
  715.             {
  716.                 System.Linq.Expressions.Expression expr = ParseExpression();
  717.                 bool ascending = true;
  718.                 if (TokenIdentifierIs("asc") || TokenIdentifierIs("ascending"))
  719.                 {
  720.                     NextToken();
  721.                 }
  722.                 else if (TokenIdentifierIs("desc") || TokenIdentifierIs("descending"))
  723.                 {
  724.                     NextToken();
  725.                     ascending = false;
  726.                 }
  727.                 orderings.Add(new DynamicOrdering { Selector = expr, Ascending = ascending });
  728.                 if (token.id != TokenId.Comma) break;
  729.                 NextToken();
  730.             }
  731.             ValidateToken(TokenId.End, Res.SyntaxError);
  732.             return orderings;
  733.         }
  734. #pragma warning restore 0219
  735.  
  736.         // ?: operator
  737.         System.Linq.Expressions.Expression ParseExpression()
  738.         {
  739.             int errorPos = token.pos;
  740.             System.Linq.Expressions.Expression expr = ParseLogicalOr();
  741.             if (token.id == TokenId.Question)
  742.             {
  743.                 NextToken();
  744.                 System.Linq.Expressions.Expression expr1 = ParseExpression();
  745.                 ValidateToken(TokenId.Colon, Res.ColonExpected);
  746.                 NextToken();
  747.                 System.Linq.Expressions.Expression expr2 = ParseExpression();
  748.                 expr = GenerateConditional(expr, expr1, expr2, errorPos);
  749.             }
  750.             return expr;
  751.         }
  752.  
  753.         // ||, or operator
  754.         System.Linq.Expressions.Expression ParseLogicalOr()
  755.         {
  756.             System.Linq.Expressions.Expression left = ParseLogicalAnd();
  757.             while (token.id == TokenId.DoubleBar || TokenIdentifierIs("or"))
  758.             {
  759.                 Token op = token;
  760.                 NextToken();
  761.                 System.Linq.Expressions.Expression right = ParseLogicalAnd();
  762.                 CheckAndPromoteOperands(typeof(ILogicalSignatures), op.text, ref left, ref right, op.pos);
  763.                 left = System.Linq.Expressions.Expression.OrElse(left, right);
  764.             }
  765.             return left;
  766.         }
  767.  
  768.         // &&, and operator
  769.         System.Linq.Expressions.Expression ParseLogicalAnd()
  770.         {
  771.             System.Linq.Expressions.Expression left = ParseComparison();
  772.             while (token.id == TokenId.DoubleAmphersand || TokenIdentifierIs("and"))
  773.             {
  774.                 Token op = token;
  775.                 NextToken();
  776.                 System.Linq.Expressions.Expression right = ParseComparison();
  777.                 CheckAndPromoteOperands(typeof(ILogicalSignatures), op.text, ref left, ref right, op.pos);
  778.                 left = System.Linq.Expressions.Expression.AndAlso(left, right);
  779.             }
  780.             return left;
  781.         }
  782.  
  783.         // =, ==, !=, <>, >, >=, <, <= operators
  784.         System.Linq.Expressions.Expression ParseComparison()
  785.         {
  786.             System.Linq.Expressions.Expression left = ParseAdditive();
  787.             while (token.id == TokenId.Equal || token.id == TokenId.DoubleEqual ||
  788.                 token.id == TokenId.ExclamationEqual || token.id == TokenId.LessGreater ||
  789.                 token.id == TokenId.GreaterThan || token.id == TokenId.GreaterThanEqual ||
  790.                 token.id == TokenId.LessThan || token.id == TokenId.LessThanEqual)
  791.             {
  792.                 Token op = token;
  793.                 NextToken();
  794.                 System.Linq.Expressions.Expression right = ParseAdditive();
  795.                 bool isEquality = op.id == TokenId.Equal || op.id == TokenId.DoubleEqual ||
  796.                     op.id == TokenId.ExclamationEqual || op.id == TokenId.LessGreater;
  797.                 if (isEquality && !left.Type.IsValueType && !right.Type.IsValueType)
  798.                 {
  799.                     if (left.Type != right.Type)
  800.                     {
  801.                         if (left.Type.IsAssignableFrom(right.Type))
  802.                         {
  803.                             right = System.Linq.Expressions.Expression.Convert(right, left.Type);
  804.                         }
  805.                         else if (right.Type.IsAssignableFrom(left.Type))
  806.                         {
  807.                             left = System.Linq.Expressions.Expression.Convert(left, right.Type);
  808.                         }
  809.                         else
  810.                         {
  811.                             throw IncompatibleOperandsError(op.text, left, right, op.pos);
  812.                         }
  813.                     }
  814.                 }
  815.                 else if (IsEnumType(left.Type) || IsEnumType(right.Type))
  816.                 {
  817.                     if (left.Type != right.Type)
  818.                     {
  819.                         System.Linq.Expressions.Expression e;
  820.                         if ((e = PromoteExpression(right, left.Type, true)) != null)
  821.                         {
  822.                             right = e;
  823.                         }
  824.                         else if ((e = PromoteExpression(left, right.Type, true)) != null)
  825.                         {
  826.                             left = e;
  827.                         }
  828.                         else
  829.                         {
  830.                             throw IncompatibleOperandsError(op.text, left, right, op.pos);
  831.                         }
  832.                     }
  833.                 }
  834.                 else
  835.                 {
  836.                     CheckAndPromoteOperands(isEquality ? typeof(IEqualitySignatures) : typeof(IRelationalSignatures),
  837.                         op.text, ref left, ref right, op.pos);
  838.                 }
  839.                 switch (op.id)
  840.                 {
  841.                     case TokenId.Equal:
  842.                     case TokenId.DoubleEqual:
  843.                         left = GenerateEqual(left, right);
  844.                         break;
  845.                     case TokenId.ExclamationEqual:
  846.                     case TokenId.LessGreater:
  847.                         left = GenerateNotEqual(left, right);
  848.                         break;
  849.                     case TokenId.GreaterThan:
  850.                         left = GenerateGreaterThan(left, right);
  851.                         break;
  852.                     case TokenId.GreaterThanEqual:
  853.                         left = GenerateGreaterThanEqual(left, right);
  854.                         break;
  855.                     case TokenId.LessThan:
  856.                         left = GenerateLessThan(left, right);
  857.                         break;
  858.                     case TokenId.LessThanEqual:
  859.                         left = GenerateLessThanEqual(left, right);
  860.                         break;
  861.                 }
  862.             }
  863.             return left;
  864.         }
  865.  
  866.         // +, -, & operators
  867.         System.Linq.Expressions.Expression ParseAdditive()
  868.         {
  869.             System.Linq.Expressions.Expression left = ParseMultiplicative();
  870.             while (token.id == TokenId.Plus || token.id == TokenId.Minus ||
  871.                 token.id == TokenId.Amphersand)
  872.             {
  873.                 Token op = token;
  874.                 NextToken();
  875.                 System.Linq.Expressions.Expression right = ParseMultiplicative();
  876.                 switch (op.id)
  877.                 {
  878.                     case TokenId.Plus:
  879.                         if (left.Type == typeof(string) || right.Type == typeof(string))
  880.                             goto case TokenId.Amphersand;
  881.                         CheckAndPromoteOperands(typeof(IAddSignatures), op.text, ref left, ref right, op.pos);
  882.                         left = GenerateAdd(left, right);
  883.                         break;
  884.                     case TokenId.Minus:
  885.                         CheckAndPromoteOperands(typeof(ISubtractSignatures), op.text, ref left, ref right, op.pos);
  886.                         left = GenerateSubtract(left, right);
  887.                         break;
  888.                     case TokenId.Amphersand:
  889.                         left = GenerateStringConcat(left, right);
  890.                         break;
  891.                 }
  892.             }
  893.             return left;
  894.         }
  895.  
  896.         // *, /, %, mod operators
  897.         System.Linq.Expressions.Expression ParseMultiplicative()
  898.         {
  899.             System.Linq.Expressions.Expression left = ParseUnary();
  900.             while (token.id == TokenId.Asterisk || token.id == TokenId.Slash ||
  901.                 token.id == TokenId.Percent || TokenIdentifierIs("mod"))
  902.             {
  903.                 Token op = token;
  904.                 NextToken();
  905.                 System.Linq.Expressions.Expression right = ParseUnary();
  906.                 CheckAndPromoteOperands(typeof(IArithmeticSignatures), op.text, ref left, ref right, op.pos);
  907.                 switch (op.id)
  908.                 {
  909.                     case TokenId.Asterisk:
  910.                         left = System.Linq.Expressions.Expression.Multiply(left, right);
  911.                         break;
  912.                     case TokenId.Slash:
  913.                         left = System.Linq.Expressions.Expression.Divide(left, right);
  914.                         break;
  915.                     case TokenId.Percent:
  916.                     case TokenId.Identifier:
  917.                         left = System.Linq.Expressions.Expression.Modulo(left, right);
  918.                         break;
  919.                 }
  920.             }
  921.             return left;
  922.         }
  923.  
  924.         // -, !, not unary operators
  925.         System.Linq.Expressions.Expression ParseUnary()
  926.         {
  927.             if (token.id == TokenId.Minus || token.id == TokenId.Exclamation ||
  928.                 TokenIdentifierIs("not"))
  929.             {
  930.                 Token op = token;
  931.                 NextToken();
  932.                 if (op.id == TokenId.Minus && (token.id == TokenId.IntegerLiteral ||
  933.                     token.id == TokenId.RealLiteral))
  934.                 {
  935.                     token.text = "-" + token.text;
  936.                     token.pos = op.pos;
  937.                     return ParsePrimary();
  938.                 }
  939.                 System.Linq.Expressions.Expression expr = ParseUnary();
  940.                 if (op.id == TokenId.Minus)
  941.                 {
  942.                     CheckAndPromoteOperand(typeof(INegationSignatures), op.text, ref expr, op.pos);
  943.                     expr = System.Linq.Expressions.Expression.Negate(expr);
  944.                 }
  945.                 else
  946.                 {
  947.                     CheckAndPromoteOperand(typeof(INotSignatures), op.text, ref expr, op.pos);
  948.                     expr = System.Linq.Expressions.Expression.Not(expr);
  949.                 }
  950.                 return expr;
  951.             }
  952.             return ParsePrimary();
  953.         }
  954.  
  955.         System.Linq.Expressions.Expression ParsePrimary()
  956.         {
  957.             System.Linq.Expressions.Expression expr = ParsePrimaryStart();
  958.             while (true)
  959.             {
  960.                 if (token.id == TokenId.Dot)
  961.                 {
  962.                     NextToken();
  963.                     expr = ParseMemberAccess(null, expr);
  964.                 }
  965.                 else if (token.id == TokenId.OpenBracket)
  966.                 {
  967.                     expr = ParseElementAccess(expr);
  968.                 }
  969.                 else
  970.                 {
  971.                     break;
  972.                 }
  973.             }
  974.             return expr;
  975.         }
  976.  
  977.         System.Linq.Expressions.Expression ParsePrimaryStart()
  978.         {
  979.             switch (token.id)
  980.             {
  981.                 case TokenId.Identifier:
  982.                     return ParseIdentifier();
  983.                 case TokenId.StringLiteral:
  984.                     return ParseStringLiteral();
  985.                 case TokenId.IntegerLiteral:
  986.                     return ParseIntegerLiteral();
  987.                 case TokenId.RealLiteral:
  988.                     return ParseRealLiteral();
  989.                 case TokenId.OpenParen:
  990.                     return ParseParenExpression();
  991.                 default:
  992.                     throw ParseError(Res.ExpressionExpected);
  993.             }
  994.         }
  995.  
  996.         System.Linq.Expressions.Expression ParseStringLiteral()
  997.         {
  998.             ValidateToken(TokenId.StringLiteral);
  999.             char quote = token.text[0];
  1000.             string s = token.text.Substring(1, token.text.Length - 2);
  1001.             int start = 0;
  1002.             while (true)
  1003.             {
  1004.                 int i = s.IndexOf(quote, start);
  1005.                 if (i < 0) break;
  1006.                 s = s.Remove(i, 1);
  1007.                 start = i + 1;
  1008.             }
  1009.             if (quote == '\'')
  1010.             {
  1011.                 if (s.Length != 1)
  1012.                     throw ParseError(Res.InvalidCharacterLiteral);
  1013.                 NextToken();
  1014.                 return CreateLiteral(s[0], s);
  1015.             }
  1016.             NextToken();
  1017.             return CreateLiteral(s, s);
  1018.         }
  1019.  
  1020.         System.Linq.Expressions.Expression ParseIntegerLiteral()
  1021.         {
  1022.             ValidateToken(TokenId.IntegerLiteral);
  1023.             string text = token.text;
  1024.             if (text[0] != '-')
  1025.             {
  1026.                 ulong value;
  1027.                 if (!UInt64.TryParse(text, out value))
  1028.                     throw ParseError(Res.InvalidIntegerLiteral, text);
  1029.                 NextToken();
  1030.                 if (value <= (ulong)Int32.MaxValue) return CreateLiteral((int)value, text);
  1031.                 if (value <= (ulong)UInt32.MaxValue) return CreateLiteral((uint)value, text);
  1032.                 if (value <= (ulong)Int64.MaxValue) return CreateLiteral((long)value, text);
  1033.                 return CreateLiteral(value, text);
  1034.             }
  1035.             else
  1036.             {
  1037.                 long value;
  1038.                 if (!Int64.TryParse(text, out value))
  1039.                     throw ParseError(Res.InvalidIntegerLiteral, text);
  1040.                 NextToken();
  1041.                 if (value >= Int32.MinValue && value <= Int32.MaxValue)
  1042.                     return CreateLiteral((int)value, text);
  1043.                 return CreateLiteral(value, text);
  1044.             }
  1045.         }
  1046.  
  1047.         System.Linq.Expressions.Expression ParseRealLiteral()
  1048.         {
  1049.             ValidateToken(TokenId.RealLiteral);
  1050.             string text = token.text;
  1051.             object value = null;
  1052.             char last = text[text.Length - 1];
  1053.             if (last == 'F' || last == 'f')
  1054.             {
  1055.                 float f;
  1056.                 if (Single.TryParse(text.Substring(0, text.Length - 1), out f)) value = f;
  1057.             }
  1058.             else
  1059.             {
  1060.                 double d;
  1061.                 if (Double.TryParse(text, out d)) value = d;
  1062.             }
  1063.             if (value == null) throw ParseError(Res.InvalidRealLiteral, text);
  1064.             NextToken();
  1065.             return CreateLiteral(value, text);
  1066.         }
  1067.  
  1068.         System.Linq.Expressions.Expression CreateLiteral(object value, string text)
  1069.         {
  1070.             System.Linq.Expressions.ConstantExpression expr = System.Linq.Expressions.Expression.Constant(value);
  1071.             literals.Add(expr, text);
  1072.             return expr;
  1073.         }
  1074.  
  1075.         System.Linq.Expressions.Expression ParseParenExpression()
  1076.         {
  1077.             ValidateToken(TokenId.OpenParen, Res.OpenParenExpected);
  1078.             NextToken();
  1079.             System.Linq.Expressions.Expression e = ParseExpression();
  1080.             ValidateToken(TokenId.CloseParen, Res.CloseParenOrOperatorExpected);
  1081.             NextToken();
  1082.             return e;
  1083.         }
  1084.  
  1085.         System.Linq.Expressions.Expression ParseIdentifier()
  1086.         {
  1087.             ValidateToken(TokenId.Identifier);
  1088.             object value;
  1089.             if (keywords.TryGetValue(token.text, out value))
  1090.             {
  1091.                 if (value is Type) return ParseTypeAccess((Type)value);
  1092.                 if (value == (object)keywordIt) return ParseIt();
  1093.                 if (value == (object)keywordIif) return ParseIif();
  1094.                 if (value == (object)keywordNew) return ParseNew();
  1095.                 NextToken();
  1096.                 return (System.Linq.Expressions.Expression)value;
  1097.             }
  1098.             if (symbols.TryGetValue(token.text, out value) ||
  1099.                 externals != null && externals.TryGetValue(token.text, out value))
  1100.             {
  1101.                 System.Linq.Expressions.Expression expr = value as System.Linq.Expressions.Expression;
  1102.                 if (expr == null)
  1103.                 {
  1104.                     expr = System.Linq.Expressions.Expression.Constant(value);
  1105.                 }
  1106.                 else
  1107.                 {
  1108.                     System.Linq.Expressions.LambdaExpression lambda = expr as System.Linq.Expressions.LambdaExpression;
  1109.                     if (lambda != null) return ParseLambdaInvocation(lambda);
  1110.                 }
  1111.                 NextToken();
  1112.                 return expr;
  1113.             }
  1114.             if (it != null) return ParseMemberAccess(null, it);
  1115.             throw ParseError(Res.UnknownIdentifier, token.text);
  1116.         }
  1117.  
  1118.         System.Linq.Expressions.Expression ParseIt()
  1119.         {
  1120.             if (it == null)
  1121.                 throw ParseError(Res.NoItInScope);
  1122.             NextToken();
  1123.             return it;
  1124.         }
  1125.  
  1126.         System.Linq.Expressions.Expression ParseIif()
  1127.         {
  1128.             int errorPos = token.pos;
  1129.             NextToken();
  1130.             System.Linq.Expressions.Expression[] args = ParseArgumentList();
  1131.             if (args.Length != 3)
  1132.                 throw ParseError(errorPos, Res.IifRequiresThreeArgs);
  1133.             return GenerateConditional(args[0], args[1], args[2], errorPos);
  1134.         }
  1135.  
  1136.         System.Linq.Expressions.Expression GenerateConditional(System.Linq.Expressions.Expression test, System.Linq.Expressions.Expression expr1, System.Linq.Expressions.Expression expr2, int errorPos)
  1137.         {
  1138.             if (test.Type != typeof(bool))
  1139.                 throw ParseError(errorPos, Res.FirstExprMustBeBool);
  1140.             if (expr1.Type != expr2.Type)
  1141.             {
  1142.                 System.Linq.Expressions.Expression expr1as2 = expr2 != nullLiteral ? PromoteExpression(expr1, expr2.Type, true) : null;
  1143.                 System.Linq.Expressions.Expression expr2as1 = expr1 != nullLiteral ? PromoteExpression(expr2, expr1.Type, true) : null;
  1144.                 if (expr1as2 != null && expr2as1 == null)
  1145.                 {
  1146.                     expr1 = expr1as2;
  1147.                 }
  1148.                 else if (expr2as1 != null && expr1as2 == null)
  1149.                 {
  1150.                     expr2 = expr2as1;
  1151.                 }
  1152.                 else
  1153.                 {
  1154.                     string type1 = expr1 != nullLiteral ? expr1.Type.Name : "null";
  1155.                     string type2 = expr2 != nullLiteral ? expr2.Type.Name : "null";
  1156.                     if (expr1as2 != null && expr2as1 != null)
  1157.                         throw ParseError(errorPos, Res.BothTypesConvertToOther, type1, type2);
  1158.                     throw ParseError(errorPos, Res.NeitherTypeConvertsToOther, type1, type2);
  1159.                 }
  1160.             }
  1161.             return System.Linq.Expressions.Expression.Condition(test, expr1, expr2);
  1162.         }
  1163.  
  1164.         System.Linq.Expressions.Expression ParseNew()
  1165.         {
  1166.             NextToken();
  1167.             ValidateToken(TokenId.OpenParen, Res.OpenParenExpected);
  1168.             NextToken();
  1169.             System.Collections.Generic.List<DynamicProperty> properties = new System.Collections.Generic.List<DynamicProperty>();
  1170.             System.Collections.Generic.List<System.Linq.Expressions.Expression> expressions = new System.Collections.Generic.List<System.Linq.Expressions.Expression>();
  1171.             while (true)
  1172.             {
  1173.                 int exprPos = token.pos;
  1174.                 System.Linq.Expressions.Expression expr = ParseExpression();
  1175.                 string propName;
  1176.                 if (TokenIdentifierIs("as"))
  1177.                 {
  1178.                     NextToken();
  1179.                     propName = GetIdentifier();
  1180.                     NextToken();
  1181.                 }
  1182.                 else
  1183.                 {
  1184.                     System.Linq.Expressions.MemberExpression me = expr as System.Linq.Expressions.MemberExpression;
  1185.                     if (me == null) throw ParseError(exprPos, Res.MissingAsClause);
  1186.                     propName = me.Member.Name;
  1187.                 }
  1188.                 expressions.Add(expr);
  1189.                 properties.Add(new DynamicProperty(propName, expr.Type));
  1190.                 if (token.id != TokenId.Comma) break;
  1191.                 NextToken();
  1192.             }
  1193.             ValidateToken(TokenId.CloseParen, Res.CloseParenOrCommaExpected);
  1194.             NextToken();
  1195.             Type type = DynamicExpression.CreateClass(properties);
  1196.             System.Linq.Expressions.MemberBinding[] bindings = new System.Linq.Expressions.MemberBinding[properties.Count];
  1197.             for (int i = 0; i < bindings.Length; i++)
  1198.                 bindings[i] = System.Linq.Expressions.Expression.Bind(type.GetProperty(properties[i].Name), expressions[i]);
  1199.             return System.Linq.Expressions.Expression.MemberInit(System.Linq.Expressions.Expression.New(type), bindings);
  1200.         }
  1201.  
  1202.         System.Linq.Expressions.Expression ParseLambdaInvocation(System.Linq.Expressions.LambdaExpression lambda)
  1203.         {
  1204.             int errorPos = token.pos;
  1205.             NextToken();
  1206.             System.Linq.Expressions.Expression[] args = ParseArgumentList();
  1207.             System.Reflection.MethodBase method;
  1208.             if (FindMethod(lambda.Type, "Invoke", false, args, out method) != 1)
  1209.                 throw ParseError(errorPos, Res.ArgsIncompatibleWithLambda);
  1210.             return System.Linq.Expressions.Expression.Invoke(lambda, args);
  1211.         }
  1212.  
  1213.         System.Linq.Expressions.Expression ParseTypeAccess(Type type)
  1214.         {
  1215.             int errorPos = token.pos;
  1216.             NextToken();
  1217.             if (token.id == TokenId.Question)
  1218.             {
  1219.                 if (!type.IsValueType || IsNullableType(type))
  1220.                     throw ParseError(errorPos, Res.TypeHasNoNullableForm, GetTypeName(type));
  1221.                 type = typeof(Nullable<>).MakeGenericType(type);
  1222.                 NextToken();
  1223.             }
  1224.             if (token.id == TokenId.OpenParen)
  1225.             {
  1226.                 System.Linq.Expressions.Expression[] args = ParseArgumentList();
  1227.                 System.Reflection.MethodBase method;
  1228.                 switch (FindBestMethod(type.GetConstructors(), args, out method))
  1229.                 {
  1230.                     case 0:
  1231.                         if (args.Length == 1)
  1232.                             return GenerateConversion(args[0], type, errorPos);
  1233.                         throw ParseError(errorPos, Res.NoMatchingConstructor, GetTypeName(type));
  1234.                     case 1:
  1235.                         return System.Linq.Expressions.Expression.New((System.Reflection.ConstructorInfo)method, args);
  1236.                     default:
  1237.                         throw ParseError(errorPos, Res.AmbiguousConstructorInvocation, GetTypeName(type));
  1238.                 }
  1239.             }
  1240.             ValidateToken(TokenId.Dot, Res.DotOrOpenParenExpected);
  1241.             NextToken();
  1242.             return ParseMemberAccess(type, null);
  1243.         }
  1244.  
  1245.         System.Linq.Expressions.Expression GenerateConversion(System.Linq.Expressions.Expression expr, Type type, int errorPos)
  1246.         {
  1247.             Type exprType = expr.Type;
  1248.             if (exprType == type) return expr;
  1249.             if (exprType.IsValueType && type.IsValueType)
  1250.             {
  1251.                 if ((IsNullableType(exprType) || IsNullableType(type)) &&
  1252.                     GetNonNullableType(exprType) == GetNonNullableType(type))
  1253.                     return System.Linq.Expressions.Expression.Convert(expr, type);
  1254.                 if ((IsNumericType(exprType) || IsEnumType(exprType)) &&
  1255.                     (IsNumericType(type)) || IsEnumType(type))
  1256.                     return System.Linq.Expressions.Expression.ConvertChecked(expr, type);
  1257.             }
  1258.             if (exprType.IsAssignableFrom(type) || type.IsAssignableFrom(exprType) ||
  1259.                 exprType.IsInterface || type.IsInterface)
  1260.                 return System.Linq.Expressions.Expression.Convert(expr, type);
  1261.             throw ParseError(errorPos, Res.CannotConvertValue,
  1262.                 GetTypeName(exprType), GetTypeName(type));
  1263.         }
  1264.  
  1265.         System.Linq.Expressions.Expression ParseMemberAccess(Type type, System.Linq.Expressions.Expression instance)
  1266.         {
  1267.             if (instance != null) type = instance.Type;
  1268.             int errorPos = token.pos;
  1269.             string id = GetIdentifier();
  1270.             NextToken();
  1271.             if (token.id == TokenId.OpenParen)
  1272.             {
  1273.                 if (instance != null && type != typeof(string))
  1274.                 {
  1275.                     Type enumerableType = FindGenericType(typeof(System.Collections.Generic.IEnumerable<>), type);
  1276.                     if (enumerableType != null)
  1277.                     {
  1278.                         Type elementType = enumerableType.GetGenericArguments()[0];
  1279.                         return ParseAggregate(instance, elementType, id, errorPos);
  1280.                     }
  1281.                 }
  1282.                 System.Linq.Expressions.Expression[] args = ParseArgumentList();
  1283.                 System.Reflection.MethodBase mb;
  1284.                 switch (FindMethod(type, id, instance == null, args, out mb))
  1285.                 {
  1286.                     case 0:
  1287.                         throw ParseError(errorPos, Res.NoApplicableMethod,
  1288.                             id, GetTypeName(type));
  1289.                     case 1:
  1290.                         System.Reflection.MethodInfo method = (System.Reflection.MethodInfo)mb;
  1291.                         if (!IsPredefinedType(method.DeclaringType))
  1292.                             throw ParseError(errorPos, Res.MethodsAreInaccessible, GetTypeName(method.DeclaringType));
  1293.                         if (method.ReturnType == typeof(void))
  1294.                             throw ParseError(errorPos, Res.MethodIsVoid,
  1295.                                 id, GetTypeName(method.DeclaringType));
  1296.                         return System.Linq.Expressions.Expression.Call(instance, (System.Reflection.MethodInfo)method, args);
  1297.                     default:
  1298.                         throw ParseError(errorPos, Res.AmbiguousMethodInvocation,
  1299.                             id, GetTypeName(type));
  1300.                 }
  1301.             }
  1302.             else
  1303.             {
  1304.                 System.Reflection.MemberInfo member = FindPropertyOrField(type, id, instance == null);
  1305.                 if (member == null)
  1306.                     throw ParseError(errorPos, Res.UnknownPropertyOrField,
  1307.                         id, GetTypeName(type));
  1308.                 return member is System.Reflection.PropertyInfo ?
  1309.                     System.Linq.Expressions.Expression.Property(instance, (System.Reflection.PropertyInfo)member) :
  1310.                     System.Linq.Expressions.Expression.Field(instance, (System.Reflection.FieldInfo)member);
  1311.             }
  1312.         }
  1313.  
  1314.         static Type FindGenericType(Type generic, Type type)
  1315.         {
  1316.             while (type != null && type != typeof(object))
  1317.             {
  1318.                 if (type.IsGenericType && type.GetGenericTypeDefinition() == generic) return type;
  1319.                 if (generic.IsInterface)
  1320.                 {
  1321.                     foreach (Type intfType in type.GetInterfaces())
  1322.                     {
  1323.                         Type found = FindGenericType(generic, intfType);
  1324.                         if (found != null) return found;
  1325.                     }
  1326.                 }
  1327.                 type = type.BaseType;
  1328.             }
  1329.             return null;
  1330.         }
  1331.  
  1332.         System.Linq.Expressions.Expression ParseAggregate(System.Linq.Expressions.Expression instance, Type elementType, string methodName, int errorPos)
  1333.         {
  1334.             System.Linq.Expressions.ParameterExpression outerIt = it;
  1335.             System.Linq.Expressions.ParameterExpression innerIt = System.Linq.Expressions.Expression.Parameter(elementType, "");
  1336.             it = innerIt;
  1337.             System.Linq.Expressions.Expression[] args = ParseArgumentList();
  1338.             it = outerIt;
  1339.             System.Reflection.MethodBase signature;
  1340.             if (FindMethod(typeof(IEnumerableSignatures), methodName, false, args, out signature) != 1)
  1341.                 throw ParseError(errorPos, Res.NoApplicableAggregate, methodName);
  1342.             Type[] typeArgs;
  1343.             if (signature.Name == "Min" || signature.Name == "Max")
  1344.             {
  1345.                 typeArgs = new Type[] { elementType, args[0].Type };
  1346.             }
  1347.             else
  1348.             {
  1349.                 typeArgs = new Type[] { elementType };
  1350.             }
  1351.             if (args.Length == 0)
  1352.             {
  1353.                 args = new System.Linq.Expressions.Expression[] { instance };
  1354.             }
  1355.             else
  1356.             {
  1357.                 args = new System.Linq.Expressions.Expression[] { instance, System.Linq.Expressions.Expression.Lambda(args[0], innerIt) };
  1358.             }
  1359.             return System.Linq.Expressions.Expression.Call(typeof(Enumerable), signature.Name, typeArgs, args);
  1360.         }
  1361.  
  1362.         System.Linq.Expressions.Expression[] ParseArgumentList()
  1363.         {
  1364.             ValidateToken(TokenId.OpenParen, Res.OpenParenExpected);
  1365.             NextToken();
  1366.             System.Linq.Expressions.Expression[] args = token.id != TokenId.CloseParen ? ParseArguments() : new System.Linq.Expressions.Expression[0];
  1367.             ValidateToken(TokenId.CloseParen, Res.CloseParenOrCommaExpected);
  1368.             NextToken();
  1369.             return args;
  1370.         }
  1371.  
  1372.         System.Linq.Expressions.Expression[] ParseArguments()
  1373.         {
  1374.             System.Collections.Generic.List<System.Linq.Expressions.Expression> argList = new System.Collections.Generic.List<System.Linq.Expressions.Expression>();
  1375.             while (true)
  1376.             {
  1377.                 argList.Add(ParseExpression());
  1378.                 if (token.id != TokenId.Comma) break;
  1379.                 NextToken();
  1380.             }
  1381.             return argList.ToArray();
  1382.         }
  1383.  
  1384.         System.Linq.Expressions.Expression ParseElementAccess(System.Linq.Expressions.Expression expr)
  1385.         {
  1386.             int errorPos = token.pos;
  1387.             ValidateToken(TokenId.OpenBracket, Res.OpenParenExpected);
  1388.             NextToken();
  1389.             System.Linq.Expressions.Expression[] args = ParseArguments();
  1390.             ValidateToken(TokenId.CloseBracket, Res.CloseBracketOrCommaExpected);
  1391.             NextToken();
  1392.             if (expr.Type.IsArray)
  1393.             {
  1394.                 if (expr.Type.GetArrayRank() != 1 || args.Length != 1)
  1395.                     throw ParseError(errorPos, Res.CannotIndexMultiDimArray);
  1396.                 System.Linq.Expressions.Expression index = PromoteExpression(args[0], typeof(int), true);
  1397.                 if (index == null)
  1398.                     throw ParseError(errorPos, Res.InvalidIndex);
  1399.                 return System.Linq.Expressions.Expression.ArrayIndex(expr, index);
  1400.             }
  1401.             else
  1402.             {
  1403.                 System.Reflection.MethodBase mb;
  1404.                 switch (FindIndexer(expr.Type, args, out mb))
  1405.                 {
  1406.                     case 0:
  1407.                         throw ParseError(errorPos, Res.NoApplicableIndexer,
  1408.                             GetTypeName(expr.Type));
  1409.                     case 1:
  1410.                         return System.Linq.Expressions.Expression.Call(expr, (System.Reflection.MethodInfo)mb, args);
  1411.                     default:
  1412.                         throw ParseError(errorPos, Res.AmbiguousIndexerInvocation,
  1413.                             GetTypeName(expr.Type));
  1414.                 }
  1415.             }
  1416.         }
  1417.  
  1418.         static bool IsPredefinedType(Type type)
  1419.         {
  1420.             foreach (Type t in predefinedTypes) if (t == type) return true;
  1421.             return false;
  1422.         }
  1423.  
  1424.         static bool IsNullableType(Type type)
  1425.         {
  1426.             return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);
  1427.         }
  1428.  
  1429.         static Type GetNonNullableType(Type type)
  1430.         {
  1431.             return IsNullableType(type) ? type.GetGenericArguments()[0] : type;
  1432.         }
  1433.  
  1434.         static string GetTypeName(Type type)
  1435.         {
  1436.             Type baseType = GetNonNullableType(type);
  1437.             string s = baseType.Name;
  1438.             if (type != baseType) s += '?';
  1439.             return s;
  1440.         }
  1441.  
  1442.         static bool IsNumericType(Type type)
  1443.         {
  1444.             return GetNumericTypeKind(type) != 0;
  1445.         }
  1446.  
  1447.         static bool IsSignedIntegralType(Type type)
  1448.         {
  1449.             return GetNumericTypeKind(type) == 2;
  1450.         }
  1451.  
  1452.         static bool IsUnsignedIntegralType(Type type)
  1453.         {
  1454.             return GetNumericTypeKind(type) == 3;
  1455.         }
  1456.  
  1457.         static int GetNumericTypeKind(Type type)
  1458.         {
  1459.             type = GetNonNullableType(type);
  1460.             if (type.IsEnum) return 0;
  1461.             switch (Type.GetTypeCode(type))
  1462.             {
  1463.                 case TypeCode.Char:
  1464.                 case TypeCode.Single:
  1465.                 case TypeCode.Double:
  1466.                 case TypeCode.Decimal:
  1467.                     return 1;
  1468.                 case TypeCode.SByte:
  1469.                 case TypeCode.Int16:
  1470.                 case TypeCode.Int32:
  1471.                 case TypeCode.Int64:
  1472.                     return 2;
  1473.                 case TypeCode.Byte:
  1474.                 case TypeCode.UInt16:
  1475.                 case TypeCode.UInt32:
  1476.                 case TypeCode.UInt64:
  1477.                     return 3;
  1478.                 default:
  1479.                     return 0;
  1480.             }
  1481.         }
  1482.  
  1483.         static bool IsEnumType(Type type)
  1484.         {
  1485.             return GetNonNullableType(type).IsEnum;
  1486.         }
  1487.  
  1488.         void CheckAndPromoteOperand(Type signatures, string opName, ref System.Linq.Expressions.Expression expr, int errorPos)
  1489.         {
  1490.             System.Linq.Expressions.Expression[] args = new System.Linq.Expressions.Expression[] { expr };
  1491.             System.Reflection.MethodBase method;
  1492.             if (FindMethod(signatures, "F", false, args, out method) != 1)
  1493.                 throw ParseError(errorPos, Res.IncompatibleOperand,
  1494.                     opName, GetTypeName(args[0].Type));
  1495.             expr = args[0];
  1496.         }
  1497.  
  1498.         void CheckAndPromoteOperands(Type signatures, string opName, ref System.Linq.Expressions.Expression left, ref System.Linq.Expressions.Expression right, int errorPos)
  1499.         {
  1500.             System.Linq.Expressions.Expression[] args = new System.Linq.Expressions.Expression[] { left, right };
  1501.             System.Reflection.MethodBase method;
  1502.             if (FindMethod(signatures, "F", false, args, out method) != 1)
  1503.                 throw IncompatibleOperandsError(opName, left, right, errorPos);
  1504.             left = args[0];
  1505.             right = args[1];
  1506.         }
  1507.  
  1508.         Exception IncompatibleOperandsError(string opName, System.Linq.Expressions.Expression left, System.Linq.Expressions.Expression right, int pos)
  1509.         {
  1510.             return ParseError(pos, Res.IncompatibleOperands,
  1511.                 opName, GetTypeName(left.Type), GetTypeName(right.Type));
  1512.         }
  1513.  
  1514.         System.Reflection.MemberInfo FindPropertyOrField(Type type, string memberName, bool staticAccess)
  1515.         {
  1516.             System.Reflection.BindingFlags flags = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.DeclaredOnly |
  1517.                 (staticAccess ? System.Reflection.BindingFlags.Static : System.Reflection.BindingFlags.Instance);
  1518.             foreach (Type t in SelfAndBaseTypes(type))
  1519.             {
  1520.                 System.Reflection.MemberInfo[] members = t.FindMembers(System.Reflection.MemberTypes.Property | System.Reflection.MemberTypes.Field,
  1521.                     flags, Type.FilterNameIgnoreCase, memberName);
  1522.                 if (members.Length != 0) return members[0];
  1523.             }
  1524.             return null;
  1525.         }
  1526.  
  1527.         int FindMethod(Type type, string methodName, bool staticAccess, System.Linq.Expressions.Expression[] args, out System.Reflection.MethodBase method)
  1528.         {
  1529.             System.Reflection.BindingFlags flags = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.DeclaredOnly |
  1530.                 (staticAccess ? System.Reflection.BindingFlags.Static : System.Reflection.BindingFlags.Instance);
  1531.             foreach (Type t in SelfAndBaseTypes(type))
  1532.             {
  1533.                 System.Reflection.MemberInfo[] members = t.FindMembers(System.Reflection.MemberTypes.Method,
  1534.                     flags, Type.FilterNameIgnoreCase, methodName);
  1535.                 int count = FindBestMethod(members.Cast<System.Reflection.MethodBase>(), args, out method);
  1536.                 if (count != 0) return count;
  1537.             }
  1538.             method = null;
  1539.             return 0;
  1540.         }
  1541.  
  1542.         int FindIndexer(Type type, System.Linq.Expressions.Expression[] args, out System.Reflection.MethodBase method)
  1543.         {
  1544.             foreach (Type t in SelfAndBaseTypes(type))
  1545.             {
  1546.                 System.Reflection.MemberInfo[] members = t.GetDefaultMembers();
  1547.                 if (members.Length != 0)
  1548.                 {
  1549.                     System.Collections.Generic.IEnumerable<System.Reflection.MethodBase> methods = members.
  1550.                         OfType<System.Reflection.PropertyInfo>().
  1551.                         Select(p => (System.Reflection.MethodBase)p.GetGetMethod()).
  1552.                         Where(m => m != null);
  1553.                     int count = FindBestMethod(methods, args, out method);
  1554.                     if (count != 0) return count;
  1555.                 }
  1556.             }
  1557.             method = null;
  1558.             return 0;
  1559.         }
  1560.  
  1561.         static System.Collections.Generic.IEnumerable<Type> SelfAndBaseTypes(Type type)
  1562.         {
  1563.             if (type.IsInterface)
  1564.             {
  1565.                 System.Collections.Generic.List<Type> types = new System.Collections.Generic.List<Type>();
  1566.                 AddInterface(types, type);
  1567.                 return types;
  1568.             }
  1569.             return SelfAndBaseClasses(type);
  1570.         }
  1571.  
  1572.         static System.Collections.Generic.IEnumerable<Type> SelfAndBaseClasses(Type type)
  1573.         {
  1574.             while (type != null)
  1575.             {
  1576.                 yield return type;
  1577.                 type = type.BaseType;
  1578.             }
  1579.         }
  1580.  
  1581.         static void AddInterface(System.Collections.Generic.List<Type> types, Type type)
  1582.         {
  1583.             if (!types.Contains(type))
  1584.             {
  1585.                 types.Add(type);
  1586.                 foreach (Type t in type.GetInterfaces()) AddInterface(types, t);
  1587.             }
  1588.         }
  1589.  
  1590.         class MethodData
  1591.         {
  1592.             public System.Reflection.MethodBase MethodBase;
  1593.             public System.Reflection.ParameterInfo[] Parameters;
  1594.             public System.Linq.Expressions.Expression[] Args;
  1595.         }
  1596.  
  1597.         int FindBestMethod(System.Collections.Generic.IEnumerable<System.Reflection.MethodBase> methods, System.Linq.Expressions.Expression[] args, out System.Reflection.MethodBase method)
  1598.         {
  1599.             MethodData[] applicable = methods.
  1600.                 Select(m => new MethodData { MethodBase = m, Parameters = m.GetParameters() }).
  1601.                 Where(m => IsApplicable(m, args)).
  1602.                 ToArray();
  1603.             if (applicable.Length > 1)
  1604.             {
  1605.                 applicable = applicable.
  1606.                     Where(m => applicable.All(n => m == n || IsBetterThan(args, m, n))).
  1607.                     ToArray();
  1608.             }
  1609.             if (applicable.Length == 1)
  1610.             {
  1611.                 MethodData md = applicable[0];
  1612.                 for (int i = 0; i < args.Length; i++) args[i] = md.Args[i];
  1613.                 method = md.MethodBase;
  1614.             }
  1615.             else
  1616.             {
  1617.                 method = null;
  1618.             }
  1619.             return applicable.Length;
  1620.         }
  1621.  
  1622.         bool IsApplicable(MethodData method, System.Linq.Expressions.Expression[] args)
  1623.         {
  1624.             if (method.Parameters.Length != args.Length) return false;
  1625.             System.Linq.Expressions.Expression[] promotedArgs = new System.Linq.Expressions.Expression[args.Length];
  1626.             for (int i = 0; i < args.Length; i++)
  1627.             {
  1628.                 System.Reflection.ParameterInfo pi = method.Parameters[i];
  1629.                 if (pi.IsOut) return false;
  1630.                 System.Linq.Expressions.Expression promoted = PromoteExpression(args[i], pi.ParameterType, false);
  1631.                 if (promoted == null) return false;
  1632.                 promotedArgs[i] = promoted;
  1633.             }
  1634.             method.Args = promotedArgs;
  1635.             return true;
  1636.         }
  1637.  
  1638.         System.Linq.Expressions.Expression PromoteExpression(System.Linq.Expressions.Expression expr, Type type, bool exact)
  1639.         {
  1640.             if (expr.Type == type) return expr;
  1641.             if (expr is System.Linq.Expressions.ConstantExpression)
  1642.             {
  1643.                 System.Linq.Expressions.ConstantExpression ce = (System.Linq.Expressions.ConstantExpression)expr;
  1644.                 if (ce == nullLiteral)
  1645.                 {
  1646.                     if (!type.IsValueType || IsNullableType(type))
  1647.                         return System.Linq.Expressions.Expression.Constant(null, type);
  1648.                 }
  1649.                 else
  1650.                 {
  1651.                     string text;
  1652.                     if (literals.TryGetValue(ce, out text))
  1653.                     {
  1654.                         Type target = GetNonNullableType(type);
  1655.                         Object value = null;
  1656.                         switch (Type.GetTypeCode(ce.Type))
  1657.                         {
  1658.                             case TypeCode.Int32:
  1659.                             case TypeCode.UInt32:
  1660.                             case TypeCode.Int64:
  1661.                             case TypeCode.UInt64:
  1662.                                 value = ParseNumber(text, target);
  1663.                                 break;
  1664.                             case TypeCode.Double:
  1665.                                 if (target == typeof(decimal)) value = ParseNumber(text, target);
  1666.                                 break;
  1667.                             case TypeCode.String:
  1668.                                 value = ParseEnum(text, target);
  1669.                                 break;
  1670.                         }
  1671.                         if (value != null)
  1672.                             return System.Linq.Expressions.Expression.Constant(value, type);
  1673.                     }
  1674.                 }
  1675.             }
  1676.             if (IsCompatibleWith(expr.Type, type))
  1677.             {
  1678.                 if (type.IsValueType || exact) return System.Linq.Expressions.Expression.Convert(expr, type);
  1679.                 return expr;
  1680.             }
  1681.             return null;
  1682.         }
  1683.  
  1684.         static object ParseNumber(string text, Type type)
  1685.         {
  1686.             switch (Type.GetTypeCode(GetNonNullableType(type)))
  1687.             {
  1688.                 case TypeCode.SByte:
  1689.                     sbyte sb;
  1690.                     if (sbyte.TryParse(text, out sb)) return sb;
  1691.                     break;
  1692.                 case TypeCode.Byte:
  1693.                     byte b;
  1694.                     if (byte.TryParse(text, out b)) return b;
  1695.                     break;
  1696.                 case TypeCode.Int16:
  1697.                     short s;
  1698.                     if (short.TryParse(text, out s)) return s;
  1699.                     break;
  1700.                 case TypeCode.UInt16:
  1701.                     ushort us;
  1702.                     if (ushort.TryParse(text, out us)) return us;
  1703.                     break;
  1704.                 case TypeCode.Int32:
  1705.                     int i;
  1706.                     if (int.TryParse(text, out i)) return i;
  1707.                     break;
  1708.                 case TypeCode.UInt32:
  1709.                     uint ui;
  1710.                     if (uint.TryParse(text, out ui)) return ui;
  1711.                     break;
  1712.                 case TypeCode.Int64:
  1713.                     long l;
  1714.                     if (long.TryParse(text, out l)) return l;
  1715.                     break;
  1716.                 case TypeCode.UInt64:
  1717.                     ulong ul;
  1718.                     if (ulong.TryParse(text, out ul)) return ul;
  1719.                     break;
  1720.                 case TypeCode.Single:
  1721.                     float f;
  1722.                     if (float.TryParse(text, out f)) return f;
  1723.                     break;
  1724.                 case TypeCode.Double:
  1725.                     double d;
  1726.                     if (double.TryParse(text, out d)) return d;
  1727.                     break;
  1728.                 case TypeCode.Decimal:
  1729.                     decimal e;
  1730.                     if (decimal.TryParse(text, out e)) return e;
  1731.                     break;
  1732.             }
  1733.             return null;
  1734.         }
  1735.  
  1736.         static object ParseEnum(string name, Type type)
  1737.         {
  1738.             if (type.IsEnum)
  1739.             {
  1740.                 System.Reflection.MemberInfo[] memberInfos = type.FindMembers(System.Reflection.MemberTypes.Field,
  1741.                     System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.DeclaredOnly | System.Reflection.BindingFlags.Static,
  1742.                     Type.FilterNameIgnoreCase, name);
  1743.                 if (memberInfos.Length != 0) return ((System.Reflection.FieldInfo)memberInfos[0]).GetValue(null);
  1744.             }
  1745.             return null;
  1746.         }
  1747.  
  1748.         static bool IsCompatibleWith(Type source, Type target)
  1749.         {
  1750.             if (source == target) return true;
  1751.             if (!target.IsValueType) return target.IsAssignableFrom(source);
  1752.             Type st = GetNonNullableType(source);
  1753.             Type tt = GetNonNullableType(target);
  1754.             if (st != source && tt == target) return false;
  1755.             TypeCode sc = st.IsEnum ? TypeCode.Object : Type.GetTypeCode(st);
  1756.             TypeCode tc = tt.IsEnum ? TypeCode.Object : Type.GetTypeCode(tt);
  1757.             switch (sc)
  1758.             {
  1759.                 case TypeCode.SByte:
  1760.                     switch (tc)
  1761.                     {
  1762.                         case TypeCode.SByte:
  1763.                         case TypeCode.Int16:
  1764.                         case TypeCode.Int32:
  1765.                         case TypeCode.Int64:
  1766.                         case TypeCode.Single:
  1767.                         case TypeCode.Double:
  1768.                         case TypeCode.Decimal:
  1769.                             return true;
  1770.                     }
  1771.                     break;
  1772.                 case TypeCode.Byte:
  1773.                     switch (tc)
  1774.                     {
  1775.                         case TypeCode.Byte:
  1776.                         case TypeCode.Int16:
  1777.                         case TypeCode.UInt16:
  1778.                         case TypeCode.Int32:
  1779.                         case TypeCode.UInt32:
  1780.                         case TypeCode.Int64:
  1781.                         case TypeCode.UInt64:
  1782.                         case TypeCode.Single:
  1783.                         case TypeCode.Double:
  1784.                         case TypeCode.Decimal:
  1785.                             return true;
  1786.                     }
  1787.                     break;
  1788.                 case TypeCode.Int16:
  1789.                     switch (tc)
  1790.                     {
  1791.                         case TypeCode.Int16:
  1792.                         case TypeCode.Int32:
  1793.                         case TypeCode.Int64:
  1794.                         case TypeCode.Single:
  1795.                         case TypeCode.Double:
  1796.                         case TypeCode.Decimal:
  1797.                             return true;
  1798.                     }
  1799.                     break;
  1800.                 case TypeCode.UInt16:
  1801.                     switch (tc)
  1802.                     {
  1803.                         case TypeCode.UInt16:
  1804.                         case TypeCode.Int32:
  1805.                         case TypeCode.UInt32:
  1806.                         case TypeCode.Int64:
  1807.                         case TypeCode.UInt64:
  1808.                         case TypeCode.Single:
  1809.                         case TypeCode.Double:
  1810.                         case TypeCode.Decimal:
  1811.                             return true;
  1812.                     }
  1813.                     break;
  1814.                 case TypeCode.Int32:
  1815.                     switch (tc)
  1816.                     {
  1817.                         case TypeCode.Int32:
  1818.                         case TypeCode.Int64:
  1819.                         case TypeCode.Single:
  1820.                         case TypeCode.Double:
  1821.                         case TypeCode.Decimal:
  1822.                             return true;
  1823.                     }
  1824.                     break;
  1825.                 case TypeCode.UInt32:
  1826.                     switch (tc)
  1827.                     {
  1828.                         case TypeCode.UInt32:
  1829.                         case TypeCode.Int64:
  1830.                         case TypeCode.UInt64:
  1831.                         case TypeCode.Single:
  1832.                         case TypeCode.Double:
  1833.                         case TypeCode.Decimal:
  1834.                             return true;
  1835.                     }
  1836.                     break;
  1837.                 case TypeCode.Int64:
  1838.                     switch (tc)
  1839.                     {
  1840.                         case TypeCode.Int64:
  1841.                         case TypeCode.Single:
  1842.                         case TypeCode.Double:
  1843.                         case TypeCode.Decimal:
  1844.                             return true;
  1845.                     }
  1846.                     break;
  1847.                 case TypeCode.UInt64:
  1848.                     switch (tc)
  1849.                     {
  1850.                         case TypeCode.UInt64:
  1851.                         case TypeCode.Single:
  1852.                         case TypeCode.Double:
  1853.                         case TypeCode.Decimal:
  1854.                             return true;
  1855.                     }
  1856.                     break;
  1857.                 case TypeCode.Single:
  1858.                     switch (tc)
  1859.                     {
  1860.                         case TypeCode.Single:
  1861.                         case TypeCode.Double:
  1862.                             return true;
  1863.                     }
  1864.                     break;
  1865.                 default:
  1866.                     if (st == tt) return true;
  1867.                     break;
  1868.             }
  1869.             return false;
  1870.         }
  1871.  
  1872.         static bool IsBetterThan(System.Linq.Expressions.Expression[] args, MethodData m1, MethodData m2)
  1873.         {
  1874.             bool better = false;
  1875.             for (int i = 0; i < args.Length; i++)
  1876.             {
  1877.                 int c = CompareConversions(args[i].Type,
  1878.                     m1.Parameters[i].ParameterType,
  1879.                     m2.Parameters[i].ParameterType);
  1880.                 if (c < 0) return false;
  1881.                 if (c > 0) better = true;
  1882.             }
  1883.             return better;
  1884.         }
  1885.  
  1886.         // Return 1 if s -> t1 is a better conversion than s -> t2
  1887.         // Return -1 if s -> t2 is a better conversion than s -> t1
  1888.         // Return 0 if neither conversion is better
  1889.         static int CompareConversions(Type s, Type t1, Type t2)
  1890.         {
  1891.             if (t1 == t2) return 0;
  1892.             if (s == t1) return 1;
  1893.             if (s == t2) return -1;
  1894.             bool t1t2 = IsCompatibleWith(t1, t2);
  1895.             bool t2t1 = IsCompatibleWith(t2, t1);
  1896.             if (t1t2 && !t2t1) return 1;
  1897.             if (t2t1 && !t1t2) return -1;
  1898.             if (IsSignedIntegralType(t1) && IsUnsignedIntegralType(t2)) return 1;
  1899.             if (IsSignedIntegralType(t2) && IsUnsignedIntegralType(t1)) return -1;
  1900.             return 0;
  1901.         }
  1902.  
  1903.         System.Linq.Expressions.Expression GenerateEqual(System.Linq.Expressions.Expression left, System.Linq.Expressions.Expression right)
  1904.         {
  1905.             return System.Linq.Expressions.Expression.Equal(left, right);
  1906.         }
  1907.  
  1908.         System.Linq.Expressions.Expression GenerateNotEqual(System.Linq.Expressions.Expression left, System.Linq.Expressions.Expression right)
  1909.         {
  1910.             return System.Linq.Expressions.Expression.NotEqual(left, right);
  1911.         }
  1912.  
  1913.         System.Linq.Expressions.Expression GenerateGreaterThan(System.Linq.Expressions.Expression left, System.Linq.Expressions.Expression right)
  1914.         {
  1915.             if (left.Type == typeof(string))
  1916.             {
  1917.                 return System.Linq.Expressions.Expression.GreaterThan(
  1918.                     GenerateStaticMethodCall("Compare", left, right),
  1919.                     System.Linq.Expressions.Expression.Constant(0)
  1920.                 );
  1921.             }
  1922.             return System.Linq.Expressions.Expression.GreaterThan(left, right);
  1923.         }
  1924.  
  1925.         System.Linq.Expressions.Expression GenerateGreaterThanEqual(System.Linq.Expressions.Expression left, System.Linq.Expressions.Expression right)
  1926.         {
  1927.             if (left.Type == typeof(string))
  1928.             {
  1929.                 return System.Linq.Expressions.Expression.GreaterThanOrEqual(
  1930.                     GenerateStaticMethodCall("Compare", left, right),
  1931.                     System.Linq.Expressions.Expression.Constant(0)
  1932.                 );
  1933.             }
  1934.             return System.Linq.Expressions.Expression.GreaterThanOrEqual(left, right);
  1935.         }
  1936.  
  1937.         System.Linq.Expressions.Expression GenerateLessThan(System.Linq.Expressions.Expression left, System.Linq.Expressions.Expression right)
  1938.         {
  1939.             if (left.Type == typeof(string))
  1940.             {
  1941.                 return System.Linq.Expressions.Expression.LessThan(
  1942.                     GenerateStaticMethodCall("Compare", left, right),
  1943.                     System.Linq.Expressions.Expression.Constant(0)
  1944.                 );
  1945.             }
  1946.             return System.Linq.Expressions.Expression.LessThan(left, right);
  1947.         }
  1948.  
  1949.         System.Linq.Expressions.Expression GenerateLessThanEqual(System.Linq.Expressions.Expression left, System.Linq.Expressions.Expression right)
  1950.         {
  1951.             if (left.Type == typeof(string))
  1952.             {
  1953.                 return System.Linq.Expressions.Expression.LessThanOrEqual(
  1954.                     GenerateStaticMethodCall("Compare", left, right),
  1955.                     System.Linq.Expressions.Expression.Constant(0)
  1956.                 );
  1957.             }
  1958.             return System.Linq.Expressions.Expression.LessThanOrEqual(left, right);
  1959.         }
  1960.  
  1961.         System.Linq.Expressions.Expression GenerateAdd(System.Linq.Expressions.Expression left, System.Linq.Expressions.Expression right)
  1962.         {
  1963.             if (left.Type == typeof(string) && right.Type == typeof(string))
  1964.             {
  1965.                 return GenerateStaticMethodCall("Concat", left, right);
  1966.             }
  1967.             return System.Linq.Expressions.Expression.Add(left, right);
  1968.         }
  1969.  
  1970.         System.Linq.Expressions.Expression GenerateSubtract(System.Linq.Expressions.Expression left, System.Linq.Expressions.Expression right)
  1971.         {
  1972.             return System.Linq.Expressions.Expression.Subtract(left, right);
  1973.         }
  1974.  
  1975.         System.Linq.Expressions.Expression GenerateStringConcat(System.Linq.Expressions.Expression left, System.Linq.Expressions.Expression right)
  1976.         {
  1977.             return System.Linq.Expressions.Expression.Call(
  1978.                 null,
  1979.                 typeof(string).GetMethod("Concat", new[] { typeof(object), typeof(object) }),
  1980.                 new[] { left, right });
  1981.         }
  1982.  
  1983.         System.Reflection.MethodInfo GetStaticMethod(string methodName, System.Linq.Expressions.Expression left, System.Linq.Expressions.Expression right)
  1984.         {
  1985.             return left.Type.GetMethod(methodName, new[] { left.Type, right.Type });
  1986.         }
  1987.  
  1988.         System.Linq.Expressions.Expression GenerateStaticMethodCall(string methodName, System.Linq.Expressions.Expression left, System.Linq.Expressions.Expression right)
  1989.         {
  1990.             return System.Linq.Expressions.Expression.Call(null, GetStaticMethod(methodName, left, right), new[] { left, right });
  1991.         }
  1992.  
  1993.         void SetTextPos(int pos)
  1994.         {
  1995.             textPos = pos;
  1996.             ch = textPos < textLen ? text[textPos] : '\0';
  1997.         }
  1998.  
  1999.         void NextChar()
  2000.         {
  2001.             if (textPos < textLen) textPos++;
  2002.             ch = textPos < textLen ? text[textPos] : '\0';
  2003.         }
  2004.  
  2005.         void NextToken()
  2006.         {
  2007.             while (Char.IsWhiteSpace(ch)) NextChar();
  2008.             TokenId t;
  2009.             int tokenPos = textPos;
  2010.             switch (ch)
  2011.             {
  2012.                 case '!':
  2013.                     NextChar();
  2014.                     if (ch == '=')
  2015.                     {
  2016.                         NextChar();
  2017.                         t = TokenId.ExclamationEqual;
  2018.                     }
  2019.                     else
  2020.                     {
  2021.                         t = TokenId.Exclamation;
  2022.                     }
  2023.                     break;
  2024.                 case '%':
  2025.                     NextChar();
  2026.                     t = TokenId.Percent;
  2027.                     break;
  2028.                 case '&':
  2029.                     NextChar();
  2030.                     if (ch == '&')
  2031.                     {
  2032.                         NextChar();
  2033.                         t = TokenId.DoubleAmphersand;
  2034.                     }
  2035.                     else
  2036.                     {
  2037.                         t = TokenId.Amphersand;
  2038.                     }
  2039.                     break;
  2040.                 case '(':
  2041.                     NextChar();
  2042.                     t = TokenId.OpenParen;
  2043.                     break;
  2044.                 case ')':
  2045.                     NextChar();
  2046.                     t = TokenId.CloseParen;
  2047.                     break;
  2048.                 case '*':
  2049.                     NextChar();
  2050.                     t = TokenId.Asterisk;
  2051.                     break;
  2052.                 case '+':
  2053.                     NextChar();
  2054.                     t = TokenId.Plus;
  2055.                     break;
  2056.                 case ',':
  2057.                     NextChar();
  2058.                     t = TokenId.Comma;
  2059.                     break;
  2060.                 case '-':
  2061.                     NextChar();
  2062.                     t = TokenId.Minus;
  2063.                     break;
  2064.                 case '.':
  2065.                     NextChar();
  2066.                     t = TokenId.Dot;
  2067.                     break;
  2068.                 case '/':
  2069.                     NextChar();
  2070.                     t = TokenId.Slash;
  2071.                     break;
  2072.                 case ':':
  2073.                     NextChar();
  2074.                     t = TokenId.Colon;
  2075.                     break;
  2076.                 case '<':
  2077.                     NextChar();
  2078.                     if (ch == '=')
  2079.                     {
  2080.                         NextChar();
  2081.                         t = TokenId.LessThanEqual;
  2082.                     }
  2083.                     else if (ch == '>')
  2084.                     {
  2085.                         NextChar();
  2086.                         t = TokenId.LessGreater;
  2087.                     }
  2088.                     else
  2089.                     {
  2090.                         t = TokenId.LessThan;
  2091.                     }
  2092.                     break;
  2093.                 case '=':
  2094.                     NextChar();
  2095.                     if (ch == '=')
  2096.                     {
  2097.                         NextChar();
  2098.                         t = TokenId.DoubleEqual;
  2099.                     }
  2100.                     else
  2101.                     {
  2102.                         t = TokenId.Equal;
  2103.                     }
  2104.                     break;
  2105.                 case '>':
  2106.                     NextChar();
  2107.                     if (ch == '=')
  2108.                     {
  2109.                         NextChar();
  2110.                         t = TokenId.GreaterThanEqual;
  2111.                     }
  2112.                     else
  2113.                     {
  2114.                         t = TokenId.GreaterThan;
  2115.                     }
  2116.                     break;
  2117.                 case '?':
  2118.                     NextChar();
  2119.                     t = TokenId.Question;
  2120.                     break;
  2121.                 case '[':
  2122.                     NextChar();
  2123.                     t = TokenId.OpenBracket;
  2124.                     break;
  2125.                 case ']':
  2126.                     NextChar();
  2127.                     t = TokenId.CloseBracket;
  2128.                     break;
  2129.                 case '|':
  2130.                     NextChar();
  2131.                     if (ch == '|')
  2132.                     {
  2133.                         NextChar();
  2134.                         t = TokenId.DoubleBar;
  2135.                     }
  2136.                     else
  2137.                     {
  2138.                         t = TokenId.Bar;
  2139.                     }
  2140.                     break;
  2141.                 case '"':
  2142.                 case '\'':
  2143.                     char quote = ch;
  2144.                     do
  2145.                     {
  2146.                         NextChar();
  2147.                         while (textPos < textLen && ch != quote) NextChar();
  2148.                         if (textPos == textLen)
  2149.                             throw ParseError(textPos, Res.UnterminatedStringLiteral);
  2150.                         NextChar();
  2151.                     } while (ch == quote);
  2152.                     t = TokenId.StringLiteral;
  2153.                     break;
  2154.                 default:
  2155.                     if (Char.IsLetter(ch) || ch == '@' || ch == '_')
  2156.                     {
  2157.                         do
  2158.                         {
  2159.                             NextChar();
  2160.                         } while (Char.IsLetterOrDigit(ch) || ch == '_');
  2161.                         t = TokenId.Identifier;
  2162.                         break;
  2163.                     }
  2164.                     if (Char.IsDigit(ch))
  2165.                     {
  2166.                         t = TokenId.IntegerLiteral;
  2167.                         do
  2168.                         {
  2169.                             NextChar();
  2170.                         } while (Char.IsDigit(ch));
  2171.                         if (ch == '.')
  2172.                         {
  2173.                             t = TokenId.RealLiteral;
  2174.                             NextChar();
  2175.                             ValidateDigit();
  2176.                             do
  2177.                             {
  2178.                                 NextChar();
  2179.                             } while (Char.IsDigit(ch));
  2180.                         }
  2181.                         if (ch == 'E' || ch == 'e')
  2182.                         {
  2183.                             t = TokenId.RealLiteral;
  2184.                             NextChar();
  2185.                             if (ch == '+' || ch == '-') NextChar();
  2186.                             ValidateDigit();
  2187.                             do
  2188.                             {
  2189.                                 NextChar();
  2190.                             } while (Char.IsDigit(ch));
  2191.                         }
  2192.                         if (ch == 'F' || ch == 'f') NextChar();
  2193.                         break;
  2194.                     }
  2195.                     if (textPos == textLen)
  2196.                     {
  2197.                         t = TokenId.End;
  2198.                         break;
  2199.                     }
  2200.                     throw ParseError(textPos, Res.InvalidCharacter, ch);
  2201.             }
  2202.             token.id = t;
  2203.             token.text = text.Substring(tokenPos, textPos - tokenPos);
  2204.             token.pos = tokenPos;
  2205.         }
  2206.  
  2207.         bool TokenIdentifierIs(string id)
  2208.         {
  2209.             return token.id == TokenId.Identifier && String.Equals(id, token.text, StringComparison.OrdinalIgnoreCase);
  2210.         }
  2211.  
  2212.         string GetIdentifier()
  2213.         {
  2214.             ValidateToken(TokenId.Identifier, Res.IdentifierExpected);
  2215.             string id = token.text;
  2216.             if (id.Length > 1 && id[0] == '@') id = id.Substring(1);
  2217.             return id;
  2218.         }
  2219.  
  2220.         void ValidateDigit()
  2221.         {
  2222.             if (!Char.IsDigit(ch)) throw ParseError(textPos, Res.DigitExpected);
  2223.         }
  2224.  
  2225.         void ValidateToken(TokenId t, string errorMessage)
  2226.         {
  2227.             if (token.id != t) throw ParseError(errorMessage);
  2228.         }
  2229.  
  2230.         void ValidateToken(TokenId t)
  2231.         {
  2232.             if (token.id != t) throw ParseError(Res.SyntaxError);
  2233.         }
  2234.  
  2235.         Exception ParseError(string format, params object[] args)
  2236.         {
  2237.             return ParseError(token.pos, format, args);
  2238.         }
  2239.  
  2240.         Exception ParseError(int pos, string format, params object[] args)
  2241.         {
  2242.             return new ParseException(string.Format(System.Globalization.CultureInfo.CurrentCulture, format, args), pos);
  2243.         }
  2244.  
  2245.         static System.Collections.Generic.Dictionary<string, object> CreateKeywords()
  2246.         {
  2247.             System.Collections.Generic.Dictionary<string, object> d = new System.Collections.Generic.Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
  2248.             d.Add("true", trueLiteral);
  2249.             d.Add("false", falseLiteral);
  2250.             d.Add("null", nullLiteral);
  2251.             d.Add(keywordIt, keywordIt);
  2252.             d.Add(keywordIif, keywordIif);
  2253.             d.Add(keywordNew, keywordNew);
  2254.             foreach (Type type in predefinedTypes) d.Add(type.Name, type);
  2255.             return d;
  2256.         }
  2257.     }
  2258.  
  2259.  
  2260.     static class Res
  2261.     {
  2262.         public const string DuplicateIdentifier = "The identifier '{0}' was defined more than once";
  2263.         public const string ExpressionTypeMismatch = "Expression of type '{0}' expected";
  2264.         public const string ExpressionExpected = "Expression expected";
  2265.         public const string InvalidCharacterLiteral = "Character literal must contain exactly one character";
  2266.         public const string InvalidIntegerLiteral = "Invalid integer literal '{0}'";
  2267.         public const string InvalidRealLiteral = "Invalid real literal '{0}'";
  2268.         public const string UnknownIdentifier = "Unknown identifier '{0}'";
  2269.         public const string NoItInScope = "No 'it' is in scope";
  2270.         public const string IifRequiresThreeArgs = "The 'iif' function requires three arguments";
  2271.         public const string FirstExprMustBeBool = "The first expression must be of type 'Boolean'";
  2272.         public const string BothTypesConvertToOther = "Both of the types '{0}' and '{1}' convert to the other";
  2273.         public const string NeitherTypeConvertsToOther = "Neither of the types '{0}' and '{1}' converts to the other";
  2274.         public const string MissingAsClause = "Expression is missing an 'as' clause";
  2275.         public const string ArgsIncompatibleWithLambda = "Argument list incompatible with lambda expression";
  2276.         public const string TypeHasNoNullableForm = "Type '{0}' has no nullable form";
  2277.         public const string NoMatchingConstructor = "No matching constructor in type '{0}'";
  2278.         public const string AmbiguousConstructorInvocation = "Ambiguous invocation of '{0}' constructor";
  2279.         public const string CannotConvertValue = "A value of type '{0}' cannot be converted to type '{1}'";
  2280.         public const string NoApplicableMethod = "No applicable method '{0}' exists in type '{1}'";
  2281.         public const string MethodsAreInaccessible = "Methods on type '{0}' are not accessible";
  2282.         public const string MethodIsVoid = "Method '{0}' in type '{1}' does not return a value";
  2283.         public const string AmbiguousMethodInvocation = "Ambiguous invocation of method '{0}' in type '{1}'";
  2284.         public const string UnknownPropertyOrField = "No property or field '{0}' exists in type '{1}'";
  2285.         public const string NoApplicableAggregate = "No applicable aggregate method '{0}' exists";
  2286.         public const string CannotIndexMultiDimArray = "Indexing of multi-dimensional arrays is not supported";
  2287.         public const string InvalidIndex = "Array index must be an integer expression";
  2288.         public const string NoApplicableIndexer = "No applicable indexer exists in type '{0}'";
  2289.         public const string AmbiguousIndexerInvocation = "Ambiguous invocation of indexer in type '{0}'";
  2290.         public const string IncompatibleOperand = "Operator '{0}' incompatible with operand type '{1}'";
  2291.         public const string IncompatibleOperands = "Operator '{0}' incompatible with operand types '{1}' and '{2}'";
  2292.         public const string UnterminatedStringLiteral = "Unterminated string literal";
  2293.         public const string InvalidCharacter = "Syntax error '{0}'";
  2294.         public const string DigitExpected = "Digit expected";
  2295.         public const string SyntaxError = "Syntax error";
  2296.         public const string TokenExpected = "{0} expected";
  2297.         public const string ParseExceptionFormat = "{0} (at index {1})";
  2298.         public const string ColonExpected = "':' expected";
  2299.         public const string OpenParenExpected = "'(' expected";
  2300.         public const string CloseParenOrOperatorExpected = "')' or operator expected";
  2301.         public const string CloseParenOrCommaExpected = "')' or ',' expected";
  2302.         public const string DotOrOpenParenExpected = "'.' or '(' expected";
  2303.         public const string OpenBracketExpected = "'[' expected";
  2304.         public const string CloseBracketOrCommaExpected = "']' or ',' expected";
  2305.         public const string IdentifierExpected = "Identifier expected";
  2306.     } // public static class DynamicQueryable
  2307.  
  2308.  
  2309. } // namespace System.Linq.Dynamic
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement