/// <summary> /// Parses specified C# expression and returns <see cref="Expression{TDelegate}"/> which could be compiled with <see cref="ExpressionExtensions.CompileAot{TResult}"/> and executed. /// </summary> /// <param name="expression">A valid c# expression. Not null, not empty string.</param> /// <param name="typeResolver">Type resolver for C# expression. Or <seealso cref="Binder.DefaultTypeResolver"/> if not specified.</param> /// <returns>A parsed and bound syntax tree.</returns> public static Expression <Action> ParseAction(string expression, ITypeResolver typeResolver = null) { if (expression == null) { throw new ArgumentNullException("expression"); } AotCompilation.RegisterAction(); var tokens = Tokenizer.Tokenize(expression); var parseTree = Parser.Parse(tokens); var expressionTree = parseTree.ToSyntaxTree(cSharpExpression: expression); var expressionBinder = new Binder(new ParameterExpression[0], resultType: typeof(void), typeResolver: typeResolver); return((Expression <Action>)expressionBinder.Bind(expressionTree)); }
/// <summary> /// Compiles specified expression into <see cref="Action"/> delegate using AOT aware expression compiler. /// </summary> /// <param name="expression">An expression syntax tree. Not null.</param> /// <param name="forceAot">True to always use AOT compiler event if environment is JIT and supports dynamic code.</param> /// <returns>A compiled expression.</returns> public static Action CompileAot(this Expression <Action> expression, bool forceAot = false) { if (expression == null) { throw new ArgumentNullException("expression"); } AotCompilation.RegisterAction(); if (AotCompilation.IsAotRuntime || forceAot) { return(AotCompiler.PrepareAction(expression.Body)); } else { return(expression.Compile()); } }
/// <summary> /// Compiles specified expression into <see cref="Func{TArg1, TArg2, TResult}"/> delegate using AOT aware expression compiler. /// </summary> /// <typeparam name="TArg1">First argument type.</typeparam> /// <typeparam name="TArg2">Second argument type.</typeparam> /// <typeparam name="TResult">Result type.</typeparam> /// <param name="expression">An expression syntax tree. Not null.</param> /// <param name="forceAot">True to always use AOT compiler event if environment is JIT and supports dynamic code.</param> /// <returns>A compiled expression.</returns> public static Func <TArg1, TArg2, TResult> CompileAot <TArg1, TArg2, TResult>(this Expression <Func <TArg1, TArg2, TResult> > expression, bool forceAot = false) { if (expression == null) { throw new ArgumentNullException("expression"); } AotCompilation.RegisterFunc <TArg1, TArg2, TResult>(); if (AotCompilation.IsAotRuntime || forceAot) { return(AotCompiler.PrepareFunc <TArg1, TArg2, TResult>(expression.Body, expression.Parameters)); } else { return(expression.Compile()); } }
/// <summary> /// Parses specified C# expression and returns <see cref="Expression{TDelegate}"/> which could be compiled with <see cref="ExpressionExtensions.CompileAot{TResult}"/> and executed. /// </summary> /// <typeparam name="Arg1T">First argument type.</typeparam> /// <param name="expression">A valid c# expression. Not null, not empty string.</param> /// <param name="arg1Name">First argument name or <see cref="ARG1_DEFAULT_NAME"/> if not specified.</param> /// <param name="typeResolver">Type resolver for C# expression. Or <seealso cref="Binder.DefaultTypeResolver"/> if not specified.</param> /// <returns>A parsed and bound syntax tree.</returns> public static Expression <Action <Arg1T> > ParseAction <Arg1T>(string expression, string arg1Name = ARG1_DEFAULT_NAME, ITypeResolver typeResolver = null) { if (expression == null) { throw new ArgumentNullException("expression"); } AotCompilation.RegisterAction <Arg1T>(); var tokens = Tokenizer.Tokenize(expression); var parseTree = Parser.Parse(tokens); var expressionTree = parseTree.ToSyntaxTree(cSharpExpression: expression); var expressionBuilder = new Binder(new[] { Expression.Parameter(typeof(Arg1T), arg1Name ?? ARG1_DEFAULT_NAME) }, resultType: typeof(void), typeResolver: typeResolver); return((Expression <Action <Arg1T> >)expressionBuilder.Bind(expressionTree)); }
/// <summary> /// Parses specified C# expression and returns <see cref="Expression{TDelegate}"/> which could be compiled with <see cref="ExpressionExtensions.CompileAot{TResult}"/> and executed. /// </summary> /// <typeparam name="Arg1T">First argument type.</typeparam> /// <typeparam name="Arg2T">Second argument type.</typeparam> /// <typeparam name="Arg3T">Third argument type.</typeparam> /// <typeparam name="ResultT">Result type.</typeparam> /// <param name="expression">A valid c# expression. Not null, not empty string.</param> /// <param name="arg1Name">First argument name or <see cref="ARG1_DEFAULT_NAME"/> if not specified.</param> /// <param name="arg2Name">Second argument name or <see cref="ARG2_DEFAULT_NAME"/> if not specified.</param> /// <param name="arg3Name">Third argument name or <see cref="ARG3_DEFAULT_NAME"/> if not specified.</param> /// <param name="typeResolver">Type resolver for C# expression. Or <seealso cref="Binder.DefaultTypeResolver"/> if not specified.</param> /// <returns>A parsed and bound syntax tree.</returns> public static Expression <Func <Arg1T, Arg2T, Arg3T, ResultT> > ParseFunc <Arg1T, Arg2T, Arg3T, ResultT>(string expression, string arg1Name = ARG1_DEFAULT_NAME, string arg2Name = ARG2_DEFAULT_NAME, string arg3Name = ARG3_DEFAULT_NAME, ITypeResolver typeResolver = null) { if (expression == null) { throw new ArgumentNullException("expression"); } AotCompilation.RegisterFunc <Arg1T, Arg2T, Arg3T, ResultT>(); var tokens = Tokenizer.Tokenize(expression); var parseTree = Parser.Parse(tokens); var expressionTree = parseTree.ToSyntaxTree(); var expressionBinder = new Binder(new[] { Expression.Parameter(typeof(Arg1T), arg1Name ?? ARG1_DEFAULT_NAME), Expression.Parameter(typeof(Arg2T), arg2Name ?? ARG2_DEFAULT_NAME), Expression.Parameter(typeof(Arg3T), arg3Name ?? ARG3_DEFAULT_NAME), }, resultType: typeof(ResultT), typeResolver: typeResolver); return((Expression <Func <Arg1T, Arg2T, Arg3T, ResultT> >)expressionBinder.Bind(expressionTree)); }