Example #1
0
        public sealed override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args)
        {
            var bound = CreateContext().ProcessArgs(target, args, HasTarget);

            Expression invocation;

            //
            var methods = ResolveMethods(bound);

            if (methods != null && methods.Length != 0)
            {
                // late static bound type, 'static' if available, otherwise the target type
                var lateStaticTypeArg = (object)bound.LateStaticType ?? bound.TargetType;

                if (bound.HasArgumentUnpacking)
                {
                    var args_var = Expression.Variable(typeof(PhpValue[]), "args_array");

                    /*
                     * args_var = ArgumentsToArray()
                     * call(...args_var...)
                     */

                    invocation = Expression.Block(new[] { args_var },
                                                  Expression.Assign(args_var, BinderHelpers.UnpackArgumentsToArray(methods, bound.Arguments, bound.Context, bound.ClassContext)),
                                                  OverloadBinder.BindOverloadCall(_returnType, bound.TargetInstance, methods, bound.Context, args_var,
                                                                                  isStaticCallSyntax: bound.IsStaticSyntax,
                                                                                  lateStaticType: lateStaticTypeArg)
                                                  );
                }
                else
                {
                    invocation = OverloadBinder.BindOverloadCall(_returnType, bound.TargetInstance, methods, bound.Context, bound.Arguments,
                                                                 isStaticCallSyntax: bound.IsStaticSyntax,
                                                                 lateStaticType: lateStaticTypeArg,
                                                                 classContext: bound.ClassContext);
                }
            }
            else
            {
                invocation = BindMissingMethod(bound);
            }

            // TODO: by alias or by value
            return(new DynamicMetaObject(invocation, bound.Restrictions));
        }