protected override PhpCallable BindCore(Context ctx) { PhpTypeInfo tinfo; object target = null; if ((target = _item1.AsObject()) != null) { tinfo = target.GetPhpTypeInfo(); } else { tinfo = ctx.ResolveType(_item1.ToString(ctx), _callerCtx, true); } if (tinfo != null) { var method = _item2.ToString(ctx); var routine = (PhpMethodInfo)tinfo.RuntimeMethods[method]; if (routine != null) { if (target != null) { return(routine.PhpInvokable.Bind(target)); } else { // calling the method statically if (routine.Methods.All(TypeMembersUtils.IsStatic)) { return(routine.PhpCallable); } else { // consider: compiler (and this binder) creates dummy instance of self; // can we create a special singleton instance marked as "null" so use of $this inside the method will fail ? // TODO: use caller instance or warning (calling instance method statically) return(routine.PhpInvokable.Bind(tinfo.GetUninitializedInstance(ctx))); } } } else { // __call // __callStatic routine = (PhpMethodInfo)tinfo.RuntimeMethods[(target != null) ? TypeMethods.MagicMethods.__call : TypeMethods.MagicMethods.__callstatic]; if (routine != null) { return(routine.PhpInvokable.BindMagicCall(target, method)); } } } return(null); }
void ResolveType(Context ctx, out PhpTypeInfo tinfo, out object target) { if ((target = _item1.AsObject()) != null) { tinfo = target.GetPhpTypeInfo(); } else { tinfo = ctx.ResolveType(_item1.ToString(ctx), _callerCtx, true); } }
protected override PhpCallable BindCore(Context ctx) { var tinfo = ctx.ResolveType(_class, _callerCtx, true); var routine = (PhpMethodInfo)tinfo?.RuntimeMethods[_method]; if (routine != null) { return(routine.PhpInvokable.Bind(null)); } else if (tinfo != null) { routine = (PhpMethodInfo)tinfo.RuntimeMethods[TypeMethods.MagicMethods.__callstatic]; if (routine != null) { return(routine.PhpInvokable.BindMagicCall(null, _method)); } } return(null); }
PhpTypeInfo ResolveType(Context ctx) => ctx.ResolveType(_class, _callerCtx, true);
PhpCallable BindCore(Context ctx, PhpTypeInfo tinfo, object target) { if (tinfo != null) { if (target == null && Target != null && tinfo.Type.IsAssignableFrom(Target.GetType())) { target = this.Target; } var routine = (PhpMethodInfo)tinfo.GetVisibleMethod(_method, _callerCtx); // [$b, "A::foo"] or [$this, "parent::foo"] int colIndex; if (routine == null && (colIndex = _method.IndexOf("::", StringComparison.Ordinal)) > 0) { var methodTypeInfo = ctx.ResolveType(_method.Substring(0, colIndex), _callerCtx, true); if (methodTypeInfo != null && methodTypeInfo.Type.IsAssignableFrom(tinfo.Type)) { tinfo = methodTypeInfo; routine = (PhpMethodInfo)methodTypeInfo.GetVisibleMethod(_method.Substring(colIndex + 2), _callerCtx); } } if (routine != null) { if (target != null) { return(routine.PhpInvokable.Bind(target)); } else { // calling the method statically if (routine.Methods.All(TypeMembersUtils.s_isMethodStatic)) { return(routine.PhpCallable); } else { // CONSIDER: compiler (and this binder) creates dummy instance of self; // can we create a special singleton instance marked as "null" so use of $this inside the method will fail ? // TODO: use caller instance or warning (calling instance method statically) return(routine.PhpInvokable.Bind(tinfo.CreateUninitializedInstance(ctx))); } } } else { // __call // __callStatic routine = (PhpMethodInfo)tinfo.RuntimeMethods[(target != null) ? TypeMethods.MagicMethods.__call : TypeMethods.MagicMethods.__callstatic]; if (routine != null) { return(routine.PhpInvokable.BindMagicCall(target, _method)); } } } return(null); }