Exemple #1
0
        static bool IsPhpStackFrame(StackFrame frame)
        {
            var method = frame.GetMethod();

            if (method == null || method.DeclaringType == null)
            {
                return(false);
            }

            // weird method names:
            if (!ReflectionUtils.IsAllowedPhpName(method.Name) && method.Name != ReflectionUtils.GlobalCodeMethodName)
            {
                return(false);
            }

            // <Script> type
            var tinfo = method.DeclaringType.GetTypeInfo();

            if (tinfo.Name == "<Script>")
            {
                return(false);
            }

            // trait implementation
            if (ReflectionUtils.IsTraitType(tinfo))
            {
                return(false);
            }

            // in Peachpie assemblies (runtime, libraries) // implicitly NonUserCode
            var ass   = tinfo.Assembly;
            var token = ass.GetName().GetPublicKeyToken();

            if (token != null)
            {
                var tokenkey = Utilities.StringUtils.BinToHex(token);
                if (tokenkey == ReflectionUtils.PeachpieAssemblyTokenKey)
                {
                    // but allow library functions
                    if (method.IsPublic && method.IsStatic && tinfo.IsPublic && tinfo.IsAbstract) // public static class + public static method
                    {
                        // ok
                    }
                    else
                    {
                        return(false);
                    }
                }
                else if (tokenkey == "b77a5c561934e089" || tokenkey == "b03f5f7f11d50a3a" || tokenkey == "7cec85d7bea7798e")    // System
                {
                    return(false);
                }
            }

            // [DebuggerHiddenAttribute]
            // [PhpHiddenAttribute]
            // [CompilerGeneratedAttribute]
            // [DebuggerNonUserCodeAttribute]
            if (method.GetCustomAttribute <DebuggerNonUserCodeAttribute>() != null ||
                method.GetCustomAttribute <DebuggerHiddenAttribute>() != null ||
                method.GetCustomAttribute <PhpHiddenAttribute>() != null ||
                method.GetCustomAttribute <CompilerGeneratedAttribute>() != null ||
                tinfo.GetCustomAttribute <DebuggerNonUserCodeAttribute>() != null ||
                tinfo.GetCustomAttribute <CompilerGeneratedAttribute>() != null)
            {
                return(false);
            }

            //
            return(true);
        }
        internal TypeMethods(PhpTypeInfo type)
        {
            // note: GetMethods() ignores "private" members on subclasses
            IEnumerable <MethodInfo> methods = type.Type
                                               .GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy);

            int index = 0;

            // skip members of {System.Object} if we are in a PHP type
            if (type.Type != typeof(object))
            {
                methods = methods.Where(s_notObjectMember);
            }

            // skip [PhpHidden] methods and hidden methods (internal, private protected)
            methods = methods.Where(s_phpvisible);

            // collect available methods (including methods on base classes)
            foreach (var m in methods.ToLookup(_MethodName, StringComparer.OrdinalIgnoreCase))
            {
                if (!ReflectionUtils.IsAllowedPhpName(m.Key))   // .ctor, implicit interface implementation
                {
                    continue;
                }

                var overrides = m.ToArray();

                // ignore methods in base classes that has been "overriden" in current class
                // in PHP we do override even if signature does not match (e.g. __construct)
                SelectVisibleOverrides(ref overrides);

                // TODO: negative {index} in case of non-user method

                var info = PhpMethodInfo.Create(++index, m.Key, overrides, type);

                MagicMethods magic;

                if (IsSpecialName(overrides))
                {
                    // 'specialname' methods,
                    // get_Item, set_Item
                    Enum.TryParse <MagicMethods>(m.Key.ToLowerInvariant(), out magic);
                }
                else
                {
                    if (_methods == null)
                    {
                        _methods = new Dictionary <string, PhpMethodInfo>(StringComparer.OrdinalIgnoreCase);
                    }

                    _methods[info.Name] = info;

                    // resolve magic methods
                    magic = MagicMethodByName(info.Name);
                }

                if (magic != MagicMethods.undefined)
                {
                    if (_magicMethods == null)
                    {
                        _magicMethods = new Dictionary <MagicMethods, PhpMethodInfo>();
                    }

                    _magicMethods[magic] = info;
                }
            }
        }