예제 #1
0
        /// <summary>
        /// Enumerates PHP routines contained in the specified method list. Filters out methods that
        /// didn't implement PHP routines (they are not argless or argfull overloads).
        /// </summary>
        internal static void EnumerateRoutines(MethodInfo[] /*!*/ methods, RoutineEnumCallback /*!*/ callback)
        {
            // TODO: can be done in a better way

            Dictionary <string, MethodInfo> arg_less_table = new Dictionary <string, MethodInfo>(
                methods.Length / 2,           // at most one half of all methods are supposed to be user routines
                StringComparer.OrdinalIgnoreCase);

            // adds arg-less overloads to the hashtable:
            foreach (MethodInfo method in methods)
            {
                if (PhpFunctionUtils.IsArglessStub(method, null))
                {
                    arg_less_table[method.Name] = method;
                }
            }

            // searches for matching argfulls:
            foreach (MethodInfo method in methods)
            {
                ParameterInfo[] parameters = method.GetParameters();

                // skips arg-less overloads:
                if (PhpFunctionUtils.IsArglessStub(method, parameters))
                {
                    continue;
                }

                // skips methods that hasn't a matching arg-less overload:
                MethodInfo argless;
                if (!arg_less_table.TryGetValue(method.Name, out argless))
                {
                    continue;
                }

                // yields the pair:
                callback(argless, method, parameters);
            }
        }
예제 #2
0
        /// <summary>
        /// Traces the calling stack to discover current PHP class context.
        /// </summary>
        /// <returns><see cref="Type"/> of the PHP class that represents current class context for this thread or
        /// <B>null</B> if this thread is executing in a function or startup Main context.</returns>
        public static DTypeDesc GetClassContext()
        {
            // SILVERLIGHT: Todo Todo .. ? what to do here ?
#if !SILVERLIGHT
            StackTrace stack_trace = new StackTrace(1);
            int        frame_count = stack_trace.FrameCount;

            for (int i = 0; i < frame_count; i++)
            {
                StackFrame stack_frame = stack_trace.GetFrame(i);

                MethodBase method = stack_frame.GetMethod();
                Type       type   = method.DeclaringType;
                if (type != null)
                {
                    if (PhpType.IsPhpRealType(type))
                    {
                        return(DTypeDesc.Create(type));
                    }

                    MethodInfo minfo = method as MethodInfo;
                    if (minfo != null)
                    {
                        ParameterInfo[] parameters = minfo.GetParameters();
                        if (!PhpFunctionUtils.IsArglessStub(minfo, parameters) &&
                            PhpScript.IsScriptType(minfo.DeclaringType) && !PhpScript.IsMainHelper(minfo, parameters))
                        {
                            return(null);
                        }
                        // if the method is a helper method (Main, an arg-less overload, a constructor, etc.),
                        // continue with the trace
                    }
                }
            }
#endif
            return(null);
        }