public static bool Returns(this ParenthesizedLambdaExpressionSyntax method, string name)
 {
     if (name == null)
     {
         return(false);
     }
     return(method.DescendantNodes <ReturnStatementSyntax>()
            .Select(rss => rss.DescendantNodes <IdentifierNameSyntax>())
            .Any(inss => inss.Any(ins => ins.Identifier.Text == name)));
 }
Ejemplo n.º 2
0
        private HybInstance RunParenthesizedLambda(ParenthesizedLambdaExpressionSyntax node)
        {
            // Detects the lambda is `Func` or `Action`.
            var hasReturn = node.DescendantNodes()
                            .Any(x => x is ReturnStatementSyntax);
            var ps      = node.ParameterList.Parameters;
            var retType = TypeDeduction.GetReturnType(Resolver, node.Body);

            MethodInfo converter = null;
            object     body      = null;

            // `Func`
            if (hasReturn)
            {
                converter = GetConverterF(ps.Count);

                var genericArgs = new Type[ps.Count + 1];
                for (int i = 0; i < ps.Count; i++)
                {
                    if (ps[i].Type == null)
                    {
                        throw new SemanticViolationException("Please provide a explicit type to all lambda parameters, this function is partialy implemented.");
                    }
                    genericArgs[i] = Resolver
                                     .GetType($"{ps[i].Type}")
                                     .Unwrap();
                }
                genericArgs[genericArgs.Length - 1] = retType.Unwrap();
                converter = converter
                            .MakeGenericMethod(genericArgs);

                if (ps.Count == 0)
                {
                    body = new Func <object>(() => {
                        RunBlock(node.Body as BlockSyntax);
                        if (Halt == HaltType.Return)
                        {
                            Halt = HaltType.None;
                        }
                        return(Ret.Unwrap());
                    });
                }
                else if (ps.Count == 1)
                {
                    body = new Func <object, object>((a) => {
                        return(FuncBody(ps, node.Body as BlockSyntax, a));
                    });
                }
                else if (ps.Count == 2)
                {
                    body = new Func <object, object, object>((a, b) => {
                        return(FuncBody(ps, node.Body as BlockSyntax, a, b));
                    });
                }
                else if (ps.Count == 3)
                {
                    body = new Func <object, object, object, object>((a, b, c) => {
                        return(FuncBody(ps, node.Body as BlockSyntax, a, b, c));
                    });
                }
                else if (ps.Count == 4)
                {
                    body = new Func <object, object, object, object, object>((a, b, c, d) => {
                        return(FuncBody(ps, node.Body as BlockSyntax, a, b, c, d));
                    });
                }
                else if (ps.Count == 5)
                {
                    body = new Func <object, object, object, object, object, object>((a, b, c, d, e) => {
                        return(FuncBody(ps, node.Body as BlockSyntax, a, b, c, d, e));
                    });
                }
                else if (ps.Count == 6)
                {
                    body = new Func <object, object, object, object, object, object, object>((a, b, c, d, e, f) => {
                        return(FuncBody(ps, node.Body as BlockSyntax, a, b, c, d, e, f));
                    });
                }
                else if (ps.Count == 7)
                {
                    body = new Func <object, object, object, object, object, object, object, object>((a, b, c, d, e, f, g) => {
                        return(FuncBody(ps, node.Body as BlockSyntax, a, b, c, d, e, f, g));
                    });
                }
            }
            // `Action`
            else
            {
                converter = GetConverterA(ps.Count);

                var genericArgs = new Type[ps.Count];
                for (int i = 0; i < ps.Count; i++)
                {
                    if (ps[i].Type == null)
                    {
                        throw new SemanticViolationException("Please provide a explicit type to all lambda parameters, this function is partialy implemented.");
                    }
                    genericArgs[i] = Resolver
                                     .GetType($"{ps[i].Type}")
                                     .Unwrap();
                }

                if (ps.Count > 0)
                {
                    converter = converter
                                .MakeGenericMethod(genericArgs);
                }

                if (ps.Count == 0)
                {
                    body = new Action(() => {
                        RunBlock(node.Body as BlockSyntax);
                        if (Halt == HaltType.Return)
                        {
                            Halt = HaltType.None;
                        }
                    });
                }
                else if (ps.Count == 1)
                {
                    body = new Action <object>((a) => {
                        ActionBody(ps, node.Body as BlockSyntax, a);
                    });
                }
                else if (ps.Count == 2)
                {
                    body = new Action <object, object>((a, b) => {
                        ActionBody(ps, node.Body as BlockSyntax, a, b);
                    });
                }
                else if (ps.Count == 3)
                {
                    body = new Action <object, object, object>((a, b, c) => {
                        ActionBody(ps, node.Body as BlockSyntax, a, b, c);
                    });
                }
                else if (ps.Count == 4)
                {
                    body = new Action <object, object, object, object>((a, b, c, d) => {
                        ActionBody(ps, node.Body as BlockSyntax, a, b, c, d);
                    });
                }
                else if (ps.Count == 5)
                {
                    body = new Action <object, object, object, object, object>((a, b, c, d, e) => {
                        ActionBody(ps, node.Body as BlockSyntax, a, b, c, d, e);
                    });
                }
                else if (ps.Count == 6)
                {
                    body = new Action <object, object, object, object, object, object>((a, b, c, d, e, f) => {
                        ActionBody(ps, node.Body as BlockSyntax, a, b, c, d, e, f);
                    });
                }
                else if (ps.Count == 7)
                {
                    body = new Action <object, object, object, object, object, object, object>((a, b, c, d, e, f, g) => {
                        ActionBody(ps, node.Body as BlockSyntax, a, b, c, d, e, f, g);
                    });
                }
            }

            var convertedDelegate = converter.Invoke(
                null, new object[] { body });

            return(new HybInstance(
                       HybTypeCache.GetHybType(convertedDelegate.GetType()),
                       convertedDelegate));
        }