mirror of https://github.com/icsharpcode/ILSpy.git
3 changed files with 392 additions and 0 deletions
@ -0,0 +1,83 @@
@@ -0,0 +1,83 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Collections.Immutable; |
||||
using System.Linq; |
||||
using System.Reflection.Metadata; |
||||
using ICSharpCode.Decompiler.CSharp.Syntax; |
||||
using ICSharpCode.Decompiler.Util; |
||||
|
||||
namespace ICSharpCode.Decompiler.CSharp |
||||
{ |
||||
class AstTypeBuilder : ISignatureTypeProvider<AstType, Unit> |
||||
{ |
||||
public AstType GetArrayType(AstType elementType, ArrayShape shape) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public AstType GetByReferenceType(AstType elementType) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public AstType GetFunctionPointerType(MethodSignature<AstType> signature) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public AstType GetGenericInstantiation(AstType genericType, ImmutableArray<AstType> typeArguments) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public AstType GetGenericMethodParameter(Unit genericContext, int index) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public AstType GetGenericTypeParameter(Unit genericContext, int index) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public AstType GetModifiedType(AstType modifier, AstType unmodifiedType, bool isRequired) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public AstType GetPinnedType(AstType elementType) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public AstType GetPointerType(AstType elementType) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public AstType GetPrimitiveType(PrimitiveTypeCode typeCode) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public AstType GetSZArrayType(AstType elementType) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public AstType GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public AstType GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
|
||||
public AstType GetTypeFromSpecification(MetadataReader reader, Unit genericContext, TypeSpecificationHandle handle, byte rawTypeKind) |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,307 @@
@@ -0,0 +1,307 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Collections.Immutable; |
||||
using System.Linq; |
||||
using System.Reflection.Metadata; |
||||
using System.Reflection.Metadata.Ecma335; |
||||
using System.Reflection.PortableExecutable; |
||||
using System.Text; |
||||
using System.Threading.Tasks; |
||||
using ICSharpCode.Decompiler.Disassembler; |
||||
using ICSharpCode.Decompiler.Util; |
||||
|
||||
using static ICSharpCode.Decompiler.Metadata.ILOpCodeExtensions; |
||||
|
||||
namespace ICSharpCode.Decompiler.CSharp |
||||
{ |
||||
class RequiredNamespaceCollector : ISignatureTypeProvider<Unit, Unit> |
||||
{ |
||||
public HashSet<string> Namespaces { get; } |
||||
|
||||
HashSet<EntityHandle> visited = new HashSet<EntityHandle>(); |
||||
|
||||
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) |
||||
{ |
||||
var typeRef = reader.GetTypeReference(handle); |
||||
|
||||
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)); |
||||
} |
||||
|
||||
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; |
||||
} |
||||
} |
||||
} |
||||
|
||||
protected RequiredNamespaceCollector(HashSet<string> namespaces) |
||||
{ |
||||
this.Namespaces = 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(); |
||||
} |
||||
} |
||||
|
||||
public static void CollectNamespaces(TypeDefinitionHandle handle, PEReader reader, HashSet<string> namespaces) |
||||
{ |
||||
var inst = new RequiredNamespaceCollector(namespaces); |
||||
inst.CollectNamespacesForDefinition(handle, reader); |
||||
} |
||||
|
||||
public static void CollectNamespaces(MethodDefinitionHandle handle, PEReader reader, 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) |
||||
{ |
||||
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; |
||||
} |
||||
} |
||||
|
||||
void CollectNamespacesFromMethodBody(MethodBodyBlock method, PEReader reader) |
||||
{ |
||||
var instructions = method.GetILReader(); |
||||
var metadata = reader.GetMetadataReader(); |
||||
while (instructions.RemainingBytes > 0) { |
||||
var opCode = instructions.DecodeOpCode(); |
||||
switch (opCode.GetOperandType()) { |
||||
case Metadata.OperandType.Field: |
||||
case Metadata.OperandType.Method: |
||||
case Metadata.OperandType.Sig: |
||||
case Metadata.OperandType.Tok: |
||||
case Metadata.OperandType.Type: |
||||
var handle = MetadataTokens.EntityHandle(instructions.ReadInt32()); |
||||
CollectNamespacesFromReference(handle, metadata); |
||||
break; |
||||
default: |
||||
instructions.SkipOperand(opCode); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue