Browse Source

Avoid unnecessary allocations of MetadataReader and clean up Dom structs a bit.

pull/1198/head
Siegfried Pammer 7 years ago
parent
commit
458f448fae
  1. 2
      ICSharpCode.Decompiler.Tests/Helpers/Tester.cs
  2. 10
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  3. 2
      ICSharpCode.Decompiler/CSharp/RequiredNamespaceCollector.cs
  4. 2
      ICSharpCode.Decompiler/CSharp/Transforms/ConvertConstructorCallIntoInitializer.cs
  5. 6
      ICSharpCode.Decompiler/CSharp/WholeProjectDecompiler.cs
  6. 2
      ICSharpCode.Decompiler/DecompilerException.cs
  7. 11
      ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs
  8. 394
      ICSharpCode.Decompiler/Disassembler/DomExtensions.cs
  9. 28
      ICSharpCode.Decompiler/Disassembler/ILStructure.cs
  10. 66
      ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs
  11. 118
      ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs
  12. 16
      ICSharpCode.Decompiler/Documentation/XmlDocKeyProvider.cs
  13. 2
      ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs
  14. 4
      ICSharpCode.Decompiler/IL/ILReader.cs
  15. 113
      ICSharpCode.Decompiler/Metadata/Dom.cs
  16. 2
      ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs
  17. 12
      ICSharpCode.Decompiler/Metadata/MetadataResolver.cs
  18. 2
      ICSharpCode.Decompiler/Pdb/PortablePdbWriter.cs
  19. 2
      ICSharpCode.Decompiler/SRMHacks.cs
  20. 16
      ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs
  21. 6
      ICSharpCode.Decompiler/TypeSystem/MetadataLoader.cs
  22. 2
      ILSpy.BamlDecompiler/ConnectMethodDecompiler.cs
  23. 2
      ILSpy/DebugInfo/DiaSymNativeDebugInfoProvider.cs
  24. 17
      ILSpy/Languages/CSharpILMixedLanguage.cs
  25. 20
      ILSpy/Languages/CSharpLanguage.cs
  26. 9
      ILSpy/Languages/ILAstLanguage.cs
  27. 27
      ILSpy/Languages/ILLanguage.cs
  28. 48
      ILSpy/Languages/Language.cs
  29. 2
      ILSpy/LoadedAssembly.cs
  30. 26
      ILSpy/SearchStrategies.cs
  31. 10
      ILSpy/TreeNodes/AssemblyListTreeNode.cs
  32. 6
      ILSpy/TreeNodes/AssemblyTreeNode.cs
  33. 4
      ILSpy/TreeNodes/BaseTypesEntryNode.cs
  34. 4
      ILSpy/TreeNodes/BaseTypesTreeNode.cs
  35. 11
      ILSpy/TreeNodes/DerivedTypesEntryNode.cs
  36. 2
      ILSpy/TreeNodes/DerivedTypesTreeNode.cs
  37. 8
      ILSpy/TreeNodes/EventTreeNode.cs
  38. 8
      ILSpy/TreeNodes/FieldTreeNode.cs
  39. 11
      ILSpy/TreeNodes/MethodTreeNode.cs
  40. 6
      ILSpy/TreeNodes/PropertyTreeNode.cs
  41. 2
      ILSpy/TreeNodes/ReferenceFolderTreeNode.cs
  42. 28
      ILSpy/TreeNodes/TypeTreeNode.cs
  43. 2
      TestPlugin/CustomLanguage.cs

2
ICSharpCode.Decompiler.Tests/Helpers/Tester.cs

@ -114,7 +114,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
using (var peFileStream = new FileStream(sourceFileName, FileMode.Open, FileAccess.Read)) using (var peFileStream = new FileStream(sourceFileName, FileMode.Open, FileAccess.Read))
using (var peFile = new PEFile(sourceFileName, peFileStream)) using (var peFile = new PEFile(sourceFileName, peFileStream))
using (var writer = new StringWriter()) { using (var writer = new StringWriter()) {
var metadata = peFile.GetMetadataReader(); var metadata = peFile.Metadata;
var output = new PlainTextOutput(writer); var output = new PlainTextOutput(writer);
ReflectionDisassembler rd = new ReflectionDisassembler(output, CancellationToken.None); ReflectionDisassembler rd = new ReflectionDisassembler(output, CancellationToken.None);
rd.DetectControlStructure = false; rd.DetectControlStructure = false;

10
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -212,7 +212,7 @@ namespace ICSharpCode.Decompiler.CSharp
{ {
if (module == null || member.IsNil) if (module == null || member.IsNil)
return false; return false;
var metadata = module.GetMetadataReader(); var metadata = module.Metadata;
string name; string name;
switch (member.Kind) { switch (member.Kind) {
case HandleKind.MethodDefinition: case HandleKind.MethodDefinition:
@ -413,7 +413,7 @@ namespace ICSharpCode.Decompiler.CSharp
CancellationToken = CancellationToken CancellationToken = CancellationToken
}; };
syntaxTree = new SyntaxTree(); syntaxTree = new SyntaxTree();
MetadataReader metadata = typeSystem.ModuleDefinition.GetMetadataReader(); MetadataReader metadata = typeSystem.ModuleDefinition.Metadata;
RequiredNamespaceCollector.CollectNamespaces(typeSystem, decompileRun.Namespaces); RequiredNamespaceCollector.CollectNamespaces(typeSystem, decompileRun.Namespaces);
DoDecompileModuleAndAssemblyAttributes(decompileRun, decompilationContext, syntaxTree); DoDecompileModuleAndAssemblyAttributes(decompileRun, decompilationContext, syntaxTree);
DoDecompileTypes(metadata.GetTopLevelTypeDefinitions(), decompileRun, decompilationContext, syntaxTree); DoDecompileTypes(metadata.GetTopLevelTypeDefinitions(), decompileRun, decompilationContext, syntaxTree);
@ -595,7 +595,7 @@ namespace ICSharpCode.Decompiler.CSharp
if (!memberDecl.GetChildByRole(EntityDeclaration.PrivateImplementationTypeRole).IsNull) { if (!memberDecl.GetChildByRole(EntityDeclaration.PrivateImplementationTypeRole).IsNull) {
yield break; // cannot create forwarder for existing explicit interface impl yield break; // cannot create forwarder for existing explicit interface impl
} }
MetadataReader metadata = typeSystem.ModuleDefinition.GetMetadataReader(); MetadataReader metadata = typeSystem.ModuleDefinition.Metadata;
foreach (var h in methodHandle.GetMethodImplementations(metadata)) { foreach (var h in methodHandle.GetMethodImplementations(metadata)) {
var mi = metadata.GetMethodImplementation(h); var mi = metadata.GetMethodImplementation(h);
IMethod m = typeSystem.ResolveAsMethod(mi.MethodDeclaration); IMethod m = typeSystem.ResolveAsMethod(mi.MethodDeclaration);
@ -825,7 +825,7 @@ namespace ICSharpCode.Decompiler.CSharp
var specializingTypeSystem = typeSystem.GetSpecializingTypeSystem(decompilationContext); var specializingTypeSystem = typeSystem.GetSpecializingTypeSystem(decompilationContext);
var ilReader = new ILReader(specializingTypeSystem); var ilReader = new ILReader(specializingTypeSystem);
ilReader.UseDebugSymbols = settings.UseDebugSymbols; ilReader.UseDebugSymbols = settings.UseDebugSymbols;
var methodDef = typeSystem.ModuleDefinition.GetMetadataReader().GetMethodDefinition((MethodDefinitionHandle)method.MetadataToken); var methodDef = typeSystem.ModuleDefinition.Metadata.GetMethodDefinition((MethodDefinitionHandle)method.MetadataToken);
var function = ilReader.ReadIL(typeSystem.ModuleDefinition, (MethodDefinitionHandle)method.MetadataToken, typeSystem.ModuleDefinition.Reader.GetMethodBody(methodDef.RelativeVirtualAddress), CancellationToken); var function = ilReader.ReadIL(typeSystem.ModuleDefinition, (MethodDefinitionHandle)method.MetadataToken, typeSystem.ModuleDefinition.Reader.GetMethodBody(methodDef.RelativeVirtualAddress), CancellationToken);
function.CheckInvariant(ILPhase.Normal); function.CheckInvariant(ILPhase.Normal);
@ -1044,7 +1044,7 @@ namespace ICSharpCode.Decompiler.CSharp
if (ev.IsExplicitInterfaceImplementation) { if (ev.IsExplicitInterfaceImplementation) {
eventDecl.Name = ev.Name.Substring(lastDot + 1); eventDecl.Name = ev.Name.Substring(lastDot + 1);
} }
var metadata = typeSystem.ModuleDefinition.GetMetadataReader(); var metadata = typeSystem.ModuleDefinition.Metadata;
if (ev.CanAdd && ev.AddAccessor.HasBody) { if (ev.CanAdd && ev.AddAccessor.HasBody) {
DecompileBody(ev.AddAccessor, ((CustomEventDeclaration)eventDecl).AddAccessor, decompileRun, decompilationContext); DecompileBody(ev.AddAccessor, ((CustomEventDeclaration)eventDecl).AddAccessor, decompileRun, decompilationContext);
} }

2
ICSharpCode.Decompiler/CSharp/RequiredNamespaceCollector.cs

@ -79,7 +79,7 @@ namespace ICSharpCode.Decompiler.CSharp
} }
if (!method.MetadataToken.IsNil && method.HasBody) { if (!method.MetadataToken.IsNil && method.HasBody) {
var reader = typeSystem.ModuleDefinition.Reader; var reader = typeSystem.ModuleDefinition.Reader;
var methodDef = typeSystem.ModuleDefinition.GetMetadataReader().GetMethodDefinition((MethodDefinitionHandle)method.MetadataToken); var methodDef = typeSystem.ModuleDefinition.Metadata.GetMethodDefinition((MethodDefinitionHandle)method.MetadataToken);
var body = reader.GetMethodBody(methodDef.RelativeVirtualAddress); var body = reader.GetMethodBody(methodDef.RelativeVirtualAddress);
CollectNamespacesFromMethodBody(body, reader, typeSystem, namespaces); CollectNamespacesFromMethodBody(body, reader, typeSystem, namespaces);
} }

2
ICSharpCode.Decompiler/CSharp/Transforms/ConvertConstructorCallIntoInitializer.cs

@ -188,7 +188,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
if (staticCtor != null) { if (staticCtor != null) {
IMethod ctorMethod = staticCtor.GetSymbol() as IMethod; IMethod ctorMethod = staticCtor.GetSymbol() as IMethod;
if (!ctorMethod.MetadataToken.IsNil) { if (!ctorMethod.MetadataToken.IsNil) {
var metadata = context.TypeSystem.ModuleDefinition.GetMetadataReader(); var metadata = context.TypeSystem.ModuleDefinition.Metadata;
SRM.MethodDefinition ctorMethodDef = metadata.GetMethodDefinition((SRM.MethodDefinitionHandle)ctorMethod.MetadataToken); SRM.MethodDefinition ctorMethodDef = metadata.GetMethodDefinition((SRM.MethodDefinitionHandle)ctorMethod.MetadataToken);
SRM.TypeDefinition declaringType = metadata.GetTypeDefinition(ctorMethodDef.GetDeclaringType()); SRM.TypeDefinition declaringType = metadata.GetTypeDefinition(ctorMethodDef.GetDeclaringType());
if (declaringType.HasFlag(System.Reflection.TypeAttributes.BeforeFieldInit)) { if (declaringType.HasFlag(System.Reflection.TypeAttributes.BeforeFieldInit)) {

6
ICSharpCode.Decompiler/CSharp/WholeProjectDecompiler.cs

@ -264,7 +264,7 @@ namespace ICSharpCode.Decompiler.CSharp
#region WriteCodeFilesInProject #region WriteCodeFilesInProject
protected virtual bool IncludeTypeWhenDecompilingProject(Metadata.PEFile module, TypeDefinitionHandle type) protected virtual bool IncludeTypeWhenDecompilingProject(Metadata.PEFile module, TypeDefinitionHandle type)
{ {
var metadata = module.GetMetadataReader(); var metadata = module.Metadata;
var typeDef = metadata.GetTypeDefinition(type); var typeDef = metadata.GetTypeDefinition(type);
if (metadata.GetString(typeDef.Name) == "<Module>" || CSharpDecompiler.MemberIsHidden(module, type, settings)) if (metadata.GetString(typeDef.Name) == "<Module>" || CSharpDecompiler.MemberIsHidden(module, type, settings))
return false; return false;
@ -300,8 +300,8 @@ namespace ICSharpCode.Decompiler.CSharp
IEnumerable<Tuple<string, string>> WriteCodeFilesInProject(Metadata.PEFile module, CancellationToken cancellationToken) IEnumerable<Tuple<string, string>> WriteCodeFilesInProject(Metadata.PEFile module, CancellationToken cancellationToken)
{ {
var metadata = module.GetMetadataReader(); var metadata = module.Metadata;
var files = module.GetMetadataReader().GetTopLevelTypeDefinitions().Where(td => IncludeTypeWhenDecompilingProject(module, td)).GroupBy( var files = module.Metadata.GetTopLevelTypeDefinitions().Where(td => IncludeTypeWhenDecompilingProject(module, td)).GroupBy(
delegate (TypeDefinitionHandle h) { delegate (TypeDefinitionHandle h) {
var type = metadata.GetTypeDefinition(h); var type = metadata.GetTypeDefinition(h);
string file = CleanUpFileName(metadata.GetString(type.Name)) + ".cs"; string file = CleanUpFileName(metadata.GetString(type.Name)) + ".cs";

2
ICSharpCode.Decompiler/DecompilerException.cs

@ -42,7 +42,7 @@ namespace ICSharpCode.Decompiler
public Metadata.PEFile Module { get; } public Metadata.PEFile Module { get; }
public DecompilerException(Metadata.PEFile module, MethodDefinitionHandle decompiledMethod, Exception innerException) public DecompilerException(Metadata.PEFile module, MethodDefinitionHandle decompiledMethod, Exception innerException)
: base("Error decompiling " + GetFullName(decompiledMethod, module.GetMetadataReader()) + Environment.NewLine, innerException) : base("Error decompiling " + GetFullName(decompiledMethod, module.Metadata) + Environment.NewLine, innerException)
{ {
this.Module = module; this.Module = module;
this.DecompiledMethod = decompiledMethod; this.DecompiledMethod = decompiledMethod;

11
ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs

@ -67,7 +67,7 @@ namespace ICSharpCode.Decompiler.Disassembler
writer.WriteReference(OffsetToString(offset.Value), offset); writer.WriteReference(OffsetToString(offset.Value), offset);
} }
public static void WriteTo(this SRM.ExceptionRegion exceptionHandler, Metadata.MethodDefinition method, ITextOutput writer) public static void WriteTo(this SRM.ExceptionRegion exceptionHandler, Metadata.PEFile module, GenericContext context, ITextOutput writer)
{ {
writer.Write(".try "); writer.Write(".try ");
WriteOffsetReference(writer, exceptionHandler.TryOffset); WriteOffsetReference(writer, exceptionHandler.TryOffset);
@ -82,7 +82,7 @@ namespace ICSharpCode.Decompiler.Disassembler
} }
if (!exceptionHandler.CatchType.IsNil) { if (!exceptionHandler.CatchType.IsNil) {
writer.Write(' '); writer.Write(' ');
exceptionHandler.CatchType.WriteTo(method.Module, writer, new GenericContext(method)); exceptionHandler.CatchType.WriteTo(module, writer, context);
} }
writer.Write(' '); writer.Write(' ');
WriteOffsetReference(writer, exceptionHandler.HandlerOffset); WriteOffsetReference(writer, exceptionHandler.HandlerOffset);
@ -129,10 +129,9 @@ namespace ICSharpCode.Decompiler.Disassembler
} }
} }
public static void WriteParameterReference(ITextOutput writer, Metadata.MethodDefinition method, int sequence) public static void WriteParameterReference(ITextOutput writer, MetadataReader metadata, MethodDefinitionHandle handle, int sequence)
{ {
var metadata = method.Module.GetMetadataReader(); var methodDefinition = metadata.GetMethodDefinition(handle);
var methodDefinition = metadata.GetMethodDefinition(method.Handle);
var signature = methodDefinition.DecodeSignature(new FullTypeNameSignatureDecoder(metadata), default); var signature = methodDefinition.DecodeSignature(new FullTypeNameSignatureDecoder(metadata), default);
var parameters = methodDefinition.GetParameters().Select(p => metadata.GetParameter(p)).ToArray(); var parameters = methodDefinition.GetParameters().Select(p => metadata.GetParameter(p)).ToArray();
var signatureHeader = signature.Header; var signatureHeader = signature.Header;
@ -152,7 +151,7 @@ namespace ICSharpCode.Decompiler.Disassembler
} }
} }
public static void WriteVariableReference(ITextOutput writer, Metadata.MethodDefinition method, int index) public static void WriteVariableReference(ITextOutput writer, MetadataReader metadata, MethodDefinitionHandle handle, int index)
{ {
writer.Write(index.ToString()); writer.Write(index.ToString());
} }

394
ICSharpCode.Decompiler/Disassembler/DomExtensions.cs

@ -30,52 +30,88 @@ namespace ICSharpCode.Decompiler.Disassembler
{ {
public static class MetadataExtensions public static class MetadataExtensions
{ {
public static void WriteTo(this Metadata.TypeDefinition typeDefinition, ITextOutput output, ILNameSyntax syntax = ILNameSyntax.Signature) public static void WriteTo(this EntityHandle entity, PEFile module, ITextOutput output, GenericContext genericContext, ILNameSyntax syntax = ILNameSyntax.Signature)
{ {
var metadata = typeDefinition.Module.GetMetadataReader(); if (entity.IsNil)
output.WriteReference(typeDefinition.This().GetFullTypeName(metadata).ToILNameString(), typeDefinition); throw new ArgumentNullException(nameof(entity));
if (module == null)
throw new ArgumentNullException(nameof(module));
var metadata = module.Metadata;
Action<ILNameSyntax> signature;
MethodSignature<Action<ILNameSyntax>> methodSignature;
string memberName;
switch (entity.Kind) {
case HandleKind.TypeDefinition: {
var td = metadata.GetTypeDefinition((TypeDefinitionHandle)entity);
output.WriteReference(td.GetFullTypeName(metadata).ToILNameString(), new Metadata.TypeDefinition(module, (TypeDefinitionHandle)entity));
break;
} }
case HandleKind.TypeReference: {
public static void WriteTo(this Metadata.FieldDefinition field, ITextOutput output) var tr = metadata.GetTypeReference((TypeReferenceHandle)entity);
{ if (!tr.ResolutionScope.IsNil) {
var metadata = field.Module.GetMetadataReader(); output.Write("[");
var fieldDefinition = metadata.GetFieldDefinition(field.Handle); var currentTypeRef = tr;
var declaringType = new Metadata.TypeDefinition(field.Module, fieldDefinition.GetDeclaringType()); while (currentTypeRef.ResolutionScope.Kind == HandleKind.TypeReference) {
var signature = fieldDefinition.DecodeSignature(new DisassemblerSignatureProvider(field.Module, output), new GenericContext(declaringType)); currentTypeRef = metadata.GetTypeReference((TypeReferenceHandle)currentTypeRef.ResolutionScope);
}
switch (currentTypeRef.ResolutionScope.Kind) {
case HandleKind.ModuleDefinition:
var modDef = metadata.GetModuleDefinition();
output.Write(DisassemblerHelpers.Escape(metadata.GetString(modDef.Name)));
break;
case HandleKind.ModuleReference:
break;
case HandleKind.AssemblyReference:
var asmRef = metadata.GetAssemblyReference((AssemblyReferenceHandle)currentTypeRef.ResolutionScope);
output.Write(DisassemblerHelpers.Escape(metadata.GetString(asmRef.Name)));
break;
}
output.Write("]");
}
output.WriteReference(entity.GetFullTypeName(metadata).ToILNameString(), new Metadata.TypeReference(module, (TypeReferenceHandle)entity));
break;
}
case HandleKind.TypeSpecification: {
var ts = metadata.GetTypeSpecification((TypeSpecificationHandle)entity);
signature = ts.DecodeSignature(new DisassemblerSignatureProvider(module, output), genericContext);
signature(syntax);
break;
}
case HandleKind.FieldDefinition: {
var fd = metadata.GetFieldDefinition((FieldDefinitionHandle)entity);
signature = fd.DecodeSignature(new DisassemblerSignatureProvider(module, output), new GenericContext(fd.GetDeclaringType(), module));
signature(ILNameSyntax.SignatureNoNamedTypeParameters); signature(ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write(' '); output.Write(' ');
declaringType.WriteTo(output, ILNameSyntax.TypeName); ((EntityHandle)fd.GetDeclaringType()).WriteTo(module, output, GenericContext.Empty, ILNameSyntax.TypeName);
output.Write("::"); output.Write("::");
output.Write(DisassemblerHelpers.Escape(metadata.GetString(fieldDefinition.Name))); output.Write(DisassemblerHelpers.Escape(metadata.GetString(fd.Name)));
break;
} }
case HandleKind.MethodDefinition: {
public static void WriteTo(this Metadata.MethodDefinition method, ITextOutput output) var md = metadata.GetMethodDefinition((MethodDefinitionHandle)entity);
{ methodSignature = md.DecodeSignature(new DisassemblerSignatureProvider(module, output), new GenericContext((MethodDefinitionHandle)entity, module));
var metadata = method.Module.GetMetadataReader(); if (methodSignature.Header.HasExplicitThis) {
var methodDefinition = method.This();
var signature = methodDefinition.DecodeSignature(new DisassemblerSignatureProvider(method.Module, output), new GenericContext(method));
if (signature.Header.HasExplicitThis) {
output.Write("instance explicit "); output.Write("instance explicit ");
} else if (signature.Header.IsInstance) { } else if (methodSignature.Header.IsInstance) {
output.Write("instance "); output.Write("instance ");
} }
if (signature.Header.CallingConvention == SignatureCallingConvention.VarArgs) { if (methodSignature.Header.CallingConvention == SignatureCallingConvention.VarArgs) {
output.Write("vararg "); output.Write("vararg ");
} }
signature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters); methodSignature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write(' '); output.Write(' ');
var declaringType = methodDefinition.GetDeclaringType(); var declaringType = md.GetDeclaringType();
if (!declaringType.IsNil) { if (!declaringType.IsNil) {
new Metadata.TypeDefinition(method.Module, declaringType).WriteTo(output, ILNameSyntax.TypeName); ((EntityHandle)declaringType).WriteTo(module, output, genericContext, ILNameSyntax.TypeName);
output.Write("::"); output.Write("::");
} }
bool isCompilerControlled = (methodDefinition.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.PrivateScope; bool isCompilerControlled = (md.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.PrivateScope;
if (isCompilerControlled) { if (isCompilerControlled) {
output.Write(DisassemblerHelpers.Escape(metadata.GetString(methodDefinition.Name) + "$PST" + MetadataTokens.GetToken(method.Handle).ToString("X8"))); output.Write(DisassemblerHelpers.Escape(metadata.GetString(md.Name) + "$PST" + MetadataTokens.GetToken(entity).ToString("X8")));
} else { } else {
output.Write(DisassemblerHelpers.Escape(metadata.GetString(methodDefinition.Name))); output.Write(DisassemblerHelpers.Escape(metadata.GetString(md.Name)));
} }
var genericParameters = methodDefinition.GetGenericParameters(); var genericParameters = md.GetGenericParameters();
if (genericParameters.Count > 0) { if (genericParameters.Count > 0) {
output.Write('<'); output.Write('<');
for (int i = 0; i < genericParameters.Count; i++) { for (int i = 0; i < genericParameters.Count; i++) {
@ -97,7 +133,7 @@ namespace ICSharpCode.Decompiler.Disassembler
if (j > 0) if (j > 0)
output.Write(", "); output.Write(", ");
var constraint = metadata.GetGenericParameterConstraint(constraints[j]); var constraint = metadata.GetGenericParameterConstraint(constraints[j]);
constraint.Type.WriteTo(method.Module, output, new GenericContext(method), ILNameSyntax.TypeName); constraint.Type.WriteTo(module, output, new GenericContext((MethodDefinitionHandle)entity, module), ILNameSyntax.TypeName);
} }
output.Write(") "); output.Write(") ");
} }
@ -111,102 +147,74 @@ namespace ICSharpCode.Decompiler.Disassembler
output.Write('>'); output.Write('>');
} }
output.Write("("); output.Write("(");
for (int i = 0; i < signature.ParameterTypes.Length; ++i) { for (int i = 0; i < methodSignature.ParameterTypes.Length; ++i) {
if (i > 0) if (i > 0)
output.Write(", "); output.Write(", ");
signature.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters); methodSignature.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters);
} }
output.Write(")"); output.Write(")");
}
public static void WriteTo(this EntityHandle entity, PEFile module, ITextOutput output, GenericContext genericContext, ILNameSyntax syntax = ILNameSyntax.Signature)
{
if (entity.IsNil)
throw new ArgumentNullException(nameof(entity));
if (module == null)
throw new ArgumentNullException(nameof(module));
WriteTo(new Entity(module, entity), output, genericContext, syntax);
}
public static void WriteTo(this Entity entity, ITextOutput output, GenericContext genericContext, ILNameSyntax syntax = ILNameSyntax.Signature)
{
if (entity.IsNil)
throw new ArgumentNullException(nameof(entity));
var metadata = entity.Module.GetMetadataReader();
switch (entity.Handle.Kind) {
case HandleKind.TypeDefinition:
WriteTo(entity, output, syntax);
break;
case HandleKind.TypeReference:
WriteTo(new Metadata.TypeReference(entity.Module, (TypeReferenceHandle)entity.Handle), output, syntax);
break;
case HandleKind.TypeSpecification:
WriteTo(new Metadata.TypeSpecification(entity.Module, (TypeSpecificationHandle)entity.Handle), output, genericContext, syntax);
break;
case HandleKind.FieldDefinition:
WriteTo((Metadata.FieldDefinition)entity, output);
break;
case HandleKind.MethodDefinition:
WriteTo((Metadata.MethodDefinition)entity, output);
break; break;
}
case HandleKind.MemberReference: case HandleKind.MemberReference:
WriteTo((MemberReferenceHandle)entity.Handle, entity.Module, output, genericContext, syntax); var mr = metadata.GetMemberReference((MemberReferenceHandle)entity);
break; memberName = metadata.GetString(mr.Name);
case HandleKind.MethodSpecification: switch (mr.GetKind()) {
WriteTo((MethodSpecificationHandle)entity.Handle, entity.Module, output, genericContext, syntax); case MemberReferenceKind.Method:
break; methodSignature = mr.DecodeMethodSignature(new DisassemblerSignatureProvider(module, output), genericContext);
case HandleKind.PropertyDefinition: if (methodSignature.Header.HasExplicitThis) {
case HandleKind.EventDefinition: output.Write("instance explicit ");
throw new NotSupportedException(); } else if (methodSignature.Header.IsInstance) {
case HandleKind.StandaloneSignature: output.Write("instance ");
var standaloneSig = metadata.GetStandaloneSignature((StandaloneSignatureHandle)entity.Handle); }
switch (standaloneSig.GetKind()) { if (methodSignature.Header.CallingConvention == SignatureCallingConvention.VarArgs) {
case StandaloneSignatureKind.Method: output.Write("vararg ");
var methodSig = standaloneSig.DecodeMethodSignature(new DisassemblerSignatureProvider(entity.Module, output), genericContext); }
methodSig.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters); methodSignature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write('('); output.Write(' ');
for (int i = 0; i < methodSig.ParameterTypes.Length; i++) { WriteParent(output, module, metadata, mr.Parent, genericContext, syntax);
output.Write("::");
output.Write(DisassemblerHelpers.Escape(memberName));
output.Write("(");
for (int i = 0; i < methodSignature.ParameterTypes.Length; ++i) {
if (i > 0) if (i > 0)
output.Write(", "); output.Write(", ");
methodSig.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters); if (i == methodSignature.RequiredParameterCount)
output.Write("..., ");
methodSignature.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters);
} }
output.Write(')'); output.Write(")");
break; break;
case StandaloneSignatureKind.LocalVariables: case MemberReferenceKind.Field:
default: var fieldSignature = mr.DecodeFieldSignature(new DisassemblerSignatureProvider(module, output), genericContext);
throw new NotSupportedException(); fieldSignature(ILNameSyntax.SignatureNoNamedTypeParameters);
} output.Write(' ');
WriteParent(output, module, metadata, mr.Parent, genericContext, syntax);
output.Write("::");
output.Write(DisassemblerHelpers.Escape(memberName));
break; break;
default:
throw new NotSupportedException();
} }
} break;
case HandleKind.MethodSpecification:
public static void WriteTo(this MethodSpecificationHandle handle, PEFile module, ITextOutput output, GenericContext genericContext, ILNameSyntax syntax) var ms = metadata.GetMethodSpecification((MethodSpecificationHandle)entity);
{
var metadata = module.GetMetadataReader();
var ms = metadata.GetMethodSpecification(handle);
var substitution = ms.DecodeSignature(new DisassemblerSignatureProvider(module, output), genericContext); var substitution = ms.DecodeSignature(new DisassemblerSignatureProvider(module, output), genericContext);
MethodSignature<Action<ILNameSyntax>> signature;
switch (ms.Method.Kind) { switch (ms.Method.Kind) {
case HandleKind.MethodDefinition: case HandleKind.MethodDefinition:
var methodDefinition = metadata.GetMethodDefinition((MethodDefinitionHandle)ms.Method); var methodDefinition = metadata.GetMethodDefinition((MethodDefinitionHandle)ms.Method);
var methodName = metadata.GetString(methodDefinition.Name); var methodName = metadata.GetString(methodDefinition.Name);
signature = methodDefinition.DecodeSignature(new DisassemblerSignatureProvider(module, output), genericContext); methodSignature = methodDefinition.DecodeSignature(new DisassemblerSignatureProvider(module, output), genericContext);
if (signature.Header.HasExplicitThis) { if (methodSignature.Header.HasExplicitThis) {
output.Write("instance explicit "); output.Write("instance explicit ");
} else if (signature.Header.IsInstance) { } else if (methodSignature.Header.IsInstance) {
output.Write("instance "); output.Write("instance ");
} }
if (signature.Header.CallingConvention == SignatureCallingConvention.VarArgs) { if (methodSignature.Header.CallingConvention == SignatureCallingConvention.VarArgs) {
output.Write("vararg "); output.Write("vararg ");
} }
signature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters); methodSignature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write(' '); output.Write(' ');
var declaringType = methodDefinition.GetDeclaringType(); var declaringType = methodDefinition.GetDeclaringType();
if (!declaringType.IsNil) { if (!declaringType.IsNil) {
new Metadata.TypeDefinition(module, declaringType).WriteTo(output, ILNameSyntax.TypeName); ((EntityHandle)declaringType).WriteTo(module, output, genericContext, ILNameSyntax.TypeName);
output.Write("::"); output.Write("::");
} }
bool isCompilerControlled = (methodDefinition.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.PrivateScope; bool isCompilerControlled = (methodDefinition.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.PrivateScope;
@ -223,26 +231,26 @@ namespace ICSharpCode.Decompiler.Disassembler
} }
output.Write('>'); output.Write('>');
output.Write("("); output.Write("(");
for (int i = 0; i < signature.ParameterTypes.Length; ++i) { for (int i = 0; i < methodSignature.ParameterTypes.Length; ++i) {
if (i > 0) if (i > 0)
output.Write(", "); output.Write(", ");
signature.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters); methodSignature.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters);
} }
output.Write(")"); output.Write(")");
break; break;
case HandleKind.MemberReference: case HandleKind.MemberReference:
var memberReference = metadata.GetMemberReference((MemberReferenceHandle)ms.Method); var memberReference = metadata.GetMemberReference((MemberReferenceHandle)ms.Method);
var memberName = metadata.GetString(memberReference.Name); memberName = metadata.GetString(memberReference.Name);
signature = memberReference.DecodeMethodSignature(new DisassemblerSignatureProvider(module, output), genericContext); methodSignature = memberReference.DecodeMethodSignature(new DisassemblerSignatureProvider(module, output), genericContext);
if (signature.Header.HasExplicitThis) { if (methodSignature.Header.HasExplicitThis) {
output.Write("instance explicit "); output.Write("instance explicit ");
} else if (signature.Header.IsInstance) { } else if (methodSignature.Header.IsInstance) {
output.Write("instance "); output.Write("instance ");
} }
if (signature.Header.CallingConvention == SignatureCallingConvention.VarArgs) { if (methodSignature.Header.CallingConvention == SignatureCallingConvention.VarArgs) {
output.Write("vararg "); output.Write("vararg ");
} }
signature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters); methodSignature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write(' '); output.Write(' ');
WriteParent(output, module, metadata, memberReference.Parent, genericContext, syntax); WriteParent(output, module, metadata, memberReference.Parent, genericContext, syntax);
output.Write("::"); output.Write("::");
@ -255,88 +263,40 @@ namespace ICSharpCode.Decompiler.Disassembler
} }
output.Write('>'); output.Write('>');
output.Write("("); output.Write("(");
for (int i = 0; i < signature.ParameterTypes.Length; ++i) { for (int i = 0; i < methodSignature.ParameterTypes.Length; ++i) {
if (i > 0) if (i > 0)
output.Write(", "); output.Write(", ");
signature.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters); methodSignature.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters);
} }
output.Write(")"); output.Write(")");
break; break;
} }
} break;
case HandleKind.PropertyDefinition:
public static void WriteTo(this MemberReferenceHandle handle, PEFile module, ITextOutput output, GenericContext genericContext, ILNameSyntax syntax = ILNameSyntax.Signature) case HandleKind.EventDefinition:
{ throw new NotSupportedException();
var metadata = module.GetMetadataReader(); case HandleKind.StandaloneSignature:
var mr = metadata.GetMemberReference(handle); var standaloneSig = metadata.GetStandaloneSignature((StandaloneSignatureHandle)entity);
var memberName = metadata.GetString(mr.Name); switch (standaloneSig.GetKind()) {
switch (mr.GetKind()) { case StandaloneSignatureKind.Method:
case MemberReferenceKind.Method: var methodSig = standaloneSig.DecodeMethodSignature(new DisassemblerSignatureProvider(module, output), genericContext);
var methodSignature = mr.DecodeMethodSignature(new DisassemblerSignatureProvider(module, output), genericContext); methodSig.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);
if (methodSignature.Header.HasExplicitThis) { output.Write('(');
output.Write("instance explicit "); for (int i = 0; i < methodSig.ParameterTypes.Length; i++) {
} else if (methodSignature.Header.IsInstance) {
output.Write("instance ");
}
if (methodSignature.Header.CallingConvention == SignatureCallingConvention.VarArgs) {
output.Write("vararg ");
}
methodSignature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write(' ');
WriteParent(output, module, metadata, mr.Parent, genericContext, syntax);
output.Write("::");
output.Write(DisassemblerHelpers.Escape(memberName));
output.Write("(");
for (int i = 0; i < methodSignature.ParameterTypes.Length; ++i) {
if (i > 0) if (i > 0)
output.Write(", "); output.Write(", ");
if (i == methodSignature.RequiredParameterCount) methodSig.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write("..., ");
methodSignature.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters);
} }
output.Write(")"); output.Write(')');
break;
case MemberReferenceKind.Field:
var fieldSignature = mr.DecodeFieldSignature(new DisassemblerSignatureProvider(module, output), genericContext);
fieldSignature(ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write(' ');
WriteParent(output, module, metadata, mr.Parent, genericContext, syntax);
output.Write("::");
output.Write(DisassemblerHelpers.Escape(memberName));
break; break;
case StandaloneSignatureKind.LocalVariables:
default:
throw new NotSupportedException();
} }
}
public static void WriteTo(this Metadata.TypeReference typeRef, ITextOutput output, ILNameSyntax syntax = ILNameSyntax.Signature)
{
var metadata = typeRef.Module.GetMetadataReader();
if (!typeRef.ResolutionScope.IsNil) {
output.Write("[");
var currentTypeRef = typeRef;
while (currentTypeRef.ResolutionScope.Kind == HandleKind.TypeReference) {
currentTypeRef = new Metadata.TypeReference(currentTypeRef.Module, (TypeReferenceHandle)currentTypeRef.ResolutionScope);
}
switch (currentTypeRef.ResolutionScope.Kind) {
case HandleKind.ModuleDefinition:
var modDef = metadata.GetModuleDefinition();
output.Write(DisassemblerHelpers.Escape(metadata.GetString(modDef.Name)));
break; break;
case HandleKind.ModuleReference: default:
break; throw new NotSupportedException();
case HandleKind.AssemblyReference:
var asmRef = metadata.GetAssemblyReference((AssemblyReferenceHandle)currentTypeRef.ResolutionScope);
output.Write(DisassemblerHelpers.Escape(metadata.GetString(asmRef.Name)));
break;
}
output.Write("]");
}
output.WriteReference(typeRef.FullName.ToILNameString(), typeRef);
} }
public static void WriteTo(this Metadata.TypeSpecification typeSpecification, ITextOutput output, GenericContext genericContext, ILNameSyntax syntax = ILNameSyntax.Signature)
{
var signature = typeSpecification.DecodeSignature(new DisassemblerSignatureProvider(typeSpecification.Module, output), genericContext);
signature(syntax);
} }
static void WriteParent(ITextOutput output, PEFile module, MetadataReader metadata, EntityHandle parentHandle, GenericContext genericContext, ILNameSyntax syntax) static void WriteParent(ITextOutput output, PEFile module, MetadataReader metadata, EntityHandle parentHandle, GenericContext genericContext, ILNameSyntax syntax)
@ -344,7 +304,7 @@ namespace ICSharpCode.Decompiler.Disassembler
switch (parentHandle.Kind) { switch (parentHandle.Kind) {
case HandleKind.MethodDefinition: case HandleKind.MethodDefinition:
var methodDef = metadata.GetMethodDefinition((MethodDefinitionHandle)parentHandle); var methodDef = metadata.GetMethodDefinition((MethodDefinitionHandle)parentHandle);
new Metadata.TypeDefinition(module, methodDef.GetDeclaringType()).WriteTo(output, syntax); ((EntityHandle)methodDef.GetDeclaringType()).WriteTo(module, output, genericContext, syntax);
break; break;
case HandleKind.ModuleReference: case HandleKind.ModuleReference:
output.Write('['); output.Write('[');
@ -353,87 +313,11 @@ namespace ICSharpCode.Decompiler.Disassembler
output.Write(']'); output.Write(']');
break; break;
case HandleKind.TypeDefinition: case HandleKind.TypeDefinition:
new Metadata.TypeDefinition(module, (TypeDefinitionHandle)parentHandle).WriteTo(output, syntax);
break;
case HandleKind.TypeReference: case HandleKind.TypeReference:
new Metadata.TypeReference(module, (TypeReferenceHandle)parentHandle).WriteTo(output, syntax);
break;
case HandleKind.TypeSpecification: case HandleKind.TypeSpecification:
new Metadata.TypeSpecification(module, (TypeSpecificationHandle)parentHandle).WriteTo(output, genericContext, syntax); parentHandle.WriteTo(module, output, genericContext, syntax);
break; break;
} }
} }
/*
public static bool IsBaseTypeOf(this ITypeReference baseType, ITypeReference derivedType)
{
var derivedTypeDefinition = derivedType.GetDefinition();
while (!derivedTypeDefinition.IsNil) {
if (derivedTypeDefinition.FullName == baseType.FullName)
return true;
derivedTypeDefinition = derivedTypeDefinition.BaseType.GetDefinition();
}
return false;
}
}
public class TypeUsedInSignature : ISignatureTypeProvider<bool, Unit>
{
readonly PEFile module;
readonly Metadata.TypeDefinition type;
public TypeUsedInSignature(ITypeReference type)
{
this.module = type.Module;
this.type = type.GetDefinition();
}
public bool GetArrayType(bool elementType, ArrayShape shape) => elementType;
public bool GetByReferenceType(bool elementType) => elementType;
public bool GetFunctionPointerType(MethodSignature<bool> signature)
{
throw new NotImplementedException();
}
public bool GetGenericInstantiation(bool genericType, ImmutableArray<bool> typeArguments)
{
throw new NotImplementedException();
}
public bool GetGenericMethodParameter(Unit genericContext, int index) => false;
public bool GetGenericTypeParameter(Unit genericContext, int index) => false;
public bool GetModifiedType(bool modifier, bool unmodifiedType, bool isRequired)
{
throw new NotImplementedException();
}
public bool GetPinnedType(bool elementType) => elementType;
public bool GetPointerType(bool elementType) => elementType;
public bool GetPrimitiveType(PrimitiveTypeCode typeCode)
{
throw new NotImplementedException();
}
public bool GetSZArrayType(bool elementType) => elementType;
public bool GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)
{
return module == type.Module && handle == type.Handle;
}
public bool GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)
{
return new Metadata.TypeReference(module, handle).GetDefinition() == type;
}
public bool GetTypeFromSpecification(MetadataReader reader, Unit genericContext, TypeSpecificationHandle handle, byte rawTypeKind)
{
return new Metadata.TypeSpecification(module, handle).GetDefinition() == type;
}*/
} }
} }

