Exemplo n.º 1
0
        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;
            }
        }