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