Пример #1
0
        /// <summary>
        /// Attempts to bind this callback to its target.
        /// </summary>
        /// <param name="quiet"><B>true</B> of no errors should be thrown, <B>false</B> otherwise.</param>
        /// <param name="nameContext">Current <see cref="NamingContext"/> for function and class name resolution.</param>
        /// <param name="caller">Current class context or a <see cref="UnknownTypeDesc"/> if the class context
        /// should be determined ad-hoc.</param>
        /// <returns><B>True</B> if the callback was successfully bound, <B>false</B> if an error occured.</returns>
        public bool Bind(bool quiet, DTypeDesc caller, NamingContext nameContext)
        {
            if (IsInvalid)
            {
                return(false);
            }

            switch (state)
            {
            case State.UnboundFunction:
            {
                if (context == null)
                {
                    context = ScriptContext.CurrentContext;
                }

                routineDesc = context.ResolveFunction(targetName, nameContext, quiet);
                if (routineDesc == null)
                {
                    return(false);
                }

                state = State.Bound;
                return(true);
            }

            case State.UnboundStaticMethod:
            {
                if (context == null)
                {
                    context = ScriptContext.CurrentContext;
                }

                if (caller != null && caller.IsUnknown)
                {
                    callingContext = PhpStackTrace.GetClassContext();
                }
                else
                {
                    callingContext = caller;
                }

                // try to find the CLR method

                // find the class according to className
                ResolveTypeFlags flags = ResolveTypeFlags.UseAutoload;
                if (!quiet)
                {
                    flags |= ResolveTypeFlags.ThrowErrors;
                }

                DTypeDesc type = context.ResolveType(className, nameContext, callingContext, null, flags);
                if (type == null)
                {
                    return(false);
                }

                // find the method
                bool is_caller_method;
                lateStaticBindType = type;
                routineDesc        = Operators.GetStaticMethodDesc(type, targetName,
                                                                   ref instance, callingContext, context, quiet, false, out is_caller_method);

                if (routineDesc == null)
                {
                    return(false);
                }

                if (instance != null)
                {
                    dummyInstance = true;
                }
                state = is_caller_method ? State.BoundToCaller : State.Bound;
                return(true);
            }

            case State.UnboundInstanceMethod:
            {
                if (caller != null && caller.IsUnknown)
                {
                    callingContext = PhpStackTrace.GetClassContext();
                }
                else
                {
                    callingContext = caller;
                }

                // ask the instance for a handle to the method
                bool is_caller_method;
                routineDesc = instance.GetMethodDesc(targetName, callingContext, quiet, out is_caller_method);
                if (routineDesc == null)
                {
                    return(false);
                }

                state = (is_caller_method ? State.BoundToCaller : State.Bound);
                return(true);
            }
            }
            return(true);
        }