public static IEnumerable <MethodDefinition> GetMethodsOnTypeHierarchy(this TypeDefinition type, LinkContext context, Func <MethodDefinition, bool> filter, BindingFlags?bindingFlags = null)
        {
            bool onBaseType = false;

            while (type != null)
            {
                foreach (var method in type.Methods)
                {
                    // Ignore constructors as those are not considered methods from a reflection's point of view
                    if (method.IsConstructor)
                    {
                        continue;
                    }

                    // Ignore private methods on a base type - those are completely ignored by reflection
                    // (anything private on the base type is not visible via the derived type)
                    if (onBaseType && method.IsPrivate)
                    {
                        continue;
                    }

                    // Note that special methods like property getter/setter, event adder/remover will still get through and will be marked.
                    // This is intentional as reflection treats these as methods as well.

                    if (filter != null && !filter(method))
                    {
                        continue;
                    }

                    if ((bindingFlags & (BindingFlags.Instance | BindingFlags.Static)) == BindingFlags.Static && !method.IsStatic)
                    {
                        continue;
                    }

                    if ((bindingFlags & (BindingFlags.Instance | BindingFlags.Static)) == BindingFlags.Instance && method.IsStatic)
                    {
                        continue;
                    }

                    if ((bindingFlags & (BindingFlags.Public | BindingFlags.NonPublic)) == BindingFlags.Public && !method.IsPublic)
                    {
                        continue;
                    }

                    if ((bindingFlags & (BindingFlags.Public | BindingFlags.NonPublic)) == BindingFlags.NonPublic && method.IsPublic)
                    {
                        continue;
                    }

                    yield return(method);
                }

                type       = context.TryResolveTypeDefinition(type.BaseType);
                onBaseType = true;
            }
        }
        public static IEnumerable <InterfaceImplementation> GetAllInterfaceImplementations(this TypeDefinition type, LinkContext context)
        {
            while (type != null)
            {
                foreach (var i in type.Interfaces)
                {
                    yield return(i);

                    TypeDefinition interfaceType = context.TryResolveTypeDefinition(i.InterfaceType);
                    if (interfaceType != null)
                    {
                        foreach (var innerInterface in interfaceType.GetAllInterfaceImplementations(context))
                        {
                            yield return(innerInterface);
                        }
                    }
                }

                type = context.TryResolveTypeDefinition(type.BaseType);
            }
        }
        public static IEnumerable <FieldDefinition> GetFieldsOnTypeHierarchy(this TypeDefinition type, LinkContext context, Func <FieldDefinition, bool> filter, BindingFlags?bindingFlags = BindingFlags.Default)
        {
            bool onBaseType = false;

            while (type != null)
            {
                foreach (var field in type.Fields)
                {
                    // Ignore private fields on a base type - those are completely ignored by reflection
                    // (anything private on the base type is not visible via the derived type)
                    if (onBaseType && field.IsPrivate)
                    {
                        continue;
                    }

                    // Note that compiler generated fields backing some properties and events will get through here.
                    // This is intentional as reflection treats these as fields as well.

                    if (filter != null && !filter(field))
                    {
                        continue;
                    }

                    if ((bindingFlags & (BindingFlags.Instance | BindingFlags.Static)) == BindingFlags.Static && !field.IsStatic)
                    {
                        continue;
                    }

                    if ((bindingFlags & (BindingFlags.Instance | BindingFlags.Static)) == BindingFlags.Instance && field.IsStatic)
                    {
                        continue;
                    }

                    if ((bindingFlags & (BindingFlags.Public | BindingFlags.NonPublic)) == BindingFlags.Public && !field.IsPublic)
                    {
                        continue;
                    }

                    if ((bindingFlags & (BindingFlags.Public | BindingFlags.NonPublic)) == BindingFlags.NonPublic && field.IsPublic)
                    {
                        continue;
                    }

                    yield return(field);
                }

                type       = context.TryResolveTypeDefinition(type.BaseType);
                onBaseType = true;
            }
        }
