/// <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); } }
/// <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); }