Ejemplo n.º 1
0
        // Returns a dynamic InvokeMember or Invoke expression, depending on the
        // Function expression.
        //
        public static DynamicExpression AnalyzeFunCallExpr(
            SymplFunCallExpr expr, AnalysisScope scope)
        {
            if (expr.Function is SymplDottedExpr)
            {
                SymplDottedExpr dottedExpr = (SymplDottedExpr)expr.Function;
                Expression      objExpr;
                int             length = dottedExpr.Exprs.Length;
                if (length > 1)
                {
                    objExpr = AnalyzeDottedExpr(
                        // create a new dot expression for the object that doesn't
                        // include the last part
                        new SymplDottedExpr(
                            dottedExpr.ObjectExpr,
                            RuntimeHelpers.RemoveLast(dottedExpr.Exprs)),
                        scope
                        );
                }
                else
                {
                    objExpr = AnalyzeExpr(dottedExpr.ObjectExpr, scope);
                }
                List <Expression> args = new List <Expression>();
                args.Add(objExpr);
                args.AddRange(expr.Arguments.Select(a => AnalyzeExpr(a, scope)));

                // last expr must be an id
                var lastExpr = (SymplIdExpr)(dottedExpr.Exprs.Last());
                return(Expression.Dynamic(
                           scope.GetRuntime().GetInvokeMemberBinder(
                               new InvokeMemberBinderKey(
                                   lastExpr.IdToken.Name,
                                   new CallInfo(expr.Arguments.Length))),
                           typeof(object),
                           args
                           ));
            }
            else
            {
                var fun = AnalyzeExpr(expr.Function, scope);
                List <Expression> args = new List <Expression>();
                args.Add(fun);
                args.AddRange(expr.Arguments.Select(a => AnalyzeExpr(a, scope)));
                // Use DynExpr so that I don't always have to have a delegate to call,
                // such as what happens with IPy interop.
                return(Expression.Dynamic(
                           scope.GetRuntime()
                           .GetInvokeBinder(new CallInfo(expr.Arguments.Length)),
                           typeof(object),
                           args
                           ));
            }
        }