Example #4
0
        private HierarchyFlags GetFlags(TypeDefinition resolvedType)
        {
            if (_cache.TryGetValue(resolvedType, out var flags))
            {
                return(flags);
            }

            if (resolvedType.Name == "IReflect" && resolvedType.Namespace == "System.Reflection")
            {
                flags |= HierarchyFlags.IsSystemReflectionIReflect;
            }

            TypeDefinition baseType = resolvedType;

            while (baseType != null)
            {
                if (baseType.Name == "Type" && baseType.Namespace == "System")
                {
                    flags |= HierarchyFlags.IsSystemType;
                }

                if (baseType.HasInterfaces)
                {
                    foreach (var iface in baseType.Interfaces)
                    {
                        if (iface.InterfaceType.Name == "IReflect" && iface.InterfaceType.Namespace == "System.Reflection")
                        {
                            flags |= HierarchyFlags.IsSystemReflectionIReflect;
                        }
                    }
                }

                baseType = context.TryResolveTypeDefinition(baseType.BaseType);
            }

            if (resolvedType != null)
            {
                _cache.Add(resolvedType, flags);
            }

            return(flags);
        }
Example #5
0
        public IEnumerable <(InterfaceImplementation, TypeDefinition)> GetReferencedInterfaces(MethodBody body)
        {
            var possibleStackTypes = AllPossibleStackTypes(body.Method);

            if (possibleStackTypes.Count == 0)
            {
                return(null);
            }

            var interfaceTypes = possibleStackTypes.Where(t => t.IsInterface).ToArray();

            if (interfaceTypes.Length == 0)
            {
                return(null);
            }

            var interfaceImplementations = new HashSet <(InterfaceImplementation, TypeDefinition)> ();

            // If a type could be on the stack in the body and an interface it implements could be on the stack on the body
            // then we need to mark that interface implementation.  When this occurs it is not safe to remove the interface implementation from the type
            // even if the type is never instantiated
            foreach (var type in possibleStackTypes)
            {
                // We only sweep interfaces on classes so that's why we only care about classes
                if (!type.IsClass)
                {
                    continue;
                }

                TypeDefinition currentType = type;
                while (currentType?.BaseType != null)                 // Checking BaseType != null to skip System.Object
                {
                    AddMatchingInterfaces(interfaceImplementations, currentType, interfaceTypes);
                    currentType = context.TryResolveTypeDefinition(currentType.BaseType);
                }
            }

            return(interfaceImplementations);
        }
        public static IEnumerable <EventDefinition> GetEventsOnTypeHierarchy(this TypeDefinition type, LinkContext context, Func <EventDefinition, bool> filter, BindingFlags?bindingFlags = BindingFlags.Default)
        {
            bool onBaseType = false;

            while (type != null)
            {
                foreach (var @event in type.Events)
                {
                    // Ignore private properties on a base type - those are completely ignored by reflection
                    // (anything private on the base type is not visible via the derived type)
                    // Note that properties themselves are not actually private, their accessors are
                    if (onBaseType &&
                        (@event.AddMethod == null || @event.AddMethod.IsPrivate) &&
                        (@event.RemoveMethod == null || @event.RemoveMethod.IsPrivate))
                    {
                        continue;
                    }

                    if (filter != null && !filter(@event))
                    {
                        continue;
                    }

                    if ((bindingFlags & (BindingFlags.Instance | BindingFlags.Static)) == BindingFlags.Static)
                    {
                        if ((@event.AddMethod != null) && [email protected])
                        {
                            continue;
                        }
                        if ((@event.RemoveMethod != null) && [email protected])
                        {
                            continue;
                        }
                    }

                    if ((bindingFlags & (BindingFlags.Instance | BindingFlags.Static)) == BindingFlags.Instance)
                    {
                        if ((@event.AddMethod != null) && @event.AddMethod.IsStatic)
                        {
                            continue;
                        }
                        if ((@event.RemoveMethod != null) && @event.RemoveMethod.IsStatic)
                        {
                            continue;
                        }
                    }

                    if ((bindingFlags & (BindingFlags.Public | BindingFlags.NonPublic)) == BindingFlags.Public)
                    {
                        if ((@event.AddMethod == null || [email protected]) &&
                            (@event.RemoveMethod == null || [email protected]))
                        {
                            continue;
                        }
                    }

                    if ((bindingFlags & (BindingFlags.Public | BindingFlags.NonPublic)) == BindingFlags.NonPublic)
                    {
                        if ((@event.AddMethod != null) && @event.AddMethod.IsPublic)
                        {
                            continue;
                        }
                        if ((@event.RemoveMethod != null) && @event.RemoveMethod.IsPublic)
                        {
                            continue;
                        }
                    }

                    yield return(@event);
                }

                type       = context.TryResolveTypeDefinition(type.BaseType);
                onBaseType = true;
            }
        }