public override async Task VisitAsync(Function function) { var args = new L.Expression[function.Expressions.Length]; for (int i = 0; i < function.Expressions.Length; i++) { await function.Expressions[i].AcceptAsync(this); args[i] = _result; } switch (function.Identifier.Name.ToLowerInvariant()) { case "if": _result = L.Expression.Condition(args[0], args[1], args[2]); break; case "in": var items = L.Expression.NewArrayInit(args[0].Type, new ArraySegment <L.Expression>(args, 1, args.Length - 1)); var smi = typeof(Array).GetRuntimeMethod("IndexOf", new[] { typeof(Array), typeof(object) }); var r = L.Expression.Call(smi, L.Expression.Convert(items, typeof(Array)), L.Expression.Convert(args[0], typeof(object))); _result = L.Expression.GreaterThanOrEqual(r, L.Expression.Constant(0)); break; default: var mi = FindMethod(function.Identifier.Name, args); var asyncAttrib = (AsyncStateMachineAttribute)mi.BaseMethodInfo.GetCustomAttribute(typeof(AsyncStateMachineAttribute)); //method is async if (asyncAttrib != null) { object classInstance = Activator.CreateInstance(_context.Type, null); var methodParamList = new List <object>(); foreach (var argItem in args) { methodParamList.Add(ValueExpression.GetUnderlyingValue(argItem)); } var invokedMethod = mi.BaseMethodInfo.Invoke(classInstance, methodParamList.ToArray()); switch (invokedMethod) { case Task <Boolean> invokedMethodTyped: _result = L.Expression.Constant(await invokedMethodTyped); break; case Task <DateTime> invokedMethodTyped: _result = L.Expression.Constant(await invokedMethodTyped); break; case Task <Decimal> invokedMethodTyped: _result = L.Expression.Constant(await invokedMethodTyped); break; case Task <Double> invokedMethodTyped: _result = L.Expression.Constant(await invokedMethodTyped); break; case Task <Single> invokedMethodTyped: _result = L.Expression.Constant(await invokedMethodTyped); break; case Task <Byte> invokedMethodTyped: _result = L.Expression.Constant(await invokedMethodTyped); break; case Task <SByte> invokedMethodTyped: _result = L.Expression.Constant(await invokedMethodTyped); break; case Task <Int16> invokedMethodTyped: _result = L.Expression.Constant(await invokedMethodTyped); break; case Task <Int32> invokedMethodTyped: _result = L.Expression.Constant(await invokedMethodTyped); break; case Task <Int64> invokedMethodTyped: _result = L.Expression.Constant(await invokedMethodTyped); break; case Task <UInt16> invokedMethodTyped: _result = L.Expression.Constant(await invokedMethodTyped); break; case Task <UInt32> invokedMethodTyped: _result = L.Expression.Constant(await invokedMethodTyped); break; case Task <UInt64> invokedMethodTyped: _result = L.Expression.Constant(await invokedMethodTyped); break; case Task <String> invokedMethodTyped: _result = L.Expression.Constant(await invokedMethodTyped); break; } } else { _result = L.Expression.Call(_context, mi.BaseMethodInfo, mi.PreparedArguments); } break; } }