|
|
|
@ -8,277 +8,68 @@ using System.Reflection.PortableExecutable;
@@ -8,277 +8,68 @@ using System.Reflection.PortableExecutable;
|
|
|
|
|
using System.Text; |
|
|
|
|
using System.Threading.Tasks; |
|
|
|
|
using ICSharpCode.Decompiler.Disassembler; |
|
|
|
|
using ICSharpCode.Decompiler.Semantics; |
|
|
|
|
using ICSharpCode.Decompiler.TypeSystem; |
|
|
|
|
using ICSharpCode.Decompiler.Util; |
|
|
|
|
|
|
|
|
|
using static ICSharpCode.Decompiler.Metadata.ILOpCodeExtensions; |
|
|
|
|
|
|
|
|
|
namespace ICSharpCode.Decompiler.CSharp |
|
|
|
|
{ |
|
|
|
|
class RequiredNamespaceCollector : ISignatureTypeProvider<Unit, Unit> |
|
|
|
|
class RequiredNamespaceCollector |
|
|
|
|
{ |
|
|
|
|
public HashSet<string> Namespaces { get; } |
|
|
|
|
|
|
|
|
|
HashSet<EntityHandle> visited = new HashSet<EntityHandle>(); |
|
|
|
|
DecompilerTypeSystem typeSystem; |
|
|
|
|
|
|
|
|
|
Unit IConstructedTypeProvider<Unit>.GetArrayType(Unit elementType, ArrayShape shape) => default; |
|
|
|
|
Unit IConstructedTypeProvider<Unit>.GetByReferenceType(Unit elementType) => default; |
|
|
|
|
Unit ISignatureTypeProvider<Unit, Unit>.GetFunctionPointerType(MethodSignature<Unit> signature) => default; |
|
|
|
|
Unit IConstructedTypeProvider<Unit>.GetGenericInstantiation(Unit genericType, ImmutableArray<Unit> typeArguments) => default; |
|
|
|
|
Unit ISignatureTypeProvider<Unit, Unit>.GetGenericMethodParameter(Unit genericContext, int index) => default; |
|
|
|
|
Unit ISignatureTypeProvider<Unit, Unit>.GetGenericTypeParameter(Unit genericContext, int index) => default; |
|
|
|
|
Unit ISignatureTypeProvider<Unit, Unit>.GetModifiedType(Unit modifier, Unit unmodifiedType, bool isRequired) => default; |
|
|
|
|
Unit ISignatureTypeProvider<Unit, Unit>.GetPinnedType(Unit elementType) => default; |
|
|
|
|
Unit IConstructedTypeProvider<Unit>.GetPointerType(Unit elementType) => default; |
|
|
|
|
Unit ISimpleTypeProvider<Unit>.GetPrimitiveType(PrimitiveTypeCode typeCode) => default; |
|
|
|
|
Unit ISZArrayTypeProvider<Unit>.GetSZArrayType(Unit elementType) => default; |
|
|
|
|
|
|
|
|
|
Unit ISimpleTypeProvider<Unit>.GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind) |
|
|
|
|
{ |
|
|
|
|
var typeDef = reader.GetTypeDefinition(handle); |
|
|
|
|
GetNamespaceFrom(typeDef, reader); |
|
|
|
|
return default; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Unit ISimpleTypeProvider<Unit>.GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind) |
|
|
|
|
public static void CollectNamespaces(DecompilerTypeSystem typeSystem, HashSet<string> namespaces) |
|
|
|
|
{ |
|
|
|
|
var typeRef = reader.GetTypeReference(handle); |
|
|
|
|
foreach (var type in typeSystem.MainAssembly.GetAllTypeDefinitions()) { |
|
|
|
|
namespaces.Add(type.Namespace); |
|
|
|
|
HandleAttributes(type.Attributes, namespaces); |
|
|
|
|
|
|
|
|
|
if (!typeRef.Namespace.IsNil) |
|
|
|
|
Namespaces.Add(reader.GetString(typeRef.Namespace)); |
|
|
|
|
return default; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Unit ISignatureTypeProvider<Unit, Unit>.GetTypeFromSpecification(MetadataReader reader, Unit genericContext, TypeSpecificationHandle handle, byte rawTypeKind) |
|
|
|
|
{ |
|
|
|
|
reader.GetTypeSpecification(handle).DecodeSignature(this, default); |
|
|
|
|
return default; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void GetNamespaceFrom(TypeDefinition typeDef, MetadataReader reader) |
|
|
|
|
{ |
|
|
|
|
TypeDefinitionHandle handle; |
|
|
|
|
while (!(handle = typeDef.GetDeclaringType()).IsNil) { |
|
|
|
|
typeDef = reader.GetTypeDefinition(handle); |
|
|
|
|
} |
|
|
|
|
if (!typeDef.Namespace.IsNil) |
|
|
|
|
Namespaces.Add(reader.GetString(typeDef.Namespace)); |
|
|
|
|
} |
|
|
|
|
foreach (var field in type.Fields) { |
|
|
|
|
HandleAttributes(field.Attributes, namespaces); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void GetNamespaceFrom(TypeReference typeRef, MetadataReader reader) |
|
|
|
|
{ |
|
|
|
|
if (!typeRef.Namespace.IsNil) { |
|
|
|
|
Namespaces.Add(reader.GetString(typeRef.Namespace)); |
|
|
|
|
} else { |
|
|
|
|
switch (typeRef.ResolutionScope.Kind) { |
|
|
|
|
case HandleKind.TypeReference: |
|
|
|
|
typeRef = reader.GetTypeReference((TypeReferenceHandle)typeRef.ResolutionScope); |
|
|
|
|
GetNamespaceFrom(typeRef, reader); |
|
|
|
|
break; |
|
|
|
|
case HandleKind.ModuleReference: |
|
|
|
|
break; |
|
|
|
|
foreach (var property in type.Properties) { |
|
|
|
|
HandleAttributes(property.Attributes, namespaces); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected RequiredNamespaceCollector(HashSet<string> namespaces) |
|
|
|
|
{ |
|
|
|
|
this.Namespaces = namespaces; |
|
|
|
|
} |
|
|
|
|
foreach (var @event in type.Events) { |
|
|
|
|
HandleAttributes(@event.Attributes, namespaces); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static void CollectNamespaces(EntityHandle handle, PEReader reader, HashSet<string> namespaces) |
|
|
|
|
{ |
|
|
|
|
switch (handle.Kind) { |
|
|
|
|
case HandleKind.TypeDefinition: |
|
|
|
|
CollectNamespaces((TypeDefinitionHandle)handle, reader, namespaces); |
|
|
|
|
break; |
|
|
|
|
case HandleKind.MethodDefinition: |
|
|
|
|
CollectNamespaces((MethodDefinitionHandle)handle, reader, namespaces); |
|
|
|
|
break; |
|
|
|
|
case HandleKind.PropertyDefinition: |
|
|
|
|
CollectNamespaces((PropertyDefinitionHandle)handle, reader, namespaces); |
|
|
|
|
break; |
|
|
|
|
case HandleKind.EventDefinition: |
|
|
|
|
CollectNamespaces((EventDefinitionHandle)handle, reader, namespaces); |
|
|
|
|
break; |
|
|
|
|
case HandleKind.FieldDefinition: |
|
|
|
|
CollectNamespaces((FieldDefinitionHandle)handle, reader, namespaces); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
throw new NotSupportedException(); |
|
|
|
|
foreach (var method in type.Methods) { |
|
|
|
|
HandleAttributes(method.Attributes, namespaces); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static void CollectNamespaces(TypeDefinitionHandle handle, PEReader reader, HashSet<string> namespaces) |
|
|
|
|
public static void CollectNamespaces(IEntity entity, DecompilerTypeSystem typeSystem, HashSet<string> namespaces) |
|
|
|
|
{ |
|
|
|
|
var inst = new RequiredNamespaceCollector(namespaces); |
|
|
|
|
inst.CollectNamespacesForDefinition(handle, reader); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static void CollectNamespaces(MethodDefinitionHandle handle, PEReader reader, HashSet<string> namespaces) |
|
|
|
|
public static void CollectNamespaces(EntityHandle entity, DecompilerTypeSystem typeSystem, HashSet<string> namespaces) |
|
|
|
|
{ |
|
|
|
|
var inst = new RequiredNamespaceCollector(namespaces); |
|
|
|
|
inst.CollectNamespacesForDefinition(handle, reader); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static void CollectNamespaces(FieldDefinitionHandle handle, PEReader reader, HashSet<string> namespaces) |
|
|
|
|
{ |
|
|
|
|
var inst = new RequiredNamespaceCollector(namespaces); |
|
|
|
|
inst.CollectNamespacesForDefinition(handle, reader); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static void CollectNamespaces(PropertyDefinitionHandle handle, PEReader reader, HashSet<string> namespaces) |
|
|
|
|
static void HandleAttributes(IEnumerable<IAttribute> attributes, HashSet<string> namespaces) |
|
|
|
|
{ |
|
|
|
|
var inst = new RequiredNamespaceCollector(namespaces); |
|
|
|
|
inst.CollectNamespacesForDefinition(handle, reader); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static void CollectNamespaces(EventDefinitionHandle handle, PEReader reader, HashSet<string> namespaces) |
|
|
|
|
{ |
|
|
|
|
var inst = new RequiredNamespaceCollector(namespaces); |
|
|
|
|
inst.CollectNamespacesForDefinition(handle, reader); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static void CollectNamespaces(MetadataReader metadata, HashSet<string> namespaces) |
|
|
|
|
{ |
|
|
|
|
foreach (var h in metadata.TypeDefinitions) { |
|
|
|
|
var td = metadata.GetTypeDefinition(h); |
|
|
|
|
if (!td.Namespace.IsNil) |
|
|
|
|
namespaces.Add(metadata.GetString(td.Namespace)); |
|
|
|
|
} |
|
|
|
|
foreach (var h in metadata.TypeReferences) { |
|
|
|
|
var tr = metadata.GetTypeReference(h); |
|
|
|
|
if (!tr.Namespace.IsNil) |
|
|
|
|
namespaces.Add(metadata.GetString(tr.Namespace)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void CollectNamespacesFromAttributes(CustomAttributeHandleCollection attributes, MetadataReader metadata) |
|
|
|
|
{ |
|
|
|
|
foreach (var handle in attributes) { |
|
|
|
|
var ca = metadata.GetCustomAttribute(handle); |
|
|
|
|
CollectNamespacesFromReference(ca.Constructor, metadata); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void CollectNamespacesFromReference(EntityHandle handle, MetadataReader metadata) |
|
|
|
|
{ |
|
|
|
|
TypeDefinition declaringType; |
|
|
|
|
switch (handle.Kind) { |
|
|
|
|
case HandleKind.TypeDefinition: |
|
|
|
|
var td = metadata.GetTypeDefinition((TypeDefinitionHandle)handle); |
|
|
|
|
GetNamespaceFrom(td, metadata); |
|
|
|
|
break; |
|
|
|
|
case HandleKind.FieldDefinition: |
|
|
|
|
var fd = metadata.GetFieldDefinition((FieldDefinitionHandle)handle); |
|
|
|
|
declaringType = metadata.GetTypeDefinition(fd.GetDeclaringType()); |
|
|
|
|
GetNamespaceFrom(declaringType, metadata); |
|
|
|
|
break; |
|
|
|
|
case HandleKind.MethodDefinition: |
|
|
|
|
var md = metadata.GetMethodDefinition((MethodDefinitionHandle)handle); |
|
|
|
|
declaringType = metadata.GetTypeDefinition(md.GetDeclaringType()); |
|
|
|
|
GetNamespaceFrom(declaringType, metadata); |
|
|
|
|
break; |
|
|
|
|
case HandleKind.TypeReference: |
|
|
|
|
var tr = metadata.GetTypeReference((TypeReferenceHandle)handle); |
|
|
|
|
GetNamespaceFrom(tr, metadata); |
|
|
|
|
break; |
|
|
|
|
case HandleKind.MemberReference: |
|
|
|
|
var mr = metadata.GetMemberReference((MemberReferenceHandle)handle); |
|
|
|
|
CollectNamespacesFromReference(mr.Parent, metadata); |
|
|
|
|
switch (mr.GetKind()) { |
|
|
|
|
case MemberReferenceKind.Field: |
|
|
|
|
mr.DecodeFieldSignature(this, default); |
|
|
|
|
break; |
|
|
|
|
case MemberReferenceKind.Method: |
|
|
|
|
mr.DecodeMethodSignature(this, default); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case HandleKind.MethodSpecification: |
|
|
|
|
var ms = metadata.GetMethodSpecification((MethodSpecificationHandle)handle); |
|
|
|
|
CollectNamespacesFromReference(ms.Method, metadata); |
|
|
|
|
ms.DecodeSignature(this, default); |
|
|
|
|
break; |
|
|
|
|
case HandleKind.TypeSpecification: |
|
|
|
|
var ts = metadata.GetTypeSpecification((TypeSpecificationHandle)handle); |
|
|
|
|
ts.DecodeSignature(this, default); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
throw new NotImplementedException(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void CollectNamespacesForDefinition(EntityHandle handle, PEReader reader) |
|
|
|
|
{ |
|
|
|
|
if (!visited.Add(handle)) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
var metadata = reader.GetMetadataReader(); |
|
|
|
|
|
|
|
|
|
TypeDefinition declaringType; |
|
|
|
|
switch (handle.Kind) { |
|
|
|
|
case HandleKind.TypeDefinition: |
|
|
|
|
var td = metadata.GetTypeDefinition((TypeDefinitionHandle)handle); |
|
|
|
|
GetNamespaceFrom(td, metadata); |
|
|
|
|
CollectNamespacesFromAttributes(td.GetCustomAttributes(), metadata); |
|
|
|
|
CollectNamespacesFromReference(td.BaseType, metadata); |
|
|
|
|
foreach (var h in td.GetInterfaceImplementations()) { |
|
|
|
|
var intf = metadata.GetInterfaceImplementation(h); |
|
|
|
|
CollectNamespacesFromReference(intf.Interface, metadata); |
|
|
|
|
} |
|
|
|
|
foreach (var nestedType in td.GetNestedTypes()) |
|
|
|
|
CollectNamespacesForDefinition(nestedType, reader); |
|
|
|
|
foreach (var field in td.GetFields()) |
|
|
|
|
CollectNamespacesForDefinition(field, reader); |
|
|
|
|
foreach (var property in td.GetProperties()) |
|
|
|
|
CollectNamespacesForDefinition(property, reader); |
|
|
|
|
foreach (var @event in td.GetEvents()) |
|
|
|
|
CollectNamespacesForDefinition(@event, reader); |
|
|
|
|
foreach (var method in td.GetMethods()) |
|
|
|
|
CollectNamespacesForDefinition(method, reader); |
|
|
|
|
break; |
|
|
|
|
case HandleKind.FieldDefinition: |
|
|
|
|
var fd = metadata.GetFieldDefinition((FieldDefinitionHandle)handle); |
|
|
|
|
declaringType = metadata.GetTypeDefinition(fd.GetDeclaringType()); |
|
|
|
|
GetNamespaceFrom(declaringType, metadata); |
|
|
|
|
CollectNamespacesFromAttributes(fd.GetCustomAttributes(), metadata); |
|
|
|
|
fd.DecodeSignature(this, default); |
|
|
|
|
if (!fd.GetMarshallingDescriptor().IsNil) |
|
|
|
|
Namespaces.Add("System.Runtime.InteropServices"); |
|
|
|
|
break; |
|
|
|
|
case HandleKind.MethodDefinition: |
|
|
|
|
var md = metadata.GetMethodDefinition((MethodDefinitionHandle)handle); |
|
|
|
|
declaringType = metadata.GetTypeDefinition(md.GetDeclaringType()); |
|
|
|
|
GetNamespaceFrom(declaringType, metadata); |
|
|
|
|
CollectNamespacesFromAttributes(md.GetCustomAttributes(), metadata); |
|
|
|
|
md.DecodeSignature(this, default); |
|
|
|
|
if (md.RelativeVirtualAddress > 0) |
|
|
|
|
CollectNamespacesFromMethodBody(reader.GetMethodBody(md.RelativeVirtualAddress), reader); |
|
|
|
|
break; |
|
|
|
|
case HandleKind.EventDefinition: |
|
|
|
|
var ed = metadata.GetEventDefinition((EventDefinitionHandle)handle); |
|
|
|
|
CollectNamespacesFromAttributes(ed.GetCustomAttributes(), metadata); |
|
|
|
|
CollectNamespacesFromReference(ed.Type, metadata); |
|
|
|
|
var edacc = ed.GetAccessors(); |
|
|
|
|
if (!edacc.Adder.IsNil) |
|
|
|
|
CollectNamespacesForDefinition(edacc.Adder, reader); |
|
|
|
|
if (!edacc.Remover.IsNil) |
|
|
|
|
CollectNamespacesForDefinition(edacc.Remover, reader); |
|
|
|
|
if (!edacc.Raiser.IsNil) |
|
|
|
|
CollectNamespacesForDefinition(edacc.Raiser, reader); |
|
|
|
|
break; |
|
|
|
|
case HandleKind.PropertyDefinition: |
|
|
|
|
var pd = metadata.GetPropertyDefinition((PropertyDefinitionHandle)handle); |
|
|
|
|
CollectNamespacesFromAttributes(pd.GetCustomAttributes(), metadata); |
|
|
|
|
pd.DecodeSignature(this, default); |
|
|
|
|
var pdacc = pd.GetAccessors(); |
|
|
|
|
if (!pdacc.Getter.IsNil) |
|
|
|
|
CollectNamespacesForDefinition(pdacc.Getter, reader); |
|
|
|
|
if (!pdacc.Setter.IsNil) |
|
|
|
|
CollectNamespacesForDefinition(pdacc.Setter, reader); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
break; |
|
|
|
|
foreach (var attr in attributes) { |
|
|
|
|
namespaces.Add(attr.AttributeType.Namespace); |
|
|
|
|
foreach (var arg in attr.PositionalArguments) { |
|
|
|
|
namespaces.Add(arg.Type.Namespace); |
|
|
|
|
if (arg is TypeOfResolveResult torr) |
|
|
|
|
namespaces.Add(torr.ReferencedType.Namespace); |
|
|
|
|
} |
|
|
|
|
foreach (var arg in attr.NamedArguments) { |
|
|
|
|
namespaces.Add(arg.Value.Type.Namespace); |
|
|
|
|
if (arg.Value is TypeOfResolveResult torr) |
|
|
|
|
namespaces.Add(torr.ReferencedType.Namespace); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -295,7 +86,7 @@ namespace ICSharpCode.Decompiler.CSharp
@@ -295,7 +86,7 @@ namespace ICSharpCode.Decompiler.CSharp
|
|
|
|
|
case Metadata.OperandType.Tok: |
|
|
|
|
case Metadata.OperandType.Type: |
|
|
|
|
var handle = MetadataTokens.EntityHandle(instructions.ReadInt32()); |
|
|
|
|
CollectNamespacesFromReference(handle, metadata); |
|
|
|
|
//CollectNamespaces(handle, metadata);
|
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
instructions.SkipOperand(opCode); |
|
|
|
|