Beispiel #1
0
        protected override MethodBase[] ResolveMethods(CallSiteContext bound)
        {
            // check bound.TargetType is assignable from bound.TargetInstance
            if (bound.TargetType == null ||
                bound.CurrentTargetInstance == null ||
                bound.TargetType.Type.IsAssignableFrom(bound.CurrentTargetInstance.GetType()) == false)
            {
                // target instance cannot be used
                bound.TargetInstance = null;
            }

            //
            if (bound.Name != null)
            {
                // candidates:
                IEnumerable <MethodBase> candidates =
                    bound.TargetType
                    .SelectRuntimeMethods(bound.Name, bound.ClassContext)
                    .SelectVisible(bound.ClassContext);

                if (bound.TargetInstance == null)
                {
                    candidates = candidates.SelectStatic();
                }

                //
                return(candidates.Construct(bound.TypeArguments).ToArray());
            }
            else
            {
                throw new ArgumentException();
            }
        }
Beispiel #2
0
        protected override Expression BindMissingMethod(CallSiteContext bound)
        {
            var type = bound.TargetType;

            if (type == null)   // already reported - class cannot be found
            {
                return(ConvertExpression.BindDefault(this.ReturnType));
            }

            if (bound.TargetInstance != null && bound.CurrentTargetInstance != null) // it has been checked it is a subclass of TargetType
            {
                // ensure current scope's __call() is favoured over the specified class
                type = bound.CurrentTargetInstance.GetPhpTypeInfo();
            }

            // try to find __call() first if we have $this
            var call = (bound.TargetInstance != null) ? BinderHelpers.FindMagicMethod(type, TypeMethods.MagicMethods.__call) : null;

            if (call == null)
            {
                // look for __callStatic()
                call = BinderHelpers.FindMagicMethod(type, TypeMethods.MagicMethods.__callstatic);
            }

            if (call != null)
            {
                Expression[] call_args;

                var name_expr = (_name != null) ? Expression.Constant(_name) : bound.IndirectName;

                if (call.Methods.All(IsClrMagicCallWithParams))
                {
                    // Template: target.__call(name, arg1, arg2, ...)
                    // flatterns the arguments:
                    call_args = ArrayUtils.AppendRange(name_expr, bound.Arguments);
                }
                else
                {
                    // Template: target.__call(name, array)
                    // regular PHP behavior:
                    call_args = new Expression[]
                    {
                        name_expr,
                        BinderHelpers.NewPhpArray(bound.Arguments, bound.Context, bound.ClassContext),
                    };
                }

                return(OverloadBinder.BindOverloadCall(_returnType, bound.TargetInstance, call.Methods, bound.Context, call_args,
                                                       isStaticCallSyntax: true,
                                                       lateStaticType: bound.TargetType,
                                                       classContext: bound.ClassContext));
            }

            //
            return(base.BindMissingMethod(bound));
        }