Browse Source

Fix #3605: Derived Types from other assemblies shown

pull/3606/head
Siegfried Pammer 2 months ago
parent
commit
067c0b3aac
  1. 2
      ILSpy/TreeNodes/DerivedTypesEntryNode.cs
  2. 49
      ILSpy/TreeNodes/DerivedTypesTreeNode.cs

2
ILSpy/TreeNodes/DerivedTypesEntryNode.cs

@ -86,7 +86,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -86,7 +86,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
IEnumerable<ILSpyTreeNode> 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)

49
ILSpy/TreeNodes/DerivedTypesTreeNode.cs

@ -23,8 +23,7 @@ using ICSharpCode.Decompiler; @@ -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 @@ -57,49 +56,31 @@ namespace ICSharpCode.ILSpy.TreeNodes
IEnumerable<ILSpyTreeNode> 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<DerivedTypesEntryNode> FindDerivedTypes(AssemblyList list, ITypeDefinition type,
internal static IEnumerable<DerivedTypesEntryNode> 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)

Loading…
Cancel
Save