28
ICSharpCode.Decompiler/Disassembler/ILStructure.cs

@ -57,7 +57,9 @@ namespace ICSharpCode.Decompiler.Disassembler
/// </summary> /// </summary>
public class ILStructure public class ILStructure
{ {
public readonly Metadata.MethodDefinition Method; public readonly PEFile Module;
public readonly MethodDefinitionHandle MethodHandle;
public readonly GenericContext GenericContext;
public readonly ILStructureType Type; public readonly ILStructureType Type;
/// <summary> /// <summary>
@ -85,17 +87,17 @@ namespace ICSharpCode.Decompiler.Disassembler
/// </summary> /// </summary>
public readonly List<ILStructure> Children = new List<ILStructure>(); public readonly List<ILStructure> Children = new List<ILStructure>();
public ILStructure(Metadata.MethodDefinition method, MethodBodyBlock body) public ILStructure(PEFile module, MethodDefinitionHandle handle, GenericContext genericContext, MethodBodyBlock body)
: this(method, ILStructureType.Root, 0, body.GetILReader().Length) : this(module, handle, genericContext, ILStructureType.Root, 0, body.GetILReader().Length)
{ {
// Build the tree of exception structures: // Build the tree of exception structures:
for (int i = 0; i < body.ExceptionRegions.Length; i++) { for (int i = 0; i < body.ExceptionRegions.Length; i++) {
ExceptionRegion eh = body.ExceptionRegions[i]; ExceptionRegion eh = body.ExceptionRegions[i];
if (!body.ExceptionRegions.Take(i).Any(oldEh => oldEh.TryOffset == eh.TryOffset && oldEh.TryLength == eh.TryLength)) if (!body.ExceptionRegions.Take(i).Any(oldEh => oldEh.TryOffset == eh.TryOffset && oldEh.TryLength == eh.TryLength))
AddNestedStructure(new ILStructure(method, ILStructureType.Try, eh.TryOffset, eh.TryOffset + eh.TryLength, eh)); AddNestedStructure(new ILStructure(module, handle, genericContext, ILStructureType.Try, eh.TryOffset, eh.TryOffset + eh.TryLength, eh));
if (eh.Kind == ExceptionRegionKind.Filter) if (eh.Kind == ExceptionRegionKind.Filter)
AddNestedStructure(new ILStructure(method, ILStructureType.Filter, eh.FilterOffset, eh.HandlerOffset, eh)); AddNestedStructure(new ILStructure(module, handle, genericContext, ILStructureType.Filter, eh.FilterOffset, eh.HandlerOffset, eh));
AddNestedStructure(new ILStructure(method, ILStructureType.Handler, eh.HandlerOffset, eh.HandlerOffset + eh.HandlerLength, eh)); AddNestedStructure(new ILStructure(module, handle, genericContext, ILStructureType.Handler, eh.HandlerOffset, eh.HandlerOffset + eh.HandlerLength, eh));
} }
// Very simple loop detection: look for backward branches // Very simple loop detection: look for backward branches
(var allBranches, var isAfterConditionalBranch) = FindAllBranches(body.GetILReader()); (var allBranches, var isAfterConditionalBranch) = FindAllBranches(body.GetILReader());
@ -125,27 +127,31 @@ namespace ICSharpCode.Decompiler.Disassembler
} }
} }
if (!multipleEntryPoints) { if (!multipleEntryPoints) {
AddNestedStructure(new ILStructure(method, ILStructureType.Loop, loopStart, loopEnd, entryPoint)); AddNestedStructure(new ILStructure(module, handle, genericContext, ILStructureType.Loop, loopStart, loopEnd, entryPoint));
} }
} }
} }
SortChildren(); SortChildren();
} }
public ILStructure(Metadata.MethodDefinition method, ILStructureType type, int startOffset, int endOffset, ExceptionRegion handler = default) public ILStructure(PEFile module, MethodDefinitionHandle handle, GenericContext genericContext, ILStructureType type, int startOffset, int endOffset, ExceptionRegion handler = default)
{ {
Debug.Assert(startOffset < endOffset); Debug.Assert(startOffset < endOffset);
this.Method = method; this.Module = module;
this.MethodHandle = handle;
this.GenericContext = genericContext;
this.Type = type; this.Type = type;
this.StartOffset = startOffset; this.StartOffset = startOffset;
this.EndOffset = endOffset; this.EndOffset = endOffset;
this.ExceptionHandler = handler; this.ExceptionHandler = handler;
} }
public ILStructure(Metadata.MethodDefinition method, ILStructureType type, int startOffset, int endOffset, int loopEntryPoint) public ILStructure(PEFile module, MethodDefinitionHandle handle, GenericContext genericContext, ILStructureType type, int startOffset, int endOffset, int loopEntryPoint)
{ {
Debug.Assert(startOffset < endOffset); Debug.Assert(startOffset < endOffset);
this.Method = method; this.Module = module;
this.MethodHandle = handle;
this.GenericContext = genericContext;
this.Type = type; this.Type = type;
this.StartOffset = startOffset; this.StartOffset = startOffset;
this.EndOffset = endOffset; this.EndOffset = endOffset;

66
ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs

@ -24,6 +24,7 @@ using System.Threading;
using ICSharpCode.Decompiler.IL; using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.Disassembler namespace ICSharpCode.Decompiler.Disassembler
{ {
@ -48,17 +49,27 @@ namespace ICSharpCode.Decompiler.Disassembler
IList<Metadata.SequencePoint> sequencePoints; IList<Metadata.SequencePoint> sequencePoints;
int nextSequencePointIndex; int nextSequencePointIndex;
// cache info
PEFile module;
MetadataReader metadata;
GenericContext genericContext;
DisassemblerSignatureProvider signatureDecoder;
public MethodBodyDisassembler(ITextOutput output, CancellationToken cancellationToken) public MethodBodyDisassembler(ITextOutput output, CancellationToken cancellationToken)
{ {
this.output = output ?? throw new ArgumentNullException(nameof(output)); this.output = output ?? throw new ArgumentNullException(nameof(output));
this.cancellationToken = cancellationToken; this.cancellationToken = cancellationToken;
} }
public unsafe virtual void Disassemble(Metadata.MethodDefinition method) public virtual void Disassemble(PEFile module, MethodDefinitionHandle handle)
{ {
this.module = module;
metadata = module.Metadata;
genericContext = new GenericContext(handle, module);
signatureDecoder = new DisassemblerSignatureProvider(module, output);
var methodDefinition = metadata.GetMethodDefinition(handle);
// start writing IL code // start writing IL code
var metadata = method.Module.GetMetadataReader();
var methodDefinition = metadata.GetMethodDefinition(method.Handle);
output.WriteLine("// Method begins at RVA 0x{0:x4}", methodDefinition.RelativeVirtualAddress); output.WriteLine("// Method begins at RVA 0x{0:x4}", methodDefinition.RelativeVirtualAddress);
if (methodDefinition.RelativeVirtualAddress == 0) { if (methodDefinition.RelativeVirtualAddress == 0) {
output.WriteLine("// Code size {0} (0x{0:x})", 0); output.WriteLine("// Code size {0} (0x{0:x})", 0);
@ -66,39 +77,37 @@ namespace ICSharpCode.Decompiler.Disassembler
output.WriteLine(); output.WriteLine();
return; return;
} }
var body = method.Module.Reader.GetMethodBody(methodDefinition.RelativeVirtualAddress); var body = module.Reader.GetMethodBody(methodDefinition.RelativeVirtualAddress);
var blob = body.GetILReader(); var blob = body.GetILReader();
output.WriteLine("// Code size {0} (0x{0:x})", blob.Length); output.WriteLine("// Code size {0} (0x{0:x})", blob.Length);
output.WriteLine(".maxstack {0}", body.MaxStack); output.WriteLine(".maxstack {0}", body.MaxStack);
var entrypointHandle = MetadataTokens.MethodDefinitionHandle(method.Module.Reader.PEHeaders.CorHeader.EntryPointTokenOrRelativeVirtualAddress); var entrypointHandle = MetadataTokens.MethodDefinitionHandle(module.Reader.PEHeaders.CorHeader.EntryPointTokenOrRelativeVirtualAddress);
if (method.Handle == entrypointHandle) if (handle == entrypointHandle)
output.WriteLine(".entrypoint"); output.WriteLine(".entrypoint");
DisassembleLocalsBlock(method, body); DisassembleLocalsBlock(body);
output.WriteLine(); output.WriteLine();
sequencePoints = module.DebugInfo?.GetSequencePoints(handle) ?? EmptyList<Metadata.SequencePoint>.Instance;
sequencePoints = method.GetSequencePoints();
nextSequencePointIndex = 0; nextSequencePointIndex = 0;
if (DetectControlStructure && blob.Length > 0) { if (DetectControlStructure && blob.Length > 0) {
blob.Reset(); blob.Reset();
HashSet<int> branchTargets = GetBranchTargets(blob); HashSet<int> branchTargets = GetBranchTargets(blob);
blob.Reset(); blob.Reset();
WriteStructureBody(new ILStructure(method, body), branchTargets, ref blob); WriteStructureBody(new ILStructure(module, handle, genericContext, body), branchTargets, ref blob);
} else { } else {
while (blob.RemainingBytes > 0) { while (blob.RemainingBytes > 0) {
WriteInstruction(output, method, ref blob); WriteInstruction(output, metadata, handle, ref blob);
} }
WriteExceptionHandlers(method, body); WriteExceptionHandlers(module, handle, body);
} }
sequencePoints = null; sequencePoints = null;
} }
void DisassembleLocalsBlock(Metadata.MethodDefinition method, MethodBodyBlock body) void DisassembleLocalsBlock(MethodBodyBlock body)
{ {
if (body.LocalSignature.IsNil) return; if (body.LocalSignature.IsNil) return;
var metadata = method.Module.GetMetadataReader();
var blob = metadata.GetStandaloneSignature(body.LocalSignature); var blob = metadata.GetStandaloneSignature(body.LocalSignature);
if (blob.GetKind() != StandaloneSignatureKind.LocalVariables) if (blob.GetKind() != StandaloneSignatureKind.LocalVariables)
return; return;
@ -108,7 +117,7 @@ namespace ICSharpCode.Decompiler.Disassembler
reader.Offset = 1; reader.Offset = 1;
if (reader.ReadCompressedInteger() == 0) if (reader.ReadCompressedInteger() == 0)
return; return;
var signature = blob.DecodeLocalSignature(new DisassemblerSignatureProvider(method.Module, output), new GenericContext(method)); var signature = blob.DecodeLocalSignature(signatureDecoder, genericContext);
if (!signature.IsEmpty) { if (!signature.IsEmpty) {
output.Write(".locals "); output.Write(".locals ");
if (body.LocalVariablesInitialized) if (body.LocalVariablesInitialized)
@ -129,13 +138,17 @@ namespace ICSharpCode.Decompiler.Disassembler
} }
} }
internal void WriteExceptionHandlers(Metadata.MethodDefinition method, MethodBodyBlock body) internal void WriteExceptionHandlers(PEFile module, MethodDefinitionHandle handle, MethodBodyBlock body)
{ {
this.module = module;
metadata = module.Metadata;
genericContext = new GenericContext(handle, module);
signatureDecoder = new DisassemblerSignatureProvider(module, output);
var handlers = body.ExceptionRegions; var handlers = body.ExceptionRegions;
if (!handlers.IsEmpty) { if (!handlers.IsEmpty) {
output.WriteLine(); output.WriteLine();
foreach (var eh in handlers) { foreach (var eh in handlers) {
eh.WriteTo(method, output); eh.WriteTo(module, genericContext, output);
output.WriteLine(); output.WriteLine();
} }
} }
@ -180,7 +193,7 @@ namespace ICSharpCode.Decompiler.Disassembler
output.Write("catch"); output.Write("catch");
if (!s.ExceptionHandler.CatchType.IsNil) { if (!s.ExceptionHandler.CatchType.IsNil) {
output.Write(' '); output.Write(' ');
s.ExceptionHandler.CatchType.WriteTo(s.Method.Module, output, new Metadata.GenericContext(s.Method), ILNameSyntax.TypeName); s.ExceptionHandler.CatchType.WriteTo(s.Module, output, s.GenericContext, ILNameSyntax.TypeName);
} }
output.WriteLine(); output.WriteLine();
break; break;
@ -223,7 +236,7 @@ namespace ICSharpCode.Decompiler.Disassembler
} }
var currentOpCode = ILParser.DecodeOpCode(ref body); var currentOpCode = ILParser.DecodeOpCode(ref body);
body.Offset = offset; // reset IL stream body.Offset = offset; // reset IL stream
WriteInstruction(output, s.Method, ref body); WriteInstruction(output, metadata, s.MethodHandle, ref body);
prevInstructionWasBranch = currentOpCode.IsBranch() prevInstructionWasBranch = currentOpCode.IsBranch()
|| currentOpCode.IsReturn() || currentOpCode.IsReturn()
|| currentOpCode == ILOpCode.Throw || currentOpCode == ILOpCode.Throw
@ -255,9 +268,8 @@ namespace ICSharpCode.Decompiler.Disassembler
} }
} }
protected virtual void WriteInstruction(ITextOutput output, Metadata.MethodDefinition method, ref BlobReader blob) protected virtual void WriteInstruction(ITextOutput output, MetadataReader metadata, MethodDefinitionHandle methodDefinition, ref BlobReader blob)
{ {
var metadata = method.Module.GetMetadataReader();
int offset = blob.Offset; int offset = blob.Offset;
if (ShowSequencePoints && nextSequencePointIndex < sequencePoints?.Count) { if (ShowSequencePoints && nextSequencePointIndex < sequencePoints?.Count) {
Metadata.SequencePoint sp = sequencePoints[nextSequencePointIndex]; Metadata.SequencePoint sp = sequencePoints[nextSequencePointIndex];
@ -292,7 +304,7 @@ namespace ICSharpCode.Decompiler.Disassembler
case OperandType.Type: case OperandType.Type:
output.Write(' '); output.Write(' ');
var handle = MetadataTokens.EntityHandle(blob.ReadInt32()); var handle = MetadataTokens.EntityHandle(blob.ReadInt32());
handle.WriteTo(method.Module, output, new GenericContext(method)); handle.WriteTo(module, output, genericContext);
break; break;
case OperandType.Tok: case OperandType.Tok:
output.Write(' '); output.Write(' ');
@ -312,7 +324,7 @@ namespace ICSharpCode.Decompiler.Disassembler
output.Write("field "); output.Write("field ");
break; break;
} }
handle.WriteTo(method.Module, output, new GenericContext(method)); handle.WriteTo(module, output, genericContext);
break; break;
case OperandType.ShortI: case OperandType.ShortI:
output.Write(' '); output.Write(' ');
@ -353,18 +365,18 @@ namespace ICSharpCode.Decompiler.Disassembler
output.Write(' '); output.Write(' ');
int index = blob.ReadUInt16(); int index = blob.ReadUInt16();
if (opCode == ILOpCode.Ldloc || opCode == ILOpCode.Ldloca || opCode == ILOpCode.Stloc) { if (opCode == ILOpCode.Ldloc || opCode == ILOpCode.Ldloca || opCode == ILOpCode.Stloc) {
DisassemblerHelpers.WriteVariableReference(output, method, index); DisassemblerHelpers.WriteVariableReference(output, metadata, methodDefinition, index);
} else { } else {
DisassemblerHelpers.WriteParameterReference(output, method, index); DisassemblerHelpers.WriteParameterReference(output, metadata, methodDefinition, index);
} }
break; break;
case OperandType.ShortVariable: case OperandType.ShortVariable:
output.Write(' '); output.Write(' ');
index = blob.ReadByte(); index = blob.ReadByte();
if (opCode == ILOpCode.Ldloc_s || opCode == ILOpCode.Ldloca_s || opCode == ILOpCode.Stloc_s) { if (opCode == ILOpCode.Ldloc_s || opCode == ILOpCode.Ldloca_s || opCode == ILOpCode.Stloc_s) {
DisassemblerHelpers.WriteVariableReference(output, method, index); DisassemblerHelpers.WriteVariableReference(output, metadata, methodDefinition, index);
} else { } else {
DisassemblerHelpers.WriteParameterReference(output, method, index); DisassemblerHelpers.WriteParameterReference(output, metadata, methodDefinition, index);
} }
break; break;
} }

