/// <summary>Compile the code or expression and return a TDelegate of type Func or Action to execute.</summary> /// <param name="context">The eval context used to compile the code or expression.</param> /// <param name="code">The code or expression to compile.</param> /// <param name="parameterTypes">The dictionary of parameter (name / type) used in the code or expression to compile.</param> /// <param name="resultType">Type of the compiled code or expression result.</param> /// <returns>A TDelegate of type Func or Action that represents the compiled code or expression.</returns> internal static EvalDelegate CompileSQLNET(EvalContext context, string code, IDictionary <string, Type> parameterTypes, Type resultType) { var cacheKey = ResolveCacheKey(context, typeof(Func <IDictionary, object>), code, parameterTypes); EvalDelegate cachedDelegate; if (EvalManager.CacheDelegate.TryGetValue(cacheKey, out cachedDelegate)) { return(cachedDelegate); } // Options var scope = new ExpressionScope { AliasExtensionMethods = context.AliasExtensionMethods, AliasNames = context.AliasNames, AliasStaticMembers = context.AliasStaticMembers, AliasTypes = context.AliasTypes, BindingFlags = context.BindingFlags, UseCaretForExponent = context.UseCaretForExponent }; // ADD global constants if (context.AliasGlobalConstants.Count > 0) { scope.Constants = new Dictionary <string, ConstantExpression>(context.AliasGlobalConstants); } // ADD global variables if (context.AliasGlobalVariables.Count > 0) { foreach (var keyValue in context.AliasGlobalVariables) { #if SQLNET scope.CreateLazyVariable(keyValue.Key, new LazySingleThread <Expression>(() => #else scope.CreateLazyVariable(keyValue.Key, new Lazy <Expression>(() => #endif { var innerParameter = scope.CreateVariable(keyValue.Value.GetType(), keyValue.Key); var innerExpression = Expression.Assign(innerParameter, Expression.Constant(keyValue.Value)); scope.Expressions.Add(innerExpression); return(innerParameter); })); } } // Resolve Parameter var parameterExpressions = ResolveParameter(scope, EvalCompilerParameterKind.Dictionary, parameterTypes); // CodeAnalysis var syntaxRoot = SyntaxParser.ParseText(code); // CodeCompiler var expression = ExpressionParser.ParseSyntax(scope, syntaxRoot, resultType); // Compile the expression var compiled = Expression.Lambda <Func <IDictionary, object> >(expression, parameterExpressions).Compile(); var evalDelegate = new EvalDelegate(cacheKey, compiled); EvalManager.CacheDelegate.TryAdd(cacheKey, evalDelegate); return(evalDelegate); }
/// <summary>Compile the code or expression and return a TDelegate of type Func or Action to execute.</summary> /// <param name="context">The eval context used to compile the code or expression.</param> /// <param name="code">The code or expression to compile.</param> /// <param name="parameterTypes">The dictionary of parameter (name / type) used in the code or expression to compile.</param> /// <param name="resultType">Type of the compiled code or expression result.</param> /// <returns>A TDelegate of type Func or Action that represents the compiled code or expression.</returns> internal static EvalDelegate Compile(EvalContext context, string code, ListDictionary parameterTypes, Type resultType) { var cacheKey = ResolveCacheKey(context, typeof (Func<IDictionary, object>), code, parameterTypes); EvalDelegate cachedDelegate; if (EvalManager.CacheDelegate.TryGetValue(cacheKey, out cachedDelegate)) { return cachedDelegate; } Dictionary<string, Type> parameterDict = new Dictionary<string, Type>(); foreach (DictionaryEntry parameterType in parameterTypes) { parameterDict.Add((string)parameterType.Key, (Type)parameterType.Value); } // Options var scope = new ExpressionScope { AliasExtensionMethods = context.AliasExtensionMethods, AliasNames = context.AliasNames, AliasStaticMembers = context.AliasStaticMembers, AliasTypes = context.AliasTypes, BindingFlags = context.BindingFlags, UseCaretForExponent = context.UseCaretForExponent }; // ADD global constants if (context.AliasGlobalConstants.Count > 0) { scope.Constants = new Dictionary<string, ConstantExpression>(context.AliasGlobalConstants); } // ADD global variables if (context.AliasGlobalVariables.Count > 0) { foreach (var keyValue in context.AliasGlobalVariables) { #if SQLNET scope.CreateLazyVariable(keyValue.Key, new LazySingleThread<Expression>(() => #else scope.CreateLazyVariable(keyValue.Key, new Lazy<Expression>(() => #endif { var innerParameter = scope.CreateVariable(keyValue.Value.GetType(), keyValue.Key); var innerExpression = Expression.Assign(innerParameter, Expression.Constant(keyValue.Value)); scope.Expressions.Add(innerExpression); return innerParameter; })); } } // Resolve Parameter var parameterExpressions = ResolveParameter(scope, parameterDict); // CodeAnalysis var syntaxRoot = SyntaxParser.ParseText(code); // CodeCompiler var expression = ExpressionParser.ParseSyntax(scope, syntaxRoot, resultType); // Compile the expression var compiled = Expression.Lambda<Func<IDictionary, object>>(expression, parameterExpressions).Compile(); var evalDelegate = new EvalDelegate(cacheKey, compiled); EvalManager.CacheDelegate.TryAdd(cacheKey, evalDelegate); return evalDelegate; }