Ejemplo n.º 1
0
        /// <summary>
        /// Used by CLR modules and PHP pure modules.
        /// </summary>
        internal static void ReflectTypes(Assembly /*!*/ realAssembly, Dictionary <string, DTypeDesc> /*!*/ types)
        {
            // types:
            foreach (Type type in realAssembly.GetTypes())
            {
                if (type.IsVisible)
                {
                    // skip PHP types that were declared conditionally:
                    if (PhpType.IsPhpRealType(type) && PhpType.IsRealConditionalDefinition(type))
                    {
                        continue;
                    }

                    // converts CLR namespaces and nested types to PHP namespaces:
                    string full_name = ClrNotationUtils.FromClrNotation(type.FullName, true).ToString();

                    DTypeDesc existing;
                    if (types.TryGetValue(full_name, out existing))
                    {
                        ClrTypeDesc existing_clr = existing as ClrTypeDesc;
                        if (existing_clr != null && (existing_clr.GenericOverloads.Count > 0 || type.IsGenericTypeDefinition))
                        {
                            ClrTypeDesc new_clr = DTypeDesc.Create(type) as ClrTypeDesc;
                            if (new_clr != null)
                            {
                                // type is overloaded by the number of generic parameters:
                                existing_clr.AddGenericOverload(new_clr);
                            }
                            else
                            {
                                // do not add, just mark existing with the flag:
                                existing.MemberAttributes |= PhpMemberAttributes.Ambiguous;
                            }
                        }
                        else
                        {
                            // do not add, just mark existing with the flag:
                            existing.MemberAttributes |= PhpMemberAttributes.Ambiguous;
                        }
                    }
                    else
                    {
                        types[full_name] = DTypeDesc.Create(type);
                    }
                }
            }
        }
Ejemplo n.º 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);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Reflect PHP classes declared statically in the given script <c>type</c>.
        /// </summary>
        /// <param name="scriptType">Script type to reflect.</param>
        /// <param name="types">List of types to reflect to.</param>
        private static void ReflectScriptTypeClasses(Type scriptType,
                                                     Dictionary <string, DTypeDesc> /*!*/ types)
        {
            ScriptDeclaresAttribute script_declares = ScriptDeclaresAttribute.Reflect(scriptType);

            if (script_declares == null)
            {
                return;
            }

            var module = scriptType.Module;

            foreach (var typeToken in script_declares.DeclaredTypes)
            {
                Type type = module.ResolveType(typeToken);

                // reflect PHP class, skip PHP types that were declared conditionally
                if (PhpType.IsPhpRealType(type) && !PhpType.IsRealConditionalDefinition(type))
                {
                    // converts CLR namespaces and nested types to PHP namespaces:
                    string full_name = QualifiedName.FromClrNotation(type.FullName, true).ToString();

                    // Creating PhpTypeDesc with cache lookup since this type can be in the cache already:
                    // Also force PHP type, because we already checked PhpType.IsPhpRealType(type)
                    PhpTypeDesc phpType = (PhpTypeDesc)DTypeDesc.Create(type.TypeHandle);

                    DTypeDesc existing;
                    if (types.TryGetValue(full_name, out existing))
                    {
                        // TODO (TP): can be generic overload!!
                        existing.MemberAttributes |= PhpMemberAttributes.Ambiguous;
                    }
                    types.Add(full_name, phpType);
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Reflect argfull function, PHP types and constants from given <c>type</c>.
        /// </summary>
        /// <param name="types">Dictionary of types where newly discovered PHP types will be placed. (Types having [ImplementsType] attribute.)</param>
        /// <param name="functions">Dictionary of reflected functions.</param>
        /// <param name="constants">Dictionary of reflected constants.</param>
        /// <param name="type">The type to reflect functions from.</param>
        /// <param name="full">Whether to perform full function reflect.</param>
        private void ReflectArgfulls(
            Dictionary <string, DTypeDesc> /*!*/ types,
            Dictionary <string, DRoutineDesc> /*!*/ functions,
            DualDictionary <string, DConstantDesc> /*!*/ constants,
            Type /*!*/ type, bool full)
        {
            // skip generic types:
            if (type.IsGenericTypeDefinition)
            {
                return;
            }

            if (PhpType.IsPhpRealType(type))
            {
                var dtype = PhpTypeDesc.Create(type);
                types[dtype.MakeSimpleName()] = dtype;
            }

            // reflect even if it is PhpType to find global functions [ImplementsFunction] and constants [ImplementsConstant]
            if (IsLibraryType(type))
            {
                ReflectLibraryType(functions, constants, type, full);
            }
        }