118
ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs

@ -118,23 +118,28 @@ namespace ICSharpCode.Decompiler.Disassembler
{ MethodImplAttributes.AggressiveInlining, "aggressiveinlining" }, { MethodImplAttributes.AggressiveInlining, "aggressiveinlining" },
}; };
public void DisassembleMethod(Metadata.MethodDefinition method) public void DisassembleMethod(PEFile module, MethodDefinitionHandle handle)
{ {
DisassembleMethodHeader(method); var metadata = module.Metadata;
DisassembleMethodBlock(method); var genericContext = new GenericContext(handle, module);
// write method header
output.WriteDefinition(".method ", new Metadata.MethodDefinition(module, handle));
DisassembleMethodHeaderInternal(module, handle, metadata, genericContext);
DisassembleMethodBlock(module, handle, metadata, genericContext);
} }
public void DisassembleMethodHeader(Metadata.MethodDefinition method) public void DisassembleMethodHeader(PEFile module, MethodDefinitionHandle handle)
{ {
var metadata = module.Metadata;
var genericContext = new GenericContext(handle, module);
// write method header // write method header
output.WriteDefinition(".method ", method); output.WriteDefinition(".method ", new Metadata.MethodDefinition(module, handle));
DisassembleMethodHeaderInternal(method); DisassembleMethodHeaderInternal(module, handle, metadata, genericContext);
} }
void DisassembleMethodHeaderInternal(Metadata.MethodDefinition method) void DisassembleMethodHeaderInternal(PEFile module, MethodDefinitionHandle handle, MetadataReader metadata, GenericContext genericContext)
{ {
var metadata = method.Module.GetMetadataReader(); var methodDefinition = metadata.GetMethodDefinition(handle);
var methodDefinition = metadata.GetMethodDefinition(method.Handle);
// .method public hidebysig specialname // .method public hidebysig specialname
// instance default class [mscorlib]System.IO.TextWriter get_BaseWriter () cil managed // instance default class [mscorlib]System.IO.TextWriter get_BaseWriter () cil managed
// //
@ -199,8 +204,8 @@ namespace ICSharpCode.Decompiler.Disassembler
output.WriteLine(); output.WriteLine();
output.Indent(); output.Indent();
var declaringType = methodDefinition.GetDeclaringType(); var declaringType = methodDefinition.GetDeclaringType();
var signatureProvider = new DisassemblerSignatureProvider(method.Module, output); var signatureProvider = new DisassemblerSignatureProvider(module, output);
var signature = methodDefinition.DecodeSignature(signatureProvider, new GenericContext(method)); var signature = methodDefinition.DecodeSignature(signatureProvider, genericContext);
if (signature.Header.HasExplicitThis) { if (signature.Header.HasExplicitThis) {
output.Write("instance explicit "); output.Write("instance explicit ");
} else if (signature.Header.IsInstance) { } else if (signature.Header.IsInstance) {
@ -224,12 +229,12 @@ namespace ICSharpCode.Decompiler.Disassembler
} }
if (isCompilerControlled) { if (isCompilerControlled) {
output.Write(DisassemblerHelpers.Escape(metadata.GetString(methodDefinition.Name) + "$PST" + MetadataTokens.GetToken(method.Handle).ToString("X8"))); output.Write(DisassemblerHelpers.Escape(metadata.GetString(methodDefinition.Name) + "$PST" + MetadataTokens.GetToken(handle).ToString("X8")));
} else { } else {
output.Write(DisassemblerHelpers.Escape(metadata.GetString(methodDefinition.Name))); output.Write(DisassemblerHelpers.Escape(metadata.GetString(methodDefinition.Name)));
} }
WriteTypeParameters(output, method.Module, new GenericContext(method), methodDefinition.GetGenericParameters()); WriteTypeParameters(output, module, genericContext, methodDefinition.GetGenericParameters());
//( params ) //( params )
output.Write(" ("); output.Write(" (");
@ -251,27 +256,26 @@ namespace ICSharpCode.Decompiler.Disassembler
output.Unindent(); output.Unindent();
} }
void DisassembleMethodBlock(Metadata.MethodDefinition method) void DisassembleMethodBlock(PEFile module, MethodDefinitionHandle handle, MetadataReader metadata, GenericContext genericContext)
{ {
var metadata = method.Module.GetMetadataReader(); var methodDefinition = metadata.GetMethodDefinition(handle);
var methodDefinition = metadata.GetMethodDefinition(method.Handle);
OpenBlock(defaultCollapsed: isInType); OpenBlock(defaultCollapsed: isInType);
WriteAttributes(method.Module, methodDefinition.GetCustomAttributes()); WriteAttributes(module, methodDefinition.GetCustomAttributes());
foreach (var h in method.Handle.GetMethodImplementations(metadata)) { foreach (var h in handle.GetMethodImplementations(metadata)) {
var impl = metadata.GetMethodImplementation(h); var impl = metadata.GetMethodImplementation(h);
output.Write(".override method "); output.Write(".override method ");
impl.MethodDeclaration.WriteTo(method.Module, output, new GenericContext(method)); impl.MethodDeclaration.WriteTo(module, output, genericContext);
output.WriteLine(); output.WriteLine();
} }
foreach (var p in methodDefinition.GetParameters()) { foreach (var p in methodDefinition.GetParameters()) {
WriteParameterAttributes(method.Module, p); WriteParameterAttributes(module, p);
} }
WriteSecurityDeclarations(method.Module, methodDefinition.GetDeclarativeSecurityAttributes()); WriteSecurityDeclarations(module, methodDefinition.GetDeclarativeSecurityAttributes());
if (method.Handle.HasBody(metadata)) { if (handle.HasBody(metadata)) {
methodBodyDisassembler.Disassemble(method); methodBodyDisassembler.Disassemble(module, handle);
} }
var declaringType = metadata.GetTypeDefinition(methodDefinition.GetDeclaringType()); var declaringType = metadata.GetTypeDefinition(methodDefinition.GetDeclaringType());
CloseBlock("end of method " + DisassemblerHelpers.Escape(metadata.GetString(declaringType.Name)) + "::" + DisassemblerHelpers.Escape(metadata.GetString(methodDefinition.Name))); CloseBlock("end of method " + DisassemblerHelpers.Escape(metadata.GetString(declaringType.Name)) + "::" + DisassemblerHelpers.Escape(metadata.GetString(methodDefinition.Name)));
@ -282,7 +286,7 @@ namespace ICSharpCode.Decompiler.Disassembler
{ {
if (secDeclProvider.Count == 0) if (secDeclProvider.Count == 0)
return; return;
var metadata = module.GetMetadataReader(); var metadata = module.Metadata;
foreach (var h in secDeclProvider) { foreach (var h in secDeclProvider) {
output.Write(".permissionset "); output.Write(".permissionset ");
var secdecl = metadata.GetDeclarativeSecurityAttribute(h); var secdecl = metadata.GetDeclarativeSecurityAttribute(h);
@ -344,18 +348,18 @@ namespace ICSharpCode.Decompiler.Disassembler
WriteXmlSecurityDeclaration(blob.ReadUTF8(blob.RemainingBytes)); WriteXmlSecurityDeclaration(blob.ReadUTF8(blob.RemainingBytes));
} else { } else {
string currentAssemblyName = null; string currentAssemblyName = null;
string currentFullAssemblyName = null;
if (metadata.IsAssembly) { if (metadata.IsAssembly) {
currentAssemblyName = metadata.GetString(metadata.GetAssemblyDefinition().Name); currentAssemblyName = metadata.GetString(metadata.GetAssemblyDefinition().Name);
currentFullAssemblyName = metadata.GetFullAssemblyName();
} }
int count = blob.ReadCompressedInteger(); int count = blob.ReadCompressedInteger();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
var typeName = blob.ReadSerializedString(); var typeName = blob.ReadSerializedString();
string[] nameParts = typeName.Split(new[] { ", " }, StringSplitOptions.None); string[] nameParts = typeName.Split(new[] { ", " }, StringSplitOptions.None);
if (nameParts.Length < 2) if (nameParts.Length < 2 || nameParts[1] == currentAssemblyName) {
throw new NotImplementedException();
if (nameParts[1] == currentAssemblyName) {
output.Write("class "); output.Write("class ");
output.Write(DisassemblerHelpers.Escape(typeName)); output.Write(DisassemblerHelpers.Escape(typeName + ", " + currentFullAssemblyName));
} else { } else {
string[] typeNameParts = typeName.Split(new[] { ", " }, StringSplitOptions.None); string[] typeNameParts = typeName.Split(new[] { ", " }, StringSplitOptions.None);
if (typeNameParts.Length < 2) if (typeNameParts.Length < 2)
@ -464,7 +468,7 @@ namespace ICSharpCode.Decompiler.Disassembler
TypeDefinitionHandle FindType(PEFile currentModule, string[] name) TypeDefinitionHandle FindType(PEFile currentModule, string[] name)
{ {
var metadata = currentModule.GetMetadataReader(); var metadata = currentModule.Metadata;
var currentNamespace = metadata.GetNamespaceDefinitionRoot(); var currentNamespace = metadata.GetNamespaceDefinitionRoot();
ImmutableArray<TypeDefinitionHandle> typeDefinitions = default; ImmutableArray<TypeDefinitionHandle> typeDefinitions = default;
@ -503,7 +507,7 @@ namespace ICSharpCode.Decompiler.Disassembler
if (containingModule != null) { if (containingModule != null) {
// try to find the type in the assembly // try to find the type in the assembly
var handle = FindType(containingModule, typeNameParts); var handle = FindType(containingModule, typeNameParts);
var metadata = containingModule.GetMetadataReader(); var metadata = containingModule.Metadata;
if (handle.IsNil || !handle.IsEnum(metadata, out var typeCode)) if (handle.IsNil || !handle.IsEnum(metadata, out var typeCode))
throw new NotSupportedException(); throw new NotSupportedException();
typeDefinition = new Metadata.TypeDefinition(containingModule, handle); typeDefinition = new Metadata.TypeDefinition(containingModule, handle);
@ -519,7 +523,7 @@ namespace ICSharpCode.Decompiler.Disassembler
throw new NotImplementedException(); throw new NotImplementedException();
module = mscorlib; module = mscorlib;
} }
var metadata = module.GetMetadataReader(); var metadata = module.Metadata;
if (handle.IsNil || !handle.IsEnum(metadata, out var typeCode)) if (handle.IsNil || !handle.IsEnum(metadata, out var typeCode))
throw new NotSupportedException(); throw new NotSupportedException();
typeDefinition = new Metadata.TypeDefinition(module, handle); typeDefinition = new Metadata.TypeDefinition(module, handle);
@ -651,7 +655,7 @@ namespace ICSharpCode.Decompiler.Disassembler
output.Write('['); output.Write('[');
output.Write(referencedModule.Name); output.Write(referencedModule.Name);
output.Write(']'); output.Write(']');
output.WriteReference(type.Handle.GetFullTypeName(type.Module.GetMetadataReader()).ToString(), type); output.WriteReference(type.Handle.GetFullTypeName(type.Module.Metadata).ToString(), type);
} else { } else {
output.Write(DisassemblerHelpers.Escape(typeName)); output.Write(DisassemblerHelpers.Escape(typeName));
} }
@ -922,7 +926,7 @@ namespace ICSharpCode.Decompiler.Disassembler
void WriteParameterAttributes(PEFile module, ParameterHandle handle) void WriteParameterAttributes(PEFile module, ParameterHandle handle)
{ {
var metadata = module.GetMetadataReader(); var metadata = module.Metadata;
var p = metadata.GetParameter(handle); var p = metadata.GetParameter(handle);
if (p.GetDefaultValue().IsNil && p.GetCustomAttributes().Count == 0) if (p.GetDefaultValue().IsNil && p.GetCustomAttributes().Count == 0)
return; return;
@ -987,7 +991,7 @@ namespace ICSharpCode.Decompiler.Disassembler
public void DisassembleField(Metadata.FieldDefinition field) public void DisassembleField(Metadata.FieldDefinition field)
{ {
var metadata = field.Module.GetMetadataReader(); var metadata = field.Module.Metadata;
var fieldDefinition = metadata.GetFieldDefinition(field.Handle); var fieldDefinition = metadata.GetFieldDefinition(field.Handle);
output.WriteDefinition(".field ", field); output.WriteDefinition(".field ", field);
int offset = fieldDefinition.GetOffset(); int offset = fieldDefinition.GetOffset();
@ -1037,7 +1041,7 @@ namespace ICSharpCode.Decompiler.Disassembler
public void DisassembleProperty(Metadata.PropertyDefinition property) public void DisassembleProperty(Metadata.PropertyDefinition property)
{ {
var metadata = property.Module.GetMetadataReader(); var metadata = property.Module.Metadata;
var propertyDefinition = metadata.GetPropertyDefinition(property.Handle); var propertyDefinition = metadata.GetPropertyDefinition(property.Handle);
output.WriteDefinition(".property ", property); output.WriteDefinition(".property ", property);
WriteFlags(propertyDefinition.Attributes, propertyAttributes); WriteFlags(propertyDefinition.Attributes, propertyAttributes);
@ -1080,7 +1084,7 @@ namespace ICSharpCode.Decompiler.Disassembler
output.Write(keyword); output.Write(keyword);
output.Write(' '); output.Write(' ');
method.WriteTo(output); ((EntityHandle)method.Handle).WriteTo(method.Module, output, GenericContext.Empty);
output.WriteLine(); output.WriteLine();
} }
#endregion #endregion
@ -1091,10 +1095,10 @@ namespace ICSharpCode.Decompiler.Disassembler
{ EventAttributes.RTSpecialName, "rtspecialname" }, { EventAttributes.RTSpecialName, "rtspecialname" },
}; };
public void DisassembleEvent(Metadata.EventDefinition ev) public void DisassembleEvent(PEFile module, EventDefinitionHandle handle)
{ {
var metadata = ev.Module.GetMetadataReader(); var metadata = module.Metadata;
var eventDefinition = metadata.GetEventDefinition(ev.Handle); var eventDefinition = metadata.GetEventDefinition(handle);
var accessors = eventDefinition.GetAccessors(); var accessors = eventDefinition.GetAccessors();
TypeDefinitionHandle declaringType; TypeDefinitionHandle declaringType;
if (!accessors.Adder.IsNil) { if (!accessors.Adder.IsNil) {
@ -1104,17 +1108,17 @@ namespace ICSharpCode.Decompiler.Disassembler
} else { } else {
declaringType = metadata.GetMethodDefinition(accessors.Raiser).GetDeclaringType(); declaringType = metadata.GetMethodDefinition(accessors.Raiser).GetDeclaringType();
} }
output.WriteDefinition(".event ", ev); output.WriteDefinition(".event ", new Metadata.EventDefinition(module, handle));
WriteFlags(eventDefinition.Attributes, eventAttributes); WriteFlags(eventDefinition.Attributes, eventAttributes);
var signature = eventDefinition.DecodeSignature(metadata, new DisassemblerSignatureProvider(ev.Module, output), new GenericContext(declaringType, ev.Module)); var signature = eventDefinition.DecodeSignature(metadata, new DisassemblerSignatureProvider(module, output), new GenericContext(declaringType, module));
signature(ILNameSyntax.TypeName); signature(ILNameSyntax.TypeName);
output.Write(' '); output.Write(' ');
output.Write(DisassemblerHelpers.Escape(metadata.GetString(eventDefinition.Name))); output.Write(DisassemblerHelpers.Escape(metadata.GetString(eventDefinition.Name)));
OpenBlock(false); OpenBlock(false);
WriteAttributes(ev.Module, eventDefinition.GetCustomAttributes()); WriteAttributes(module, eventDefinition.GetCustomAttributes());
WriteNestedMethod(".addon", new Metadata.MethodDefinition(ev.Module, accessors.Adder)); WriteNestedMethod(".addon", new Metadata.MethodDefinition(module, accessors.Adder));
WriteNestedMethod(".removeon", new Metadata.MethodDefinition(ev.Module, accessors.Remover)); WriteNestedMethod(".removeon", new Metadata.MethodDefinition(module, accessors.Remover));
WriteNestedMethod(".fire", new Metadata.MethodDefinition(ev.Module, accessors.Raiser)); WriteNestedMethod(".fire", new Metadata.MethodDefinition(module, accessors.Raiser));
/*foreach (var method in ev.OtherMethods) { /*foreach (var method in ev.OtherMethods) {
WriteNestedMethod(".other", method); WriteNestedMethod(".other", method);
}*/ }*/
@ -1159,7 +1163,7 @@ namespace ICSharpCode.Decompiler.Disassembler
public void DisassembleType(Metadata.TypeDefinition type) public void DisassembleType(Metadata.TypeDefinition type)
{ {
var metadata = type.Module.GetMetadataReader(); var metadata = type.Module.Metadata;
var typeDefinition = metadata.GetTypeDefinition(type.Handle); var typeDefinition = metadata.GetTypeDefinition(type.Handle);
output.WriteDefinition(".class ", type); output.WriteDefinition(".class ", type);
@ -1209,7 +1213,7 @@ namespace ICSharpCode.Decompiler.Disassembler
isInType = true; isInType = true;
WriteAttributes(type.Module, typeDefinition.GetCustomAttributes()); WriteAttributes(type.Module, typeDefinition.GetCustomAttributes());
WriteSecurityDeclarations(type.Module, typeDefinition.GetDeclarativeSecurityAttributes()); WriteSecurityDeclarations(type.Module, typeDefinition.GetDeclarativeSecurityAttributes());
var layout = type.This().GetLayout(); var layout = typeDefinition.GetLayout();
if (!layout.IsDefault) { if (!layout.IsDefault) {
output.WriteLine(".pack {0}", layout.PackingSize); output.WriteLine(".pack {0}", layout.PackingSize);
output.WriteLine(".size {0}", layout.Size); output.WriteLine(".size {0}", layout.Size);
@ -1239,7 +1243,7 @@ namespace ICSharpCode.Decompiler.Disassembler
output.WriteLine("// Methods"); output.WriteLine("// Methods");
foreach (var m in methods) { foreach (var m in methods) {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
DisassembleMethod(new Metadata.MethodDefinition(type.Module, m)); DisassembleMethod(type.Module, m);
output.WriteLine(); output.WriteLine();
} }
} }
@ -1248,7 +1252,7 @@ namespace ICSharpCode.Decompiler.Disassembler
output.WriteLine("// Events"); output.WriteLine("// Events");
foreach (var ev in events) { foreach (var ev in events) {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
DisassembleEvent(new Metadata.EventDefinition(type.Module, ev)); DisassembleEvent(type.Module, ev);
output.WriteLine(); output.WriteLine();
} }
output.WriteLine(); output.WriteLine();
@ -1270,7 +1274,7 @@ namespace ICSharpCode.Decompiler.Disassembler
{ {
if (p.Count > 0) { if (p.Count > 0) {
output.Write('<'); output.Write('<');
var metadata = module.GetMetadataReader(); var metadata = module.Metadata;
for (int i = 0; i < p.Count; i++) { for (int i = 0; i < p.Count; i++) {
if (i > 0) if (i > 0)
output.Write(", "); output.Write(", ");
@ -1309,7 +1313,7 @@ namespace ICSharpCode.Decompiler.Disassembler
#region Helper methods #region Helper methods
void WriteAttributes(PEFile module, CustomAttributeHandleCollection attributes) void WriteAttributes(PEFile module, CustomAttributeHandleCollection attributes)
{ {
var metadata = module.GetMetadataReader(); var metadata = module.Metadata;
foreach (CustomAttributeHandle a in attributes) { foreach (CustomAttributeHandle a in attributes) {
output.Write(".custom "); output.Write(".custom ");
var attr = metadata.GetCustomAttribute(a); var attr = metadata.GetCustomAttribute(a);
@ -1436,7 +1440,7 @@ namespace ICSharpCode.Decompiler.Disassembler
public void WriteAssemblyHeader(PEFile module) public void WriteAssemblyHeader(PEFile module)
{ {
var metadata = module.GetMetadataReader(); var metadata = module.Metadata;
if (!metadata.IsAssembly) return; if (!metadata.IsAssembly) return;
output.Write(".assembly "); output.Write(".assembly ");
var asm = metadata.GetAssemblyDefinition(); var asm = metadata.GetAssemblyDefinition();
@ -1492,7 +1496,7 @@ namespace ICSharpCode.Decompiler.Disassembler
public void WriteModuleHeader(PEFile module, bool skipMVID = false) public void WriteModuleHeader(PEFile module, bool skipMVID = false)
{ {
var metadata = module.GetMetadataReader(); var metadata = module.Metadata;
void WriteExportedType(ExportedType exportedType) void WriteExportedType(ExportedType exportedType)
{ {
@ -1573,7 +1577,7 @@ namespace ICSharpCode.Decompiler.Disassembler
{ {
this.module = module ?? throw new ArgumentNullException(nameof(module)); this.module = module ?? throw new ArgumentNullException(nameof(module));
this.output = output ?? throw new ArgumentNullException(nameof(output)); this.output = output ?? throw new ArgumentNullException(nameof(output));
this.metadata = module.GetMetadataReader(); this.metadata = module.Metadata;
} }
public Action<ILNameSyntax> GetArrayType(Action<ILNameSyntax> elementType, ArrayShape shape) public Action<ILNameSyntax> GetArrayType(Action<ILNameSyntax> elementType, ArrayShape shape)
@ -1769,8 +1773,7 @@ namespace ICSharpCode.Decompiler.Disassembler
default: default:
throw new NotSupportedException($"rawTypeKind: {rawTypeKind} (0x{rawTypeKind:x})"); throw new NotSupportedException($"rawTypeKind: {rawTypeKind} (0x{rawTypeKind:x})");
} }
var td = new Metadata.TypeDefinition(module, handle); ((EntityHandle)handle).WriteTo(module, output, GenericContext.Empty);
td.WriteTo(output);
}; };
} }
@ -1789,8 +1792,7 @@ namespace ICSharpCode.Decompiler.Disassembler
default: default:
throw new NotSupportedException($"rawTypeKind: {rawTypeKind} (0x{rawTypeKind:x})"); throw new NotSupportedException($"rawTypeKind: {rawTypeKind} (0x{rawTypeKind:x})");
} }
var typeRef = new Metadata.TypeReference(module, handle); ((EntityHandle)handle).WriteTo(module, output, GenericContext.Empty);
typeRef.WriteTo(output);
}; };
} }

16
ICSharpCode.Decompiler/Documentation/XmlDocKeyProvider.cs

@ -37,7 +37,7 @@ namespace ICSharpCode.Decompiler.Documentation
#region GetKey #region GetKey
public static string GetKey(Entity entity) public static string GetKey(Entity entity)
{ {
return GetKey(entity.Module.GetMetadataReader(), entity.Handle); return GetKey(entity.Module.Metadata, entity.Handle);
} }
public static string GetKey(SRM.MetadataReader metadata, SRM.EntityHandle member) public static string GetKey(SRM.MetadataReader metadata, SRM.EntityHandle member)
@ -249,13 +249,13 @@ namespace ICSharpCode.Decompiler.Documentation
case 'T': case 'T':
return FindType(module, key.Substring(2)); return FindType(module, key.Substring(2));
case 'F': case 'F':
return FindMember(module, key, type => type.This().GetFields().Select(f => new Entity(module, f))); return FindMember(module, key, type => module.Metadata.GetTypeDefinition(type.Handle).GetFields().Select(f => new Entity(module, f)));
case 'P': case 'P':
return FindMember(module, key, type => type.This().GetProperties().Select(p => new Entity(module, p))); return FindMember(module, key, type => module.Metadata.GetTypeDefinition(type.Handle).GetProperties().Select(p => new Entity(module, p)));
case 'E': case 'E':
return FindMember(module, key, type => type.This().GetEvents().Select(e => new Entity(module, e))); return FindMember(module, key, type => module.Metadata.GetTypeDefinition(type.Handle).GetEvents().Select(e => new Entity(module, e)));
case 'M': case 'M':
return FindMember(module, key, type => type.This().GetMethods().Select(m => new Entity(module, m))); return FindMember(module, key, type => module.Metadata.GetTypeDefinition(type.Handle).GetMethods().Select(m => new Entity(module, m)));
default: default:
return default(Entity); return default(Entity);
} }
@ -282,9 +282,9 @@ namespace ICSharpCode.Decompiler.Documentation
} else { } else {
shortName = key.Substring(dotPos + 1); shortName = key.Substring(dotPos + 1);
} }
Debug.WriteLine("Searching in type {0} for {1}", type.Handle.GetFullTypeName(module.GetMetadataReader()), shortName); var metadata = module.Metadata;
Debug.WriteLine("Searching in type {0} for {1}", type.Handle.GetFullTypeName(metadata), shortName);
Entity shortNameMatch = default(Entity); Entity shortNameMatch = default(Entity);
var metadata = module.GetMetadataReader();
foreach (var member in memberSelector(type)) { foreach (var member in memberSelector(type)) {
string memberKey = GetKey(member); string memberKey = GetKey(member);
Debug.WriteLine(memberKey); Debug.WriteLine(memberKey);
@ -316,7 +316,7 @@ namespace ICSharpCode.Decompiler.Documentation
static TypeDefinition FindType(PEFile module, string name) static TypeDefinition FindType(PEFile module, string name)
{ {
var metadata = module.GetMetadataReader(); var metadata = module.Metadata;
string[] segments = name.Split('.'); string[] segments = name.Split('.');
var currentNamespace = metadata.GetNamespaceDefinitionRoot(); var currentNamespace = metadata.GetNamespaceDefinitionRoot();
int i = 0; int i = 0;

2
ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs

@ -48,7 +48,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
public static bool IsCompilerGeneratedMainMethod(Metadata.PEFile module, MethodDefinitionHandle method) public static bool IsCompilerGeneratedMainMethod(Metadata.PEFile module, MethodDefinitionHandle method)
{ {
var metadata = module.GetMetadataReader(); var metadata = module.Metadata;
var definition = metadata.GetMethodDefinition(method); var definition = metadata.GetMethodDefinition(method);
var entrypoint = System.Reflection.Metadata.Ecma335.MetadataTokens.MethodDefinitionHandle(module.Reader.PEHeaders.CorHeader.EntryPointTokenOrRelativeVirtualAddress); var entrypoint = System.Reflection.Metadata.Ecma335.MetadataTokens.MethodDefinitionHandle(module.Reader.PEHeaders.CorHeader.EntryPointTokenOrRelativeVirtualAddress);
return method == entrypoint && metadata.GetString(definition.Name).Equals("<Main>", StringComparison.Ordinal); return method == entrypoint && metadata.GetString(definition.Name).Equals("<Main>", StringComparison.Ordinal);

4
ICSharpCode.Decompiler/IL/ILReader.cs

@ -76,7 +76,7 @@ namespace ICSharpCode.Decompiler.IL
{ {
if (body == null) if (body == null)
throw new ArgumentNullException(nameof(body)); throw new ArgumentNullException(nameof(body));
this.metadata = module.GetMetadataReader(); this.metadata = module.Metadata;
this.method = typeSystem.ResolveAsMethod(methodDefinitionHandle); this.method = typeSystem.ResolveAsMethod(methodDefinitionHandle);
var methodDefinition = metadata.GetMethodDefinition(methodDefinitionHandle); var methodDefinition = metadata.GetMethodDefinition(methodDefinitionHandle);
this.methodSignature = methodDefinition.DecodeSignature(TypeSystem.Implementation.TypeReferenceSignatureDecoder.Instance, default); this.methodSignature = methodDefinition.DecodeSignature(TypeSystem.Implementation.TypeReferenceSignatureDecoder.Instance, default);
@ -432,7 +432,7 @@ namespace ICSharpCode.Decompiler.IL
output.WriteLine(); output.WriteLine();
} }
new Disassembler.MethodBodyDisassembler(output, cancellationToken) { DetectControlStructure = false } new Disassembler.MethodBodyDisassembler(output, cancellationToken) { DetectControlStructure = false }
.WriteExceptionHandlers(new Metadata.MethodDefinition(module, method), body); .WriteExceptionHandlers(module, method, body);
} }
/// <summary> /// <summary>

113
ICSharpCode.Decompiler/Metadata/Dom.cs

@ -84,6 +84,7 @@ namespace ICSharpCode.Decompiler.Metadata
public enum TargetRuntime public enum TargetRuntime
{ {
Unknown,
Net_1_0, Net_1_0,
Net_1_1, Net_1_1,
Net_2_0, Net_2_0,
@ -94,6 +95,7 @@ namespace ICSharpCode.Decompiler.Metadata
{ {
public string FileName { get; } public string FileName { get; }
public PEReader Reader { get; } public PEReader Reader { get; }
public MetadataReader Metadata { get; }
public IAssemblyResolver AssemblyResolver { get; } public IAssemblyResolver AssemblyResolver { get; }
public IAssemblyDocumentationResolver DocumentationResolver { get; set; } public IAssemblyDocumentationResolver DocumentationResolver { get; set; }
public IDebugInfoProvider DebugInfo { get; set; } public IDebugInfoProvider DebugInfo { get; set; }
@ -102,6 +104,7 @@ namespace ICSharpCode.Decompiler.Metadata
{ {
this.FileName = fileName; this.FileName = fileName;
this.Reader = new PEReader(stream, options); this.Reader = new PEReader(stream, options);
this.Metadata = Reader.GetMetadataReader();
this.AssemblyResolver = new UniversalAssemblyResolver(fileName, throwOnResolveError, Reader.DetectTargetFrameworkId(), options); this.AssemblyResolver = new UniversalAssemblyResolver(fileName, throwOnResolveError, Reader.DetectTargetFrameworkId(), options);
} }
@ -109,16 +112,17 @@ namespace ICSharpCode.Decompiler.Metadata
{ {
this.FileName = fileName; this.FileName = fileName;
this.Reader = new PEReader(stream, options); this.Reader = new PEReader(stream, options);
this.Metadata = Reader.GetMetadataReader();
this.AssemblyResolver = assemblyResolver; this.AssemblyResolver = assemblyResolver;
} }
public bool IsAssembly => GetMetadataReader().IsAssembly; public bool IsAssembly => Metadata.IsAssembly;
public string Name => GetName(); public string Name => GetName();
public string FullName => IsAssembly ? GetMetadataReader().GetFullAssemblyName() : Name; public string FullName => IsAssembly ? Metadata.GetFullAssemblyName() : Name;
public TargetRuntime GetRuntime() public TargetRuntime GetRuntime()
{ {
string version = GetMetadataReader().MetadataVersion; string version = Metadata.MetadataVersion;
switch (version[1]) { switch (version[1]) {
case '1': case '1':
if (version[3] == 1) if (version[3] == 1)
@ -130,29 +134,27 @@ namespace ICSharpCode.Decompiler.Metadata
case '4': case '4':
return TargetRuntime.Net_4_0; return TargetRuntime.Net_4_0;
default: default:
throw new NotSupportedException($"metadata version {version} is not supported!"); return TargetRuntime.Unknown;
} }
} }
public MetadataReader GetMetadataReader() => Reader.GetMetadataReader();
string GetName() string GetName()
{ {
var metadata = GetMetadataReader(); var metadata = Metadata;
if (metadata.IsAssembly) if (metadata.IsAssembly)
return metadata.GetString(metadata.GetAssemblyDefinition().Name); return metadata.GetString(metadata.GetAssemblyDefinition().Name);
return metadata.GetString(metadata.GetModuleDefinition().Name); return metadata.GetString(metadata.GetModuleDefinition().Name);
} }
public ImmutableArray<AssemblyReference> AssemblyReferences => GetMetadataReader().AssemblyReferences.Select(r => new AssemblyReference(this, r)).ToImmutableArray(); public ImmutableArray<AssemblyReference> AssemblyReferences => Metadata.AssemblyReferences.Select(r => new AssemblyReference(this, r)).ToImmutableArray();
public ImmutableArray<ModuleReferenceHandle> ModuleReferences => GetMetadataReader().GetModuleReferences().ToImmutableArray(); public ImmutableArray<ModuleReferenceHandle> ModuleReferences => Metadata.GetModuleReferences().ToImmutableArray();
public ImmutableArray<TypeDefinition> TypeDefinitions => Reader.GetMetadataReader().GetTopLevelTypeDefinitions().Select(t => new TypeDefinition(this, t)).ToImmutableArray(); public ImmutableArray<TypeDefinition> TypeDefinitions => Metadata.GetTopLevelTypeDefinitions().Select(t => new TypeDefinition(this, t)).ToImmutableArray();
public ImmutableArray<Resource> Resources => GetResources().ToImmutableArray(); public ImmutableArray<Resource> Resources => GetResources().ToImmutableArray();
IEnumerable<Resource> GetResources() IEnumerable<Resource> GetResources()
{ {
var metadata = GetMetadataReader(); var metadata = Metadata;
foreach (var h in metadata.ManifestResources) { foreach (var h in metadata.ManifestResources) {
yield return new Resource(this, h); yield return new Resource(this, h);
} }
@ -183,7 +185,7 @@ namespace ICSharpCode.Decompiler.Metadata
this.Handle = handle; this.Handle = handle;
} }
ManifestResource This() => Module.GetMetadataReader().GetManifestResource(Handle); ManifestResource This() => Module.Metadata.GetManifestResource(Handle);
public bool Equals(Resource other) public bool Equals(Resource other)
{ {
@ -205,7 +207,7 @@ namespace ICSharpCode.Decompiler.Metadata
public static bool operator ==(Resource lhs, Resource rhs) => lhs.Equals(rhs); public static bool operator ==(Resource lhs, Resource rhs) => lhs.Equals(rhs);
public static bool operator !=(Resource lhs, Resource rhs) => !lhs.Equals(rhs); public static bool operator !=(Resource lhs, Resource rhs) => !lhs.Equals(rhs);
public string Name => Module.GetMetadataReader().GetString(This().Name); public string Name => Module.Metadata.GetString(This().Name);
public ManifestResourceAttributes Attributes => This().Attributes; public ManifestResourceAttributes Attributes => This().Attributes;
public bool HasFlag(ManifestResourceAttributes flag) => (Attributes & flag) == flag; public bool HasFlag(ManifestResourceAttributes flag) => (Attributes & flag) == flag;
@ -343,15 +345,15 @@ namespace ICSharpCode.Decompiler.Metadata
public AssemblyReferenceHandle Handle { get; } public AssemblyReferenceHandle Handle { get; }
public bool IsNil => Handle.IsNil; public bool IsNil => Handle.IsNil;
SRMAssemblyReference This() => Module.GetMetadataReader().GetAssemblyReference(Handle); SRMAssemblyReference This() => Module.Metadata.GetAssemblyReference(Handle);
public bool IsWindowsRuntime => (This().Flags & AssemblyFlags.WindowsRuntime) != 0; public bool IsWindowsRuntime => (This().Flags & AssemblyFlags.WindowsRuntime) != 0;
public bool IsRetargetable => (This().Flags & AssemblyFlags.Retargetable) != 0; public bool IsRetargetable => (This().Flags & AssemblyFlags.Retargetable) != 0;
public string Name => Module.GetMetadataReader().GetString(This().Name); public string Name => Module.Metadata.GetString(This().Name);
public string FullName => This().GetFullAssemblyName(Module.GetMetadataReader()); public string FullName => This().GetFullAssemblyName(Module.Metadata);
public Version Version => This().Version; public Version Version => This().Version;
public string Culture => Module.GetMetadataReader().GetString(This().Culture); public string Culture => Module.Metadata.GetString(This().Culture);
byte[] IAssemblyReference.PublicKeyToken => GetPublicKeyToken(); byte[] IAssemblyReference.PublicKeyToken => GetPublicKeyToken();
public byte[] GetPublicKeyToken() public byte[] GetPublicKeyToken()
@ -359,7 +361,7 @@ namespace ICSharpCode.Decompiler.Metadata
var inst = This(); var inst = This();
if (inst.PublicKeyOrToken.IsNil) if (inst.PublicKeyOrToken.IsNil)
return Empty<byte>.Array; return Empty<byte>.Array;
var bytes = Module.GetMetadataReader().GetBlobBytes(inst.PublicKeyOrToken); var bytes = Module.Metadata.GetBlobBytes(inst.PublicKeyOrToken);
if ((inst.Flags & AssemblyFlags.PublicKey) != 0) { if ((inst.Flags & AssemblyFlags.PublicKey) != 0) {
return sha1.ComputeHash(bytes).Skip(12).ToArray(); return sha1.ComputeHash(bytes).Skip(12).ToArray();
} }
@ -506,8 +508,6 @@ namespace ICSharpCode.Decompiler.Metadata
this.Handle = handle; this.Handle = handle;
} }
public SRMMethod This() => Module.GetMetadataReader().GetMethodDefinition(Handle);
public bool Equals(MethodDefinition other) public bool Equals(MethodDefinition other)
{ {
return Module == other.Module && Handle == other.Handle; return Module == other.Module && Handle == other.Handle;
@ -552,8 +552,6 @@ namespace ICSharpCode.Decompiler.Metadata
this.Handle = handle; this.Handle = handle;
} }
public SRMProperty This() => Module.GetMetadataReader().GetPropertyDefinition(Handle);
public bool Equals(PropertyDefinition other) public bool Equals(PropertyDefinition other)
{ {
return Module == other.Module && Handle == other.Handle; return Module == other.Module && Handle == other.Handle;
@ -588,8 +586,6 @@ namespace ICSharpCode.Decompiler.Metadata
this.Handle = handle; this.Handle = handle;
} }
public SRMField This() => Module.GetMetadataReader().GetFieldDefinition(Handle);
public bool Equals(FieldDefinition other) public bool Equals(FieldDefinition other)
{ {
return Module == other.Module && Handle == other.Handle; return Module == other.Module && Handle == other.Handle;
@ -612,8 +608,8 @@ namespace ICSharpCode.Decompiler.Metadata
public object DecodeConstant() public object DecodeConstant()
{ {
var metadata = Module.GetMetadataReader(); var metadata = Module.Metadata;
var constant = metadata.GetConstant(This().GetDefaultValue()); var constant = metadata.GetConstant(metadata.GetFieldDefinition(Handle).GetDefaultValue());
var blob = metadata.GetBlobReader(constant.Value); var blob = metadata.GetBlobReader(constant.Value);
switch (constant.TypeCode) { switch (constant.TypeCode) {
case ConstantTypeCode.Boolean: case ConstantTypeCode.Boolean:
@ -663,8 +659,6 @@ namespace ICSharpCode.Decompiler.Metadata
this.Handle = handle; this.Handle = handle;
} }
public SRMEvent This() => Module.GetMetadataReader().GetEventDefinition(Handle);
public bool Equals(EventDefinition other) public bool Equals(EventDefinition other)
{ {
return Module == other.Module && Handle == other.Handle; return Module == other.Module && Handle == other.Handle;
@ -700,8 +694,6 @@ namespace ICSharpCode.Decompiler.Metadata
this.Handle = handle; this.Handle = handle;
} }
public SRMTypeDef This() => Module.GetMetadataReader().GetTypeDefinition(Handle);
public bool Equals(TypeDefinition other) public bool Equals(TypeDefinition other)
{ {
return Module == other.Module && Handle == other.Handle; return Module == other.Module && Handle == other.Handle;
@ -734,30 +726,6 @@ namespace ICSharpCode.Decompiler.Metadata
this.Module = module ?? throw new ArgumentNullException(nameof(module)); this.Module = module ?? throw new ArgumentNullException(nameof(module));
this.Handle = handle; this.Handle = handle;
} }
SRMTypeRef This() => Module.GetMetadataReader().GetTypeReference(Handle);
public string Name {
get {
var reader = Module.GetMetadataReader();
return reader.GetString(This().Name);
}
}
public FullTypeName FullName {
get {
return Handle.GetFullTypeName(Module.GetMetadataReader());
}
}
public string Namespace => throw new NotImplementedException();
public EntityHandle ResolutionScope => This().ResolutionScope;
public TypeDefinition GetDefinition()
{
return MetadataResolver.Resolve(Handle, new SimpleMetadataResolveContext(Module));
}
} }
public struct TypeSpecification public struct TypeSpecification
@ -771,28 +739,6 @@ namespace ICSharpCode.Decompiler.Metadata
this.Module = module ?? throw new ArgumentNullException(nameof(module)); this.Module = module ?? throw new ArgumentNullException(nameof(module));
this.Handle = handle; this.Handle = handle;
} }
SRMTypeSpec This() => Module.GetMetadataReader().GetTypeSpecification(Handle);
public FullTypeName FullName {
get {
return DecodeSignature(new FullTypeNameSignatureDecoder(Module.GetMetadataReader()), default);
}
}
public string Name => FullName.Name;
public string Namespace => FullName.TopLevelTypeName.Namespace;
public TypeDefinition GetDefinition()
{
return MetadataResolver.Resolve(Handle, new SimpleMetadataResolveContext(Module));
}
public TType DecodeSignature<TType, TGenericContext>(ISignatureTypeProvider<TType, TGenericContext> provider, TGenericContext genericContext)
{
return This().DecodeSignature(provider, genericContext);
}
} }
public struct MethodSpecification public struct MethodSpecification
@ -814,8 +760,6 @@ namespace ICSharpCode.Decompiler.Metadata
public MemberReferenceHandle Handle { get; } public MemberReferenceHandle Handle { get; }
public bool IsNil => Handle.IsNil; public bool IsNil => Handle.IsNil;
SRMMemberRef This() => Module.GetMetadataReader().GetMemberReference(Handle);
public MemberReference(PEFile module, MemberReferenceHandle handle) public MemberReference(PEFile module, MemberReferenceHandle handle)
{ {
this.Module = module ?? throw new ArgumentNullException(nameof(module)); this.Module = module ?? throw new ArgumentNullException(nameof(module));
@ -906,7 +850,6 @@ namespace ICSharpCode.Decompiler.Metadata
public class GenericContext public class GenericContext
{ {
readonly PEFile module; readonly PEFile module;
readonly MetadataReader metadata;
readonly TypeDefinitionHandle declaringType; readonly TypeDefinitionHandle declaringType;
readonly MethodDefinitionHandle method; readonly MethodDefinitionHandle method;
@ -917,9 +860,8 @@ namespace ICSharpCode.Decompiler.Metadata
public GenericContext(MethodDefinitionHandle method, PEFile module) public GenericContext(MethodDefinitionHandle method, PEFile module)
{ {
this.module = module; this.module = module;
this.metadata = module.GetMetadataReader();
this.method = method; this.method = method;
this.declaringType = metadata.GetMethodDefinition(method).GetDeclaringType(); this.declaringType = module.Metadata.GetMethodDefinition(method).GetDeclaringType();
} }
public GenericContext(MethodDefinition method) public GenericContext(MethodDefinition method)
@ -930,7 +872,6 @@ namespace ICSharpCode.Decompiler.Metadata
public GenericContext(TypeDefinitionHandle declaringType, PEFile module) public GenericContext(TypeDefinitionHandle declaringType, PEFile module)
{ {
this.module = module; this.module = module;
this.metadata = module.GetMetadataReader();
this.declaringType = declaringType; this.declaringType = declaringType;
} }
@ -944,7 +885,7 @@ namespace ICSharpCode.Decompiler.Metadata
GenericParameterHandle genericParameter = GetGenericTypeParameterHandleOrNull(index); GenericParameterHandle genericParameter = GetGenericTypeParameterHandleOrNull(index);
if (genericParameter.IsNil) if (genericParameter.IsNil)
return index.ToString(); return index.ToString();
return metadata.GetString(metadata.GetGenericParameter(genericParameter).Name); return module.Metadata.GetString(module.Metadata.GetGenericParameter(genericParameter).Name);
} }
public string GetGenericMethodTypeParameterName(int index) public string GetGenericMethodTypeParameterName(int index)
@ -952,13 +893,13 @@ namespace ICSharpCode.Decompiler.Metadata
GenericParameterHandle genericParameter = GetGenericMethodTypeParameterHandleOrNull(index); GenericParameterHandle genericParameter = GetGenericMethodTypeParameterHandleOrNull(index);
if (genericParameter.IsNil) if (genericParameter.IsNil)
return index.ToString(); return index.ToString();
return metadata.GetString(metadata.GetGenericParameter(genericParameter).Name); return module.Metadata.GetString(module.Metadata.GetGenericParameter(genericParameter).Name);
} }
public GenericParameterHandle GetGenericTypeParameterHandleOrNull(int index) public GenericParameterHandle GetGenericTypeParameterHandleOrNull(int index)
{ {
GenericParameterHandleCollection genericParameters; GenericParameterHandleCollection genericParameters;
if (declaringType.IsNil || index < 0 || index >= (genericParameters = metadata.GetTypeDefinition(declaringType).GetGenericParameters()).Count) if (declaringType.IsNil || index < 0 || index >= (genericParameters = module.Metadata.GetTypeDefinition(declaringType).GetGenericParameters()).Count)
return MetadataTokens.GenericParameterHandle(0); return MetadataTokens.GenericParameterHandle(0);
return genericParameters[index]; return genericParameters[index];
} }
@ -966,7 +907,7 @@ namespace ICSharpCode.Decompiler.Metadata
public GenericParameterHandle GetGenericMethodTypeParameterHandleOrNull(int index) public GenericParameterHandle GetGenericMethodTypeParameterHandleOrNull(int index)
{ {
GenericParameterHandleCollection genericParameters; GenericParameterHandleCollection genericParameters;
if (method.IsNil || index < 0 || index >= (genericParameters = metadata.GetMethodDefinition(method).GetGenericParameters()).Count) if (method.IsNil || index < 0 || index >= (genericParameters = module.Metadata.GetMethodDefinition(method).GetGenericParameters()).Count)
return MetadataTokens.GenericParameterHandle(0); return MetadataTokens.GenericParameterHandle(0);
return genericParameters[index]; return genericParameters[index];
} }

2
ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs

@ -158,7 +158,7 @@ namespace ICSharpCode.Decompiler.Metadata
public static bool HasMatchingDefaultMemberAttribute(this PropertyDefinitionHandle handle, PEFile module, out CustomAttributeHandle defaultMemberAttribute) public static bool HasMatchingDefaultMemberAttribute(this PropertyDefinitionHandle handle, PEFile module, out CustomAttributeHandle defaultMemberAttribute)
{ {
defaultMemberAttribute = default(CustomAttributeHandle); defaultMemberAttribute = default(CustomAttributeHandle);
var metadata = module.GetMetadataReader(); var metadata = module.Metadata;
var propertyDefinition = metadata.GetPropertyDefinition(handle); var propertyDefinition = metadata.GetPropertyDefinition(handle);
var accessorHandle = propertyDefinition.GetAccessors().GetAny(); var accessorHandle = propertyDefinition.GetAccessors().GetAny();
var accessor = metadata.GetMethodDefinition(accessorHandle); var accessor = metadata.GetMethodDefinition(accessorHandle);

12
ICSharpCode.Decompiler/Metadata/MetadataResolver.cs

@ -64,7 +64,7 @@ namespace ICSharpCode.Decompiler.Metadata
return new MethodDefinition(context.CurrentModule, (MethodDefinitionHandle)handle); return new MethodDefinition(context.CurrentModule, (MethodDefinitionHandle)handle);
case HandleKind.MemberReference: case HandleKind.MemberReference:
var memberRefHandle = (MemberReferenceHandle)handle; var memberRefHandle = (MemberReferenceHandle)handle;
var metadata = context.CurrentModule.GetMetadataReader(); var metadata = context.CurrentModule.Metadata;
var memberRef = metadata.GetMemberReference(memberRefHandle); var memberRef = metadata.GetMemberReference(memberRefHandle);
if (memberRef.GetKind() != MemberReferenceKind.Method) if (memberRef.GetKind() != MemberReferenceKind.Method)
return default; return default;
@ -80,7 +80,7 @@ namespace ICSharpCode.Decompiler.Metadata
return new FieldDefinition(context.CurrentModule, (FieldDefinitionHandle)handle); return new FieldDefinition(context.CurrentModule, (FieldDefinitionHandle)handle);
case HandleKind.MemberReference: case HandleKind.MemberReference:
var memberRefHandle = (MemberReferenceHandle)handle; var memberRefHandle = (MemberReferenceHandle)handle;
var metadata = context.CurrentModule.GetMetadataReader(); var metadata = context.CurrentModule.Metadata;
var memberRef = metadata.GetMemberReference(memberRefHandle); var memberRef = metadata.GetMemberReference(memberRefHandle);
if (memberRef.GetKind() != MemberReferenceKind.Field) if (memberRef.GetKind() != MemberReferenceKind.Field)
throw new ArgumentException("MemberReferenceKind must be Field!", nameof(handle)); throw new ArgumentException("MemberReferenceKind must be Field!", nameof(handle));
@ -95,7 +95,7 @@ namespace ICSharpCode.Decompiler.Metadata
/// </summary> /// </summary>
public static TypeDefinition Resolve(this TypeReferenceHandle handle, IMetadataResolveContext context) public static TypeDefinition Resolve(this TypeReferenceHandle handle, IMetadataResolveContext context)
{ {
var metadata = context.CurrentModule.GetMetadataReader(); var metadata = context.CurrentModule.Metadata;
var tr = metadata.GetTypeReference(handle); var tr = metadata.GetTypeReference(handle);
if (tr.ResolutionScope.IsNil) { if (tr.ResolutionScope.IsNil) {
foreach (var h in metadata.ExportedTypes) { foreach (var h in metadata.ExportedTypes) {
@ -113,7 +113,7 @@ namespace ICSharpCode.Decompiler.Metadata
break; break;
case HandleKind.AssemblyReference: case HandleKind.AssemblyReference:
var module = context.ResolveAssembly(new AssemblyReference(context.CurrentModule, (AssemblyReferenceHandle)tr.ResolutionScope)); var module = context.ResolveAssembly(new AssemblyReference(context.CurrentModule, (AssemblyReferenceHandle)tr.ResolutionScope));
var moduleMetadata = module.GetMetadataReader(); var moduleMetadata = module.Metadata;
var @namespace = ResolveNamespace(moduleMetadata, metadata.GetString(tr.Namespace).Split('.')); var @namespace = ResolveNamespace(moduleMetadata, metadata.GetString(tr.Namespace).Split('.'));
if (@namespace == null) if (@namespace == null)
throw new NotSupportedException(); throw new NotSupportedException();
@ -150,7 +150,7 @@ namespace ICSharpCode.Decompiler.Metadata
public static IMetadataEntity Resolve(MemberReferenceHandle handle, IMetadataResolveContext context) public static IMetadataEntity Resolve(MemberReferenceHandle handle, IMetadataResolveContext context)
{ {
var metadata = context.CurrentModule.GetMetadataReader(); var metadata = context.CurrentModule.Metadata;
var mr = metadata.GetMemberReference(handle); var mr = metadata.GetMemberReference(handle);
TypeDefinition declaringType; TypeDefinition declaringType;
switch (mr.Parent.Kind) { switch (mr.Parent.Kind) {
@ -189,7 +189,7 @@ namespace ICSharpCode.Decompiler.Metadata
public static TypeDefinition Resolve(TypeSpecificationHandle handle, IMetadataResolveContext context) public static TypeDefinition Resolve(TypeSpecificationHandle handle, IMetadataResolveContext context)
{ {
var metadata = context.CurrentModule.GetMetadataReader(); var metadata = context.CurrentModule.Metadata;
var ts = metadata.GetTypeSpecification(handle); var ts = metadata.GetTypeSpecification(handle);
var unspecialized = ts.DecodeSignature(new Unspecializer(), default(Unit)); var unspecialized = ts.DecodeSignature(new Unspecializer(), default(Unit));
switch (unspecialized.Kind) { switch (unspecialized.Kind) {

2
ICSharpCode.Decompiler/Pdb/PortablePdbWriter.cs

@ -33,7 +33,7 @@ namespace ICSharpCode.Decompiler.Pdb
public static void WritePdb(PEFile file, CSharpDecompiler decompiler, DecompilerSettings settings, Stream targetStream) public static void WritePdb(PEFile file, CSharpDecompiler decompiler, DecompilerSettings settings, Stream targetStream)
{ {
MetadataBuilder metadata = new MetadataBuilder(); MetadataBuilder metadata = new MetadataBuilder();
MetadataReader reader = file.GetMetadataReader(); MetadataReader reader = file.Metadata;
var entrypointHandle = MetadataTokens.MethodDefinitionHandle(file.Reader.PEHeaders.CorHeader.EntryPointTokenOrRelativeVirtualAddress); var entrypointHandle = MetadataTokens.MethodDefinitionHandle(file.Reader.PEHeaders.CorHeader.EntryPointTokenOrRelativeVirtualAddress);
var hasher = SHA256.Create(); var hasher = SHA256.Create();

2
ICSharpCode.Decompiler/SRMHacks.cs

@ -50,7 +50,7 @@ namespace ICSharpCode.Decompiler
/* /*
internal static unsafe ImmutableArray<(MethodSemanticsAttributes Kind, MethodDefinition Method)> GetAccessors(PEFile module, uint encodedTag) internal static unsafe ImmutableArray<(MethodSemanticsAttributes Kind, MethodDefinition Method)> GetAccessors(PEFile module, uint encodedTag)
{ {
var reader = module.GetMetadataReader(); var reader = Module.Metadata;
byte* startPointer = reader.MetadataPointer; byte* startPointer = reader.MetadataPointer;
int offset = reader.GetTableMetadataOffset(TableIndex.MethodSemantics); int offset = reader.GetTableMetadataOffset(TableIndex.MethodSemantics);

16
ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs

@ -53,7 +53,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
var asm = moduleDefinition.AssemblyResolver.Resolve(asmRef); var asm = moduleDefinition.AssemblyResolver.Resolve(asmRef);
if (asm != null) { if (asm != null) {
referencedAssemblies.Add(cecilLoader.LoadModule(asm)); referencedAssemblies.Add(cecilLoader.LoadModule(asm));
var metadata = asm.GetMetadataReader(); var metadata = asm.Metadata;
foreach (var h in metadata.ExportedTypes) { foreach (var h in metadata.ExportedTypes) {
var forwarder = metadata.GetExportedType(h); var forwarder = metadata.GetExportedType(h);
if (!forwarder.IsForwarder || forwarder.Implementation.Kind != SRM.HandleKind.AssemblyReference) continue; if (!forwarder.IsForwarder || forwarder.Implementation.Kind != SRM.HandleKind.AssemblyReference) continue;
@ -83,7 +83,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
get { return moduleDefinition; } get { return moduleDefinition; }
} }
public SRM.MetadataReader GetMetadata() => moduleDefinition.GetMetadataReader(); public SRM.MetadataReader GetMetadata() => moduleDefinition.Metadata;
public IType ResolveFromSignature(ITypeReference typeReference) public IType ResolveFromSignature(ITypeReference typeReference)
{ {
@ -98,7 +98,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
case SRM.HandleKind.MethodDefinition: case SRM.HandleKind.MethodDefinition:
return ResolveAsMethod(memberReference); return ResolveAsMethod(memberReference);
case SRM.HandleKind.MemberReference: case SRM.HandleKind.MemberReference:
var mr = moduleDefinition.GetMetadataReader().GetMemberReference((SRM.MemberReferenceHandle)memberReference); var mr = moduleDefinition.Metadata.GetMemberReference((SRM.MemberReferenceHandle)memberReference);
switch (mr.GetKind()) { switch (mr.GetKind()) {
case SRM.MemberReferenceKind.Method: case SRM.MemberReferenceKind.Method:
return ResolveAsMethod(memberReference); return ResolveAsMethod(memberReference);
@ -139,7 +139,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
lock (fieldLookupCache) { lock (fieldLookupCache) {
IField field; IField field;
if (!fieldLookupCache.TryGetValue(fieldReference, out field)) { if (!fieldLookupCache.TryGetValue(fieldReference, out field)) {
var metadata = moduleDefinition.GetMetadataReader(); var metadata = moduleDefinition.Metadata;
IType declaringType; IType declaringType;
ITypeReference returnType; ITypeReference returnType;
switch (fieldReference.Kind) { switch (fieldReference.Kind) {
@ -226,7 +226,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
IReadOnlyList<IType> methodTypeArguments = null; IReadOnlyList<IType> methodTypeArguments = null;
SRM.MethodSignature<ITypeReference>? signature = null; SRM.MethodSignature<ITypeReference>? signature = null;
if (!methodLookupCache.TryGetValue(methodReference, out method)) { if (!methodLookupCache.TryGetValue(methodReference, out method)) {
var metadata = moduleDefinition.GetMetadataReader(); var metadata = moduleDefinition.Metadata;
switch (methodReference.Kind) { switch (methodReference.Kind) {
case SRM.HandleKind.MethodDefinition: case SRM.HandleKind.MethodDefinition:
var methodDef = metadata.GetMethodDefinition((SRM.MethodDefinitionHandle)methodReference); var methodDef = metadata.GetMethodDefinition((SRM.MethodDefinitionHandle)methodReference);
@ -381,7 +381,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
m.IsStatic = !signature.Header.IsInstance; m.IsStatic = !signature.Header.IsInstance;
lock (typeReferenceCecilLoader) { lock (typeReferenceCecilLoader) {
var metadata = moduleDefinition.GetMetadataReader(); var metadata = moduleDefinition.Metadata;
for (int i = 0; i < signature.GenericParameterCount; i++) { for (int i = 0; i < signature.GenericParameterCount; i++) {
m.TypeParameters.Add(new DefaultUnresolvedTypeParameter(SymbolKind.Method, i, "")); m.TypeParameters.Add(new DefaultUnresolvedTypeParameter(SymbolKind.Method, i, ""));
} }
@ -419,7 +419,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
lock (propertyLookupCache) { lock (propertyLookupCache) {
IProperty property; IProperty property;
if (!propertyLookupCache.TryGetValue(propertyReference, out property)) { if (!propertyLookupCache.TryGetValue(propertyReference, out property)) {
var metadata = moduleDefinition.GetMetadataReader(); var metadata = moduleDefinition.Metadata;
property = FindNonGenericProperty(metadata, (SRM.PropertyDefinitionHandle)propertyReference); property = FindNonGenericProperty(metadata, (SRM.PropertyDefinitionHandle)propertyReference);
/*if (propertyReference.DeclaringType.IsGenericInstance) { /*if (propertyReference.DeclaringType.IsGenericInstance) {
var git = (GenericInstanceType)propertyReference.DeclaringType; var git = (GenericInstanceType)propertyReference.DeclaringType;
@ -457,7 +457,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
lock (eventLookupCache) { lock (eventLookupCache) {
IEvent ev; IEvent ev;
if (!eventLookupCache.TryGetValue(eventReference, out ev)) { if (!eventLookupCache.TryGetValue(eventReference, out ev)) {
var metadata = moduleDefinition.GetMetadataReader(); var metadata = moduleDefinition.Metadata;
ev = FindNonGenericEvent(metadata, (SRM.EventDefinitionHandle)eventReference); ev = FindNonGenericEvent(metadata, (SRM.EventDefinitionHandle)eventReference);
/*if (eventReference.DeclaringType.IsGenericInstance) { /*if (eventReference.DeclaringType.IsGenericInstance) {
var git = (GenericInstanceType)eventReference.DeclaringType; var git = (GenericInstanceType)eventReference.DeclaringType;

6
ICSharpCode.Decompiler/TypeSystem/MetadataLoader.cs

@ -148,7 +148,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
public IUnresolvedAssembly LoadModule(Metadata.PEFile module) public IUnresolvedAssembly LoadModule(Metadata.PEFile module)
{ {
this.currentModule = module; this.currentModule = module;
this.currentMetadata = module.GetMetadataReader(); this.currentMetadata = module.Metadata;
// Read assembly and module attributes // Read assembly and module attributes
IList<IUnresolvedAttribute> assemblyAttributes = new List<IUnresolvedAttribute>(); IList<IUnresolvedAttribute> assemblyAttributes = new List<IUnresolvedAttribute>();
@ -253,7 +253,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
public void SetCurrentModule(Metadata.PEFile module) public void SetCurrentModule(Metadata.PEFile module)
{ {
this.currentModule = module; this.currentModule = module;
this.currentMetadata = module.GetMetadataReader(); this.currentMetadata = module.Metadata;
} }
/// <summary> /// <summary>
@ -1013,7 +1013,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
{ {
this.loader = loader; this.loader = loader;
this.module = module; this.module = module;
this.metadata = module.GetMetadataReader(); this.metadata = module.Metadata;
this.MetadataToken = typeDefinition; this.MetadataToken = typeDefinition;
this.SymbolKind = SymbolKind.TypeDefinition; this.SymbolKind = SymbolKind.TypeDefinition;
var td = metadata.GetTypeDefinition(typeDefinition); var td = metadata.GetTypeDefinition(typeDefinition);

2
ILSpy.BamlDecompiler/ConnectMethodDecompiler.cs

@ -39,7 +39,7 @@ namespace ILSpy.BamlDecompiler
if (typeDefinition.IsNil) if (typeDefinition.IsNil)
return result; return result;
var metadata = module.GetMetadataReader(); var metadata = Module.Metadata;
TypeDefinition type = metadata.GetTypeDefinition(typeDefinition.Handle); TypeDefinition type = metadata.GetTypeDefinition(typeDefinition.Handle);
MethodDefinition method = default; MethodDefinition method = default;

2
ILSpy/DebugInfo/DiaSymNativeDebugInfoProvider.cs

@ -44,7 +44,7 @@ namespace ICSharpCode.ILSpy.DebugInfo
this.module = module; this.module = module;
this.pdbFileName = pdbFileName; this.pdbFileName = pdbFileName;
this.stream = stream; this.stream = stream;
this.metadata = module.GetMetadataReader(); this.metadata = module.Metadata;
this.reader = SymUnmanagedReaderFactory.CreateReader<ISymUnmanagedReader5>(stream, this); this.reader = SymUnmanagedReaderFactory.CreateReader<ISymUnmanagedReader5>(stream, this);
} }

17
ILSpy/Languages/CSharpILMixedLanguage.cs

@ -22,6 +22,7 @@ using System.ComponentModel.Composition;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection.Metadata;
using System.Threading; using System.Threading;
using System.Windows; using System.Windows;
using System.Windows.Media; using System.Windows.Media;
@ -37,6 +38,8 @@ using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.ILSpy namespace ICSharpCode.ILSpy
{ {
using SequencePoint = ICSharpCode.Decompiler.Metadata.SequencePoint;
[Export(typeof(Language))] [Export(typeof(Language))]
class CSharpILMixedLanguage : ILLanguage class CSharpILMixedLanguage : ILLanguage
{ {
@ -81,24 +84,24 @@ namespace ICSharpCode.ILSpy
this.options = options; this.options = options;
} }
public override void Disassemble(MethodDefinition method) public override void Disassemble(PEFile module, MethodDefinitionHandle handle)
{ {
try { try {
var csharpOutput = new StringWriter(); var csharpOutput = new StringWriter();
CSharpDecompiler decompiler = CreateDecompiler(method.Module, options); CSharpDecompiler decompiler = CreateDecompiler(module, options);
var st = decompiler.Decompile(method.Handle); var st = decompiler.Decompile(handle);
WriteCode(csharpOutput, options.DecompilerSettings, st, decompiler.TypeSystem); WriteCode(csharpOutput, options.DecompilerSettings, st, decompiler.TypeSystem);
var mapping = decompiler.CreateSequencePoints(st).FirstOrDefault(kvp => kvp.Key.Method.MetadataToken == method.Handle); var mapping = decompiler.CreateSequencePoints(st).FirstOrDefault(kvp => kvp.Key.Method.MetadataToken == handle);
this.sequencePoints = mapping.Value ?? (IList<SequencePoint>)EmptyList<SequencePoint>.Instance; this.sequencePoints = mapping.Value ?? (IList<SequencePoint>)EmptyList<SequencePoint>.Instance;
this.codeLines = csharpOutput.ToString().Split(new[] { Environment.NewLine }, StringSplitOptions.None); this.codeLines = csharpOutput.ToString().Split(new[] { Environment.NewLine }, StringSplitOptions.None);
base.Disassemble(method); base.Disassemble(module, handle);
} finally { } finally {
this.sequencePoints = null; this.sequencePoints = null;
this.codeLines = null; this.codeLines = null;
} }
} }
protected override void WriteInstruction(ITextOutput output, Decompiler.Metadata.MethodDefinition method, ref System.Reflection.Metadata.BlobReader blob) protected override void WriteInstruction(ITextOutput output, MetadataReader metadata, MethodDefinitionHandle methodDefinition, ref BlobReader blob)
{ {
int index = sequencePoints.BinarySearch(blob.Offset, seq => seq.Offset); int index = sequencePoints.BinarySearch(blob.Offset, seq => seq.Offset);
if (index >= 0) { if (index >= 0) {
@ -125,7 +128,7 @@ namespace ICSharpCode.ILSpy
highlightingOutput?.EndSpan(); highlightingOutput?.EndSpan();
} }
} }
base.WriteInstruction(output, method, ref blob); base.WriteInstruction(output, metadata, methodDefinition, ref blob);
} }
HighlightingColor gray = new HighlightingColor { Foreground = new SimpleHighlightingBrush(Colors.DarkGray) }; HighlightingColor gray = new HighlightingColor { Foreground = new SimpleHighlightingBrush(Colors.DarkGray) };

20
ILSpy/Languages/CSharpLanguage.cs

@ -131,7 +131,7 @@ namespace ICSharpCode.ILSpy
public override void DecompileMethod(Decompiler.Metadata.MethodDefinition method, ITextOutput output, DecompilationOptions options) public override void DecompileMethod(Decompiler.Metadata.MethodDefinition method, ITextOutput output, DecompilationOptions options)
{ {
AddReferenceWarningMessage(method.Module, output); AddReferenceWarningMessage(method.Module, output);
var md = method.This(); var md = method.Module.Metadata.GetMethodDefinition(method.Handle);
WriteCommentLine(output, TypeDefinitionToString(new Entity(method.Module, md.GetDeclaringType()), includeNamespace: true)); WriteCommentLine(output, TypeDefinitionToString(new Entity(method.Module, md.GetDeclaringType()), includeNamespace: true));
CSharpDecompiler decompiler = CreateDecompiler(method.Module, options); CSharpDecompiler decompiler = CreateDecompiler(method.Module, options);
var methodDefinition = decompiler.TypeSystem.ResolveAsMethod(method.Handle); var methodDefinition = decompiler.TypeSystem.ResolveAsMethod(method.Handle);
@ -199,7 +199,7 @@ namespace ICSharpCode.ILSpy
{ {
AddReferenceWarningMessage(property.Module, output); AddReferenceWarningMessage(property.Module, output);
CSharpDecompiler decompiler = CreateDecompiler(property.Module, options); CSharpDecompiler decompiler = CreateDecompiler(property.Module, options);
var metadata = property.Module.GetMetadataReader(); var metadata = property.Module.Metadata;
var accessorHandle = metadata.GetPropertyDefinition(property.Handle).GetAccessors().GetAny(); var accessorHandle = metadata.GetPropertyDefinition(property.Handle).GetAccessors().GetAny();
WriteCommentLine(output, TypeDefinitionToString(new Decompiler.Metadata.TypeDefinition(property.Module, metadata.GetMethodDefinition(accessorHandle).GetDeclaringType()), includeNamespace: true)); WriteCommentLine(output, TypeDefinitionToString(new Decompiler.Metadata.TypeDefinition(property.Module, metadata.GetMethodDefinition(accessorHandle).GetDeclaringType()), includeNamespace: true));
WriteCode(output, options.DecompilerSettings, decompiler.Decompile(property.Handle), decompiler.TypeSystem); WriteCode(output, options.DecompilerSettings, decompiler.Decompile(property.Handle), decompiler.TypeSystem);
@ -208,7 +208,7 @@ namespace ICSharpCode.ILSpy
public override void DecompileField(Decompiler.Metadata.FieldDefinition field, ITextOutput output, DecompilationOptions options) public override void DecompileField(Decompiler.Metadata.FieldDefinition field, ITextOutput output, DecompilationOptions options)
{ {
AddReferenceWarningMessage(field.Module, output); AddReferenceWarningMessage(field.Module, output);
var fd = field.This(); var fd = field.Module.Metadata.GetFieldDefinition(field.Handle);
WriteCommentLine(output, TypeDefinitionToString(new Decompiler.Metadata.TypeDefinition(field.Module, fd.GetDeclaringType()), includeNamespace: true)); WriteCommentLine(output, TypeDefinitionToString(new Decompiler.Metadata.TypeDefinition(field.Module, fd.GetDeclaringType()), includeNamespace: true));
CSharpDecompiler decompiler = CreateDecompiler(field.Module, options); CSharpDecompiler decompiler = CreateDecompiler(field.Module, options);
var fieldDefinition = decompiler.TypeSystem.ResolveAsField(field.Handle); var fieldDefinition = decompiler.TypeSystem.ResolveAsField(field.Handle);
@ -268,7 +268,7 @@ namespace ICSharpCode.ILSpy
public override void DecompileEvent(Decompiler.Metadata.EventDefinition ev, ITextOutput output, DecompilationOptions options) public override void DecompileEvent(Decompiler.Metadata.EventDefinition ev, ITextOutput output, DecompilationOptions options)
{ {
AddReferenceWarningMessage(ev.Module, output); AddReferenceWarningMessage(ev.Module, output);
var metadata = ev.Module.GetMetadataReader(); var metadata = ev.Module.Metadata;
var accessorHandle = metadata.GetEventDefinition(ev.Handle).GetAccessors().GetAny(); var accessorHandle = metadata.GetEventDefinition(ev.Handle).GetAccessors().GetAny();
base.WriteCommentLine(output, TypeDefinitionToString(new Decompiler.Metadata.TypeDefinition(ev.Module, metadata.GetMethodDefinition(accessorHandle).GetDeclaringType()), includeNamespace: true)); base.WriteCommentLine(output, TypeDefinitionToString(new Decompiler.Metadata.TypeDefinition(ev.Module, metadata.GetMethodDefinition(accessorHandle).GetDeclaringType()), includeNamespace: true));
CSharpDecompiler decompiler = CreateDecompiler(ev.Module, options); CSharpDecompiler decompiler = CreateDecompiler(ev.Module, options);
@ -327,7 +327,7 @@ namespace ICSharpCode.ILSpy
AddReferenceWarningMessage(module, output); AddReferenceWarningMessage(module, output);
output.WriteLine(); output.WriteLine();
base.DecompileAssembly(assembly, output, options); base.DecompileAssembly(assembly, output, options);
var metadata = module.GetMetadataReader(); var metadata = module.Metadata;
if (metadata.TypeDefinitions.Count > 0) { if (metadata.TypeDefinitions.Count > 0) {
output.Write("// Global type: "); output.Write("// Global type: ");
@ -404,7 +404,7 @@ namespace ICSharpCode.ILSpy
public override string TypeDefinitionToString(Decompiler.Metadata.TypeDefinition type, bool includeNamespace) public override string TypeDefinitionToString(Decompiler.Metadata.TypeDefinition type, bool includeNamespace)
{ {
var metadata = type.Module.GetMetadataReader(); var metadata = type.Module.Metadata;
var td = metadata.GetTypeDefinition(type.Handle); var td = metadata.GetTypeDefinition(type.Handle);
var genericParams = td.GetGenericParameters(); var genericParams = td.GetGenericParameters();
@ -437,7 +437,7 @@ namespace ICSharpCode.ILSpy
{ {
if (field.Handle.IsNil) if (field.Handle.IsNil)
throw new ArgumentNullException(nameof(field)); throw new ArgumentNullException(nameof(field));
var metadata = field.Module.GetMetadataReader(); var metadata = field.Module.Metadata;
var fd = metadata.GetFieldDefinition(field.Handle); var fd = metadata.GetFieldDefinition(field.Handle);
AstType fieldType = fd.DecodeSignature(new AstTypeBuilder(ConvertTypeOptions.IncludeTypeParameterDefinitions), new GenericContext(fd.GetDeclaringType(), field.Module)); AstType fieldType = fd.DecodeSignature(new AstTypeBuilder(ConvertTypeOptions.IncludeTypeParameterDefinitions), new GenericContext(fd.GetDeclaringType(), field.Module));
string simple = metadata.GetString(fd.Name) + " : " + TypeToString(fieldType, metadata, fd.GetCustomAttributes()); string simple = metadata.GetString(fd.Name) + " : " + TypeToString(fieldType, metadata, fd.GetCustomAttributes());
@ -453,7 +453,7 @@ namespace ICSharpCode.ILSpy
{ {
if (property.IsNil) if (property.IsNil)
throw new ArgumentNullException(nameof(property)); throw new ArgumentNullException(nameof(property));
var metadata = property.Module.GetMetadataReader(); var metadata = property.Module.Metadata;
var pd = metadata.GetPropertyDefinition(property.Handle); var pd = metadata.GetPropertyDefinition(property.Handle);
var accessors = pd.GetAccessors(); var accessors = pd.GetAccessors();
var accessorHandle = accessors.GetAny(); var accessorHandle = accessors.GetAny();
@ -562,7 +562,7 @@ namespace ICSharpCode.ILSpy
{ {
if (method.IsNil) if (method.IsNil)
throw new ArgumentNullException("method"); throw new ArgumentNullException("method");
var metadata = method.Module.GetMetadataReader(); var metadata = method.Module.Metadata;
var md = metadata.GetMethodDefinition(method.Handle); var md = metadata.GetMethodDefinition(method.Handle);
var name = (md.IsConstructor(metadata)) ? TypeDefinitionToString(new Decompiler.Metadata.TypeDefinition(method.Module, md.GetDeclaringType()), includeNamespace) : metadata.GetString(md.Name); var name = (md.IsConstructor(metadata)) ? TypeDefinitionToString(new Decompiler.Metadata.TypeDefinition(method.Module, md.GetDeclaringType()), includeNamespace) : metadata.GetString(md.Name);
var signature = md.DecodeSignature(new AstTypeBuilder(ConvertTypeOptions.IncludeTypeParameterDefinitions), new GenericContext(method)); var signature = md.DecodeSignature(new AstTypeBuilder(ConvertTypeOptions.IncludeTypeParameterDefinitions), new GenericContext(method));
@ -622,7 +622,7 @@ namespace ICSharpCode.ILSpy
{ {
if (@event.IsNil) if (@event.IsNil)
throw new ArgumentNullException(nameof(@event)); throw new ArgumentNullException(nameof(@event));
var metadata = @event.Module.GetMetadataReader(); var metadata = @event.Module.Metadata;
var ed = metadata.GetEventDefinition(@event.Handle); var ed = metadata.GetEventDefinition(@event.Handle);
var accessors = ed.GetAccessors(); var accessors = ed.GetAccessors();
var accessorHandle = accessors.GetAny(); var accessorHandle = accessors.GetAny();

9
ILSpy/Languages/ILAstLanguage.cs

@ -73,14 +73,15 @@ namespace ICSharpCode.ILSpy
public override string TypeDefinitionToString(TypeDefinition type, bool includeNamespace) public override string TypeDefinitionToString(TypeDefinition type, bool includeNamespace)
{ {
PlainTextOutput output = new PlainTextOutput(); PlainTextOutput output = new PlainTextOutput();
type.WriteTo(output, includeNamespace ? ILNameSyntax.TypeName : ILNameSyntax.ShortTypeName); ((SRM.EntityHandle)type.Handle).WriteTo(type.Module, output, GenericContext.Empty, includeNamespace ? ILNameSyntax.TypeName : ILNameSyntax.ShortTypeName);
return output.ToString(); return output.ToString();
} }
public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options) public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options)
{ {
base.DecompileMethod(method, output, options); base.DecompileMethod(method, output, options);
new ReflectionDisassembler(output, options.CancellationToken).DisassembleMethodHeader(method); var module = method.Module;
new ReflectionDisassembler(output, options.CancellationToken).DisassembleMethodHeader(module, method.Handle);
output.WriteLine(); output.WriteLine();
output.WriteLine(); output.WriteLine();
} }
@ -92,7 +93,7 @@ namespace ICSharpCode.ILSpy
public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options) public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options)
{ {
base.DecompileMethod(method, output, options); base.DecompileMethod(method, output, options);
var metadata = method.Module.GetMetadataReader(); var metadata = method.Module.Metadata;
if (!method.Handle.HasBody(metadata)) if (!method.Handle.HasBody(metadata))
return; return;
var methodDef = metadata.GetMethodDefinition(method.Handle); var methodDef = metadata.GetMethodDefinition(method.Handle);
@ -115,7 +116,7 @@ namespace ICSharpCode.ILSpy
public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options) public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options)
{ {
base.DecompileMethod(method, output, options); base.DecompileMethod(method, output, options);
var metadata = method.Module.GetMetadataReader(); var metadata = method.Module.Metadata;
if (!method.Handle.HasBody(metadata)) if (!method.Handle.HasBody(metadata))
return; return;
var methodDef = metadata.GetMethodDefinition(method.Handle); var methodDef = metadata.GetMethodDefinition(method.Handle);

27
ILSpy/Languages/ILLanguage.cs

@ -61,7 +61,7 @@ namespace ICSharpCode.ILSpy
public override void DecompileMethod(Decompiler.Metadata.MethodDefinition method, ITextOutput output, DecompilationOptions options) public override void DecompileMethod(Decompiler.Metadata.MethodDefinition method, ITextOutput output, DecompilationOptions options)
{ {
var dis = CreateDisassembler(output, options); var dis = CreateDisassembler(output, options);
dis.DisassembleMethod(method); dis.DisassembleMethod(method.Module, method.Handle);
} }
public override void DecompileField(Decompiler.Metadata.FieldDefinition field, ITextOutput output, DecompilationOptions options) public override void DecompileField(Decompiler.Metadata.FieldDefinition field, ITextOutput output, DecompilationOptions options)
@ -74,16 +74,16 @@ namespace ICSharpCode.ILSpy
{ {
var dis = CreateDisassembler(output, options); var dis = CreateDisassembler(output, options);
dis.DisassembleProperty(property); dis.DisassembleProperty(property);
var pd = property.Module.Metadata.GetPropertyDefinition(property.Handle);
var accessors = property.This().GetAccessors(); var accessors = pd.GetAccessors();
if (!accessors.Getter.IsNil) { if (!accessors.Getter.IsNil) {
output.WriteLine(); output.WriteLine();
dis.DisassembleMethod(new Decompiler.Metadata.MethodDefinition(property.Module, accessors.Getter)); dis.DisassembleMethod(property.Module, accessors.Getter);
} }
if (!accessors.Setter.IsNil) { if (!accessors.Setter.IsNil) {
output.WriteLine(); output.WriteLine();
dis.DisassembleMethod(new Decompiler.Metadata.MethodDefinition(property.Module, accessors.Setter)); dis.DisassembleMethod(property.Module, accessors.Setter);
} }
/*foreach (var m in property.OtherMethods) { /*foreach (var m in property.OtherMethods) {
output.WriteLine(); output.WriteLine();
@ -94,19 +94,22 @@ namespace ICSharpCode.ILSpy
public override void DecompileEvent(Decompiler.Metadata.EventDefinition ev, ITextOutput output, DecompilationOptions options) public override void DecompileEvent(Decompiler.Metadata.EventDefinition ev, ITextOutput output, DecompilationOptions options)
{ {
var dis = CreateDisassembler(output, options); var dis = CreateDisassembler(output, options);
dis.DisassembleEvent(ev); var metadata = ev.Module.Metadata;
var accessors = ev.This().GetAccessors(); dis.DisassembleEvent(ev.Module, ev.Handle);
var ed = metadata.GetEventDefinition(ev.Handle);
var accessors = ed.GetAccessors();
if (!accessors.Adder.IsNil) { if (!accessors.Adder.IsNil) {
output.WriteLine(); output.WriteLine();
dis.DisassembleMethod(new Decompiler.Metadata.MethodDefinition(ev.Module, accessors.Adder)); dis.DisassembleMethod(ev.Module, accessors.Adder);
} }
if (!accessors.Remover.IsNil) { if (!accessors.Remover.IsNil) {
output.WriteLine(); output.WriteLine();
dis.DisassembleMethod(new Decompiler.Metadata.MethodDefinition(ev.Module, accessors.Remover)); dis.DisassembleMethod(ev.Module, accessors.Remover);
} }
if (!accessors.Raiser.IsNil) { if (!accessors.Raiser.IsNil) {
output.WriteLine(); output.WriteLine();
dis.DisassembleMethod(new Decompiler.Metadata.MethodDefinition(ev.Module, accessors.Raiser)); dis.DisassembleMethod(ev.Module, accessors.Raiser);
} }
/*foreach (var m in ev.OtherMethods) { /*foreach (var m in ev.OtherMethods) {
output.WriteLine(); output.WriteLine();
@ -131,7 +134,7 @@ namespace ICSharpCode.ILSpy
output.WriteLine("// " + assembly.FileName); output.WriteLine("// " + assembly.FileName);
output.WriteLine(); output.WriteLine();
var module = assembly.GetPEFileOrNull(); var module = assembly.GetPEFileOrNull();
var metadata = module.GetMetadataReader(); var metadata = module.Metadata;
var dis = CreateDisassembler(output, options); var dis = CreateDisassembler(output, options);
if (options.FullDecompilation) if (options.FullDecompilation)
dis.WriteAssemblyReferences(metadata); dis.WriteAssemblyReferences(metadata);
@ -149,7 +152,7 @@ namespace ICSharpCode.ILSpy
public override string TypeDefinitionToString(Decompiler.Metadata.TypeDefinition type, bool includeNamespace) public override string TypeDefinitionToString(Decompiler.Metadata.TypeDefinition type, bool includeNamespace)
{ {
PlainTextOutput output = new PlainTextOutput(); PlainTextOutput output = new PlainTextOutput();
type.WriteTo(output, includeNamespace ? ILNameSyntax.TypeName : ILNameSyntax.ShortTypeName); ((EntityHandle)type.Handle).WriteTo(type.Module, output, GenericContext.Empty, includeNamespace ? ILNameSyntax.TypeName : ILNameSyntax.ShortTypeName);
return output.ToString(); return output.ToString();
} }
} }

48
ILSpy/Languages/Language.cs

@ -99,14 +99,14 @@ namespace ICSharpCode.ILSpy
public virtual void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options) public virtual void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options)
{ {
var metadata = method.Module.GetMetadataReader(); var metadata = method.Module.Metadata;
var methodDefinition = metadata.GetMethodDefinition(method.Handle); var methodDefinition = metadata.GetMethodDefinition(method.Handle);
WriteCommentLine(output, TypeDefinitionToString(new TypeDefinition(method.Module, methodDefinition.GetDeclaringType()), true) + "." + metadata.GetString(methodDefinition.Name)); WriteCommentLine(output, TypeDefinitionToString(new TypeDefinition(method.Module, methodDefinition.GetDeclaringType()), true) + "." + metadata.GetString(methodDefinition.Name));
} }
public virtual void DecompileProperty(PropertyDefinition property, ITextOutput output, DecompilationOptions options) public virtual void DecompileProperty(PropertyDefinition property, ITextOutput output, DecompilationOptions options)
{ {
var metadata = property.Module.GetMetadataReader(); var metadata = property.Module.Metadata;
var propertyDefinition = metadata.GetPropertyDefinition(property.Handle); var propertyDefinition = metadata.GetPropertyDefinition(property.Handle);
var declaringType = metadata.GetMethodDefinition(propertyDefinition.GetAccessors().GetAny()).GetDeclaringType(); var declaringType = metadata.GetMethodDefinition(propertyDefinition.GetAccessors().GetAny()).GetDeclaringType();
WriteCommentLine(output, TypeDefinitionToString(new TypeDefinition(property.Module, declaringType), true) + "." + metadata.GetString(propertyDefinition.Name)); WriteCommentLine(output, TypeDefinitionToString(new TypeDefinition(property.Module, declaringType), true) + "." + metadata.GetString(propertyDefinition.Name));
@ -114,14 +114,14 @@ namespace ICSharpCode.ILSpy
public virtual void DecompileField(FieldDefinition field, ITextOutput output, DecompilationOptions options) public virtual void DecompileField(FieldDefinition field, ITextOutput output, DecompilationOptions options)
{ {
var metadata = field.Module.GetMetadataReader(); var metadata = field.Module.Metadata;
var fieldDefinition = metadata.GetFieldDefinition(field.Handle); var fieldDefinition = metadata.GetFieldDefinition(field.Handle);
WriteCommentLine(output, TypeDefinitionToString(new TypeDefinition(field.Module, fieldDefinition.GetDeclaringType()), true) + "." + metadata.GetString(fieldDefinition.Name)); WriteCommentLine(output, TypeDefinitionToString(new TypeDefinition(field.Module, fieldDefinition.GetDeclaringType()), true) + "." + metadata.GetString(fieldDefinition.Name));
} }
public virtual void DecompileEvent(EventDefinition ev, ITextOutput output, DecompilationOptions options) public virtual void DecompileEvent(EventDefinition ev, ITextOutput output, DecompilationOptions options)
{ {
var metadata = ev.Module.GetMetadataReader(); var metadata = ev.Module.Metadata;
var eventDefinition = metadata.GetEventDefinition(ev.Handle); var eventDefinition = metadata.GetEventDefinition(ev.Handle);
var declaringType = metadata.GetMethodDefinition(eventDefinition.GetAccessors().GetAny()).GetDeclaringType(); var declaringType = metadata.GetMethodDefinition(eventDefinition.GetAccessors().GetAny()).GetDeclaringType();
WriteCommentLine(output, TypeDefinitionToString(new TypeDefinition(ev.Module, declaringType), true) + "." + metadata.GetString(eventDefinition.Name)); WriteCommentLine(output, TypeDefinitionToString(new TypeDefinition(ev.Module, declaringType), true) + "." + metadata.GetString(eventDefinition.Name));
@ -142,16 +142,16 @@ namespace ICSharpCode.ILSpy
WriteCommentLine(output, assembly.FileName); WriteCommentLine(output, assembly.FileName);
var asm = assembly.GetPEFileOrNull(); var asm = assembly.GetPEFileOrNull();
if (asm == null) return; if (asm == null) return;
var reader = asm.GetMetadataReader(); var metadata = asm.Metadata;
if (reader.IsAssembly) { if (metadata.IsAssembly) {
var name = reader.GetAssemblyDefinition(); var name = metadata.GetAssemblyDefinition();
if ((name.Flags & System.Reflection.AssemblyFlags.WindowsRuntime) != 0) { if ((name.Flags & System.Reflection.AssemblyFlags.WindowsRuntime) != 0) {
WriteCommentLine(output, name.Name + " [WinRT]"); WriteCommentLine(output, name.Name + " [WinRT]");
} else { } else {
WriteCommentLine(output, reader.GetFullAssemblyName()); WriteCommentLine(output, metadata.GetFullAssemblyName());
} }
} else { } else {
WriteCommentLine(output, reader.GetString(reader.GetModuleDefinition().Name)); WriteCommentLine(output, metadata.GetString(metadata.GetModuleDefinition().Name));
} }
} }
@ -165,7 +165,7 @@ namespace ICSharpCode.ILSpy
/// </summary> /// </summary>
public virtual string TypeDefinitionToString(TypeDefinition type, bool includeNamespace) public virtual string TypeDefinitionToString(TypeDefinition type, bool includeNamespace)
{ {
var metadata = type.Module.GetMetadataReader(); var metadata = type.Module.Metadata;
var fullName = type.Handle.GetFullTypeName(metadata); var fullName = type.Handle.GetFullTypeName(metadata);
if (includeNamespace) if (includeNamespace)
return fullName.ToString(); return fullName.ToString();
@ -179,7 +179,7 @@ namespace ICSharpCode.ILSpy
/// </summary> /// </summary>
public virtual string GetTooltip(Entity entity) public virtual string GetTooltip(Entity entity)
{ {
var metadata = entity.Module.GetMetadataReader(); var metadata = entity.Module.Metadata;
switch (entity.Handle.Kind) { switch (entity.Handle.Kind) {
case SRM.HandleKind.TypeReference: case SRM.HandleKind.TypeReference:
case SRM.HandleKind.TypeDefinition: case SRM.HandleKind.TypeDefinition:
@ -204,7 +204,7 @@ namespace ICSharpCode.ILSpy
{ {
if (field.Handle.IsNil) if (field.Handle.IsNil)
throw new ArgumentNullException(nameof(field)); throw new ArgumentNullException(nameof(field));
var metadata = field.Module.GetMetadataReader(); var metadata = field.Module.Metadata;
var fd = metadata.GetFieldDefinition(field.Handle); var fd = metadata.GetFieldDefinition(field.Handle);
string fieldType = fd.DecodeSignature(ILSignatureProvider.WithoutNamespace, new GenericContext(fd.GetDeclaringType(), field.Module)); string fieldType = fd.DecodeSignature(ILSignatureProvider.WithoutNamespace, new GenericContext(fd.GetDeclaringType(), field.Module));
string simple = metadata.GetString(fd.Name) + " : " + fieldType; string simple = metadata.GetString(fd.Name) + " : " + fieldType;
@ -220,7 +220,7 @@ namespace ICSharpCode.ILSpy
{ {
if (property.Handle.IsNil) if (property.Handle.IsNil)
throw new ArgumentNullException(nameof(property)); throw new ArgumentNullException(nameof(property));
var metadata = property.Module.GetMetadataReader(); var metadata = property.Module.Metadata;
var pd = metadata.GetPropertyDefinition(property.Handle); var pd = metadata.GetPropertyDefinition(property.Handle);
var declaringType = metadata.GetMethodDefinition(pd.GetAccessors().GetAny()).GetDeclaringType(); var declaringType = metadata.GetMethodDefinition(pd.GetAccessors().GetAny()).GetDeclaringType();
var signature = pd.DecodeSignature(!includeNamespace ? ILSignatureProvider.WithoutNamespace : ILSignatureProvider.WithNamespace, new GenericContext(declaringType, property.Module)); var signature = pd.DecodeSignature(!includeNamespace ? ILSignatureProvider.WithoutNamespace : ILSignatureProvider.WithNamespace, new GenericContext(declaringType, property.Module));
@ -237,7 +237,7 @@ namespace ICSharpCode.ILSpy
{ {
if (method.Handle.IsNil) if (method.Handle.IsNil)
throw new ArgumentNullException(nameof(method)); throw new ArgumentNullException(nameof(method));
var metadata = method.Module.GetMetadataReader(); var metadata = method.Module.Metadata;
return metadata.GetString(metadata.GetMethodDefinition(method.Handle).Name); return metadata.GetString(metadata.GetMethodDefinition(method.Handle).Name);
} }
@ -245,7 +245,7 @@ namespace ICSharpCode.ILSpy
{ {
if (@event.Handle.IsNil) if (@event.Handle.IsNil)
throw new ArgumentNullException(nameof(@event)); throw new ArgumentNullException(nameof(@event));
var metadata = @event.Module.GetMetadataReader(); var metadata = @event.Module.Metadata;
return metadata.GetString(metadata.GetEventDefinition(@event.Handle).Name); return metadata.GetString(metadata.GetEventDefinition(@event.Handle).Name);
} }
@ -291,25 +291,9 @@ namespace ICSharpCode.ILSpy
} }
} }
public static string GetRuntimeDisplayName(TargetRuntime runtime)
{
switch (runtime) {
case TargetRuntime.Net_1_0:
return ".NET 1.1";
case TargetRuntime.Net_1_1:
return ".NET 1.0";
case TargetRuntime.Net_2_0:
return ".NET 2.0";
case TargetRuntime.Net_4_0:
return ".NET 4.0";
}
return null;
}
public static string GetRuntimeDisplayName(PEFile module) public static string GetRuntimeDisplayName(PEFile module)
{ {
return GetRuntimeDisplayName(module.GetRuntime()); return module.Metadata.MetadataVersion;
} }
} }

2
ILSpy/LoadedAssembly.cs

@ -242,7 +242,7 @@ namespace ICSharpCode.ILSpy
LoadedAssembly asm; LoadedAssembly asm;
lock (loadingAssemblies) { lock (loadingAssemblies) {
foreach (LoadedAssembly loaded in assemblyList.GetAssemblies()) { foreach (LoadedAssembly loaded in assemblyList.GetAssemblies()) {
var reader = loaded.GetPEFileOrNull()?.GetMetadataReader(); var reader = loaded.GetPEFileOrNull()?.Metadata;
if (reader == null || !reader.IsAssembly) continue; if (reader == null || !reader.IsAssembly) continue;
var asmDef = reader.GetAssemblyDefinition(); var asmDef = reader.GetAssemblyDefinition();
if (GetName(fullName).Equals(isWinRT ? reader.GetString(asmDef.Name) : reader.GetFullAssemblyName(), StringComparison.OrdinalIgnoreCase)) { if (GetName(fullName).Equals(isWinRT ? reader.GetString(asmDef.Name) : reader.GetFullAssemblyName(), StringComparison.OrdinalIgnoreCase)) {

26
ILSpy/SearchStrategies.cs

@ -45,7 +45,7 @@ namespace ICSharpCode.ILSpy
protected float CalculateFitness(IMetadataEntity member) protected float CalculateFitness(IMetadataEntity member)
{ {
var metadata = member.Module.GetMetadataReader(); var metadata = member.Module.Metadata;
string text; string text;
switch (member) { switch (member) {
case TypeDefinition td: case TypeDefinition td:
@ -149,7 +149,7 @@ namespace ICSharpCode.ILSpy
string GetLanguageSpecificName(Language language, IMetadataEntity member, bool fullName = false) string GetLanguageSpecificName(Language language, IMetadataEntity member, bool fullName = false)
{ {
var metadata = member.Module.GetMetadataReader(); var metadata = member.Module.Metadata;
switch (member) { switch (member) {
case TypeDefinition t: case TypeDefinition t:
return language.TypeDefinitionToString(t, fullName); return language.TypeDefinitionToString(t, fullName);
@ -190,8 +190,8 @@ namespace ICSharpCode.ILSpy
public virtual void Search(TypeDefinition type, Language language, Action<SearchResult> addResult) public virtual void Search(TypeDefinition type, Language language, Action<SearchResult> addResult)
{ {
var td = type.This(); var metadata = type.Module.Metadata;
var metadata = type.Module.GetMetadataReader(); var td = metadata.GetTypeDefinition(type.Handle);
Add(() => td.GetFields().Select(f => new FieldDefinition(type.Module, f)), type, language, addResult, IsMatch, FieldTreeNode.GetIcon); Add(() => td.GetFields().Select(f => new FieldDefinition(type.Module, f)), type, language, addResult, IsMatch, FieldTreeNode.GetIcon);
Add(() => td.GetProperties().Select(p => new PropertyDefinition(type.Module, p)), type, language, addResult, IsMatch, p => PropertyTreeNode.GetIcon(p)); Add(() => td.GetProperties().Select(p => new PropertyDefinition(type.Module, p)), type, language, addResult, IsMatch, p => PropertyTreeNode.GetIcon(p));
Add(() => td.GetEvents().Select(e => new EventDefinition(type.Module, e)), type, language, addResult, IsMatch, EventTreeNode.GetIcon); Add(() => td.GetEvents().Select(e => new EventDefinition(type.Module, e)), type, language, addResult, IsMatch, EventTreeNode.GetIcon);
@ -284,13 +284,13 @@ namespace ICSharpCode.ILSpy
protected override bool IsMatch(PropertyDefinition property, Language language) protected override bool IsMatch(PropertyDefinition property, Language language)
{ {
var accessors = property.This().GetAccessors(); var accessors = property.Module.Metadata.GetPropertyDefinition(property.Handle).GetAccessors();
return MethodIsLiteralMatch(accessors.Getter, property.Module) || MethodIsLiteralMatch(accessors.Setter, property.Module); return MethodIsLiteralMatch(accessors.Getter, property.Module) || MethodIsLiteralMatch(accessors.Setter, property.Module);
} }
protected override bool IsMatch(EventDefinition ev, Language language) protected override bool IsMatch(EventDefinition ev, Language language)
{ {
var accessors = ev.This().GetAccessors(); var accessors = ev.Module.Metadata.GetEventDefinition(ev.Handle).GetAccessors();
return MethodIsLiteralMatch(accessors.Adder, ev.Module) || MethodIsLiteralMatch(accessors.Remover, ev.Module) || MethodIsLiteralMatch(accessors.Raiser, ev.Module); return MethodIsLiteralMatch(accessors.Adder, ev.Module) || MethodIsLiteralMatch(accessors.Remover, ev.Module) || MethodIsLiteralMatch(accessors.Raiser, ev.Module);
} }
@ -324,7 +324,7 @@ namespace ICSharpCode.ILSpy
{ {
if (module == null) if (module == null)
return false; return false;
var metadata = module.GetMetadataReader(); var metadata = module.Metadata;
if (m.IsNil || !m.HasBody(metadata)) if (m.IsNil || !m.HasBody(metadata))
return false; return false;
var methodDefinition = metadata.GetMethodDefinition(m); var methodDefinition = metadata.GetMethodDefinition(m);
@ -496,10 +496,12 @@ namespace ICSharpCode.ILSpy
public override void Search(TypeDefinition type, Language language, Action<SearchResult> addResult) public override void Search(TypeDefinition type, Language language, Action<SearchResult> addResult)
{ {
var metadata = type.Module.Metadata;
var td = metadata.GetTypeDefinition(type.Handle);
if (MatchName(type, language)) { if (MatchName(type, language)) {
string name = language.TypeDefinitionToString(type, includeNamespace: false); string name = language.TypeDefinitionToString(type, includeNamespace: false);
var metadata = type.Module.GetMetadataReader(); var declaringType = td.GetDeclaringType();
var declaringType = type.This().GetDeclaringType();
addResult(new SearchResult { addResult(new SearchResult {
Member = type, Member = type,
Fitness = CalculateFitness(type), Fitness = CalculateFitness(type),
@ -510,7 +512,7 @@ namespace ICSharpCode.ILSpy
}); });
} }
foreach (var nestedType in type.This().GetNestedTypes()) { foreach (var nestedType in td.GetNestedTypes()) {
Search(new TypeDefinition(type.Module, nestedType), language, addResult); Search(new TypeDefinition(type.Module, nestedType), language, addResult);
} }
} }
@ -528,8 +530,8 @@ namespace ICSharpCode.ILSpy
if (MatchName(type, language)) if (MatchName(type, language))
{ {
string name = language.TypeDefinitionToString(type, includeNamespace: false); string name = language.TypeDefinitionToString(type, includeNamespace: false);
var metadata = type.Module.GetMetadataReader(); var metadata = type.Module.Metadata;
var declaringType = type.This().GetDeclaringType(); var declaringType = metadata.GetTypeDefinition(type.Handle).GetDeclaringType();
addResult(new SearchResult { addResult(new SearchResult {
Member = type, Member = type,
Image = TypeTreeNode.GetIcon(type), Image = TypeTreeNode.GetIcon(type),

10
ILSpy/TreeNodes/AssemblyListTreeNode.cs

@ -206,7 +206,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// </summary> /// </summary>
public TypeTreeNode FindTypeNode(TypeDefinition def) public TypeTreeNode FindTypeNode(TypeDefinition def)
{ {
var declaringType = def.This().GetDeclaringType(); var declaringType = def.Module.Metadata.GetTypeDefinition(def.Handle).GetDeclaringType();
if (!declaringType.IsNil) { if (!declaringType.IsNil) {
TypeTreeNode decl = FindTypeNode(new TypeDefinition(def.Module, declaringType)); TypeTreeNode decl = FindTypeNode(new TypeDefinition(def.Module, declaringType));
if (decl != null) { if (decl != null) {
@ -228,7 +228,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// </summary> /// </summary>
public ILSpyTreeNode FindMethodNode(MethodDefinition def) public ILSpyTreeNode FindMethodNode(MethodDefinition def)
{ {
TypeTreeNode typeNode = FindTypeNode(new TypeDefinition(def.Module, def.This().GetDeclaringType())); TypeTreeNode typeNode = FindTypeNode(new TypeDefinition(def.Module, def.Module.Metadata.GetMethodDefinition(def.Handle).GetDeclaringType()));
if (typeNode == null) if (typeNode == null)
return null; return null;
typeNode.EnsureLazyChildren(); typeNode.EnsureLazyChildren();
@ -263,7 +263,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// </summary> /// </summary>
public FieldTreeNode FindFieldNode(FieldDefinition def) public FieldTreeNode FindFieldNode(FieldDefinition def)
{ {
TypeTreeNode typeNode = FindTypeNode(new TypeDefinition(def.Module, def.This().GetDeclaringType())); TypeTreeNode typeNode = FindTypeNode(new TypeDefinition(def.Module, def.Module.Metadata.GetFieldDefinition(def.Handle).GetDeclaringType()));
if (typeNode == null) if (typeNode == null)
return null; return null;
typeNode.EnsureLazyChildren(); typeNode.EnsureLazyChildren();
@ -276,7 +276,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// </summary> /// </summary>
public PropertyTreeNode FindPropertyNode(PropertyDefinition def) public PropertyTreeNode FindPropertyNode(PropertyDefinition def)
{ {
var metadata = def.Module.GetMetadataReader(); var metadata = def.Module.Metadata;
var accessor = metadata.GetMethodDefinition(metadata.GetPropertyDefinition(def.Handle).GetAccessors().GetAny()); var accessor = metadata.GetMethodDefinition(metadata.GetPropertyDefinition(def.Handle).GetAccessors().GetAny());
TypeTreeNode typeNode = FindTypeNode(new TypeDefinition(def.Module, accessor.GetDeclaringType())); TypeTreeNode typeNode = FindTypeNode(new TypeDefinition(def.Module, accessor.GetDeclaringType()));
if (typeNode == null) if (typeNode == null)
@ -291,7 +291,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// </summary> /// </summary>
public EventTreeNode FindEventNode(EventDefinition def) public EventTreeNode FindEventNode(EventDefinition def)
{ {
var metadata = def.Module.GetMetadataReader(); var metadata = def.Module.Metadata;
var accessor = metadata.GetMethodDefinition(metadata.GetEventDefinition(def.Handle).GetAccessors().GetAny()); var accessor = metadata.GetMethodDefinition(metadata.GetEventDefinition(def.Handle).GetAccessors().GetAny());
TypeTreeNode typeNode = FindTypeNode(new TypeDefinition(def.Module, accessor.GetDeclaringType())); TypeTreeNode typeNode = FindTypeNode(new TypeDefinition(def.Module, accessor.GetDeclaringType()));
if (typeNode == null) if (typeNode == null)

6
ILSpy/TreeNodes/AssemblyTreeNode.cs

@ -99,7 +99,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
if (tooltip == null && assembly.IsLoaded) { if (tooltip == null && assembly.IsLoaded) {
tooltip = new TextBlock(); tooltip = new TextBlock();
var module = assembly.GetPEFileOrNull(); var module = assembly.GetPEFileOrNull();
var metadata = module?.GetMetadataReader(); var metadata = module?.Metadata;
if (metadata?.IsAssembly == true) { if (metadata?.IsAssembly == true) {
tooltip.Inlines.Add(new Bold(new Run("Name: "))); tooltip.Inlines.Add(new Bold(new Run("Name: ")));
tooltip.Inlines.Add(new Run(metadata.GetFullAssemblyName())); tooltip.Inlines.Add(new Run(metadata.GetFullAssemblyName()));
@ -152,7 +152,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
// if we crashed on loading, then we don't have any children // if we crashed on loading, then we don't have any children
return; return;
} }
var metadata = module.GetMetadataReader(); var metadata = module.Metadata;
this.Children.Add(new ReferenceFolderTreeNode(module, this)); this.Children.Add(new ReferenceFolderTreeNode(module, this));
if (module.Resources.Any()) if (module.Resources.Any())
@ -404,7 +404,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
var la = ((AssemblyTreeNode)node).LoadedAssembly; var la = ((AssemblyTreeNode)node).LoadedAssembly;
var module = la.GetPEFileOrNull(); var module = la.GetPEFileOrNull();
if (module != null) { if (module != null) {
var metadata = module.GetMetadataReader(); var metadata = module.Metadata;
foreach (var assyRef in metadata.AssemblyReferences) { foreach (var assyRef in metadata.AssemblyReferences) {
la.LookupReferencedAssembly(new AssemblyReference(module, assyRef)); la.LookupReferencedAssembly(new AssemblyReference(module, assyRef));
} }

4
ILSpy/TreeNodes/BaseTypesEntryNode.cs

@ -43,14 +43,14 @@ namespace ICSharpCode.ILSpy.TreeNodes
{ {
get { get {
if (td.IsNil) return false; if (td.IsNil) return false;
var typeDef = td.This(); var typeDef = td.Module.Metadata.GetTypeDefinition(td.Handle);
return !typeDef.BaseType.IsNil || typeDef.GetInterfaceImplementations().Any(); return !typeDef.BaseType.IsNil || typeDef.GetInterfaceImplementations().Any();
} }
} }
public override object Text public override object Text
{ {
get { return tr.Handle.GetFullTypeName(tr.Module.GetMetadataReader()) + tr.Handle.ToSuffixString(); } get { return tr.Handle.GetFullTypeName(tr.Module.Metadata) + tr.Handle.ToSuffixString(); }
} }
public override object Icon public override object Icon

4
ILSpy/TreeNodes/BaseTypesTreeNode.cs

@ -48,8 +48,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
internal static void AddBaseTypes(SharpTreeNodeCollection children, TypeDefinition type) internal static void AddBaseTypes(SharpTreeNodeCollection children, TypeDefinition type)
{ {
var metadata = type.Module.GetMetadataReader(); var metadata = type.Module.Metadata;
var def = type.This(); var def = metadata.GetTypeDefinition(type.Handle);
if (!def.BaseType.IsNil) if (!def.BaseType.IsNil)
children.Add(new BaseTypesEntryNode(new Entity(type.Module, def.BaseType), false)); children.Add(new BaseTypesEntryNode(new Entity(type.Module, def.BaseType), false));
foreach (var i in def.GetInterfaceImplementations()) { foreach (var i in def.GetInterfaceImplementations()) {

11
ILSpy/TreeNodes/DerivedTypesEntryNode.cs

@ -22,6 +22,7 @@ using System.Reflection.PortableExecutable;
using System.Threading; using System.Threading;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using SRM = System.Reflection.Metadata;
namespace ICSharpCode.ILSpy.TreeNodes namespace ICSharpCode.ILSpy.TreeNodes
{ {
@ -30,10 +31,12 @@ namespace ICSharpCode.ILSpy.TreeNodes
private readonly TypeDefinition type; private readonly TypeDefinition type;
private readonly PEFile[] assemblies; private readonly PEFile[] assemblies;
private readonly ThreadingSupport threading; private readonly ThreadingSupport threading;
private readonly SRM.TypeDefinition td;
public DerivedTypesEntryNode(TypeDefinition type, PEFile[] assemblies) public DerivedTypesEntryNode(TypeDefinition type, PEFile[] assemblies)
{ {
this.type = type; this.type = type;
this.td = type.Module.Metadata.GetTypeDefinition(type.Handle);
this.assemblies = assemblies; this.assemblies = assemblies;
this.LazyLoading = true; this.LazyLoading = true;
threading = new ThreadingSupport(); threading = new ThreadingSupport();
@ -41,12 +44,12 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override bool ShowExpander public override bool ShowExpander
{ {
get { return !type.This().HasFlag(TypeAttributes.Sealed) && base.ShowExpander; } get { return !type.Module.Metadata.GetTypeDefinition(type.Handle).HasFlag(TypeAttributes.Sealed) && base.ShowExpander; }
} }
public override object Text public override object Text
{ {
get { return type.Handle.GetFullTypeName(type.Module.GetMetadataReader()) + type.Handle.ToSuffixString(); } get { return type.Handle.GetFullTypeName(type.Module.Metadata) + type.Handle.ToSuffixString(); }
} }
public override object Icon public override object Icon
@ -58,7 +61,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
{ {
if (!settings.ShowInternalApi && !IsPublicAPI) if (!settings.ShowInternalApi && !IsPublicAPI)
return FilterResult.Hidden; return FilterResult.Hidden;
var metadata = type.Module.GetMetadataReader(); var metadata = type.Module.Metadata;
var typeDefinition = metadata.GetTypeDefinition(type.Handle); var typeDefinition = metadata.GetTypeDefinition(type.Handle);
if (settings.SearchTermMatches(metadata.GetString(typeDefinition.Name))) { if (settings.SearchTermMatches(metadata.GetString(typeDefinition.Name))) {
if (!typeDefinition.GetDeclaringType().IsNil && !settings.Language.ShowMember(type)) if (!typeDefinition.GetDeclaringType().IsNil && !settings.Language.ShowMember(type))
@ -71,7 +74,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override bool IsPublicAPI { public override bool IsPublicAPI {
get { get {
switch (type.This().Attributes & TypeAttributes.VisibilityMask) { switch (td.Attributes & TypeAttributes.VisibilityMask) {
case TypeAttributes.Public: case TypeAttributes.Public:
case TypeAttributes.NestedPublic: case TypeAttributes.NestedPublic:
case TypeAttributes.NestedFamily: case TypeAttributes.NestedFamily:

2
ILSpy/TreeNodes/DerivedTypesTreeNode.cs

@ -71,7 +71,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
internal static IEnumerable<DerivedTypesEntryNode> FindDerivedTypes(TypeDefinition type, PEFile[] assemblies, CancellationToken cancellationToken) internal static IEnumerable<DerivedTypesEntryNode> FindDerivedTypes(TypeDefinition type, PEFile[] assemblies, CancellationToken cancellationToken)
{ {
foreach (var module in assemblies) { foreach (var module in assemblies) {
var metadata = module.GetMetadataReader(); var metadata = module.Metadata;
foreach (var h in TreeTraversal.PreOrder(metadata.GetTopLevelTypeDefinitions(), t => metadata.GetTypeDefinition(t).GetNestedTypes())) { foreach (var h in TreeTraversal.PreOrder(metadata.GetTopLevelTypeDefinitions(), t => metadata.GetTypeDefinition(t).GetNestedTypes())) {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
var td = new TypeDefinition(module, h); var td = new TypeDefinition(module, h);

8
ILSpy/TreeNodes/EventTreeNode.cs

@ -36,7 +36,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
if (ev.IsNil) if (ev.IsNil)
throw new ArgumentNullException(nameof(ev)); throw new ArgumentNullException(nameof(ev));
this.EventDefinition = ev; this.EventDefinition = ev;
var metadata = ev.Module.GetMetadataReader(); var metadata = ev.Module.Metadata;
var eventDefinition = metadata.GetEventDefinition(ev.Handle); var eventDefinition = metadata.GetEventDefinition(ev.Handle);
var accessors = eventDefinition.GetAccessors(); var accessors = eventDefinition.GetAccessors();
if (!accessors.Adder.IsNil) if (!accessors.Adder.IsNil)
@ -62,7 +62,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public static ImageSource GetIcon(EventDefinition @event) public static ImageSource GetIcon(EventDefinition @event)
{ {
var metadata = @event.Module.GetMetadataReader(); var metadata = @event.Module.Metadata;
var accessor = metadata.GetEventDefinition(@event.Handle).GetAccessors().GetAny(); var accessor = metadata.GetEventDefinition(@event.Handle).GetAccessors().GetAny();
if (!accessor.IsNil) { if (!accessor.IsNil) {
var accessorMethod = metadata.GetMethodDefinition(accessor); var accessorMethod = metadata.GetMethodDefinition(accessor);
@ -97,7 +97,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
{ {
if (!settings.ShowInternalApi && !IsPublicAPI) if (!settings.ShowInternalApi && !IsPublicAPI)
return FilterResult.Hidden; return FilterResult.Hidden;
var metadata = EventDefinition.Module.GetMetadataReader(); var metadata = EventDefinition.Module.Metadata;
if (settings.SearchTermMatches(metadata.GetString(metadata.GetEventDefinition(EventDefinition.Handle).Name)) && settings.Language.ShowMember(EventDefinition)) if (settings.SearchTermMatches(metadata.GetString(metadata.GetEventDefinition(EventDefinition.Handle).Name)) && settings.Language.ShowMember(EventDefinition))
return FilterResult.Match; return FilterResult.Match;
else else
@ -111,7 +111,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override bool IsPublicAPI { public override bool IsPublicAPI {
get { get {
var metadata = EventDefinition.Module.GetMetadataReader(); var metadata = EventDefinition.Module.Metadata;
var accessor = metadata.GetEventDefinition(EventDefinition.Handle).GetAccessors().GetAny(); var accessor = metadata.GetEventDefinition(EventDefinition.Handle).GetAccessors().GetAny();
if (accessor.IsNil) return false; if (accessor.IsNil) return false;
var accessorMethod = metadata.GetMethodDefinition(accessor); var accessorMethod = metadata.GetMethodDefinition(accessor);

8
ILSpy/TreeNodes/FieldTreeNode.cs

@ -50,7 +50,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public static ImageSource GetIcon(FieldDefinition field) public static ImageSource GetIcon(FieldDefinition field)
{ {
var metadata = field.Module.GetMetadataReader(); var metadata = field.Module.Metadata;
var fieldDefinition = metadata.GetFieldDefinition(field.Handle); var fieldDefinition = metadata.GetFieldDefinition(field.Handle);
if (fieldDefinition.GetDeclaringType().IsEnum(metadata) && !fieldDefinition.HasFlag(FieldAttributes.SpecialName)) if (fieldDefinition.GetDeclaringType().IsEnum(metadata) && !fieldDefinition.HasFlag(FieldAttributes.SpecialName))
return Images.GetIcon(MemberIcon.EnumValue, GetOverlayIcon(fieldDefinition.Attributes), false); return Images.GetIcon(MemberIcon.EnumValue, GetOverlayIcon(fieldDefinition.Attributes), false);
@ -68,7 +68,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
private static bool IsDecimalConstant(FieldDefinition field) private static bool IsDecimalConstant(FieldDefinition field)
{ {
var metadata = field.Module.GetMetadataReader(); var metadata = field.Module.Metadata;
var fieldDefinition = metadata.GetFieldDefinition(field.Handle); var fieldDefinition = metadata.GetFieldDefinition(field.Handle);
var fieldType = fieldDefinition.DecodeSignature(new FullTypeNameSignatureDecoder(metadata), default(Unit)); var fieldType = fieldDefinition.DecodeSignature(new FullTypeNameSignatureDecoder(metadata), default(Unit));
@ -110,7 +110,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
{ {
if (!settings.ShowInternalApi && !IsPublicAPI) if (!settings.ShowInternalApi && !IsPublicAPI)
return FilterResult.Hidden; return FilterResult.Hidden;
var metadata = FieldDefinition.Module.GetMetadataReader(); var metadata = FieldDefinition.Module.Metadata;
var fieldDefinition = metadata.GetFieldDefinition(FieldDefinition.Handle); var fieldDefinition = metadata.GetFieldDefinition(FieldDefinition.Handle);
if (settings.SearchTermMatches(metadata.GetString(fieldDefinition.Name)) && settings.Language.ShowMember(FieldDefinition)) if (settings.SearchTermMatches(metadata.GetString(fieldDefinition.Name)) && settings.Language.ShowMember(FieldDefinition))
return FilterResult.Match; return FilterResult.Match;
@ -125,7 +125,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override bool IsPublicAPI { public override bool IsPublicAPI {
get { get {
var metadata = FieldDefinition.Module.GetMetadataReader(); var metadata = FieldDefinition.Module.Metadata;
var fieldDefinition = metadata.GetFieldDefinition(FieldDefinition.Handle); var fieldDefinition = metadata.GetFieldDefinition(FieldDefinition.Handle);
switch (fieldDefinition.Attributes & FieldAttributes.FieldAccessMask) { switch (fieldDefinition.Attributes & FieldAttributes.FieldAccessMask) {

11
ILSpy/TreeNodes/MethodTreeNode.cs

@ -35,12 +35,14 @@ namespace ICSharpCode.ILSpy.TreeNodes
public sealed class MethodTreeNode : ILSpyTreeNode, IMemberTreeNode public sealed class MethodTreeNode : ILSpyTreeNode, IMemberTreeNode
{ {
public MethodDefinition MethodDefinition { get; } public MethodDefinition MethodDefinition { get; }
SRM.MethodDefinition md;
public MethodTreeNode(MethodDefinition method) public MethodTreeNode(MethodDefinition method)
{ {
if (method.IsNil) if (method.IsNil)
throw new ArgumentNullException(nameof(method)); throw new ArgumentNullException(nameof(method));
this.MethodDefinition = method; this.MethodDefinition = method;
this.md = method.Module.Metadata.GetMethodDefinition(method.Handle);
} }
public override object Text => GetText(MethodDefinition, Language) + MethodDefinition.Handle.ToSuffixString(); public override object Text => GetText(MethodDefinition, Language) + MethodDefinition.Handle.ToSuffixString();
@ -54,7 +56,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public static ImageSource GetIcon(MethodDefinition method) public static ImageSource GetIcon(MethodDefinition method)
{ {
var metadata = method.Module.GetMetadataReader(); var metadata = method.Module.Metadata;
var methodDefinition = metadata.GetMethodDefinition(method.Handle); var methodDefinition = metadata.GetMethodDefinition(method.Handle);
var methodName = metadata.GetString(methodDefinition.Name); var methodName = metadata.GetString(methodDefinition.Name);
if (methodDefinition.HasFlag(MethodAttributes.SpecialName) && methodName.StartsWith("op_", StringComparison.Ordinal)) { if (methodDefinition.HasFlag(MethodAttributes.SpecialName) && methodName.StartsWith("op_", StringComparison.Ordinal)) {
@ -114,9 +116,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
{ {
if (!settings.ShowInternalApi && !IsPublicAPI) if (!settings.ShowInternalApi && !IsPublicAPI)
return FilterResult.Hidden; return FilterResult.Hidden;
var metadata = MethodDefinition.Module.GetMetadataReader(); var metadata = MethodDefinition.Module.Metadata;
var methodDefinition = metadata.GetMethodDefinition(MethodDefinition.Handle); if (settings.SearchTermMatches(metadata.GetString(md.Name)) && settings.Language.ShowMember(MethodDefinition))
if (settings.SearchTermMatches(metadata.GetString(methodDefinition.Name)) && settings.Language.ShowMember(MethodDefinition))
return FilterResult.Match; return FilterResult.Match;
else else
return FilterResult.Hidden; return FilterResult.Hidden;
@ -124,7 +125,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override bool IsPublicAPI { public override bool IsPublicAPI {
get { get {
switch (MethodDefinition.This().Attributes & MethodAttributes.MemberAccessMask) { switch (md.Attributes & MethodAttributes.MemberAccessMask) {
case MethodAttributes.Public: case MethodAttributes.Public:
case MethodAttributes.Family: case MethodAttributes.Family:
case MethodAttributes.FamORAssem: case MethodAttributes.FamORAssem:

6
ILSpy/TreeNodes/PropertyTreeNode.cs

@ -38,7 +38,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
if (property == null) if (property == null)
throw new ArgumentNullException(nameof(property)); throw new ArgumentNullException(nameof(property));
this.PropertyDefinition = property; this.PropertyDefinition = property;
var metadata = property.Module.GetMetadataReader(); var metadata = property.Module.Metadata;
var propertyDefinition = metadata.GetPropertyDefinition(property.Handle); var propertyDefinition = metadata.GetPropertyDefinition(property.Handle);
var accessors = propertyDefinition.GetAccessors(); var accessors = propertyDefinition.GetAccessors();
using (LoadedAssembly.DisableAssemblyLoad()) { using (LoadedAssembly.DisableAssemblyLoad()) {
@ -105,7 +105,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
// in numeric order, so we can do an integer comparison of the masked attribute // in numeric order, so we can do an integer comparison of the masked attribute
int accessLevel = 0; int accessLevel = 0;
var metadata = property.Module.GetMetadataReader(); var metadata = property.Module.Metadata;
var propertyDefinition = metadata.GetPropertyDefinition(property.Handle); var propertyDefinition = metadata.GetPropertyDefinition(property.Handle);
var accessors = propertyDefinition.GetAccessors(); var accessors = propertyDefinition.GetAccessors();
@ -142,7 +142,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
{ {
if (!settings.ShowInternalApi && !IsPublicAPI) if (!settings.ShowInternalApi && !IsPublicAPI)
return FilterResult.Hidden; return FilterResult.Hidden;
var metadata = PropertyDefinition.Module.GetMetadataReader(); var metadata = PropertyDefinition.Module.Metadata;
var propertyDefinition = metadata.GetPropertyDefinition(PropertyDefinition.Handle); var propertyDefinition = metadata.GetPropertyDefinition(PropertyDefinition.Handle);
if (settings.SearchTermMatches(metadata.GetString(propertyDefinition.Name)) && settings.Language.ShowMember(PropertyDefinition)) if (settings.SearchTermMatches(metadata.GetString(propertyDefinition.Name)) && settings.Language.ShowMember(PropertyDefinition))
return FilterResult.Match; return FilterResult.Match;

2
ILSpy/TreeNodes/ReferenceFolderTreeNode.cs

@ -54,7 +54,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
protected override void LoadChildren() protected override void LoadChildren()
{ {
var metadata = module.GetMetadataReader(); var metadata = module.Metadata;
foreach (var r in module.AssemblyReferences.OrderBy(r => r.Name)) foreach (var r in module.AssemblyReferences.OrderBy(r => r.Name))
this.Children.Add(new AssemblyReferenceTreeNode(r, parentAssembly)); this.Children.Add(new AssemblyReferenceTreeNode(r, parentAssembly));
foreach (var r in module.ModuleReferences.OrderBy(r => metadata.GetString(metadata.GetModuleReference(r).Name))) foreach (var r in module.ModuleReferences.OrderBy(r => metadata.GetString(metadata.GetModuleReference(r).Name)))

28
ILSpy/TreeNodes/TypeTreeNode.cs

@ -31,7 +31,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public sealed class TypeTreeNode : ILSpyTreeNode, IMemberTreeNode public sealed class TypeTreeNode : ILSpyTreeNode, IMemberTreeNode
{ {
readonly TypeDefinition typeDefinition; readonly TypeDefinition typeDefinition;
readonly SRM.TypeDefinition metadataTypeDefinition; readonly SRM.TypeDefinition td;
public TypeTreeNode(TypeDefinition typeDefinition, AssemblyTreeNode parentAssemblyNode) public TypeTreeNode(TypeDefinition typeDefinition, AssemblyTreeNode parentAssemblyNode)
{ {
@ -39,7 +39,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
throw new ArgumentNullException(nameof(typeDefinition)); throw new ArgumentNullException(nameof(typeDefinition));
this.ParentAssemblyNode = parentAssemblyNode ?? throw new ArgumentNullException(nameof(parentAssemblyNode)); this.ParentAssemblyNode = parentAssemblyNode ?? throw new ArgumentNullException(nameof(parentAssemblyNode));
this.typeDefinition = typeDefinition; this.typeDefinition = typeDefinition;
this.metadataTypeDefinition = typeDefinition.This(); this.td = typeDefinition.Module.Metadata.GetTypeDefinition(typeDefinition.Handle);
this.LazyLoading = true; this.LazyLoading = true;
} }
@ -51,7 +51,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override bool IsPublicAPI { public override bool IsPublicAPI {
get { get {
switch (metadataTypeDefinition.Attributes & TypeAttributes.VisibilityMask) { switch (td.Attributes & TypeAttributes.VisibilityMask) {
case TypeAttributes.Public: case TypeAttributes.Public:
case TypeAttributes.NestedPublic: case TypeAttributes.NestedPublic:
case TypeAttributes.NestedFamily: case TypeAttributes.NestedFamily:
@ -67,7 +67,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
{ {
if (!settings.ShowInternalApi && !IsPublicAPI) if (!settings.ShowInternalApi && !IsPublicAPI)
return FilterResult.Hidden; return FilterResult.Hidden;
if (settings.SearchTermMatches(TypeDefinition.Module.GetMetadataReader().GetString(metadataTypeDefinition.Name))) { if (settings.SearchTermMatches(TypeDefinition.Module.Metadata.GetString(td.Name))) {
if (settings.Language.ShowMember(TypeDefinition)) if (settings.Language.ShowMember(TypeDefinition))
return FilterResult.Match; return FilterResult.Match;
else else
@ -79,25 +79,25 @@ namespace ICSharpCode.ILSpy.TreeNodes
protected override void LoadChildren() protected override void LoadChildren()
{ {
var metadata = TypeDefinition.Module.GetMetadataReader(); var metadata = TypeDefinition.Module.Metadata;
if (!metadataTypeDefinition.BaseType.IsNil || metadataTypeDefinition.GetInterfaceImplementations().Any()) if (!td.BaseType.IsNil || td.GetInterfaceImplementations().Any())
this.Children.Add(new BaseTypesTreeNode(TypeDefinition)); this.Children.Add(new BaseTypesTreeNode(TypeDefinition));
if (!metadataTypeDefinition.HasFlag(TypeAttributes.Sealed)) if (!td.HasFlag(TypeAttributes.Sealed))
this.Children.Add(new DerivedTypesTreeNode(ParentAssemblyNode.AssemblyList, TypeDefinition)); this.Children.Add(new DerivedTypesTreeNode(ParentAssemblyNode.AssemblyList, TypeDefinition));
foreach (var nestedType in metadataTypeDefinition.GetNestedTypes().OrderBy(m => metadata.GetString(metadata.GetTypeDefinition(m).Name), NaturalStringComparer.Instance)) { foreach (var nestedType in td.GetNestedTypes().OrderBy(m => metadata.GetString(metadata.GetTypeDefinition(m).Name), NaturalStringComparer.Instance)) {
this.Children.Add(new TypeTreeNode(new TypeDefinition(TypeDefinition.Module, nestedType), ParentAssemblyNode)); this.Children.Add(new TypeTreeNode(new TypeDefinition(TypeDefinition.Module, nestedType), ParentAssemblyNode));
} }
foreach (var field in metadataTypeDefinition.GetFields().OrderBy(m => metadata.GetString(metadata.GetFieldDefinition(m).Name), NaturalStringComparer.Instance)) { foreach (var field in td.GetFields().OrderBy(m => metadata.GetString(metadata.GetFieldDefinition(m).Name), NaturalStringComparer.Instance)) {
this.Children.Add(new FieldTreeNode(new FieldDefinition(TypeDefinition.Module, field))); this.Children.Add(new FieldTreeNode(new FieldDefinition(TypeDefinition.Module, field)));
} }
foreach (var property in metadataTypeDefinition.GetProperties().OrderBy(m => metadata.GetString(metadata.GetPropertyDefinition(m).Name), NaturalStringComparer.Instance)) { foreach (var property in td.GetProperties().OrderBy(m => metadata.GetString(metadata.GetPropertyDefinition(m).Name), NaturalStringComparer.Instance)) {
this.Children.Add(new PropertyTreeNode(new PropertyDefinition(TypeDefinition.Module, property))); this.Children.Add(new PropertyTreeNode(new PropertyDefinition(TypeDefinition.Module, property)));
} }
foreach (var ev in metadataTypeDefinition.GetEvents().OrderBy(m => metadata.GetString(metadata.GetEventDefinition(m).Name), NaturalStringComparer.Instance)) { foreach (var ev in td.GetEvents().OrderBy(m => metadata.GetString(metadata.GetEventDefinition(m).Name), NaturalStringComparer.Instance)) {
this.Children.Add(new EventTreeNode(new EventDefinition(TypeDefinition.Module, ev))); this.Children.Add(new EventTreeNode(new EventDefinition(TypeDefinition.Module, ev)));
} }
foreach (var method in metadataTypeDefinition.GetMethods().OrderBy(m => metadata.GetString(metadata.GetMethodDefinition(m).Name), NaturalStringComparer.Instance)) { foreach (var method in td.GetMethods().OrderBy(m => metadata.GetString(metadata.GetMethodDefinition(m).Name), NaturalStringComparer.Instance)) {
if (method.GetMethodSemanticsAttributes(metadata) == 0) { if (method.GetMethodSemanticsAttributes(metadata) == 0) {
this.Children.Add(new MethodTreeNode(new MethodDefinition(TypeDefinition.Module, method))); this.Children.Add(new MethodTreeNode(new MethodDefinition(TypeDefinition.Module, method)));
} }
@ -123,7 +123,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
static TypeIcon GetTypeIcon(TypeDefinition type) static TypeIcon GetTypeIcon(TypeDefinition type)
{ {
var metadata = type.Module.GetMetadataReader(); var metadata = type.Module.Metadata;
var typeDefinition = metadata.GetTypeDefinition(type.Handle); var typeDefinition = metadata.GetTypeDefinition(type.Handle);
if (typeDefinition.IsValueType(metadata)) { if (typeDefinition.IsValueType(metadata)) {
if (typeDefinition.IsEnum(metadata)) if (typeDefinition.IsEnum(metadata))
@ -144,7 +144,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
private static AccessOverlayIcon GetOverlayIcon(TypeDefinition type) private static AccessOverlayIcon GetOverlayIcon(TypeDefinition type)
{ {
var def = type.This(); var def = type.Module.Metadata.GetTypeDefinition(type.Handle);
AccessOverlayIcon overlay; AccessOverlayIcon overlay;
switch (def.Attributes & TypeAttributes.VisibilityMask) { switch (def.Attributes & TypeAttributes.VisibilityMask) {
case TypeAttributes.Public: case TypeAttributes.Public:

2
TestPlugin/CustomLanguage.cs

@ -32,7 +32,7 @@ namespace TestPlugin
// There are several methods available to override; in this sample, we deal with methods only // There are several methods available to override; in this sample, we deal with methods only
public override void DecompileMethod(ICSharpCode.Decompiler.Metadata.MethodDefinition method, ITextOutput output, DecompilationOptions options) public override void DecompileMethod(ICSharpCode.Decompiler.Metadata.MethodDefinition method, ITextOutput output, DecompilationOptions options)
{ {
var metadata = method.Module.GetMetadataReader(); var metadata = method.Module.Metadata;
var methodDef = metadata.GetMethodDefinition(method.Handle); var methodDef = metadata.GetMethodDefinition(method.Handle);
if (methodDef.HasBody()) { if (methodDef.HasBody()) {
var methodBody = method.Module.Reader.GetMethodBody(methodDef.RelativeVirtualAddress); var methodBody = method.Module.Reader.GetMethodBody(methodDef.RelativeVirtualAddress);

Loading…
Cancel
Save