diff --git a/ILSpy/TreeNodes/DerivedTypesEntryNode.cs b/ILSpy/TreeNodes/DerivedTypesEntryNode.cs index ac068f24c..ee60a3e9c 100644 --- a/ILSpy/TreeNodes/DerivedTypesEntryNode.cs +++ b/ILSpy/TreeNodes/DerivedTypesEntryNode.cs @@ -86,7 +86,7 @@ namespace ICSharpCode.ILSpy.TreeNodes IEnumerable FetchChildren(CancellationToken ct) { // FetchChildren() runs on the main thread; but the enumerator will be consumed on a background thread - return DerivedTypesTreeNode.FindDerivedTypes(list, type, ct); + return DerivedTypesTreeNode.FindDerivedTypes(list, Language, type, ct); } public override void ActivateItem(IPlatformRoutedEventArgs e) diff --git a/ILSpy/TreeNodes/DerivedTypesTreeNode.cs b/ILSpy/TreeNodes/DerivedTypesTreeNode.cs index 21b471ea9..220250ec0 100644 --- a/ILSpy/TreeNodes/DerivedTypesTreeNode.cs +++ b/ILSpy/TreeNodes/DerivedTypesTreeNode.cs @@ -23,8 +23,7 @@ using ICSharpCode.Decompiler; using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.ILSpy.Properties; using ICSharpCode.ILSpyX; - -using SRM = System.Reflection.Metadata; +using ICSharpCode.ILSpyX.Analyzers; namespace ICSharpCode.ILSpy.TreeNodes { @@ -57,49 +56,31 @@ namespace ICSharpCode.ILSpy.TreeNodes IEnumerable FetchChildren(CancellationToken cancellationToken) { // FetchChildren() runs on the main thread; but the enumerator will be consumed on a background thread - return FindDerivedTypes(list, type, cancellationToken); + return FindDerivedTypes(list, Language, type, cancellationToken); } - internal static IEnumerable FindDerivedTypes(AssemblyList list, ITypeDefinition type, + internal static IEnumerable FindDerivedTypes(AssemblyList list, Language language, ITypeDefinition type, CancellationToken cancellationToken) { - var definitionMetadata = type.ParentModule.MetadataFile.Metadata; - var metadataToken = (SRM.TypeDefinitionHandle)type.MetadataToken; - var assemblies = list.GetAllAssemblies().GetAwaiter().GetResult(); - foreach (var loadedAssembly in assemblies) + var context = new AnalyzerContext { + CancellationToken = cancellationToken, + Language = language, + AssemblyList = list + }; + var scope = context.GetScopeOf(type); + + foreach (var td in scope.GetTypesInScope(cancellationToken)) { - var module = loadedAssembly.GetMetadataFileOrNull(); - if (module == null) - continue; - var metadata = module.Metadata; - var assembly = module.GetTypeSystemOrNull()?.MainModule as MetadataModule; - if (assembly == null) - continue; - foreach (var h in metadata.TypeDefinitions) + foreach (var baseType in td.DirectBaseTypes) { cancellationToken.ThrowIfCancellationRequested(); - var td = metadata.GetTypeDefinition(h); - foreach (var iface in td.GetInterfaceImplementations()) - { - var ifaceImpl = metadata.GetInterfaceImplementation(iface); - if (!ifaceImpl.Interface.IsNil && IsSameType(metadata, ifaceImpl.Interface, definitionMetadata, metadataToken)) - yield return new DerivedTypesEntryNode(list, assembly.GetDefinition(h)); - } - SRM.EntityHandle baseType = td.GetBaseTypeOrNil(); - if (!baseType.IsNil && IsSameType(metadata, baseType, definitionMetadata, metadataToken)) + if (baseType.FullName == type.FullName) { - yield return new DerivedTypesEntryNode(list, assembly.GetDefinition(h)); + yield return new DerivedTypesEntryNode(list, td); + break; } } } - yield break; - } - - static bool IsSameType(SRM.MetadataReader referenceMetadata, SRM.EntityHandle typeRef, - SRM.MetadataReader definitionMetadata, SRM.TypeDefinitionHandle typeDef) - { - // FullName contains only namespace, name and type parameter count, therefore this should suffice. - return typeRef.GetFullTypeName(referenceMetadata) == typeDef.GetFullTypeName(definitionMetadata); } public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)