|
|
|
|
@ -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) |
|
|
|
|
|