Browse Source

Rename Dom -> Metadata; Remove bogus abstraction

pull/1198/head
Siegfried Pammer 7 years ago
parent
commit
87ced033ba
  1. 2
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  2. 16
      ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs
  3. 6
      ICSharpCode.Decompiler/CSharp/Transforms/AddXmlDocumentationTransform.cs
  4. 5
      ICSharpCode.Decompiler/CecilExtensions.cs
  5. 4
      ICSharpCode.Decompiler/Disassembler/BlobDecoder.cs
  6. 20
      ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs
  7. 455
      ICSharpCode.Decompiler/Disassembler/DomExtensions.cs
  8. 10
      ICSharpCode.Decompiler/Disassembler/ILStructure.cs
  9. 57
      ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs
  10. 29
      ICSharpCode.Decompiler/Disassembler/OpCodeInfo.cs
  11. 234
      ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs
  12. 389
      ICSharpCode.Decompiler/Documentation/XmlDocKeyProvider.cs
  13. 43
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  14. 168
      ICSharpCode.Decompiler/IL/ILOpCodes.tt
  15. 585
      ICSharpCode.Decompiler/Metadata/Dom.cs
  16. 3
      ICSharpCode.Decompiler/Metadata/DotNetCorePathFinder.cs
  17. 2
      ICSharpCode.Decompiler/Metadata/DotNetCorePathFinderExtensions.cs
  18. 108
      ICSharpCode.Decompiler/Metadata/ILOpCodes.cs
  19. 64
      ICSharpCode.Decompiler/Metadata/ILOpCodes.tt
  20. 0
      ICSharpCode.Decompiler/Metadata/LightJson/JsonArray.cs
  21. 0
      ICSharpCode.Decompiler/Metadata/LightJson/JsonObject.cs
  22. 0
      ICSharpCode.Decompiler/Metadata/LightJson/JsonValue.cs
  23. 0
      ICSharpCode.Decompiler/Metadata/LightJson/JsonValueType.cs
  24. 0
      ICSharpCode.Decompiler/Metadata/LightJson/Serialization/JsonParseException.cs
  25. 0
      ICSharpCode.Decompiler/Metadata/LightJson/Serialization/JsonReader.cs
  26. 0
      ICSharpCode.Decompiler/Metadata/LightJson/Serialization/JsonSerializationException.cs
  27. 0
      ICSharpCode.Decompiler/Metadata/LightJson/Serialization/JsonWriter.cs
  28. 0
      ICSharpCode.Decompiler/Metadata/LightJson/Serialization/TextPosition.cs
  29. 0
      ICSharpCode.Decompiler/Metadata/LightJson/Serialization/TextScanner.cs
  30. 193
      ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs
  31. 40
      ICSharpCode.Decompiler/Metadata/MetadataResolver.cs
  32. 114
      ICSharpCode.Decompiler/Metadata/OperandType.cs
  33. 2
      ICSharpCode.Decompiler/Metadata/SequencePoint.cs
  34. 4
      ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs
  35. 2
      ICSharpCode.Decompiler/Metadata/UnresolvedAssemblyNameReference.cs
  36. 204
      ICSharpCode.Decompiler/SRMExtensions.cs
  37. 62
      ICSharpCode.Decompiler/SRMHacks.cs
  38. 3
      ICSharpCode.Decompiler/TypeSystem/CecilLoader.cs
  39. 42
      ICSharpCode.Decompiler/TypeSystem/Implementation/TypeSpecification.cs
  40. 8
      ILSpy/ExtensionMethods.cs
  41. 1
      ILSpy/ILSpy.csproj
  42. 2
      ILSpy/Languages/ILAstLanguage.cs
  43. 47
      ILSpy/Languages/ILLanguage.cs
  44. 86
      ILSpy/Languages/ITypeProvider.cs
  45. 80
      ILSpy/Languages/Language.cs
  46. 2
      ILSpy/LoadedAssembly.cs
  47. 6
      ILSpy/MainWindow.xaml.cs
  48. 4
      ILSpy/SearchPane.cs
  49. 106
      ILSpy/SearchStrategies.cs
  50. 18
      ILSpy/TextView/DecompilerTextView.cs
  51. 1
      ILSpy/TreeNodes/Analyzer/AnalyzedPropertyOverridesTreeNode.cs
  52. 4
      ILSpy/TreeNodes/Analyzer/AnalyzerEntityTreeNode.cs
  53. 19
      ILSpy/TreeNodes/AssemblyListTreeNode.cs
  54. 12
      ILSpy/TreeNodes/AssemblyTreeNode.cs
  55. 41
      ILSpy/TreeNodes/BaseTypesEntryNode.cs
  56. 13
      ILSpy/TreeNodes/BaseTypesTreeNode.cs
  57. 16
      ILSpy/TreeNodes/DerivedTypesEntryNode.cs
  58. 23
      ILSpy/TreeNodes/DerivedTypesTreeNode.cs
  59. 65
      ILSpy/TreeNodes/EventTreeNode.cs
  60. 62
      ILSpy/TreeNodes/FieldTreeNode.cs
  61. 4
      ILSpy/TreeNodes/IMemberTreeNode.cs
  62. 39
      ILSpy/TreeNodes/MethodTreeNode.cs
  63. 68
      ILSpy/TreeNodes/PropertyTreeNode.cs
  64. 2
      ILSpy/TreeNodes/ResourceListTreeNode.cs
  65. 2
      ILSpy/TreeNodes/ResourceNodes/CursorResourceEntryNode.cs
  66. 2
      ILSpy/TreeNodes/ResourceNodes/IResourceNodeFactory.cs
  67. 2
      ILSpy/TreeNodes/ResourceNodes/IconResourceEntryNode.cs
  68. 2
      ILSpy/TreeNodes/ResourceNodes/ImageListResourceEntryNode.cs
  69. 2
      ILSpy/TreeNodes/ResourceNodes/ImageResourceEntryNode.cs
  70. 2
      ILSpy/TreeNodes/ResourceNodes/ResourceTreeNode.cs
  71. 2
      ILSpy/TreeNodes/ResourceNodes/ResourcesFileTreeNode.cs
  72. 2
      ILSpy/TreeNodes/ResourceNodes/XamlResourceNode.cs
  73. 2
      ILSpy/TreeNodes/ResourceNodes/XmlResourceNode.cs
  74. 57
      ILSpy/TreeNodes/TypeTreeNode.cs

2
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -1158,7 +1158,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1158,7 +1158,7 @@ namespace ICSharpCode.Decompiler.CSharp
///
/// This only works correctly when the nodes in the syntax tree have line/column information.
/// </summary>
public Dictionary<ILFunction, List<Dom.SequencePoint>> CreateSequencePoints(SyntaxTree syntaxTree)
public Dictionary<ILFunction, List<Metadata.SequencePoint>> CreateSequencePoints(SyntaxTree syntaxTree)
{
SequencePointBuilder spb = new SequencePointBuilder();
syntaxTree.AcceptVisitor(spb);

16
ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs

@ -56,7 +56,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -56,7 +56,7 @@ namespace ICSharpCode.Decompiler.CSharp
}
}
readonly List<(ILFunction, Dom.SequencePoint)> sequencePoints = new List<(ILFunction, Dom.SequencePoint)>();
readonly List<(ILFunction, Metadata.SequencePoint)> sequencePoints = new List<(ILFunction, Metadata.SequencePoint)>();
readonly HashSet<ILInstruction> mappedInstructions = new HashSet<ILInstruction>();
// Stack holding information for outer statements.
@ -219,7 +219,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -219,7 +219,7 @@ namespace ICSharpCode.Decompiler.CSharp
// use LongSet to deduplicate and merge the intervals
var longSet = new LongSet(current.Intervals.Select(i => new LongInterval(i.Start, i.End)));
Debug.Assert(!longSet.IsEmpty);
sequencePoints.Add((current.Function, new Dom.SequencePoint {
sequencePoints.Add((current.Function, new Metadata.SequencePoint {
Offset = (int)longSet.Intervals[0].Start,
EndOffset = (int)longSet.Intervals[0].End,
StartLine = startLocation.Line,
@ -277,18 +277,18 @@ namespace ICSharpCode.Decompiler.CSharp @@ -277,18 +277,18 @@ namespace ICSharpCode.Decompiler.CSharp
/// <summary>
/// Called after the visitor is done to return the results.
/// </summary>
internal Dictionary<ILFunction, List<Dom.SequencePoint>> GetSequencePoints()
internal Dictionary<ILFunction, List<Metadata.SequencePoint>> GetSequencePoints()
{
var dict = new Dictionary<ILFunction, List<Dom.SequencePoint>>();
var dict = new Dictionary<ILFunction, List<Metadata.SequencePoint>>();
foreach (var (function, sequencePoint) in this.sequencePoints) {
if (!dict.TryGetValue(function, out var list)) {
dict.Add(function, list = new List<Dom.SequencePoint>());
dict.Add(function, list = new List<Metadata.SequencePoint>());
}
list.Add(sequencePoint);
}
foreach (var (function, list) in dict.ToList()) {
// For each function, sort sequence points and fix overlaps+gaps
var newList = new List<Dom.SequencePoint>();
var newList = new List<Metadata.SequencePoint>();
int pos = 0;
foreach (var sequencePoint in list.OrderBy(sp => sp.Offset).ThenBy(sp => sp.EndOffset)) {
if (sequencePoint.Offset < pos) {
@ -305,7 +305,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -305,7 +305,7 @@ namespace ICSharpCode.Decompiler.CSharp
}
} else if (sequencePoint.Offset > pos) {
// insert hidden sequence point in the gap.
var hidden = new Dom.SequencePoint();
var hidden = new Metadata.SequencePoint();
hidden.Offset = pos;
hidden.EndOffset = sequencePoint.Offset;
hidden.SetHidden();
@ -315,7 +315,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -315,7 +315,7 @@ namespace ICSharpCode.Decompiler.CSharp
pos = sequencePoint.EndOffset;
}
if (pos < function.CecilMethod.Body.CodeSize) {
var hidden = new Dom.SequencePoint();
var hidden = new Metadata.SequencePoint();
hidden.Offset = pos;
hidden.EndOffset = function.CecilMethod.Body.CodeSize;
hidden.SetHidden();

6
ICSharpCode.Decompiler/CSharp/Transforms/AddXmlDocumentationTransform.cs

@ -41,8 +41,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -41,8 +41,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
return;
foreach (var entity in rootNode.DescendantsAndSelf.OfType<EntityDeclaration>()) {
var symbol = entity.GetSymbol();
Mono.Cecil.MemberReference mr;
switch (symbol) {
#warning TODO : replace with SRM
/*switch (symbol) {
case IMember member:
mr = context.TypeSystem.GetCecil(member);
break;
@ -57,7 +57,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -57,7 +57,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
string doc = xmldoc.GetDocumentation(XmlDocKeyProvider.GetKey(mr));
if (doc != null) {
InsertXmlDocumentation(entity, new StringReader(doc));
}
}*/
}
} catch (XmlException ex) {
string[] msg = (" Exception while reading XmlDoc: " + ex).Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);

5
ICSharpCode.Decompiler/CecilExtensions.cs

@ -219,11 +219,6 @@ namespace ICSharpCode.Decompiler @@ -219,11 +219,6 @@ namespace ICSharpCode.Decompiler
}
}
public static FullTypeName GetFullTypeName(this TypeDefinition typeDef)
{
return new FullTypeName(typeDef.FullName);
}
public static bool IsDelegate(this TypeDefinition type)
{
if (type.BaseType != null && type.BaseType.Namespace == "System") {

4
ICSharpCode.Decompiler/Disassembler/BlobDecoder.cs

@ -133,14 +133,10 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -133,14 +133,10 @@ namespace ICSharpCode.Decompiler.Disassembler
public KeyValuePair<string, ResolveResult> ReadNamedArg()
{
SymbolKind memberType;
var b = blob.ReadByte();
switch (b) {
case 0x53:
memberType = SymbolKind.Field;
break;
case 0x54:
memberType = SymbolKind.Property;
break;
default:
throw new NotSupportedException(string.Format("Custom member type 0x{0:x} is not supported.", b));

20
ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs

@ -21,7 +21,7 @@ using System.Collections.Generic; @@ -21,7 +21,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection.Metadata;
using System.Text;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.Util;
using SRM = System.Reflection.Metadata;
@ -67,7 +67,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -67,7 +67,7 @@ namespace ICSharpCode.Decompiler.Disassembler
writer.WriteReference(OffsetToString(offset.Value), offset);
}
public static void WriteTo(this SRM.ExceptionRegion exceptionHandler, Dom.MethodDefinition method, ITextOutput writer)
public static void WriteTo(this SRM.ExceptionRegion exceptionHandler, Metadata.MethodDefinition method, ITextOutput writer)
{
writer.Write(".try ");
WriteOffsetReference(writer, exceptionHandler.TryOffset);
@ -82,7 +82,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -82,7 +82,7 @@ namespace ICSharpCode.Decompiler.Disassembler
}
if (!exceptionHandler.CatchType.IsNil) {
writer.Write(' ');
exceptionHandler.CatchType.CoerceTypeReference(method.Module).WriteTo(writer, new GenericContext(method));
exceptionHandler.CatchType.WriteTo(method.Module, writer, new GenericContext(method));
}
writer.Write(' ');
WriteOffsetReference(writer, exceptionHandler.HandlerOffset);
@ -120,7 +120,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -120,7 +120,7 @@ namespace ICSharpCode.Decompiler.Disassembler
public static string Escape(string identifier)
{
if (IsValidIdentifier(identifier) && !IL.ILOpCodeExtensions.ILKeywords.Contains(identifier)) {
if (IsValidIdentifier(identifier) && !Metadata.ILOpCodeExtensions.ILKeywords.Contains(identifier)) {
return identifier;
} else {
// The ECMA specification says that ' inside SQString should be ecaped using an octal escape sequence,
@ -129,15 +129,17 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -129,15 +129,17 @@ namespace ICSharpCode.Decompiler.Disassembler
}
}
public static void WriteParameterReference(ITextOutput writer, Dom.MethodDefinition method, int sequence)
public static void WriteParameterReference(ITextOutput writer, Metadata.MethodDefinition method, int sequence)
{
var metadata = method.Module.GetMetadataReader();
var signatureHeader = method.DecodeSignature(new FullTypeNameSignatureDecoder(metadata), default(Unit)).Header;
var methodDefinition = metadata.GetMethodDefinition(method.Handle);
var signatureHeader = methodDefinition.DecodeSignature(new FullTypeNameSignatureDecoder(metadata), default(Unit)).Header;
int index = signatureHeader.IsInstance && !signatureHeader.HasExplicitThis ? sequence - 1 : sequence;
if (index < 0 || index >= method.Parameters.Count) {
var parameters = methodDefinition.GetParameters();
if (index < 0 || index >= parameters.Count) {
writer.Write(sequence.ToString());
} else {
var param = metadata.GetParameter(method.Parameters.ElementAt(index));
var param = metadata.GetParameter(parameters.ElementAt(index));
if (param.Name.IsNil) {
writer.Write(sequence.ToString());
} else {
@ -146,7 +148,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -146,7 +148,7 @@ namespace ICSharpCode.Decompiler.Disassembler
}
}
public static void WriteVariableReference(ITextOutput writer, Dom.MethodDefinition method, int index)
public static void WriteVariableReference(ITextOutput writer, Metadata.MethodDefinition method, int index)
{
writer.Write(index.ToString());
}

455
ICSharpCode.Decompiler/Disassembler/DomExtensions.cs

@ -20,220 +20,40 @@ using System; @@ -20,220 +20,40 @@ using System;
using System.Collections.Immutable;
using System.Reflection;
using System.Reflection.Metadata;
using SRM = System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.Disassembler
{
public static class DomExtensions
public static class MetadataExtensions
{
public static void WriteTo(this Dom.FieldDefinition field, ITextOutput output)
public static void WriteTo(this Metadata.TypeDefinition typeDefinition, ITextOutput output, ILNameSyntax syntax = ILNameSyntax.Signature)
{
var signature = field.DecodeSignature(new DisassemblerSignatureProvider(field.Module, output), new GenericContext(field.DeclaringType));
signature(ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write(' ');
field.DeclaringType.WriteTo(output, ILNameSyntax.TypeName);
output.Write("::");
output.Write(DisassemblerHelpers.Escape(field.Name));
}
public static void WriteTo(this IMemberReference member, ITextOutput output, GenericContext genericContext, ILNameSyntax syntax = ILNameSyntax.Signature)
{
void WriteParent(EntityHandle parentHandle)
{
var metadata = member.Module.GetMetadataReader();
switch (parentHandle.Kind) {
case HandleKind.MethodDefinition:
new Dom.MethodDefinition(member.Module, (MethodDefinitionHandle)parentHandle).WriteTo(output, genericContext, syntax);
break;
case HandleKind.ModuleReference:
output.Write('[');
var moduleRef = metadata.GetModuleReference((ModuleReferenceHandle)parentHandle);
output.Write(metadata.GetString(moduleRef.Name));
output.Write(']');
break;
case HandleKind.TypeDefinition:
new Dom.TypeDefinition(member.Module, (TypeDefinitionHandle)parentHandle).WriteTo(output, syntax);
break;
case HandleKind.TypeReference:
new Dom.TypeReference(member.Module, (TypeReferenceHandle)parentHandle).WriteTo(output, syntax);
break;
case HandleKind.TypeSpecification:
new Dom.TypeSpecification(member.Module, (TypeSpecificationHandle)parentHandle).WriteTo(output, genericContext, syntax);
break;
}
}
MethodSignature<Action<ILNameSyntax>> signature;
switch (member) {
case Dom.MethodDefinition md:
md.WriteTo(output);
break;
case Dom.MemberReference mr:
switch (mr.Kind) {
case MemberReferenceKind.Method:
signature = mr.DecodeMethodSignature(new DisassemblerSignatureProvider(member.Module, output), genericContext);
if (signature.Header.HasExplicitThis) {
output.Write("instance explicit ");
} else if (signature.Header.IsInstance) {
output.Write("instance ");
}
if (signature.Header.CallingConvention == SignatureCallingConvention.VarArgs) {
output.Write("vararg ");
}
signature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write(' ');
WriteParent(mr.Parent);
output.Write("::");
output.Write(DisassemblerHelpers.Escape(mr.Name));
output.Write("(");
for (int i = 0; i < signature.ParameterTypes.Length; ++i) {
if (i > 0)
output.Write(", ");
signature.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters);
}
output.Write(")");
break;
case MemberReferenceKind.Field:
var fieldSignature = mr.DecodeFieldSignature(new DisassemblerSignatureProvider(member.Module, output), genericContext);
fieldSignature(ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write(' ');
WriteParent(mr.Parent);
output.Write("::");
output.Write(DisassemblerHelpers.Escape(mr.Name));
break;
}
break;
case Dom.MethodSpecification ms:
var substitution = ms.DecodeSignature(new DisassemblerSignatureProvider(ms.Module, output), genericContext);
switch (ms.Method) {
case Dom.MethodDefinition method:
var metadata = method.Module.GetMetadataReader();
signature = method.DecodeSignature(new DisassemblerSignatureProvider(method.Module, output), new GenericContext(method));
if (signature.Header.HasExplicitThis) {
output.Write("instance explicit ");
} else if (signature.Header.IsInstance) {
output.Write("instance ");
}
if (signature.Header.CallingConvention == SignatureCallingConvention.VarArgs) {
output.Write("vararg ");
}
signature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write(' ');
if (!method.DeclaringType.IsNil) {
method.DeclaringType.WriteTo(output, ILNameSyntax.TypeName);
output.Write("::");
}
bool isCompilerControlled = (method.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.PrivateScope;
if (isCompilerControlled) {
output.Write(DisassemblerHelpers.Escape(method.Name + "$PST" + MetadataTokens.GetToken(method.Handle).ToString("X8")));
} else {
output.Write(DisassemblerHelpers.Escape(method.Name));
}
output.Write('<');
for (int i = 0; i < substitution.Length; i++) {
if (i > 0)
output.Write(", ");
substitution[i](syntax);
}
output.Write('>');
output.Write("(");
for (int i = 0; i < signature.ParameterTypes.Length; ++i) {
if (i > 0)
output.Write(", ");
signature.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters);
}
output.Write(")");
break;
case Dom.MemberReference mr:
signature = mr.DecodeMethodSignature(new DisassemblerSignatureProvider(member.Module, output), genericContext);
if (signature.Header.HasExplicitThis) {
output.Write("instance explicit ");
} else if (signature.Header.IsInstance) {
output.Write("instance ");
}
if (signature.Header.CallingConvention == SignatureCallingConvention.VarArgs) {
output.Write("vararg ");
}
signature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write(' ');
WriteParent(mr.Parent);
output.Write("::");
output.Write(DisassemblerHelpers.Escape(mr.Name));
output.Write('<');
for (int i = 0; i < substitution.Length; i++) {
if (i > 0)
output.Write(", ");
substitution[i](syntax);
}
output.Write('>');
output.Write("(");
for (int i = 0; i < signature.ParameterTypes.Length; ++i) {
if (i > 0)
output.Write(", ");
signature.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters);
}
output.Write(")");
break;
}
break;
}
}
public static void WriteTo(this Dom.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 Dom.TypeReference(currentTypeRef.Module, (TypeReferenceHandle)currentTypeRef.ResolutionScope);
}
switch (currentTypeRef.ResolutionScope.Kind) {
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(typeRef.FullName.ToILNameString(), typeRef);
}
public static void WriteTo(this Dom.TypeDefinition typeDefinition, ITextOutput output, ILNameSyntax syntax = ILNameSyntax.Signature)
{
output.WriteReference(typeDefinition.FullName.ToILNameString(), typeDefinition);
}
public static void WriteTo(this Dom.TypeSpecification typeSpecification, ITextOutput output, GenericContext genericContext, ILNameSyntax syntax = ILNameSyntax.Signature)
{
var signature = typeSpecification.DecodeSignature(new DisassemblerSignatureProvider(typeSpecification.Module, output), genericContext);
signature(syntax);
var metadata = typeDefinition.Module.GetMetadataReader();
output.WriteReference(typeDefinition.This().GetFullTypeName(metadata).ToILNameString(), typeDefinition);
}
public static void WriteTo(this ITypeReference type, ITextOutput output, GenericContext genericContext, ILNameSyntax syntax = ILNameSyntax.Signature)
public static void WriteTo(this Metadata.FieldDefinition field, ITextOutput output)
{
switch (type) {
case Dom.TypeDefinition td:
td.WriteTo(output, syntax);
break;
case Dom.TypeReference tr:
tr.WriteTo(output, syntax);
break;
case Dom.TypeSpecification ts:
ts.WriteTo(output, genericContext, syntax);
break;
}
var metadata = field.Module.GetMetadataReader();
var fieldDefinition = metadata.GetFieldDefinition(field.Handle);
var declaringType = new Metadata.TypeDefinition(field.Module, fieldDefinition.GetDeclaringType());
var signature = fieldDefinition.DecodeSignature(new DisassemblerSignatureProvider(field.Module, output), new GenericContext(declaringType));
signature(ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write(' ');
declaringType.WriteTo(output, ILNameSyntax.TypeName);
output.Write("::");
output.Write(DisassemblerHelpers.Escape(metadata.GetString(fieldDefinition.Name)));
}
public static void WriteTo(this Dom.MethodDefinition method, ITextOutput output)
public static void WriteTo(this Metadata.MethodDefinition method, ITextOutput output)
{
var metadata = method.Module.GetMetadataReader();
var signature = method.DecodeSignature(new DisassemblerSignatureProvider(method.Module, output), new GenericContext(method));
var methodDefinition = method.This();
var signature = methodDefinition.DecodeSignature(new DisassemblerSignatureProvider(method.Module, output), new GenericContext(method));
if (signature.Header.HasExplicitThis) {
output.Write("instance explicit ");
} else if (signature.Header.IsInstance) {
@ -244,17 +64,18 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -244,17 +64,18 @@ namespace ICSharpCode.Decompiler.Disassembler
}
signature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write(' ');
if (!method.DeclaringType.IsNil) {
method.DeclaringType.WriteTo(output, ILNameSyntax.TypeName);
var declaringType = methodDefinition.GetDeclaringType();
if (!declaringType.IsNil) {
new Metadata.TypeDefinition(method.Module, declaringType).WriteTo(output, ILNameSyntax.TypeName);
output.Write("::");
}
bool isCompilerControlled = (method.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.PrivateScope;
bool isCompilerControlled = (methodDefinition.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.PrivateScope;
if (isCompilerControlled) {
output.Write(DisassemblerHelpers.Escape(method.Name + "$PST" + MetadataTokens.GetToken(method.Handle).ToString("X8")));
} else {
output.Write(DisassemblerHelpers.Escape(method.Name));
}
var genericParameters = method.GenericParameters;
var genericParameters = methodDefinition.GetGenericParameters();
if (genericParameters.Count > 0) {
output.Write('<');
for (int i = 0; i < genericParameters.Count; i++) {
@ -276,7 +97,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -276,7 +97,7 @@ namespace ICSharpCode.Decompiler.Disassembler
if (j > 0)
output.Write(", ");
var constraint = metadata.GetGenericParameterConstraint(constraints[j]);
constraint.Type.CoerceTypeReference(method.Module).WriteTo(output, new GenericContext(method), ILNameSyntax.TypeName);
constraint.Type.WriteTo(method.Module, output, new GenericContext(method), ILNameSyntax.TypeName);
}
output.Write(") ");
}
@ -298,6 +119,224 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -298,6 +119,224 @@ namespace ICSharpCode.Decompiler.Disassembler
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;
case HandleKind.MemberReference:
WriteTo((MemberReferenceHandle)entity.Handle, entity.Module, output, genericContext, syntax);
break;
case HandleKind.MethodSpecification:
WriteTo((MethodSpecificationHandle)entity.Handle, entity.Module, output, genericContext, syntax);
break;
case HandleKind.PropertyDefinition:
case HandleKind.EventDefinition:
default:
throw new NotSupportedException();
}
}
public static void WriteTo(this MethodSpecificationHandle handle, PEFile module, ITextOutput output, GenericContext genericContext, ILNameSyntax syntax)
{
var metadata = module.GetMetadataReader();
var ms = metadata.GetMethodSpecification(handle);
var substitution = ms.DecodeSignature(new DisassemblerSignatureProvider(module, output), genericContext);
MethodSignature<Action<ILNameSyntax>> signature;
switch (ms.Method.Kind) {
case HandleKind.MethodDefinition:
var methodDefinition = metadata.GetMethodDefinition((MethodDefinitionHandle)ms.Method);
var methodName = metadata.GetString(methodDefinition.Name);
signature = methodDefinition.DecodeSignature(new DisassemblerSignatureProvider(module, output), genericContext);
if (signature.Header.HasExplicitThis) {
output.Write("instance explicit ");
} else if (signature.Header.IsInstance) {
output.Write("instance ");
}
if (signature.Header.CallingConvention == SignatureCallingConvention.VarArgs) {
output.Write("vararg ");
}
signature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write(' ');
var declaringType = methodDefinition.GetDeclaringType();
if (!declaringType.IsNil) {
new Metadata.TypeDefinition(module, declaringType).WriteTo(output, ILNameSyntax.TypeName);
output.Write("::");
}
bool isCompilerControlled = (methodDefinition.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.PrivateScope;
if (isCompilerControlled) {
output.Write(DisassemblerHelpers.Escape(methodName + "$PST" + MetadataTokens.GetToken(ms.Method).ToString("X8")));
} else {
output.Write(DisassemblerHelpers.Escape(methodName));
}
output.Write('<');
for (int i = 0; i < substitution.Length; i++) {
if (i > 0)
output.Write(", ");
substitution[i](syntax);
}
output.Write('>');
output.Write("(");
for (int i = 0; i < signature.ParameterTypes.Length; ++i) {
if (i > 0)
output.Write(", ");
signature.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters);
}
output.Write(")");
break;
case HandleKind.MemberReference:
var memberReference = metadata.GetMemberReference((MemberReferenceHandle)ms.Method);
var memberName = metadata.GetString(memberReference.Name);
signature = memberReference.DecodeMethodSignature(new DisassemblerSignatureProvider(module, output), genericContext);
if (signature.Header.HasExplicitThis) {
output.Write("instance explicit ");
} else if (signature.Header.IsInstance) {
output.Write("instance ");
}
if (signature.Header.CallingConvention == SignatureCallingConvention.VarArgs) {
output.Write("vararg ");
}
signature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write(' ');
WriteParent(output, module, metadata, memberReference.Parent, genericContext, syntax);
output.Write("::");
output.Write(DisassemblerHelpers.Escape(memberName));
output.Write('<');
for (int i = 0; i < substitution.Length; i++) {
if (i > 0)
output.Write(", ");
substitution[i](syntax);
}
output.Write('>');
output.Write("(");
for (int i = 0; i < signature.ParameterTypes.Length; ++i) {
if (i > 0)
output.Write(", ");
signature.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters);
}
output.Write(")");
break;
}
}
public static void WriteTo(this MemberReferenceHandle handle, PEFile module, ITextOutput output, GenericContext genericContext, ILNameSyntax syntax = ILNameSyntax.Signature)
{
var metadata = module.GetMetadataReader();
var mr = metadata.GetMemberReference(handle);
var memberName = metadata.GetString(mr.Name);
switch (mr.GetKind()) {
case MemberReferenceKind.Method:
var methodSignature = mr.DecodeMethodSignature(new DisassemblerSignatureProvider(module, output), genericContext);
if (methodSignature.Header.HasExplicitThis) {
output.Write("instance explicit ");
} 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)
output.Write(", ");
methodSignature.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters);
}
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;
}
}
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.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(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)
{
switch (parentHandle.Kind) {
case HandleKind.MethodDefinition:
new Metadata.MethodDefinition(module, (MethodDefinitionHandle)parentHandle).WriteTo(output);
break;
case HandleKind.ModuleReference:
output.Write('[');
var moduleRef = metadata.GetModuleReference((ModuleReferenceHandle)parentHandle);
output.Write(metadata.GetString(moduleRef.Name));
output.Write(']');
break;
case HandleKind.TypeDefinition:
new Metadata.TypeDefinition(module, (TypeDefinitionHandle)parentHandle).WriteTo(output, syntax);
break;
case HandleKind.TypeReference:
new Metadata.TypeReference(module, (TypeReferenceHandle)parentHandle).WriteTo(output, syntax);
break;
case HandleKind.TypeSpecification:
new Metadata.TypeSpecification(module, (TypeSpecificationHandle)parentHandle).WriteTo(output, genericContext, syntax);
break;
}
}
/*
public static bool IsBaseTypeOf(this ITypeReference baseType, ITypeReference derivedType)
{
var derivedTypeDefinition = derivedType.GetDefinition();
@ -313,7 +352,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -313,7 +352,7 @@ namespace ICSharpCode.Decompiler.Disassembler
public class TypeUsedInSignature : ISignatureTypeProvider<bool, Unit>
{
readonly PEFile module;
readonly Dom.TypeDefinition type;
readonly Metadata.TypeDefinition type;
public TypeUsedInSignature(ITypeReference type)
{
@ -362,12 +401,12 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -362,12 +401,12 @@ namespace ICSharpCode.Decompiler.Disassembler
public bool GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)
{
return new Dom.TypeReference(module, handle).GetDefinition() == type;
return new Metadata.TypeReference(module, handle).GetDefinition() == type;
}
public bool GetTypeFromSpecification(MetadataReader reader, Unit genericContext, TypeSpecificationHandle handle, byte rawTypeKind)
{
return new Dom.TypeSpecification(module, handle).GetDefinition() == type;
}
return new Metadata.TypeSpecification(module, handle).GetDefinition() == type;
}*/
}
}

10
ICSharpCode.Decompiler/Disassembler/ILStructure.cs

@ -20,7 +20,7 @@ using System.Collections.Generic; @@ -20,7 +20,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection.Metadata;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.Disassembler
@ -57,7 +57,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -57,7 +57,7 @@ namespace ICSharpCode.Decompiler.Disassembler
/// </summary>
public class ILStructure
{
public readonly Dom.MethodDefinition Method;
public readonly Metadata.MethodDefinition Method;
public readonly ILStructureType Type;
/// <summary>
@ -85,7 +85,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -85,7 +85,7 @@ namespace ICSharpCode.Decompiler.Disassembler
/// </summary>
public readonly List<ILStructure> Children = new List<ILStructure>();
public ILStructure(Dom.MethodDefinition method, MethodBodyBlock body)
public ILStructure(Metadata.MethodDefinition method, MethodBodyBlock body)
: this(method, ILStructureType.Root, 0, body.GetILReader().Length)
{
// Build the tree of exception structures:
@ -132,7 +132,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -132,7 +132,7 @@ namespace ICSharpCode.Decompiler.Disassembler
SortChildren();
}
public ILStructure(Dom.MethodDefinition method, ILStructureType type, int startOffset, int endOffset, ExceptionRegion handler = default(ExceptionRegion))
public ILStructure(Metadata.MethodDefinition method, ILStructureType type, int startOffset, int endOffset, ExceptionRegion handler = default(ExceptionRegion))
{
Debug.Assert(startOffset < endOffset);
this.Method = method;
@ -142,7 +142,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -142,7 +142,7 @@ namespace ICSharpCode.Decompiler.Disassembler
this.ExceptionHandler = handler;
}
public ILStructure(Dom.MethodDefinition method, ILStructureType type, int startOffset, int endOffset, int loopEntryPoint)
public ILStructure(Metadata.MethodDefinition method, ILStructureType type, int startOffset, int endOffset, int loopEntryPoint)
{
Debug.Assert(startOffset < endOffset);
this.Method = method;

57
ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs

@ -23,6 +23,7 @@ using System.Reflection.Metadata.Ecma335; @@ -23,6 +23,7 @@ using System.Reflection.Metadata.Ecma335;
using System.Threading;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.Decompiler.Disassembler
{
@ -44,7 +45,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -44,7 +45,7 @@ namespace ICSharpCode.Decompiler.Disassembler
/// </summary>
public bool ShowSequencePoints { get; set; }
IList<Dom.SequencePoint> sequencePoints;
IList<Metadata.SequencePoint> sequencePoints;
int nextSequencePointIndex;
public MethodBodyDisassembler(ITextOutput output, CancellationToken cancellationToken)
@ -53,17 +54,19 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -53,17 +54,19 @@ namespace ICSharpCode.Decompiler.Disassembler
this.cancellationToken = cancellationToken;
}
public unsafe virtual void Disassemble(Dom.MethodDefinition method)
public unsafe virtual void Disassemble(Metadata.MethodDefinition method)
{
// start writing IL code
output.WriteLine("// Method begins at RVA 0x{0:x4}", method.RVA);
if (method.RVA == 0) {
var metadata = method.Module.GetMetadataReader();
var methodDefinition = metadata.GetMethodDefinition(method.Handle);
output.WriteLine("// Method begins at RVA 0x{0:x4}", methodDefinition.RelativeVirtualAddress);
if (methodDefinition.RelativeVirtualAddress == 0) {
output.WriteLine("// Code size {0} (0x{0:x})", 0);
output.WriteLine(".maxstack {0}", 0);
output.WriteLine();
return;
}
var body = method.Body;
var body = method.Module.Reader.GetMethodBody(methodDefinition.RelativeVirtualAddress);
var blob = body.GetILReader();
output.WriteLine("// Code size {0} (0x{0:x})", blob.Length);
output.WriteLine(".maxstack {0}", body.MaxStack);
@ -75,7 +78,6 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -75,7 +78,6 @@ namespace ICSharpCode.Decompiler.Disassembler
DisassembleLocalsBlock(method, body);
output.WriteLine();
var metadata = method.Module.GetMetadataReader();
sequencePoints = method.GetSequencePoints();
nextSequencePointIndex = 0;
@ -93,11 +95,11 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -93,11 +95,11 @@ namespace ICSharpCode.Decompiler.Disassembler
sequencePoints = null;
}
void DisassembleLocalsBlock(Dom.MethodDefinition method, MethodBodyBlock body)
void DisassembleLocalsBlock(Metadata.MethodDefinition method, MethodBodyBlock body)
{
if (body.LocalSignature.IsNil) return;
var metadata = method.Module.GetMetadataReader();
var signature = metadata.GetStandaloneSignature(body.LocalSignature).DecodeLocalSignature(new DisassemblerSignatureProvider(method.Module, output), new Dom.GenericContext(method));
var signature = metadata.GetStandaloneSignature(body.LocalSignature).DecodeLocalSignature(new DisassemblerSignatureProvider(method.Module, output), new Metadata.GenericContext(method));
if (!signature.IsEmpty) {
output.Write(".locals ");
if (body.LocalVariablesInitialized)
@ -118,7 +120,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -118,7 +120,7 @@ namespace ICSharpCode.Decompiler.Disassembler
}
}
internal void WriteExceptionHandlers(Dom.MethodDefinition method, MethodBodyBlock body)
internal void WriteExceptionHandlers(Metadata.MethodDefinition method, MethodBodyBlock body)
{
var handlers = body.ExceptionRegions;
if (!handlers.IsEmpty) {
@ -169,7 +171,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -169,7 +171,7 @@ namespace ICSharpCode.Decompiler.Disassembler
output.Write("catch");
if (!s.ExceptionHandler.CatchType.IsNil) {
output.Write(' ');
s.ExceptionHandler.CatchType.CoerceTypeReference(s.Method.Module).WriteTo(output, new Dom.GenericContext(s.Method), ILNameSyntax.TypeName);
s.ExceptionHandler.CatchType.WriteTo(s.Method.Module, output, new Metadata.GenericContext(s.Method), ILNameSyntax.TypeName);
}
output.WriteLine();
break;
@ -243,12 +245,12 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -243,12 +245,12 @@ namespace ICSharpCode.Decompiler.Disassembler
}
}
protected virtual void WriteInstruction(ITextOutput output, Dom.MethodDefinition method, ref BlobReader blob)
protected virtual void WriteInstruction(ITextOutput output, Metadata.MethodDefinition method, ref BlobReader blob)
{
var metadata = method.Module.GetMetadataReader();
int offset = blob.Offset;
if (ShowSequencePoints && nextSequencePointIndex < sequencePoints?.Count) {
Dom.SequencePoint sp = sequencePoints[nextSequencePointIndex];
Metadata.SequencePoint sp = sequencePoints[nextSequencePointIndex];
if (sp.Offset <= offset) {
output.Write("// sequence point: ");
if (sp.Offset != offset) {
@ -280,7 +282,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -280,7 +282,7 @@ namespace ICSharpCode.Decompiler.Disassembler
case OperandType.Type:
output.Write(' ');
var handle = MetadataTokens.EntityHandle(blob.ReadInt32());
WriteEntityHandle(handle, method.Module, new Dom.GenericContext(method), output);
handle.WriteTo(method.Module, output, new GenericContext(method));
break;
case OperandType.Tok:
output.Write(' ');
@ -300,7 +302,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -300,7 +302,7 @@ namespace ICSharpCode.Decompiler.Disassembler
output.Write("field ");
break;
}
WriteEntityHandle(handle, method.Module, new Dom.GenericContext(method), output);
handle.WriteTo(method.Module, output, new GenericContext(method));
break;
case OperandType.ShortI:
output.Write(' ');
@ -361,32 +363,5 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -361,32 +363,5 @@ namespace ICSharpCode.Decompiler.Disassembler
}
output.WriteLine();
}
void WriteEntityHandle(EntityHandle entity, Dom.PEFile module, Dom.GenericContext context, ITextOutput output)
{
switch (entity.Kind) {
case HandleKind.TypeReference:
new Dom.TypeReference(module, (TypeReferenceHandle)entity).WriteTo(output);
break;
case HandleKind.TypeDefinition:
new Dom.TypeDefinition(module, (TypeDefinitionHandle)entity).WriteTo(output);
break;
case HandleKind.FieldDefinition:
new Dom.FieldDefinition(module, (FieldDefinitionHandle)entity).WriteTo(output);
break;
case HandleKind.MethodDefinition:
new Dom.MethodDefinition(module, (MethodDefinitionHandle)entity).WriteTo(output);
break;
case HandleKind.MemberReference:
new Dom.MemberReference(module, (MemberReferenceHandle)entity).WriteTo(output, context);
break;
case HandleKind.TypeSpecification:
new Dom.TypeSpecification(module, (TypeSpecificationHandle)entity).WriteTo(output, context);
break;
case HandleKind.MethodSpecification:
new Dom.MethodSpecification(module, (MethodSpecificationHandle)entity).WriteTo(output, context);
break;
}
}
}
}

29
ICSharpCode.Decompiler/Disassembler/OpCodeInfo.cs

@ -21,9 +21,7 @@ using System.Collections.Generic; @@ -21,9 +21,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Text;
using System.Threading.Tasks;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.Decompiler.Disassembler
{
@ -165,34 +163,11 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -165,34 +163,11 @@ namespace ICSharpCode.Decompiler.Disassembler
return targets;
}
public static string DecodeUserString(ref BlobReader blob, Dom.PEFile module)
public static string DecodeUserString(ref BlobReader blob, Metadata.PEFile module)
{
return module.GetMetadataReader().GetUserString(MetadataTokens.UserStringHandle(blob.ReadInt32()));
}
public static Dom.IMemberReference DecodeMemberToken(ref BlobReader blob, Dom.PEFile module)
{
var handle = MetadataTokens.EntityHandle(blob.ReadInt32());
switch (handle.Kind) {
case HandleKind.TypeDefinition:
return new Dom.TypeDefinition(module, (TypeDefinitionHandle)handle);
case HandleKind.TypeReference:
return new Dom.TypeReference(module, (TypeReferenceHandle)handle);
case HandleKind.TypeSpecification:
return new Dom.TypeSpecification(module, (TypeSpecificationHandle)handle);
case HandleKind.MethodDefinition:
return new Dom.MethodDefinition(module, (MethodDefinitionHandle)handle);
case HandleKind.MethodSpecification:
return new Dom.MethodSpecification(module, (MethodSpecificationHandle)handle);
case HandleKind.FieldDefinition:
return new Dom.FieldDefinition(module, (FieldDefinitionHandle)handle);
case HandleKind.MemberReference:
return new Dom.MemberReference(module, (MemberReferenceHandle)handle);
default:
throw new NotSupportedException();
}
}
public static bool IsReturn(this ILOpCode opCode)
{
return opCode == ILOpCode.Ret || opCode == ILOpCode.Endfilter || opCode == ILOpCode.Endfinally;

234
ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs

@ -25,7 +25,7 @@ using System.Reflection.Metadata; @@ -25,7 +25,7 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Threading;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.IL;
namespace ICSharpCode.Decompiler.Disassembler
@ -113,37 +113,39 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -113,37 +113,39 @@ namespace ICSharpCode.Decompiler.Disassembler
{ MethodImplAttributes.PreserveSig, "preservesig" },
{ MethodImplAttributes.InternalCall, "internalcall" },
{ MethodImplAttributes.ForwardRef, "forwardref" },
{ MethodImplAttributes.AggressiveInlining, "aggressiveinlining" },
};
public void DisassembleMethod(Dom.MethodDefinition method)
public void DisassembleMethod(Metadata.MethodDefinition method)
{
DisassembleMethodHeader(method);
DisassembleMethodBlock(method);
}
public void DisassembleMethodHeader(Dom.MethodDefinition method)
public void DisassembleMethodHeader(Metadata.MethodDefinition method)
{
// write method header
output.WriteDefinition(".method ", method);
DisassembleMethodHeaderInternal(method);
}
void DisassembleMethodHeaderInternal(Dom.MethodDefinition method)
void DisassembleMethodHeaderInternal(Metadata.MethodDefinition method)
{
var metadata = method.Module.GetMetadataReader();
var methodDefinition = metadata.GetMethodDefinition(method.Handle);
// .method public hidebysig specialname
// instance default class [mscorlib]System.IO.TextWriter get_BaseWriter () cil managed
//
//emit flags
WriteEnum(method.Attributes & MethodAttributes.MemberAccessMask, methodVisibility);
WriteFlags(method.Attributes & ~MethodAttributes.MemberAccessMask, methodAttributeFlags);
bool isCompilerControlled = (method.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.PrivateScope;
WriteEnum(methodDefinition.Attributes & MethodAttributes.MemberAccessMask, methodVisibility);
WriteFlags(methodDefinition.Attributes & ~MethodAttributes.MemberAccessMask, methodAttributeFlags);
bool isCompilerControlled = (methodDefinition.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.PrivateScope;
if (isCompilerControlled)
output.Write("privatescope ");
if ((method.Attributes & MethodAttributes.PinvokeImpl) == MethodAttributes.PinvokeImpl) {
if ((methodDefinition.Attributes & MethodAttributes.PinvokeImpl) == MethodAttributes.PinvokeImpl) {
output.Write("pinvokeimpl");
var info = method.Import;
var info = methodDefinition.GetImport();
if (!info.Module.IsNil) {
var moduleRef = metadata.GetModuleReference(info.Module);
output.Write("(\"" + DisassemblerHelpers.EscapeString(metadata.GetString(moduleRef.Name)) + "\"");
@ -194,8 +196,8 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -194,8 +196,8 @@ namespace ICSharpCode.Decompiler.Disassembler
output.WriteLine();
output.Indent();
var declaringType = method.DeclaringType;
var signature = method.DecodeSignature(new DisassemblerSignatureProvider(method.Module, output), new GenericContext(method));
var declaringType = methodDefinition.GetDeclaringType();
var signature = methodDefinition.DecodeSignature(new DisassemblerSignatureProvider(method.Module, output), new GenericContext(method));
if (signature.Header.HasExplicitThis) {
output.Write("instance explicit ");
} else if (signature.Header.IsInstance) {
@ -209,7 +211,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -209,7 +211,7 @@ namespace ICSharpCode.Decompiler.Disassembler
signature.ReturnType(ILNameSyntax.Signature);
output.Write(' ');
var parameters = method.Parameters.ToImmutableArray();
var parameters = methodDefinition.GetParameters().ToArray();
if (parameters.Length > 0) {
var marshallingDesc = metadata.GetParameter(parameters[0]).GetMarshallingDescriptor();
@ -224,7 +226,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -224,7 +226,7 @@ namespace ICSharpCode.Decompiler.Disassembler
output.Write(DisassemblerHelpers.Escape(method.Name));
}
WriteTypeParameters(output, method.Module, new GenericContext(method), method.GenericParameters);
WriteTypeParameters(output, method.Module, new GenericContext(method), methodDefinition.GetGenericParameters());
//( params )
output.Write(" (");
@ -236,40 +238,40 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -236,40 +238,40 @@ namespace ICSharpCode.Decompiler.Disassembler
}
output.Write(") ");
//cil managed
WriteEnum(method.ImplAttributes & MethodImplAttributes.CodeTypeMask, methodCodeType);
if ((method.ImplAttributes & MethodImplAttributes.ManagedMask) == MethodImplAttributes.Managed)
WriteEnum(methodDefinition.ImplAttributes & MethodImplAttributes.CodeTypeMask, methodCodeType);
if ((methodDefinition.ImplAttributes & MethodImplAttributes.ManagedMask) == MethodImplAttributes.Managed)
output.Write("managed ");
else
output.Write("unmanaged ");
WriteFlags(method.ImplAttributes & ~(MethodImplAttributes.CodeTypeMask | MethodImplAttributes.ManagedMask), methodImpl);
WriteFlags(methodDefinition.ImplAttributes & ~(MethodImplAttributes.CodeTypeMask | MethodImplAttributes.ManagedMask), methodImpl);
output.Unindent();
}
void DisassembleMethodBlock(Dom.MethodDefinition method)
void DisassembleMethodBlock(Metadata.MethodDefinition method)
{
OpenBlock(defaultCollapsed: isInType);
WriteAttributes(method);
var metadata = method.Module.GetMetadataReader();
var methodDefinition = metadata.GetMethodDefinition(method.Handle);
foreach (var h in method.GetMethodImplementations()) {
OpenBlock(defaultCollapsed: isInType);
WriteAttributes(method.Module, methodDefinition.GetCustomAttributes());
foreach (var h in method.Handle.GetMethodImplementations(metadata)) {
var impl = metadata.GetMethodImplementation(h);
output.Write(".override method ");
var memberRef = impl.MethodDeclaration.CoerceMemberReference(method.Module);
memberRef.WriteTo(output, new GenericContext(method));
impl.MethodDeclaration.WriteTo(method.Module, output, new GenericContext(method));
output.WriteLine();
}
foreach (var p in method.Parameters) {
foreach (var p in methodDefinition.GetParameters()) {
WriteParameterAttributes(method.Module, p);
}
WriteSecurityDeclarations(method.Module, method.DeclarativeSecurityAttributes);
WriteSecurityDeclarations(method.Module, methodDefinition.GetDeclarativeSecurityAttributes());
if (method.HasBody) {
if (method.Handle.HasBody(metadata)) {
methodBodyDisassembler.Disassemble(method);
}
CloseBlock("end of method " + DisassemblerHelpers.Escape(method.DeclaringType.Name) + "::" + DisassemblerHelpers.Escape(method.Name));
var declaringType = metadata.GetTypeDefinition(methodDefinition.GetDeclaringType());
CloseBlock("end of method " + DisassemblerHelpers.Escape(metadata.GetString(declaringType.Name)) + "::" + DisassemblerHelpers.Escape(metadata.GetString(methodDefinition.Name)));
}
#region Write Security Declarations
@ -630,7 +632,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -630,7 +632,7 @@ namespace ICSharpCode.Decompiler.Disassembler
}
#endregion
void WriteParameters(MetadataReader metadata, ImmutableArray<ParameterHandle> parameters, MethodSignature<Action<ILNameSyntax>> signature)
void WriteParameters(MetadataReader metadata, ParameterHandle[] parameters, MethodSignature<Action<ILNameSyntax>> signature)
{
int parameterOffset = parameters.Length > signature.ParameterTypes.Length ? 1 : 0;
for (int i = 0; i < signature.ParameterTypes.Length; i++) {
@ -719,37 +721,43 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -719,37 +721,43 @@ namespace ICSharpCode.Decompiler.Disassembler
{ FieldAttributes.NotSerialized, "notserialized" },
};
public void DisassembleField(Dom.FieldDefinition field)
public void DisassembleField(Metadata.FieldDefinition field)
{
var metadata = field.Module.GetMetadataReader();
var fieldDefinition = metadata.GetFieldDefinition(field.Handle);
output.WriteDefinition(".field ", field);
int offset = field.Offset;
int offset = fieldDefinition.GetOffset();
if (offset > -1) {
output.Write("[" + offset + "] ");
}
WriteEnum(field.Attributes & FieldAttributes.FieldAccessMask, fieldVisibility);
WriteEnum(fieldDefinition.Attributes & FieldAttributes.FieldAccessMask, fieldVisibility);
const FieldAttributes hasXAttributes = FieldAttributes.HasDefault | FieldAttributes.HasFieldMarshal | FieldAttributes.HasFieldRVA;
WriteFlags(field.Attributes & ~(FieldAttributes.FieldAccessMask | hasXAttributes), fieldAttributes);
WriteFlags(fieldDefinition.Attributes & ~(FieldAttributes.FieldAccessMask | hasXAttributes), fieldAttributes);
var signature = field.DecodeSignature(new DisassemblerSignatureProvider(field.Module, output), new GenericContext(field.DeclaringType));
var signature = fieldDefinition.DecodeSignature(new DisassemblerSignatureProvider(field.Module, output), new GenericContext(fieldDefinition.GetDeclaringType(), field.Module));
if (!field.GetMarshallingDescriptor().IsNil) {
WriteMarshalInfo(metadata.GetBlobReader(field.GetMarshallingDescriptor()));
var marshallingDescriptor = fieldDefinition.GetMarshallingDescriptor();
if (!marshallingDescriptor.IsNil) {
WriteMarshalInfo(metadata.GetBlobReader(marshallingDescriptor));
}
signature(ILNameSyntax.Signature);
output.Write(' ');
output.Write(DisassemblerHelpers.Escape(field.Name));
if (field.HasFlag(FieldAttributes.HasFieldRVA)) {
output.Write(" at I_{0:x8}", field.RVA);
output.Write(DisassemblerHelpers.Escape(metadata.GetString(fieldDefinition.Name)));
if (fieldDefinition.HasFlag(FieldAttributes.HasFieldRVA)) {
output.Write(" at I_{0:x8}", fieldDefinition.GetRelativeVirtualAddress());
}
if (!field.GetDefaultValue().IsNil) {
var defaultValue = fieldDefinition.GetDefaultValue();
if (!defaultValue.IsNil) {
output.Write(" = ");
WriteConstant(metadata, metadata.GetConstant(field.GetDefaultValue()));
WriteConstant(metadata, metadata.GetConstant(defaultValue));
}
output.WriteLine();
if (field.CustomAttributes.Count > 0) {
var attributes = fieldDefinition.GetCustomAttributes();
if (attributes.Count > 0) {
output.MarkFoldStart();
WriteAttributes(field);
WriteAttributes(field.Module, fieldDefinition.GetCustomAttributes());
output.MarkFoldEnd();
}
}
@ -762,39 +770,43 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -762,39 +770,43 @@ namespace ICSharpCode.Decompiler.Disassembler
{ PropertyAttributes.HasDefault, "hasdefault" },
};
public void DisassembleProperty(Dom.PropertyDefinition property)
public void DisassembleProperty(Metadata.PropertyDefinition property)
{
var metadata = property.Module.GetMetadataReader();
var propertyDefinition = metadata.GetPropertyDefinition(property.Handle);
output.WriteDefinition(".property ", property);
WriteFlags(property.Attributes, propertyAttributes);
var declaringType = property.DeclaringType;
var signature = property.DecodeSignature(new DisassemblerSignatureProvider(property.Module, output), new GenericContext(declaringType));
WriteFlags(propertyDefinition.Attributes, propertyAttributes);
var accessors = propertyDefinition.GetAccessors();
var declaringType = metadata.GetMethodDefinition(accessors.GetAny()).GetDeclaringType();
var signature = propertyDefinition.DecodeSignature(new DisassemblerSignatureProvider(property.Module, output), new GenericContext(declaringType, property.Module));
if (signature.Header.IsInstance)
output.Write("instance ");
signature.ReturnType(ILNameSyntax.Signature);
output.Write(' ');
output.Write(DisassemblerHelpers.Escape(property.Name));
output.Write(DisassemblerHelpers.Escape(metadata.GetString(propertyDefinition.Name)));
output.Write("(");
var parameters = property.GetAccessors().First().Method.Parameters;
var parameters = metadata.GetMethodDefinition(accessors.Getter).GetParameters();
if (parameters.Count > 0) {
output.WriteLine();
output.Indent();
WriteParameters(metadata, parameters.ToImmutableArray(), signature);
WriteParameters(metadata, parameters.ToArray(), signature);
output.Unindent();
}
output.Write(")");
OpenBlock(false);
WriteAttributes(property);
WriteNestedMethod(".get", property.GetMethod);
WriteNestedMethod(".set", property.SetMethod);
WriteAttributes(property.Module, propertyDefinition.GetCustomAttributes());
WriteNestedMethod(".get", new Metadata.MethodDefinition(property.Module, accessors.Getter));
WriteNestedMethod(".set", new Metadata.MethodDefinition(property.Module, accessors.Setter));
/*foreach (var method in property.OtherMethods) {
WriteNestedMethod(".other", method);
}*/
CloseBlock();
}
void WriteNestedMethod(string keyword, Dom.MethodDefinition method)
void WriteNestedMethod(string keyword, Metadata.MethodDefinition method)
{
if (method.IsNil)
return;
@ -812,23 +824,33 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -812,23 +824,33 @@ namespace ICSharpCode.Decompiler.Disassembler
{ EventAttributes.RTSpecialName, "rtspecialname" },
};
public void DisassembleEvent(Dom.EventDefinition ev)
public void DisassembleEvent(Metadata.EventDefinition ev)
{
var metadata = ev.Module.GetMetadataReader();
var eventDefinition = metadata.GetEventDefinition(ev.Handle);
var accessors = eventDefinition.GetAccessors();
TypeDefinitionHandle declaringType;
if (!accessors.Adder.IsNil) {
declaringType = metadata.GetMethodDefinition(accessors.Adder).GetDeclaringType();
} else if (!accessors.Remover.IsNil) {
declaringType = metadata.GetMethodDefinition(accessors.Remover).GetDeclaringType();
} else {
declaringType = metadata.GetMethodDefinition(accessors.Raiser).GetDeclaringType();
}
output.WriteDefinition(".event ", ev);
WriteFlags(ev.Attributes, eventAttributes);
var signature = ev.DecodeSignature(new DisassemblerSignatureProvider(ev.Module, output), new GenericContext(ev.DeclaringType));
WriteFlags(eventDefinition.Attributes, eventAttributes);
var signature = eventDefinition.DecodeSignature(metadata, new DisassemblerSignatureProvider(ev.Module, output), new GenericContext(declaringType, ev.Module));
signature(ILNameSyntax.TypeName);
output.Write(' ');
output.Write(DisassemblerHelpers.Escape(ev.Name));
output.Write(DisassemblerHelpers.Escape(metadata.GetString(eventDefinition.Name)));
OpenBlock(false);
WriteAttributes(ev);
WriteNestedMethod(".addon", ev.AddMethod);
WriteNestedMethod(".removeon", ev.RemoveMethod);
WriteNestedMethod(".fire", ev.InvokeMethod);
foreach (var method in ev.OtherMethods) {
WriteAttributes(ev.Module, eventDefinition.GetCustomAttributes());
WriteNestedMethod(".addon", new Metadata.MethodDefinition(ev.Module, accessors.Adder));
WriteNestedMethod(".removeon", new Metadata.MethodDefinition(ev.Module, accessors.Remover));
WriteNestedMethod(".fire", new Metadata.MethodDefinition(ev.Module, accessors.Raiser));
/*foreach (var method in ev.OtherMethods) {
WriteNestedMethod(".other", method);
}
}*/
CloseBlock();
}
#endregion
@ -868,32 +890,33 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -868,32 +890,33 @@ namespace ICSharpCode.Decompiler.Disassembler
{ TypeAttributes.HasSecurity, null },
};
public void DisassembleType(Dom.TypeDefinition type)
public void DisassembleType(Metadata.TypeDefinition type)
{
var metadata = type.Module.GetMetadataReader();
var typeDefinition = metadata.GetTypeDefinition(type.Handle);
output.WriteDefinition(".class ", type);
if ((type.Attributes & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface)
if ((typeDefinition.Attributes & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface)
output.Write("interface ");
WriteEnum(type.Attributes & TypeAttributes.VisibilityMask, typeVisibility);
WriteEnum(type.Attributes & TypeAttributes.LayoutMask, typeLayout);
WriteEnum(type.Attributes & TypeAttributes.StringFormatMask, typeStringFormat);
WriteEnum(typeDefinition.Attributes & TypeAttributes.VisibilityMask, typeVisibility);
WriteEnum(typeDefinition.Attributes & TypeAttributes.LayoutMask, typeLayout);
WriteEnum(typeDefinition.Attributes & TypeAttributes.StringFormatMask, typeStringFormat);
const TypeAttributes masks = TypeAttributes.ClassSemanticsMask | TypeAttributes.VisibilityMask | TypeAttributes.LayoutMask | TypeAttributes.StringFormatMask;
WriteFlags(type.Attributes & ~masks, typeAttributes);
WriteFlags(typeDefinition.Attributes & ~masks, typeAttributes);
output.Write(type.DeclaringType.IsNil ? type.FullName.ToILNameString() : DisassemblerHelpers.Escape(type.Name));
WriteTypeParameters(output, type.Module, new GenericContext(type), type.GenericParameters);
output.Write(typeDefinition.GetDeclaringType().IsNil ? typeDefinition.GetFullTypeName(metadata).ToILNameString() : DisassemblerHelpers.Escape(metadata.GetString(typeDefinition.Name)));
WriteTypeParameters(output, type.Module, new GenericContext(type), typeDefinition.GetGenericParameters());
output.MarkFoldStart(defaultCollapsed: isInType);
output.WriteLine();
if (type.BaseType != null) {
if (!typeDefinition.BaseType.IsNil) {
output.Indent();
output.Write("extends ");
type.BaseType.WriteTo(output, new GenericContext(type), ILNameSyntax.TypeName);
typeDefinition.BaseType.WriteTo(type.Module, output, new GenericContext(type), ILNameSyntax.TypeName);
output.WriteLine();
output.Unindent();
}
var interfaces = type.GetInterfaceImplementations();
var interfaces = typeDefinition.GetInterfaceImplementations();
if (interfaces.Count > 0) {
output.Indent();
bool first = true;
@ -907,8 +930,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -907,8 +930,7 @@ namespace ICSharpCode.Decompiler.Disassembler
first = false;
var iface = metadata.GetInterfaceImplementation(i);
WriteAttributes(type.Module, iface.GetCustomAttributes());
var ifaceRef = iface.Interface.CoerceTypeReference(type.Module);
ifaceRef.WriteTo(output, new GenericContext(type), ILNameSyntax.TypeName);
iface.Interface.WriteTo(type.Module, output, new GenericContext(type), ILNameSyntax.TypeName);
}
output.WriteLine();
output.Unindent();
@ -918,57 +940,62 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -918,57 +940,62 @@ namespace ICSharpCode.Decompiler.Disassembler
output.Indent();
bool oldIsInType = isInType;
isInType = true;
WriteAttributes(type);
WriteSecurityDeclarations(type.Module, type.DeclarativeSecurityAttributes);
var layout = type.GetLayout();
WriteAttributes(type.Module, typeDefinition.GetCustomAttributes());
WriteSecurityDeclarations(type.Module, typeDefinition.GetDeclarativeSecurityAttributes());
var layout = type.This().GetLayout();
if (!layout.IsDefault) {
output.WriteLine(".pack {0}", layout.PackingSize);
output.WriteLine(".size {0}", layout.Size);
output.WriteLine();
}
if (!type.NestedTypes.IsEmpty) {
var nestedTypes = typeDefinition.GetNestedTypes();
if (!nestedTypes.IsEmpty) {
output.WriteLine("// Nested Types");
foreach (var nestedType in type.NestedTypes) {
foreach (var nestedType in nestedTypes) {
cancellationToken.ThrowIfCancellationRequested();
DisassembleType(nestedType);
DisassembleType(new Metadata.TypeDefinition(type.Module, nestedType));
output.WriteLine();
}
output.WriteLine();
}
if (!type.Fields.IsEmpty) {
var fields = typeDefinition.GetFields();
if (fields.Any()) {
output.WriteLine("// Fields");
foreach (var field in type.Fields) {
foreach (var field in fields) {
cancellationToken.ThrowIfCancellationRequested();
DisassembleField(field);
DisassembleField(new Metadata.FieldDefinition(type.Module, field));
}
output.WriteLine();
}
if (!type.Methods.IsEmpty) {
var methods = typeDefinition.GetMethods();
if (methods.Any()) {
output.WriteLine("// Methods");
foreach (var m in type.Methods) {
foreach (var m in methods) {
cancellationToken.ThrowIfCancellationRequested();
DisassembleMethod(m);
DisassembleMethod(new Metadata.MethodDefinition(type.Module, m));
output.WriteLine();
}
}
if (!type.Events.IsEmpty) {
var events = typeDefinition.GetEvents();
if (events.Any()) {
output.WriteLine("// Events");
foreach (var ev in type.Events) {
foreach (var ev in events) {
cancellationToken.ThrowIfCancellationRequested();
DisassembleEvent(ev);
DisassembleEvent(new Metadata.EventDefinition(type.Module, ev));
output.WriteLine();
}
output.WriteLine();
}
if (!type.Properties.IsEmpty) {
var properties = typeDefinition.GetProperties();
if (properties.Any()) {
output.WriteLine("// Properties");
foreach (var prop in type.Properties) {
foreach (var prop in properties) {
cancellationToken.ThrowIfCancellationRequested();
DisassembleProperty(prop);
DisassembleProperty(new Metadata.PropertyDefinition(type.Module, prop));
}
output.WriteLine();
}
CloseBlock("end of class " + (!type.DeclaringType.IsNil ? type.Name : type.FullName.ToString()));
CloseBlock("end of class " + (!typeDefinition.GetDeclaringType().IsNil ? metadata.GetString(typeDefinition.Name) : typeDefinition.GetFullTypeName(metadata).ToString()));
isInType = oldIsInType;
}
@ -996,7 +1023,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -996,7 +1023,7 @@ namespace ICSharpCode.Decompiler.Disassembler
if (j > 0)
output.Write(", ");
var constraint = metadata.GetGenericParameterConstraint(constraints[j]);
constraint.Type.CoerceTypeReference(module).WriteTo(output, context, ILNameSyntax.TypeName);
constraint.Type.WriteTo(module, output, context, ILNameSyntax.TypeName);
}
output.Write(") ");
}
@ -1013,18 +1040,13 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1013,18 +1040,13 @@ namespace ICSharpCode.Decompiler.Disassembler
#endregion
#region Helper methods
void WriteAttributes(Dom.ICustomAttributeProvider attributes)
{
WriteAttributes(attributes.Module, attributes.CustomAttributes);
}
void WriteAttributes(PEFile module, CustomAttributeHandleCollection attributes)
{
var metadata = module.GetMetadataReader();
foreach (CustomAttributeHandle a in attributes) {
output.Write(".custom ");
var attr = metadata.GetCustomAttribute(a);
attr.Constructor.CoerceMemberReference(module).WriteTo(output, GenericContext.Empty);
attr.Constructor.WriteTo(module, output, GenericContext.Empty);
byte[] blob = metadata.GetBlobBytes(attr.Value);
if (blob.Length > 0) {
output.Write(" = ");
@ -1126,7 +1148,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1126,7 +1148,7 @@ namespace ICSharpCode.Decompiler.Disassembler
}
#endregion
public void DisassembleNamespace(string nameSpace, IEnumerable<Dom.TypeDefinition> types)
public void DisassembleNamespace(string nameSpace, IEnumerable<Metadata.TypeDefinition> types)
{
if (!string.IsNullOrEmpty(nameSpace)) {
output.Write(".namespace " + DisassemblerHelpers.Escape(nameSpace));
@ -1440,7 +1462,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1440,7 +1462,7 @@ namespace ICSharpCode.Decompiler.Disassembler
default:
throw new NotSupportedException($"rawTypeKind: {rawTypeKind} (0x{rawTypeKind:x})");
}
var td = new Dom.TypeDefinition(module, handle);
var td = new Metadata.TypeDefinition(module, handle);
td.WriteTo(output);
};
}
@ -1460,7 +1482,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1460,7 +1482,7 @@ namespace ICSharpCode.Decompiler.Disassembler
default:
throw new NotSupportedException($"rawTypeKind: {rawTypeKind} (0x{rawTypeKind:x})");
}
var typeRef = new Dom.TypeReference(module, handle);
var typeRef = new Metadata.TypeReference(module, handle);
typeRef.WriteTo(output);
};
}

389
ICSharpCode.Decompiler/Documentation/XmlDocKeyProvider.cs

@ -22,10 +22,10 @@ using System.Diagnostics; @@ -22,10 +22,10 @@ using System.Diagnostics;
using System.Linq;
using System.Text;
using ICSharpCode.Decompiler.TypeSystem;
using Mono.Cecil;
using ArrayType = Mono.Cecil.ArrayType;
using ByReferenceType = Mono.Cecil.ByReferenceType;
using PointerType = Mono.Cecil.PointerType;
using ICSharpCode.Decompiler.Metadata;
using SRM = System.Reflection.Metadata;
using ICSharpCode.Decompiler.Util;
using System.Collections.Immutable;
namespace ICSharpCode.Decompiler.Documentation
{
@ -35,160 +35,233 @@ namespace ICSharpCode.Decompiler.Documentation @@ -35,160 +35,233 @@ namespace ICSharpCode.Decompiler.Documentation
public sealed class XmlDocKeyProvider
{
#region GetKey
public static string GetKey(MemberReference member)
public static string GetKey(Entity entity)
{
return GetKey(entity.Module.GetMetadataReader(), entity.Handle);
}
public static string GetKey(SRM.MetadataReader metadata, SRM.EntityHandle member)
{
StringBuilder b = new StringBuilder();
if (member is TypeReference) {
b.Append("T:");
AppendTypeName(b, (TypeReference)member);
} else {
if (member is FieldReference)
b.Append("F:");
else if (member is PropertyDefinition)
b.Append("P:");
else if (member is EventDefinition)
b.Append("E:");
else if (member is MethodReference)
b.Append("M:");
AppendTypeName(b, member.DeclaringType);
b.Append('.');
b.Append(member.Name.Replace('.', '#'));
IList<ParameterDefinition> parameters;
TypeReference explicitReturnType = null;
if (member is PropertyDefinition) {
parameters = ((PropertyDefinition)member).Parameters;
} else if (member is MethodReference) {
MethodReference mr = (MethodReference)member;
if (mr.HasGenericParameters) {
b.Append("``");
b.Append(mr.GenericParameters.Count);
}
parameters = mr.Parameters;
if (mr.Name == "op_Implicit" || mr.Name == "op_Explicit") {
explicitReturnType = mr.ReturnType;
}
} else {
parameters = null;
void AppendTypeName(SRM.EntityHandle type)
{
switch (type.Kind) {
case SRM.HandleKind.TypeDefinition:
b.Append("T:");
b.Append(((SRM.TypeDefinitionHandle)type).GetFullTypeName(metadata));
break;
case SRM.HandleKind.TypeReference:
b.Append("T:");
b.Append(((SRM.TypeReferenceHandle)type).GetFullTypeName(metadata));
break;
default:
throw new NotImplementedException();
/*case SRM.HandleKind.TypeSpecification:
b.Append("T:");
var typeSpec = metadata.GetTypeSpecification((SRM.TypeSpecificationHandle)type);
b.Append(typeSpec.DecodeSignature(new DocumentationKeySignatureTypeProvider(), default(Unit)));
break;*/
}
if (parameters != null && parameters.Count > 0) {
b.Append('(');
for (int i = 0; i < parameters.Count; i++) {
if (i > 0) b.Append(',');
AppendTypeName(b, parameters[i].ParameterType);
}
b.Append(')');
}
void AppendSignature(SRM.MethodSignature<string> signature, bool printExplicitReturnType = false)
{
if (signature.GenericParameterCount > 0) {
b.Append("``");
b.Append(signature.GenericParameterCount);
}
if (explicitReturnType != null) {
b.Append('(');
for (int i = 0; i < signature.ParameterTypes.Length; i++) {
if (i > 0)
b.Append(',');
b.Append(signature.ParameterTypes[i]);
}
b.Append(')');
if (printExplicitReturnType) {
b.Append('~');
AppendTypeName(b, explicitReturnType);
b.Append(signature.ReturnType);
}
}
return b.ToString();
}
static void AppendTypeName(StringBuilder b, TypeReference type)
{
if (type == null) {
// could happen when a TypeSpecification has no ElementType; e.g. function pointers in C++/CLI assemblies
return;
}
if (type is GenericInstanceType) {
GenericInstanceType giType = (GenericInstanceType)type;
AppendTypeNameWithArguments(b, giType.ElementType, giType.GenericArguments);
} else if (type is TypeSpecification) {
AppendTypeName(b, ((TypeSpecification)type).ElementType);
ArrayType arrayType = type as ArrayType;
if (arrayType != null) {
b.Append('[');
for (int i = 0; i < arrayType.Dimensions.Count; i++) {
if (i > 0)
b.Append(',');
ArrayDimension ad = arrayType.Dimensions[i];
if (ad.IsSized) {
b.Append(ad.LowerBound);
b.Append(':');
b.Append(ad.UpperBound);
}
switch (member.Kind) {
case SRM.HandleKind.TypeDefinition:
case SRM.HandleKind.TypeReference:
case SRM.HandleKind.TypeSpecification:
b.Append("T:");
AppendTypeName(member);
break;
case SRM.HandleKind.FieldDefinition:
b.Append("F:");
var field = metadata.GetFieldDefinition((SRM.FieldDefinitionHandle)member);
AppendTypeName(field.GetDeclaringType());
b.Append('.');
b.Append(metadata.GetString(field.Name).Replace('.', '#'));
break;
case SRM.HandleKind.PropertyDefinition: {
b.Append("P:");
var property = metadata.GetPropertyDefinition((SRM.PropertyDefinitionHandle)member);
var accessors = property.GetAccessors();
SRM.TypeDefinitionHandle declaringType;
if (!accessors.Getter.IsNil) {
declaringType = metadata.GetMethodDefinition(accessors.Getter).GetDeclaringType();
} else {
declaringType = metadata.GetMethodDefinition(accessors.Setter).GetDeclaringType();
}
b.Append(']');
}
ByReferenceType refType = type as ByReferenceType;
if (refType != null) {
b.Append('@');
}
PointerType ptrType = type as PointerType;
if (ptrType != null) {
b.Append('*');
AppendTypeName(declaringType);
b.Append('.');
b.Append(metadata.GetString(property.Name).Replace('.', '#'));
AppendSignature(property.DecodeSignature(new DocumentationKeySignatureTypeProvider(), default(Unit)));
break;
}
} else {
GenericParameter gp = type as GenericParameter;
if (gp != null) {
b.Append('`');
if (gp.Owner.GenericParameterType == GenericParameterType.Method) {
b.Append('`');
case SRM.HandleKind.MethodDefinition:
b.Append("M:");
var method = metadata.GetMethodDefinition((SRM.MethodDefinitionHandle)member);
AppendTypeName(method.GetDeclaringType());
b.Append('.');
var methodName = metadata.GetString(method.Name);
b.Append(metadata.GetString(method.Name).Replace('.', '#'));
AppendSignature(method.DecodeSignature(new DocumentationKeySignatureTypeProvider(), default(Unit)), methodName == "op_Implicit" || methodName == "op_Explicit");
break;
case SRM.HandleKind.EventDefinition: {
b.Append("E:");
var @event = metadata.GetEventDefinition((SRM.EventDefinitionHandle)member);
var accessors = @event.GetAccessors();
SRM.TypeDefinitionHandle declaringType;
if (!accessors.Adder.IsNil) {
declaringType = metadata.GetMethodDefinition(accessors.Adder).GetDeclaringType();
} else if (!accessors.Remover.IsNil) {
declaringType = metadata.GetMethodDefinition(accessors.Remover).GetDeclaringType();
} else {
declaringType = metadata.GetMethodDefinition(accessors.Raiser).GetDeclaringType();
}
b.Append(gp.Position);
} else if (type.DeclaringType != null) {
AppendTypeName(b, type.DeclaringType);
AppendTypeName(declaringType);
b.Append('.');
b.Append(type.Name);
} else {
b.Append(type.FullName);
b.Append(metadata.GetString(@event.Name).Replace('.', '#'));
break;
}
default:
throw new NotImplementedException();
}
return b.ToString();
}
static int AppendTypeNameWithArguments(StringBuilder b, TypeReference type, IList<TypeReference> genericArguments)
public sealed class DocumentationKeySignatureTypeProvider : SRM.ISignatureTypeProvider<string, Unit>
{
int outerTypeParameterCount = 0;
if (type.DeclaringType != null) {
TypeReference declType = type.DeclaringType;
outerTypeParameterCount = AppendTypeNameWithArguments(b, declType, genericArguments);
b.Append('.');
} else if (!string.IsNullOrEmpty(type.Namespace)) {
b.Append(type.Namespace);
b.Append('.');
}
int localTypeParameterCount = 0;
b.Append(ReflectionHelper.SplitTypeParameterCountFromReflectionName(type.Name, out localTypeParameterCount));
if (localTypeParameterCount > 0) {
int totalTypeParameterCount = outerTypeParameterCount + localTypeParameterCount;
b.Append('{');
for (int i = outerTypeParameterCount; i < totalTypeParameterCount && i < genericArguments.Count; i++) {
if (i > outerTypeParameterCount) b.Append(',');
AppendTypeName(b, genericArguments[i]);
public string GetArrayType(string elementType, SRM.ArrayShape shape)
{
string shapeString = "";
for (int i = 0; i < shape.Rank; i++) {
if (i > 0)
shapeString += ',';
int? lowerBound = i < shape.LowerBounds.Length ? (int?)shape.LowerBounds[i] : null;
int? size = i < shape.Sizes.Length ? (int?)shape.Sizes[i] : null;
if (lowerBound != null || size != null) {
shapeString += lowerBound.ToString();
shapeString += ':';
shapeString += (lowerBound + size - 1).ToString();
}
}
b.Append('}');
return elementType + "[" + shapeString + "]";
}
public string GetByReferenceType(string elementType)
{
return elementType + '@';
}
public string GetFunctionPointerType(SRM.MethodSignature<string> signature)
{
return "";
}
public string GetGenericInstantiation(string genericType, ImmutableArray<string> typeArguments)
{
string arguments = "";
for (int i = 0; i < typeArguments.Length; i++) {
if (i > 0)
arguments += ',';
arguments += typeArguments[i];
}
return genericType + "{" + arguments + "}";
}
public string GetGenericMethodParameter(Unit genericContext, int index)
{
return "``" + index;
}
public string GetGenericTypeParameter(Unit genericContext, int index)
{
return "`" + index;
}
public string GetModifiedType(string modifier, string unmodifiedType, bool isRequired)
{
throw new NotImplementedException();
}
public string GetPinnedType(string elementType)
{
throw new NotImplementedException();
}
public string GetPointerType(string elementType)
{
return elementType + '*';
}
public string GetPrimitiveType(SRM.PrimitiveTypeCode typeCode)
{
return $"System.{typeCode}";
}
public string GetSZArrayType(string elementType)
{
return elementType + "[]";
}
public string GetTypeFromDefinition(SRM.MetadataReader reader, SRM.TypeDefinitionHandle handle, byte rawTypeKind)
{
return handle.GetFullTypeName(reader).ToString();
}
public string GetTypeFromReference(SRM.MetadataReader reader, SRM.TypeReferenceHandle handle, byte rawTypeKind)
{
return handle.GetFullTypeName(reader).ToString();
}
public string GetTypeFromSpecification(SRM.MetadataReader reader, Unit genericContext, SRM.TypeSpecificationHandle handle, byte rawTypeKind)
{
return handle.GetFullTypeName(reader).ToString();
}
return outerTypeParameterCount + localTypeParameterCount;
}
#endregion
#region FindMemberByKey
public static MemberReference FindMemberByKey(ModuleDefinition module, string key)
public static Entity FindMemberByKey(PEFile module, string key)
{
if (module == null)
throw new ArgumentNullException(nameof(module));
if (key == null || key.Length < 2 || key[1] != ':')
return null;
return default(Entity);
switch (key[0]) {
case 'T':
return FindType(module, key.Substring(2));
case 'F':
return FindMember(module, key, type => type.Fields);
return FindMember(module, key, type => type.This().GetFields().Select(f => new Entity(module, f)));
case 'P':
return FindMember(module, key, type => type.Properties);
return FindMember(module, key, type => type.This().GetProperties().Select(p => new Entity(module, p)));
case 'E':
return FindMember(module, key, type => type.Events);
return FindMember(module, key, type => type.This().GetEvents().Select(e => new Entity(module, e)));
case 'M':
return FindMember(module, key, type => type.Methods);
return FindMember(module, key, type => type.This().GetMethods().Select(m => new Entity(module, m)));
default:
return null;
return default(Entity);
}
}
static MemberReference FindMember(ModuleDefinition module, string key, Func<TypeDefinition, IEnumerable<MemberReference>> memberSelector)
static Entity FindMember(PEFile module, string key, Func<TypeDefinition, IEnumerable<Entity>> memberSelector)
{
Debug.WriteLine("Looking for member " + key);
int parenPos = key.IndexOf('(');
@ -198,50 +271,80 @@ namespace ICSharpCode.Decompiler.Documentation @@ -198,50 +271,80 @@ namespace ICSharpCode.Decompiler.Documentation
} else {
dotPos = key.LastIndexOf('.');
}
if (dotPos < 0) return null;
if (dotPos < 0)
return default(Entity);
TypeDefinition type = FindType(module, key.Substring(2, dotPos - 2));
if (type == null)
return null;
return default(Entity);
string shortName;
if (parenPos > 0) {
shortName = key.Substring(dotPos + 1, parenPos - (dotPos + 1));
} else {
shortName = key.Substring(dotPos + 1);
}
Debug.WriteLine("Searching in type {0} for {1}", type.FullName, shortName);
MemberReference shortNameMatch = null;
foreach (MemberReference member in memberSelector(type)) {
Debug.WriteLine("Searching in type {0} for {1}", type.Handle.GetFullTypeName(module.GetMetadataReader()), shortName);
Entity shortNameMatch = default(Entity);
var metadata = module.GetMetadataReader();
foreach (var member in memberSelector(type)) {
string memberKey = GetKey(member);
Debug.WriteLine(memberKey);
if (memberKey == key)
return member;
if (shortName == member.Name.Replace('.', '#'))
string name;
switch (member.Handle.Kind) {
case SRM.HandleKind.MethodDefinition:
name = metadata.GetString(metadata.GetMethodDefinition((SRM.MethodDefinitionHandle)member.Handle).Name);
break;
case SRM.HandleKind.FieldDefinition:
name = metadata.GetString(metadata.GetFieldDefinition((SRM.FieldDefinitionHandle)member.Handle).Name);
break;
case SRM.HandleKind.PropertyDefinition:
name = metadata.GetString(metadata.GetPropertyDefinition((SRM.PropertyDefinitionHandle)member.Handle).Name);
break;
case SRM.HandleKind.EventDefinition:
name = metadata.GetString(metadata.GetEventDefinition((SRM.EventDefinitionHandle)member.Handle).Name);
break;
default:
throw new NotSupportedException();
}
if (shortName == name.Replace('.', '#'))
shortNameMatch = member;
}
// if there's no match by ID string (key), return the match by name.
return shortNameMatch;
}
static TypeDefinition FindType(ModuleDefinition module, string name)
static TypeDefinition FindType(PEFile module, string name)
{
int pos = name.LastIndexOf('.');
string ns;
if (pos >= 0) {
ns = name.Substring(0, pos);
name = name.Substring(pos + 1);
} else {
ns = string.Empty;
}
if (string.IsNullOrEmpty(name)) return null;
TypeDefinition type = module.GetType(ns, name);
if (type == null && ns.Length > 0) {
// try if this is a nested type
type = FindType(module, ns);
if (type != null) {
type = type.NestedTypes.FirstOrDefault(t => t.Name == name);
var metadata = module.GetMetadataReader();
string[] segments = name.Split('.');
var currentNamespace = metadata.GetNamespaceDefinitionRoot();
int i = 0;
while (i < segments.Length) {
string part = segments[i];
var next = currentNamespace.NamespaceDefinitions.FirstOrDefault(ns => metadata.GetString(metadata.GetNamespaceDefinition(ns).Name) == part);
if (next.IsNil)
break;
currentNamespace = metadata.GetNamespaceDefinition(next);
i++;
}
if (i == segments.Length)
return default(TypeDefinition);
var typeDefinitions = currentNamespace.TypeDefinitions;
while (i < segments.Length) {
string part = segments[i];
foreach (var t in typeDefinitions) {
var type = metadata.GetTypeDefinition(t);
if (metadata.GetString(type.Name) == part) {
if (i + 1 == segments.Length)
return new TypeDefinition(module, t);
typeDefinitions = type.GetNestedTypes();
i++;
break;
}
}
}
return type;
return default(TypeDefinition);
}
#endregion
}

43
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -277,26 +277,27 @@ @@ -277,26 +277,27 @@
<Compile Include="Documentation\XmlDocKeyProvider.cs" />
<Compile Include="Documentation\XmlDocLoader.cs" />
<Compile Include="Documentation\XmlDocumentationProvider.cs" />
<Compile Include="Dom\Dom.cs" />
<Compile Include="Dom\MetadataResolver.cs" />
<Compile Include="DotNetCore\DotNetCorePathFinder.cs" />
<Compile Include="DotNetCore\DotNetCorePathFinderExtensions.cs" />
<Compile Include="DotNetCore\LightJson\JsonArray.cs" />
<Compile Include="DotNetCore\LightJson\JsonObject.cs" />
<Compile Include="DotNetCore\LightJson\JsonValue.cs" />
<Compile Include="DotNetCore\LightJson\JsonValueType.cs" />
<Compile Include="DotNetCore\LightJson\Serialization\JsonParseException.cs" />
<Compile Include="DotNetCore\LightJson\Serialization\JsonReader.cs" />
<Compile Include="DotNetCore\LightJson\Serialization\JsonSerializationException.cs" />
<Compile Include="DotNetCore\LightJson\Serialization\JsonWriter.cs" />
<Compile Include="DotNetCore\LightJson\Serialization\TextPosition.cs" />
<Compile Include="DotNetCore\LightJson\Serialization\TextScanner.cs" />
<Compile Include="DotNetCore\UniversalAssemblyResolver.cs" />
<Compile Include="DotNetCore\UnresolvedAssemblyNameReference.cs" />
<Compile Include="Metadata\Dom.cs" />
<Compile Include="Metadata\MetadataResolver.cs" />
<Compile Include="Metadata\DotNetCorePathFinder.cs" />
<Compile Include="Metadata\DotNetCorePathFinderExtensions.cs" />
<Compile Include="Metadata\LightJson\JsonArray.cs" />
<Compile Include="Metadata\LightJson\JsonObject.cs" />
<Compile Include="Metadata\LightJson\JsonValue.cs" />
<Compile Include="Metadata\LightJson\JsonValueType.cs" />
<Compile Include="Metadata\LightJson\Serialization\JsonParseException.cs" />
<Compile Include="Metadata\LightJson\Serialization\JsonReader.cs" />
<Compile Include="Metadata\LightJson\Serialization\JsonSerializationException.cs" />
<Compile Include="Metadata\LightJson\Serialization\JsonWriter.cs" />
<Compile Include="Metadata\LightJson\Serialization\TextPosition.cs" />
<Compile Include="Metadata\LightJson\Serialization\TextScanner.cs" />
<Compile Include="Metadata\OperandType.cs" />
<Compile Include="Metadata\UniversalAssemblyResolver.cs" />
<Compile Include="Metadata\UnresolvedAssemblyNameReference.cs" />
<Compile Include="IL\ILAstWritingOptions.cs" />
<Compile Include="IL\Instructions\LdFlda.cs" />
<Compile Include="IL\Instructions\StLoc.cs" />
<Compile Include="Dom\SequencePoint.cs" />
<Compile Include="Metadata\SequencePoint.cs" />
<Compile Include="IL\Instructions\CallIndirect.cs" />
<Compile Include="IL\Instructions\DefaultValue.cs" />
<Compile Include="IL\Transforms\EarlyExpressionTransforms.cs" />
@ -329,8 +330,10 @@ @@ -329,8 +330,10 @@
<Compile Include="IL\Transforms\StatementTransform.cs" />
<Compile Include="IL\Transforms\TransformCollectionAndObjectInitializers.cs" />
<Compile Include="Output\TextTokenWriter.cs" />
<Compile Include="SRMExtensions.cs" />
<Compile Include="SRMHacks.cs" />
<Compile Include="TypeSystem\Implementation\TypeSpecification.cs" />
<Compile Include="Dom\MetadataExtensions.cs" />
<Compile Include="Metadata\MetadataExtensions.cs" />
<Compile Include="Util\GraphVizGraph.cs" />
<Compile Include="Util\KeyComparer.cs" />
<Compile Include="Util\LongDict.cs" />
@ -396,7 +399,7 @@ @@ -396,7 +399,7 @@
<Compile Include="Disassembler\ReflectionDisassembler.cs" />
<Compile Include="IL\SemanticHelper.cs" />
<Compile Include="IL\BlockBuilder.cs" />
<Compile Include="IL\ILOpCodes.cs">
<Compile Include="Metadata\ILOpCodes.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>ILOpCodes.tt</DependentUpon>
@ -576,7 +579,7 @@ @@ -576,7 +579,7 @@
<None Include="ICSharpCode.Decompiler.nuspec.template" />
<None Include="ICSharpCode.Decompiler.ruleset" />
<None Include="ICSharpCode.Decompiler.snk" />
<None Include="IL\ILOpCodes.tt">
<None Include="Metadata\ILOpCodes.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>ILOpCodes.cs</LastGenOutput>
</None>

168
ICSharpCode.Decompiler/IL/ILOpCodes.tt

@ -1,168 +0,0 @@ @@ -1,168 +0,0 @@
// Copyright (c) 2014 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Reflection.Metadata" #>
<#@ import namespace="System.Reflection.Emit" #>
<#@ output extension=".cs" #>
using System;
using System.Collections.Generic;
using System.Reflection.Metadata;
<#
var operandTypes = Enumerable.Repeat((OperandType)0xff, 0x11f).ToArray();
var operandNames = new string[0x11f];
#>
namespace ICSharpCode.Decompiler.IL
{
/// <summary>Describes the operand type of Microsoft intermediate language (MSIL) instruction.</summary>
public enum OperandType
{
/// <summary>The operand is a 32-bit integer branch target.</summary>
BrTarget,
/// <summary>The operand is a 32-bit metadata token.</summary>
Field,
/// <summary>The operand is a 32-bit integer.</summary>
I,
/// <summary>The operand is a 64-bit integer.</summary>
I8,
/// <summary>The operand is a 32-bit metadata token.</summary>
Method,
/// <summary>No operand.</summary>
None,
/// <summary>The operand is reserved and should not be used.</summary>
[Obsolete("This API has been deprecated. http://go.microsoft.com/fwlink/?linkid=14202")]
Phi,
/// <summary>The operand is a 64-bit IEEE floating point number.</summary>
R,
/// <summary>The operand is a 32-bit metadata signature token.</summary>
Sig = 9,
/// <summary>The operand is a 32-bit metadata string token.</summary>
String,
/// <summary>The operand is the 32-bit integer argument to a switch instruction.</summary>
Switch,
/// <summary>The operand is a <see langword="FieldRef" />, <see langword="MethodRef" />, or <see langword="TypeRef" /> token.</summary>
Tok,
/// <summary>The operand is a 32-bit metadata token.</summary>
Type,
/// <summary>The operand is 16-bit integer containing the ordinal of a local variable or an argument.</summary>
Variable,
/// <summary>The operand is an 8-bit integer branch target.</summary>
ShortBrTarget,
/// <summary>The operand is an 8-bit integer.</summary>
ShortI,
/// <summary>The operand is a 32-bit IEEE floating point number.</summary>
ShortR,
/// <summary>The operand is an 8-bit integer containing the ordinal of a local variable or an argumenta.</summary>
ShortVariable
}
<#
foreach (var field in typeof(OpCodes).GetFields()) {
var opCode = (OpCode)field.GetValue(null);
ushort index = (ushort)(((opCode.Value & 0x200) >> 1) | (opCode.Value & 0xff));
operandTypes[index] = opCode.OperandType;
operandNames[index] = opCode.Name;
} #>
static class ILOpCodeExtensions
{
// We use a byte array instead of an enum array because it can be initialized more efficiently
static readonly byte[] operandTypes = { <#
foreach (var operandType in operandTypes) {
if ((byte)operandType == 255) {
Write("255, ");
} else {
string operandTypeName = operandType.ToString().Replace("Inline", "").Replace("Var", "Variable");
Write("(byte)OperandType." + operandTypeName + ", ");
}
}
#> };
static readonly string[] operandNames = { <#
foreach (var operandName in operandNames) {
Write("\"" + operandName + "\", ");
}
#> };
public static OperandType GetOperandType(this ILOpCode opCode)
{
ushort index = (ushort)((((int)opCode & 0x200) >> 1) | ((int)opCode & 0xff));
if (index >= operandTypes.Length)
return (OperandType)255;
return (OperandType)operandTypes[index];
}
public static string GetDisplayName(this ILOpCode opCode)
{
ushort index = (ushort)((((int)opCode & 0x200) >> 1) | ((int)opCode & 0xff));
if (index >= operandNames.Length)
return "";
return operandNames[index];
}
public static bool IsDefined(this ILOpCode opCode)
{
return !string.IsNullOrEmpty(GetDisplayName(opCode));
}
public static readonly HashSet<string> ILKeywords = BuildKeywordList(
"abstract", "algorithm", "alignment", "ansi", "any", "arglist",
"array", "as", "assembly", "assert", "at", "auto", "autochar", "beforefieldinit",
"blob", "blob_object", "bool", "brnull", "brnull.s", "brzero", "brzero.s", "bstr",
"bytearray", "byvalstr", "callmostderived", "carray", "catch", "cdecl", "cf",
"char", "cil", "class", "clsid", "const", "currency", "custom", "date", "decimal",
"default", "demand", "deny", "endmac", "enum", "error", "explicit", "extends", "extern",
"false", "famandassem", "family", "famorassem", "fastcall", "fault", "field", "filetime",
"filter", "final", "finally", "fixed", "float", "float32", "float64", "forwardref",
"fromunmanaged", "handler", "hidebysig", "hresult", "idispatch", "il", "illegal",
"implements", "implicitcom", "implicitres", "import", "in", "inheritcheck", "init",
"initonly", "instance", "int", "int16", "int32", "int64", "int8", "interface", "internalcall",
"iunknown", "lasterr", "lcid", "linkcheck", "literal", "localloc", "lpstr", "lpstruct", "lptstr",
"lpvoid", "lpwstr", "managed", "marshal", "method", "modopt", "modreq", "native", "nested",
"newslot", "noappdomain", "noinlining", "nomachine", "nomangle", "nometadata", "noncasdemand",
"noncasinheritance", "noncaslinkdemand", "noprocess", "not", "not_in_gc_heap", "notremotable",
"notserialized", "null", "nullref", "object", "objectref", "opt", "optil", "out",
"permitonly", "pinned", "pinvokeimpl", "prefix1", "prefix2", "prefix3", "prefix4", "prefix5", "prefix6",
"prefix7", "prefixref", "prejitdeny", "prejitgrant", "preservesig", "private", "privatescope", "protected",
"public", "record", "refany", "reqmin", "reqopt", "reqrefuse", "reqsecobj", "request", "retval",
"rtspecialname", "runtime", "safearray", "sealed", "sequential", "serializable", "special", "specialname",
"static", "stdcall", "storage", "stored_object", "stream", "streamed_object", "string", "struct",
"synchronized", "syschar", "sysstring", "tbstr", "thiscall", "tls", "to", "true", "typedref",
"unicode", "unmanaged", "unmanagedexp", "unsigned", "unused", "userdefined", "value", "valuetype",
"vararg", "variant", "vector", "virtual", "void", "wchar", "winapi", "with", "wrapper",
// These are not listed as keywords in spec, but ILAsm treats them as such
"property", "type", "flags", "callconv", "strict"
);
static HashSet<string> BuildKeywordList(params string[] keywords)
{
HashSet<string> s = new HashSet<string>(keywords);
foreach (var inst in operandNames) {
if (string.IsNullOrEmpty(inst))
continue;
s.Add(inst);
}
return s;
}
}
}

585
ICSharpCode.Decompiler/Dom/Dom.cs → ICSharpCode.Decompiler/Metadata/Dom.cs

@ -9,10 +9,11 @@ using System.Reflection.Metadata.Ecma335; @@ -9,10 +9,11 @@ using System.Reflection.Metadata.Ecma335;
using System.Reflection.PortableExecutable;
using System.Security.Cryptography;
using System.Text;
using ICSharpCode.Decompiler.Documentation;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.Dom
namespace ICSharpCode.Decompiler.Metadata
{
using SRMMemberRef = System.Reflection.Metadata.MemberReference;
using SRMMethod = System.Reflection.Metadata.MethodDefinition;
@ -41,12 +42,6 @@ namespace ICSharpCode.Decompiler.Dom @@ -41,12 +42,6 @@ namespace ICSharpCode.Decompiler.Dom
}
}
public interface ICustomAttributeProvider
{
PEFile Module { get; }
CustomAttributeHandleCollection CustomAttributes { get; }
}
public interface IAssemblyResolver
{
PEFile Resolve(IAssemblyReference reference);
@ -66,45 +61,21 @@ namespace ICSharpCode.Decompiler.Dom @@ -66,45 +61,21 @@ namespace ICSharpCode.Decompiler.Dom
public interface IAssemblyDocumentationResolver
{
XmlDocumentationProvider GetProvider();
}
public struct Variable { }
public interface IDebugInfoProvider
{
IList<SequencePoint> GetSequencePoints(MethodDefinition method);
IList<Variable> GetVariables(MethodDefinition method);
}
public interface IMemberReference
public interface IMetadataEntity
{
PEFile Module { get; }
string Name { get; }
IMemberDefinition GetDefinition();
ITypeReference DeclaringType { get; }
EntityHandle Handle { get; }
}
public interface IMemberDefinition : IMemberReference, ICustomAttributeProvider
{
new TypeDefinition DeclaringType { get; }
}
public interface IMethodReference : IMemberReference
{
}
public interface ITypeReference : IMemberReference
{
PEFile Module { get; }
FullTypeName FullName { get; }
string Namespace { get; }
new TypeDefinition GetDefinition();
}
public struct Variable { }
public interface ITypeDefinition : ITypeReference, IMemberDefinition
public interface IDebugInfoProvider
{
new PEFile Module { get; }
TypeDefinitionHandle Handle { get; }
IList<SequencePoint> GetSequencePoints(MethodDefinition method);
IList<Variable> GetVariables(MethodDefinition method);
}
public class PEFile
@ -348,11 +319,107 @@ namespace ICSharpCode.Decompiler.Dom @@ -348,11 +319,107 @@ namespace ICSharpCode.Decompiler.Dom
}
}
public struct MethodDefinition : IEquatable<MethodDefinition>, IMethodReference, IMemberDefinition
public struct Entity : IEquatable<Entity>, IMetadataEntity
{
public PEFile Module { get; }
public EntityHandle Handle { get; }
public bool IsNil => Handle.IsNil;
public Entity(PEFile module, EntityHandle handle) : this()
{
this.Module = module ?? throw new ArgumentNullException(nameof(module));
this.Handle = handle;
}
public bool IsType() => Handle.Kind == HandleKind.TypeDefinition || Handle.Kind == HandleKind.TypeReference || Handle.Kind == HandleKind.TypeSpecification;
public TypeDefinition ResolveAsType()
{
return MetadataResolver.ResolveType(Handle, new SimpleMetadataResolveContext(Module));
}
public MethodDefinition ResolveAsMethod()
{
return MetadataResolver.ResolveMember(Handle, new SimpleMetadataResolveContext(Module));
}
public bool Equals(Entity other)
{
return Module == other.Module && Handle == other.Handle;
}
public override bool Equals(object obj)
{
if (obj is Entity entity)
return Equals(entity);
return false;
}
public override int GetHashCode()
{
return unchecked(982451629 * Module.GetHashCode() + 982451653 * MetadataTokens.GetToken(Handle));
}
public static bool operator ==(Entity lhs, Entity rhs) => lhs.Equals(rhs);
public static bool operator !=(Entity lhs, Entity rhs) => !lhs.Equals(rhs);
public static implicit operator Entity(MethodDefinition method)
{
return new Entity(method.Module, method.Handle);
}
public static implicit operator Entity(PropertyDefinition property)
{
return new Entity(property.Module, property.Handle);
}
public static implicit operator Entity(EventDefinition @event)
{
return new Entity(@event.Module, @event.Handle);
}
public static implicit operator Entity(FieldDefinition field)
{
return new Entity(field.Module, field.Handle);
}
public static implicit operator Entity(TypeDefinition type)
{
return new Entity(type.Module, type.Handle);
}
public static implicit operator TypeDefinition(Entity entity)
{
return new TypeDefinition(entity.Module, (TypeDefinitionHandle)entity.Handle);
}
public static implicit operator MethodDefinition(Entity entity)
{
return new MethodDefinition(entity.Module, (MethodDefinitionHandle)entity.Handle);
}
public static implicit operator PropertyDefinition(Entity entity)
{
return new PropertyDefinition(entity.Module, (PropertyDefinitionHandle)entity.Handle);
}
public static implicit operator EventDefinition(Entity entity)
{
return new EventDefinition(entity.Module, (EventDefinitionHandle)entity.Handle);
}
public static implicit operator FieldDefinition(Entity entity)
{
return new FieldDefinition(entity.Module, (FieldDefinitionHandle)entity.Handle);
}
}
public struct MethodDefinition : IEquatable<MethodDefinition>, IMetadataEntity
{
public PEFile Module { get; }
public MethodDefinitionHandle Handle { get; }
public bool IsNil => Handle.IsNil;
EntityHandle IMetadataEntity.Handle => Handle;
public MethodDefinition(PEFile module, MethodDefinitionHandle handle) : this()
{
@ -360,7 +427,7 @@ namespace ICSharpCode.Decompiler.Dom @@ -360,7 +427,7 @@ namespace ICSharpCode.Decompiler.Dom
this.Handle = handle;
}
SRMMethod This() => Module.GetMetadataReader().GetMethodDefinition(Handle);
public SRMMethod This() => Module.GetMetadataReader().GetMethodDefinition(Handle);
public bool Equals(MethodDefinition other)
{
@ -388,9 +455,8 @@ namespace ICSharpCode.Decompiler.Dom @@ -388,9 +455,8 @@ namespace ICSharpCode.Decompiler.Dom
return reader.GetString(reader.GetMethodDefinition(Handle).Name);
}
}
/*
public TypeDefinition DeclaringType => new TypeDefinition(Module, This().GetDeclaringType());
ITypeReference IMemberReference.DeclaringType => DeclaringType;
public MethodAttributes Attributes => This().Attributes;
public MethodImplAttributes ImplAttributes => This().ImplAttributes;
@ -399,80 +465,7 @@ namespace ICSharpCode.Decompiler.Dom @@ -399,80 +465,7 @@ namespace ICSharpCode.Decompiler.Dom
public bool HasFlag(MethodAttributes attribute) => (This().Attributes & attribute) == attribute;
public bool HasPInvokeInfo => !This().GetImport().Module.IsNil || HasFlag(MethodAttributes.PinvokeImpl);
public bool IsConstructor => This().IsConstructor(Module.GetMetadataReader());
public bool HasParameters => This().GetParameters().Count > 0;
public bool HasBody => (Attributes & MethodAttributes.Abstract) == 0 &&
(Attributes & MethodAttributes.PinvokeImpl) == 0 &&
(ImplAttributes & MethodImplAttributes.InternalCall) == 0 &&
(ImplAttributes & MethodImplAttributes.Native) == 0 &&
(ImplAttributes & MethodImplAttributes.Unmanaged) == 0 &&
(ImplAttributes & MethodImplAttributes.Runtime) == 0;
public int RVA => This().RelativeVirtualAddress;
public MethodBodyBlock Body => Module.Reader.GetMethodBody(RVA);
public MethodImport Import => This().GetImport();
public GenericParameterHandleCollection GenericParameters => This().GetGenericParameters();
public ParameterHandleCollection Parameters => This().GetParameters();
public bool IsExtensionMethod {
get {
if (!HasFlag(MethodAttributes.Static)) {
var metadata = Module.GetMetadataReader();
foreach (var attribute in This().GetCustomAttributes()) {
string typeName = metadata.GetCustomAttribute(attribute).GetAttributeType(Module).FullName.ToString();
if (typeName == "System.Runtime.CompilerServices.ExtensionAttribute")
return true;
}
}
return false;
}
}
public unsafe MethodSemanticsAttributes GetMethodSemanticsAttributes()
{
var reader = Module.GetMetadataReader();
byte* startPointer = reader.MetadataPointer;
int offset = reader.GetTableMetadataOffset(TableIndex.MethodSemantics);
int rowSize = reader.GetTableRowSize(TableIndex.MethodSemantics);
int rowCount = reader.GetTableRowCount(TableIndex.MethodSemantics);
var small = reader.IsSmallReference(TableIndex.MethodDef);
int methodRowNo = reader.GetRowNumber(Handle);
for (int row = rowCount - 1; row >= 0; row--) {
byte* ptr = startPointer + offset + rowSize * row;
uint rowNo = small ? *(ushort*)(ptr + 2) : *(uint*)(ptr + 2);
if (methodRowNo == rowNo) {
return (MethodSemanticsAttributes)(*(ushort*)ptr);
}
}
return 0;
}
public unsafe ImmutableArray<MethodImplementationHandle> GetMethodImplementations()
{
var reader = Module.GetMetadataReader();
byte* startPointer = reader.MetadataPointer;
int offset = reader.GetTableMetadataOffset(TableIndex.MethodImpl);
int rowSize = reader.GetTableRowSize(TableIndex.MethodImpl);
int rowCount = reader.GetTableRowCount(TableIndex.MethodImpl);
var methodDefSize = reader.GetReferenceSize(TableIndex.MethodDef);
var typeDefSize = reader.GetReferenceSize(TableIndex.TypeDef);
var containingTypeRow = reader.GetRowNumber(This().GetDeclaringType());
var methodDefRow = reader.GetRowNumber(Handle);
var list = new List<MethodImplementationHandle>();
// TODO : if sorted -> binary search?
for (int row = 0; row < reader.GetTableRowCount(TableIndex.MethodImpl); row++) {
byte* ptr = startPointer + offset + rowSize * row;
uint currentTypeRow = typeDefSize == 2 ? *(ushort*)ptr : *(uint*)ptr;
if (currentTypeRow != containingTypeRow) continue;
uint currentMethodRowCoded = methodDefSize == 2 ? *(ushort*)(ptr + typeDefSize) : *(uint*)(ptr + typeDefSize);
if ((currentMethodRowCoded >> 1) != methodDefRow) continue;
list.Add(MetadataTokens.MethodImplementationHandle(row + 1));
}
return list.ToImmutableArray();
}
public bool HasParameters => This().GetParameters().Count > 0;*/
public IList<SequencePoint> GetSequencePoints()
{
@ -483,20 +476,14 @@ namespace ICSharpCode.Decompiler.Dom @@ -483,20 +476,14 @@ namespace ICSharpCode.Decompiler.Dom
{
return Module.DebugInfo?.GetVariables(this);
}
public MethodSignature<TType> DecodeSignature<TType, TGenericContext>(ISignatureTypeProvider<TType, TGenericContext> provider, TGenericContext genericContext)
{
return This().DecodeSignature(provider, genericContext);
}
IMemberDefinition IMemberReference.GetDefinition() => this;
}
public struct PropertyDefinition : IEquatable<PropertyDefinition>, IMemberDefinition, ICustomAttributeProvider
public struct PropertyDefinition : IEquatable<PropertyDefinition>, IMetadataEntity
{
public PEFile Module { get; }
public PropertyDefinitionHandle Handle { get; }
public bool IsNil => Handle.IsNil;
EntityHandle IMetadataEntity.Handle => Handle;
public PropertyDefinition(PEFile module, PropertyDefinitionHandle handle) : this()
{
@ -504,7 +491,7 @@ namespace ICSharpCode.Decompiler.Dom @@ -504,7 +491,7 @@ namespace ICSharpCode.Decompiler.Dom
this.Handle = handle;
}
SRMProperty This() => Module.GetMetadataReader().GetPropertyDefinition(Handle);
public SRMProperty This() => Module.GetMetadataReader().GetPropertyDefinition(Handle);
public bool Equals(PropertyDefinition other)
{
@ -525,7 +512,7 @@ namespace ICSharpCode.Decompiler.Dom @@ -525,7 +512,7 @@ namespace ICSharpCode.Decompiler.Dom
public static bool operator ==(PropertyDefinition lhs, PropertyDefinition rhs) => lhs.Equals(rhs);
public static bool operator !=(PropertyDefinition lhs, PropertyDefinition rhs) => !lhs.Equals(rhs);
/*
public string Name {
get {
var reader = Module.GetMetadataReader();
@ -534,7 +521,6 @@ namespace ICSharpCode.Decompiler.Dom @@ -534,7 +521,6 @@ namespace ICSharpCode.Decompiler.Dom
}
public TypeDefinition DeclaringType => GetAccessors().First().Method.DeclaringType;
ITypeReference IMemberReference.DeclaringType => DeclaringType;
public MethodDefinition GetMethod => GetAccessors().FirstOrDefault(m => m.Kind == MethodSemanticsAttributes.Getter).Method;
public MethodDefinition SetMethod => GetAccessors().FirstOrDefault(m => m.Kind == MethodSemanticsAttributes.Setter).Method;
@ -547,44 +533,17 @@ namespace ICSharpCode.Decompiler.Dom @@ -547,44 +533,17 @@ namespace ICSharpCode.Decompiler.Dom
public bool IsIndexer => HasMatchingDefaultMemberAttribute(out var attr);
public bool HasMatchingDefaultMemberAttribute(out CustomAttributeHandle defaultMemberAttribute)
public unsafe ImmutableArray<(MethodSemanticsAttributes Kind, MethodDefinition Method)> GetAccessors()
{
var metadata = Module.GetMetadataReader();
defaultMemberAttribute = default(CustomAttributeHandle);
if (HasParameters) {
var accessor = GetAccessors().First(a => a.Kind != MethodSemanticsAttributes.Other).Method;
PropertyDefinition basePropDef = this;
var firstOverrideHandle = accessor.GetMethodImplementations().FirstOrDefault();
if (!firstOverrideHandle.IsNil) {
// if the property is explicitly implementing an interface, look up the property in the interface:
var firstOverride = metadata.GetMethodImplementation(firstOverrideHandle);
var baseAccessor = firstOverride.MethodDeclaration.CoerceMemberReference(Module).GetDefinition() as MethodDefinition?;
if (baseAccessor != null) {
foreach (PropertyDefinition baseProp in baseAccessor?.DeclaringType.Properties) {
if (baseProp.GetMethod == baseAccessor || baseProp.SetMethod == baseAccessor) {
basePropDef = baseProp;
break;
}
}
} else
return false;
}
var defaultMemberName = basePropDef.DeclaringType.Handle.GetDefaultMemberName(metadata, out var attr);
if (defaultMemberName == basePropDef.Name) {
defaultMemberAttribute = attr;
return true;
}
}
return false;
return GetAccessors(Module, (uint)(MetadataTokens.GetRowNumber(Handle) << 1) | 1);
}
public unsafe ImmutableArray<(MethodSemanticsAttributes Kind, MethodDefinition Method)> GetAccessors()
internal static unsafe ImmutableArray<(MethodSemanticsAttributes Kind, MethodDefinition Method)> GetAccessors(PEFile module, uint encodedTag)
{
var reader = Module.GetMetadataReader();
var reader = module.GetMetadataReader();
byte* startPointer = reader.MetadataPointer;
int offset = reader.GetTableMetadataOffset(TableIndex.MethodSemantics);
uint encodedTag = (uint)(MetadataTokens.GetRowNumber(Handle) << 1) | 1;
var methodDefRefSize = reader.GetReferenceSize(TableIndex.MethodDef);
(int startRow, int endRow) = reader.BinarySearchRange(TableIndex.MethodSemantics, 2 + methodDefRefSize, encodedTag, reader.IsSmallReference(TableIndex.MethodSemantics));
if (startRow == -1)
@ -595,8 +554,9 @@ namespace ICSharpCode.Decompiler.Dom @@ -595,8 +554,9 @@ namespace ICSharpCode.Decompiler.Dom
int rowOffset = row * rowSize;
byte* ptr = startPointer + offset + rowOffset;
var kind = (MethodSemanticsAttributes)(*(ushort*)ptr);
var handle = MetadataTokens.MethodDefinitionHandle(*(ushort*)(ptr + 2));
methods[row - startRow] = (kind, new MethodDefinition(Module, handle));
uint rowNo = methodDefRefSize == 2 ? *(ushort*)(ptr + 2) : *(uint*)(ptr + 2);
var handle = MetadataTokens.MethodDefinitionHandle((int)rowNo);
methods[row - startRow] = (kind, new MethodDefinition(module, handle));
}
return methods.ToImmutableArray();
}
@ -605,15 +565,15 @@ namespace ICSharpCode.Decompiler.Dom @@ -605,15 +565,15 @@ namespace ICSharpCode.Decompiler.Dom
{
return This().DecodeSignature(provider, genericContext);
}
IMemberDefinition IMemberReference.GetDefinition() => this;
*/
}
public struct FieldDefinition : IEquatable<FieldDefinition>, IMemberDefinition, ICustomAttributeProvider
public struct FieldDefinition : IEquatable<FieldDefinition>, IMetadataEntity
{
public PEFile Module { get; }
public FieldDefinitionHandle Handle { get; }
public bool IsNil => Handle.IsNil;
EntityHandle IMetadataEntity.Handle => Handle;
public FieldDefinition(PEFile module, FieldDefinitionHandle handle) : this()
{
@ -621,7 +581,7 @@ namespace ICSharpCode.Decompiler.Dom @@ -621,7 +581,7 @@ namespace ICSharpCode.Decompiler.Dom
this.Handle = handle;
}
SRMField This() => Module.GetMetadataReader().GetFieldDefinition(Handle);
public SRMField This() => Module.GetMetadataReader().GetFieldDefinition(Handle);
public bool Equals(FieldDefinition other)
{
@ -643,34 +603,10 @@ namespace ICSharpCode.Decompiler.Dom @@ -643,34 +603,10 @@ namespace ICSharpCode.Decompiler.Dom
public static bool operator ==(FieldDefinition lhs, FieldDefinition rhs) => lhs.Equals(rhs);
public static bool operator !=(FieldDefinition lhs, FieldDefinition rhs) => !lhs.Equals(rhs);
public string Name {
get {
var reader = Module.GetMetadataReader();
return reader.GetString(reader.GetFieldDefinition(Handle).Name);
}
}
public TypeDefinition DeclaringType => new TypeDefinition(Module, This().GetDeclaringType());
ITypeReference IMemberReference.DeclaringType => DeclaringType;
public FieldAttributes Attributes => This().Attributes;
public bool HasFlag(FieldAttributes attribute) => (This().Attributes & attribute) == attribute;
public CustomAttributeHandleCollection CustomAttributes => This().GetCustomAttributes();
public int RVA => This().GetRelativeVirtualAddress();
public int Offset => This().GetOffset();
public BlobHandle GetMarshallingDescriptor() => This().GetMarshallingDescriptor();
public ConstantHandle GetDefaultValue() => This().GetDefaultValue();
public TType DecodeSignature<TType, TGenericContext>(ISignatureTypeProvider<TType, TGenericContext> provider, TGenericContext genericContext)
{
return This().DecodeSignature(provider, genericContext);
}
public object DecodeConstant()
{
var metadata = Module.GetMetadataReader();
var constant = metadata.GetConstant(GetDefaultValue());
var constant = metadata.GetConstant(This().GetDefaultValue());
var blob = metadata.GetBlobReader(constant.Value);
switch (constant.TypeCode) {
case ConstantTypeCode.Boolean:
@ -705,15 +641,14 @@ namespace ICSharpCode.Decompiler.Dom @@ -705,15 +641,14 @@ namespace ICSharpCode.Decompiler.Dom
throw new NotSupportedException();
}
}
IMemberDefinition IMemberReference.GetDefinition() => this;
}
public struct EventDefinition : IEquatable<EventDefinition>, IMemberDefinition, ICustomAttributeProvider
public struct EventDefinition : IEquatable<EventDefinition>, IMetadataEntity
{
public PEFile Module { get; }
public EventDefinitionHandle Handle { get; }
public bool IsNil => Handle.IsNil;
EntityHandle IMetadataEntity.Handle => Handle;
public EventDefinition(PEFile module, EventDefinitionHandle handle)
{
@ -721,7 +656,7 @@ namespace ICSharpCode.Decompiler.Dom @@ -721,7 +656,7 @@ namespace ICSharpCode.Decompiler.Dom
this.Handle = handle;
}
SRMEvent This() => Module.GetMetadataReader().GetEventDefinition(Handle);
public SRMEvent This() => Module.GetMetadataReader().GetEventDefinition(Handle);
public bool Equals(EventDefinition other)
{
@ -742,7 +677,7 @@ namespace ICSharpCode.Decompiler.Dom @@ -742,7 +677,7 @@ namespace ICSharpCode.Decompiler.Dom
public static bool operator ==(EventDefinition lhs, EventDefinition rhs) => lhs.Equals(rhs);
public static bool operator !=(EventDefinition lhs, EventDefinition rhs) => !lhs.Equals(rhs);
/*
public string Name {
get {
var reader = Module.GetMetadataReader();
@ -751,7 +686,6 @@ namespace ICSharpCode.Decompiler.Dom @@ -751,7 +686,6 @@ namespace ICSharpCode.Decompiler.Dom
}
public TypeDefinition DeclaringType => GetAccessors().First().Method.DeclaringType;
ITypeReference IMemberReference.DeclaringType => DeclaringType;
public EventAttributes Attributes => This().Attributes;
public bool HasFlag(EventAttributes attribute) => (This().Attributes & attribute) == attribute;
@ -764,59 +698,25 @@ namespace ICSharpCode.Decompiler.Dom @@ -764,59 +698,25 @@ namespace ICSharpCode.Decompiler.Dom
public unsafe ImmutableArray<(MethodSemanticsAttributes Kind, MethodDefinition Method)> GetAccessors()
{
var reader = Module.GetMetadataReader();
byte* startPointer = reader.MetadataPointer;
int offset = reader.GetTableMetadataOffset(TableIndex.MethodSemantics);
uint encodedTag = (uint)(MetadataTokens.GetRowNumber(Handle) << 1) | 0;
var methodDefRefSize = reader.GetReferenceSize(TableIndex.MethodDef);
(int startRow, int endRow) = reader.BinarySearchRange(TableIndex.MethodSemantics, 2 + methodDefRefSize, encodedTag, reader.IsSmallReference(TableIndex.MethodSemantics));
if (startRow == -1)
return ImmutableArray<(MethodSemanticsAttributes Kind, MethodDefinition Method)>.Empty;
var methods = new(MethodSemanticsAttributes Kind, MethodDefinition Method)[endRow - startRow + 1];
int rowSize = reader.GetTableRowSize(TableIndex.MethodSemantics);
for (int row = startRow; row <= endRow; row++) {
int rowOffset = row * rowSize;
byte* ptr = startPointer + offset + rowOffset;
var kind = (MethodSemanticsAttributes)(*(ushort*)ptr);
var handle = MetadataTokens.MethodDefinitionHandle(*(ushort*)(ptr + 2));
methods[row - startRow] = (kind, new MethodDefinition(Module, handle));
}
return methods.ToImmutableArray();
}
public TType DecodeSignature<TType, TGenericContext>(ISignatureTypeProvider<TType, TGenericContext> provider, TGenericContext genericContext)
{
var type = This().Type;
var reader = Module.GetMetadataReader();
switch (type.Kind) {
case HandleKind.TypeDefinition:
return provider.GetTypeFromDefinition(reader, (TypeDefinitionHandle)type, 0);
case HandleKind.TypeReference:
return provider.GetTypeFromReference(reader, (TypeReferenceHandle)type, 0);
case HandleKind.TypeSpecification:
return provider.GetTypeFromSpecification(reader, genericContext, (TypeSpecificationHandle)type, 0);
default:
throw new NotSupportedException();
}
}
IMemberDefinition IMemberReference.GetDefinition() => this;
return PropertyDefinition.GetAccessors(Module, (uint)(MetadataTokens.GetRowNumber(Handle) << 1) | 0);
}*/
}
public struct TypeDefinition : IEquatable<TypeDefinition>, ITypeDefinition, ICustomAttributeProvider
public struct TypeDefinition : IEquatable<TypeDefinition>, IMetadataEntity
{
public PEFile Module { get; }
public TypeDefinitionHandle Handle { get; }
public bool IsNil => Handle.IsNil;
EntityHandle IMetadataEntity.Handle => Handle;
public TypeDefinition(PEFile module, TypeDefinitionHandle handle)
{
this.Module = module ?? throw new ArgumentNullException(nameof(module));
this.Handle = handle;
}
internal SRMTypeDef This() => Module.GetMetadataReader().GetTypeDefinition(Handle);
public SRMTypeDef This() => Module.GetMetadataReader().GetTypeDefinition(Handle);
public bool Equals(TypeDefinition other)
{
@ -837,106 +737,9 @@ namespace ICSharpCode.Decompiler.Dom @@ -837,106 +737,9 @@ namespace ICSharpCode.Decompiler.Dom
public static bool operator ==(TypeDefinition lhs, TypeDefinition rhs) => lhs.Equals(rhs);
public static bool operator !=(TypeDefinition lhs, TypeDefinition rhs) => !lhs.Equals(rhs);
public string Name => Module.GetMetadataReader().GetString(This().Name);
public string Namespace => Module.GetMetadataReader().GetString(This().Namespace);
public FullTypeName FullName => This().GetFullTypeName(Module.GetMetadataReader());
public TypeAttributes Attributes => This().Attributes;
public bool HasFlag(TypeAttributes attribute) => (This().Attributes & attribute) == attribute;
public TypeDefinition DeclaringType => new TypeDefinition(Module, This().GetDeclaringType());
ITypeReference IMemberReference.DeclaringType => DeclaringType;
public GenericParameterHandleCollection GenericParameters => This().GetGenericParameters();
public CustomAttributeHandleCollection CustomAttributes => This().GetCustomAttributes();
public DeclarativeSecurityAttributeHandleCollection DeclarativeSecurityAttributes => This().GetDeclarativeSecurityAttributes();
public TypeLayout GetLayout() => This().GetLayout();
public ITypeReference BaseType {
get {
var baseType = This().BaseType;
return CreateTypeReference(baseType);
}
}
ITypeReference CreateTypeReference(EntityHandle baseType)
{
if (baseType.IsNil)
return null;
switch (baseType.Kind) {
case HandleKind.TypeDefinition:
return new TypeDefinition(Module, (TypeDefinitionHandle)baseType);
case HandleKind.TypeReference:
return new TypeReference(Module, (TypeReferenceHandle)baseType);
case HandleKind.TypeSpecification:
return new TypeSpecification(Module, (TypeSpecificationHandle)baseType);
default:
throw new NotSupportedException();
}
}
public bool HasInterfaces => This().GetInterfaceImplementations().Count > 0;
public ImmutableArray<ITypeReference> Interfaces => GetInterfaces().ToImmutableArray();
IEnumerable<ITypeReference> GetInterfaces()
{
var reader = Module.GetMetadataReader();
foreach (var h in This().GetInterfaceImplementations()) {
var interfaceImpl = reader.GetInterfaceImplementation(h);
yield return CreateTypeReference(interfaceImpl.Interface);
}
}
public bool IsValueType => This().IsValueType(Module.GetMetadataReader());
public bool IsEnum => This().IsEnum(Module.GetMetadataReader());
public bool IsInterface => (This().Attributes & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface;
public bool IsClass => (This().Attributes & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Class;
public bool IsNotPublic => (This().Attributes & TypeAttributes.VisibilityMask) == 0;
public bool IsDelegate {
get {
var baseType = This().BaseType;
return !baseType.IsNil && baseType.GetFullTypeName(Module.GetMetadataReader()).ToString() == typeof(MulticastDelegate).FullName;
}
}
public ImmutableArray<TypeDefinition> NestedTypes {
get {
var module = Module;
return This().GetNestedTypes().Select(nt => new TypeDefinition(module, nt)).ToImmutableArray();
}
}
public ImmutableArray<FieldDefinition> Fields {
get {
var module = Module;
return This().GetFields().Select(f => new FieldDefinition(module, f)).ToImmutableArray();
}
}
public ImmutableArray<PropertyDefinition> Properties {
get {
var module = Module;
return This().GetProperties().Select(p => new PropertyDefinition(module, p)).ToImmutableArray();
}
}
public ImmutableArray<EventDefinition> Events {
get {
var module = Module;
return This().GetEvents().Select(e => new EventDefinition(module, e)).ToImmutableArray();
}
}
public ImmutableArray<MethodDefinition> Methods {
get {
var module = Module;
return This().GetMethods().Select(m => new MethodDefinition(module, m)).ToImmutableArray();
}
}
TypeDefinition ITypeReference.GetDefinition() => this;
public InterfaceImplementationHandleCollection GetInterfaceImplementations() => This().GetInterfaceImplementations();
IMemberDefinition IMemberReference.GetDefinition() => this;
}
public struct TypeReference : ITypeReference
public struct TypeReference
{
public PEFile Module { get; }
public TypeReferenceHandle Handle { get; }
@ -971,12 +774,9 @@ namespace ICSharpCode.Decompiler.Dom @@ -971,12 +774,9 @@ namespace ICSharpCode.Decompiler.Dom
{
return MetadataResolver.Resolve(Handle, new SimpleMetadataResolveContext(Module));
}
IMemberDefinition IMemberReference.GetDefinition() => GetDefinition();
ITypeReference IMemberReference.DeclaringType => new TypeReference(Module, This().GetDeclaringType());
}
public struct TypeSpecification : ITypeReference
public struct TypeSpecification
{
public PEFile Module { get; }
public TypeSpecificationHandle Handle { get; }
@ -1000,56 +800,31 @@ namespace ICSharpCode.Decompiler.Dom @@ -1000,56 +800,31 @@ namespace ICSharpCode.Decompiler.Dom
public string Namespace => FullName.TopLevelTypeName.Namespace;
public ITypeReference DeclaringType => GetDefinition().DeclaringType;
public TypeDefinition GetDefinition()
{
return MetadataResolver.Resolve(Handle, new SimpleMetadataResolveContext(Module));
}
IMemberDefinition IMemberReference.GetDefinition()
{
return GetDefinition();
}
public TType DecodeSignature<TType, TGenericContext>(ISignatureTypeProvider<TType, TGenericContext> provider, TGenericContext genericContext)
{
return This().DecodeSignature(provider, genericContext);
}
}
public struct MethodSpecification : IMethodReference
public struct MethodSpecification
{
public PEFile Module { get; }
public MethodSpecificationHandle Handle { get; }
public bool IsNil => Handle.IsNil;
public string Name => This().Method.CoerceMemberReference(Module).Name;
public MethodSpecification(PEFile module, MethodSpecificationHandle handle)
{
this.Module = module ?? throw new ArgumentNullException(nameof(module));
this.Handle = handle;
}
SRMMethodSpec This() => Module.GetMetadataReader().GetMethodSpecification(Handle);
public ImmutableArray<TType> DecodeSignature<TType, TGenericContext>(ISignatureTypeProvider<TType, TGenericContext> provider, TGenericContext genericContext)
{
return This().DecodeSignature(provider, genericContext);
}
public IMemberDefinition GetDefinition()
{
return Method.GetDefinition();
}
public ITypeReference DeclaringType => Method.DeclaringType;
public IMemberReference Method => This().Method.CoerceMemberReference(Module);
}
public struct MemberReference : IMemberReference
public struct MemberReference
{
public PEFile Module { get; }
public MemberReferenceHandle Handle { get; }
@ -1062,42 +837,9 @@ namespace ICSharpCode.Decompiler.Dom @@ -1062,42 +837,9 @@ namespace ICSharpCode.Decompiler.Dom
this.Module = module ?? throw new ArgumentNullException(nameof(module));
this.Handle = handle;
}
public string Name {
get {
var reader = Module.GetMetadataReader();
return reader.GetString(reader.GetMemberReference(Handle).Name);
}
}
public MemberReferenceKind Kind => This().GetKind();
/// <summary>
/// MethodDef, ModuleRef,TypeDef, TypeRef, or TypeSpec handle.
/// </summary>
public EntityHandle Parent => This().Parent;
public MethodSignature<TType> DecodeMethodSignature<TType, TGenericContext>(ISignatureTypeProvider<TType, TGenericContext> provider, TGenericContext genericContext)
{
return This().DecodeMethodSignature(provider, genericContext);
}
public TType DecodeFieldSignature<TType, TGenericContext>(ISignatureTypeProvider<TType, TGenericContext> provider, TGenericContext genericContext)
{
return This().DecodeFieldSignature(provider, genericContext);
}
public IMemberDefinition GetDefinition()
{
return MetadataResolver.Resolve(Handle, new SimpleMetadataResolveContext(Module));
}
public TypeDefinition DeclaringType => GetDefinition().DeclaringType;
ITypeReference IMemberReference.DeclaringType => DeclaringType;
}
class FullTypeNameSignatureDecoder : ISignatureTypeProvider<FullTypeName, Unit>
public sealed class FullTypeNameSignatureDecoder : ISignatureTypeProvider<FullTypeName, Unit>
{
readonly MetadataReader metadata;
@ -1179,53 +921,70 @@ namespace ICSharpCode.Decompiler.Dom @@ -1179,53 +921,70 @@ namespace ICSharpCode.Decompiler.Dom
public class GenericContext
{
readonly MethodDefinition method;
readonly TypeDefinition declaringType;
readonly PEFile module;
readonly MetadataReader metadata;
readonly TypeDefinitionHandle declaringType;
readonly MethodDefinitionHandle method;
public static readonly GenericContext Empty = new GenericContext();
private GenericContext() { }
public GenericContext(MethodDefinition method)
public GenericContext(MethodDefinitionHandle method, PEFile module)
{
this.module = module;
this.metadata = module.GetMetadataReader();
this.method = method;
this.declaringType = method.DeclaringType;
this.metadata = method.Module.GetMetadataReader();
this.declaringType = metadata.GetMethodDefinition(method).GetDeclaringType();
}
public GenericContext(TypeDefinition declaringType)
public GenericContext(MethodDefinition method)
: this(method.Handle, method.Module)
{
}
public GenericContext(TypeDefinitionHandle declaringType, PEFile module)
{
this.module = module;
this.metadata = module.GetMetadataReader();
this.declaringType = declaringType;
this.metadata = declaringType.Module.GetMetadataReader();
}
public GenericContext(TypeDefinition declaringType)
: this(declaringType.Handle, declaringType.Module)
{
}
public string GetGenericTypeParameterName(int index)
{
if (declaringType.IsNil || index < 0 || index >= declaringType.GenericParameters.Count)
GenericParameterHandle genericParameter = GetGenericTypeParameterHandleOrNull(index);
if (genericParameter.IsNil)
return index.ToString();
return metadata.GetString(metadata.GetGenericParameter(declaringType.GenericParameters[index]).Name);
return metadata.GetString(metadata.GetGenericParameter(genericParameter).Name);
}
public string GetGenericMethodTypeParameterName(int index)
{
if (method.IsNil || index < 0 || index >= method.GenericParameters.Count)
GenericParameterHandle genericParameter = GetGenericMethodTypeParameterHandleOrNull(index);
if (genericParameter.IsNil)
return index.ToString();
return metadata.GetString(metadata.GetGenericParameter(method.GenericParameters[index]).Name);
return metadata.GetString(metadata.GetGenericParameter(genericParameter).Name);
}
public GenericParameterHandle GetGenericTypeParameterHandleOrNull(int index)
{
if (declaringType.IsNil || index < 0 || index >= declaringType.GenericParameters.Count)
GenericParameterHandleCollection genericParameters;
if (declaringType.IsNil || index < 0 || index >= (genericParameters = metadata.GetTypeDefinition(declaringType).GetGenericParameters()).Count)
return MetadataTokens.GenericParameterHandle(0);
return declaringType.GenericParameters[index];
return genericParameters[index];
}
public GenericParameterHandle GetGenericMethodTypeParameterHandleOrNull(int index)
{
if (method.IsNil || index < 0 || index >= method.GenericParameters.Count)
GenericParameterHandleCollection genericParameters;
if (method.IsNil || index < 0 || index >= (genericParameters = metadata.GetMethodDefinition(method).GetGenericParameters()).Count)
return MetadataTokens.GenericParameterHandle(0);
return method.GenericParameters[index];
return genericParameters[index];
}
}
}

3
ICSharpCode.Decompiler/DotNetCore/DotNetCorePathFinder.cs → ICSharpCode.Decompiler/Metadata/DotNetCorePathFinder.cs

@ -5,10 +5,9 @@ using System.IO; @@ -5,10 +5,9 @@ using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using ICSharpCode.Decompiler.Dom;
using LightJson.Serialization;
namespace ICSharpCode.Decompiler
namespace ICSharpCode.Decompiler.Metadata
{
public class DotNetCorePathFinder
{

2
ICSharpCode.Decompiler/DotNetCore/DotNetCorePathFinderExtensions.cs → ICSharpCode.Decompiler/Metadata/DotNetCorePathFinderExtensions.cs

@ -4,7 +4,7 @@ using System.Linq; @@ -4,7 +4,7 @@ using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
namespace ICSharpCode.Decompiler
namespace ICSharpCode.Decompiler.Metadata
{
public static class DotNetCorePathFinderExtensions
{

108
ICSharpCode.Decompiler/IL/ILOpCodes.cs → ICSharpCode.Decompiler/Metadata/ILOpCodes.cs

File diff suppressed because one or more lines are too long

64
ICSharpCode.Decompiler/Metadata/ILOpCodes.tt

@ -0,0 +1,64 @@ @@ -0,0 +1,64 @@
// Copyright (c) 2014 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Reflection.Metadata" #>
<#@ import namespace="System.Reflection.Emit" #>
<#@ output extension=".cs" #>
using System;
using System.Collections.Generic;
using System.Reflection.Metadata;
<#
var operandTypes = Enumerable.Repeat((OperandType)0xff, 0x11f).ToArray();
var operandNames = new string[0x11f];
#>
namespace ICSharpCode.Decompiler.Metadata
{
<#
foreach (var field in typeof(OpCodes).GetFields()) {
var opCode = (OpCode)field.GetValue(null);
ushort index = (ushort)(((opCode.Value & 0x200) >> 1) | (opCode.Value & 0xff));
operandTypes[index] = opCode.OperandType;
operandNames[index] = opCode.Name;
} #>
static partial class ILOpCodeExtensions
{
// We use a byte array instead of an enum array because it can be initialized more efficiently
static readonly byte[] operandTypes = { <#
foreach (var operandType in operandTypes) {
if ((byte)operandType == 255) {
Write("255, ");
} else {
string operandTypeName = operandType.ToString().Replace("Inline", "").Replace("Var", "Variable");
Write("(byte)OperandType." + operandTypeName + ", ");
}
}
#> };
static readonly string[] operandNames = { <#
foreach (var operandName in operandNames) {
Write("\"" + operandName + "\", ");
}
#> };
}
}

0
ICSharpCode.Decompiler/DotNetCore/LightJson/JsonArray.cs → ICSharpCode.Decompiler/Metadata/LightJson/JsonArray.cs

0
ICSharpCode.Decompiler/DotNetCore/LightJson/JsonObject.cs → ICSharpCode.Decompiler/Metadata/LightJson/JsonObject.cs

0
ICSharpCode.Decompiler/DotNetCore/LightJson/JsonValue.cs → ICSharpCode.Decompiler/Metadata/LightJson/JsonValue.cs

0
ICSharpCode.Decompiler/DotNetCore/LightJson/JsonValueType.cs → ICSharpCode.Decompiler/Metadata/LightJson/JsonValueType.cs

0
ICSharpCode.Decompiler/DotNetCore/LightJson/Serialization/JsonParseException.cs → ICSharpCode.Decompiler/Metadata/LightJson/Serialization/JsonParseException.cs

0
ICSharpCode.Decompiler/DotNetCore/LightJson/Serialization/JsonReader.cs → ICSharpCode.Decompiler/Metadata/LightJson/Serialization/JsonReader.cs

0
ICSharpCode.Decompiler/DotNetCore/LightJson/Serialization/JsonSerializationException.cs → ICSharpCode.Decompiler/Metadata/LightJson/Serialization/JsonSerializationException.cs

0
ICSharpCode.Decompiler/DotNetCore/LightJson/Serialization/JsonWriter.cs → ICSharpCode.Decompiler/Metadata/LightJson/Serialization/JsonWriter.cs

0
ICSharpCode.Decompiler/DotNetCore/LightJson/Serialization/TextPosition.cs → ICSharpCode.Decompiler/Metadata/LightJson/Serialization/TextPosition.cs

0
ICSharpCode.Decompiler/DotNetCore/LightJson/Serialization/TextScanner.cs → ICSharpCode.Decompiler/Metadata/LightJson/Serialization/TextScanner.cs

193
ICSharpCode.Decompiler/Dom/MetadataExtensions.cs → ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs

@ -3,6 +3,7 @@ using System.Collections.Generic; @@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
using SRM = System.Reflection.Metadata;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Reflection.PortableExecutable;
@ -13,43 +14,20 @@ using ICSharpCode.Decompiler.TypeSystem; @@ -13,43 +14,20 @@ using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler
namespace ICSharpCode.Decompiler.Metadata
{
public static class MetadataExtensions
{
public static Dom.ITypeReference CoerceTypeReference(this EntityHandle handle, Dom.PEFile module)
#region Resolver
public static TypeDefinition ResolveAsType(this EntityHandle entity, PEFile module)
{
if (handle.IsNil)
return null;
switch (handle.Kind) {
case HandleKind.TypeDefinition:
return new Dom.TypeDefinition(module, (TypeDefinitionHandle)handle);
case HandleKind.TypeReference:
return new Dom.TypeReference(module, (TypeReferenceHandle)handle);
case HandleKind.TypeSpecification:
return new Dom.TypeSpecification(module, (TypeSpecificationHandle)handle);
default:
throw new ArgumentException("must be either TypeDef, TypeRef or TypeSpec!", nameof(handle));
}
}
public static Dom.IMemberReference CoerceMemberReference(this EntityHandle handle, Dom.PEFile module)
{
if (handle.IsNil)
return null;
switch (handle.Kind) {
case HandleKind.MemberReference:
return new Dom.MemberReference(module, (MemberReferenceHandle)handle);
case HandleKind.MethodDefinition:
return new Dom.MethodDefinition(module, (MethodDefinitionHandle)handle);
default:
throw new ArgumentException("must be either MethodDef or MemberRef!", nameof(handle));
}
return new Entity(module, entity).ResolveAsType();
}
#endregion
public static bool IsNil(this Dom.IAssemblyReference reference)
public static bool IsNil(this IAssemblyReference reference)
{
return reference == null || (reference is Dom.AssemblyReference ar && ar.IsNil);
return reference == null || (reference is Metadata.AssemblyReference ar && ar.IsNil);
}
public static string GetFullAssemblyName(this MetadataReader reader)
@ -63,10 +41,10 @@ namespace ICSharpCode.Decompiler @@ -63,10 +41,10 @@ namespace ICSharpCode.Decompiler
var publicKeyTokenBytes = sha1.ComputeHash(reader.GetBlobBytes(asm.PublicKey)).Skip(12).ToArray();
publicKey = publicKeyTokenBytes.ToHexString();
}
return $"{reader.GetString(asm.Name)}, Version={asm.Version}, Culture={reader.GetString(asm.Culture)}, PublicKeyToken={publicKey}";
return $"{reader.GetString(asm.Name)}, Version={asm.Version}, Culture={(asm.Culture.IsNil ? "neutral" : reader.GetString(asm.Culture))}, PublicKeyToken={publicKey}";
}
public static string GetFullAssemblyName(this AssemblyReference reference, MetadataReader reader)
public static string GetFullAssemblyName(this SRM.AssemblyReference reference, MetadataReader reader)
{
string publicKey = "null";
if (!reference.PublicKeyOrToken.IsNil && (reference.Flags & AssemblyFlags.PublicKey) != 0) {
@ -88,41 +66,6 @@ namespace ICSharpCode.Decompiler @@ -88,41 +66,6 @@ namespace ICSharpCode.Decompiler
return sb.ToString();
}
/// <summary>
/// Gets the type of the attribute.
/// </summary>
public static Dom.ITypeReference GetAttributeType(this CustomAttribute attribute, Dom.PEFile module)
{
var reader = module.GetMetadataReader();
switch (attribute.Constructor.Kind) {
case HandleKind.MethodDefinition:
var md = reader.GetMethodDefinition((MethodDefinitionHandle)attribute.Constructor);
return new Dom.TypeDefinition(module, md.GetDeclaringType());
case HandleKind.MemberReference:
var mr = reader.GetMemberReference((MemberReferenceHandle)attribute.Constructor);
return mr.Parent.CoerceTypeReference(module);
default:
throw new NotSupportedException();
}
}
/// <summary>
/// Gets the type of the attribute.
/// </summary>
public static EntityHandle GetAttributeType(this CustomAttribute attribute, MetadataReader reader)
{
switch (attribute.Constructor.Kind) {
case HandleKind.MethodDefinition:
var md = reader.GetMethodDefinition((MethodDefinitionHandle)attribute.Constructor);
return md.GetDeclaringType();
case HandleKind.MemberReference:
var mr = reader.GetMemberReference((MemberReferenceHandle)attribute.Constructor);
return mr.Parent;
default:
throw new NotSupportedException();
}
}
public static IEnumerable<TypeDefinitionHandle> GetTopLevelTypeDefinitions(this MetadataReader reader)
{
var queue = new Queue<NamespaceDefinition>();
@ -136,62 +79,6 @@ namespace ICSharpCode.Decompiler @@ -136,62 +79,6 @@ namespace ICSharpCode.Decompiler
}
}
public static FullTypeName GetFullTypeName(this EntityHandle handle, MetadataReader reader)
{
if (handle.IsNil)
throw new ArgumentNullException(nameof(handle));
switch (handle.Kind) {
case HandleKind.TypeDefinition:
return ((TypeDefinitionHandle)handle).GetFullTypeName(reader);
case HandleKind.TypeReference:
return ((TypeReferenceHandle)handle).GetFullTypeName(reader);
case HandleKind.TypeSpecification:
return ((TypeSpecificationHandle)handle).GetFullTypeName(reader);
default:
throw new NotSupportedException();
}
}
public static FullTypeName GetFullTypeName(this TypeSpecificationHandle handle, MetadataReader reader, bool omitGenericParamCount = false)
{
if (handle.IsNil)
throw new ArgumentNullException(nameof(handle));
var ts = reader.GetTypeSpecification(handle);
return ts.DecodeSignature(new Dom.FullTypeNameSignatureDecoder(reader), default(Unit));
}
public static FullTypeName GetFullTypeName(this TypeReferenceHandle handle, MetadataReader reader, bool omitGenericParamCount = false)
{
if (handle.IsNil)
throw new ArgumentNullException(nameof(handle));
var tr = reader.GetTypeReference(handle);
TypeReferenceHandle declaringTypeHandle;
if ((declaringTypeHandle = tr.GetDeclaringType()).IsNil) {
string @namespace = tr.Namespace.IsNil ? "" : reader.GetString(tr.Namespace);
return new FullTypeName(new TopLevelTypeName(@namespace, reader.GetString(tr.Name)));
} else {
return declaringTypeHandle.GetFullTypeName(reader, omitGenericParamCount).NestedType(reader.GetString(tr.Name), 0);
}
}
public static FullTypeName GetFullTypeName(this TypeDefinitionHandle handle, MetadataReader reader)
{
if (handle.IsNil)
throw new ArgumentNullException(nameof(handle));
return reader.GetTypeDefinition(handle).GetFullTypeName(reader);
}
public static FullTypeName GetFullTypeName(this TypeDefinition td, MetadataReader reader)
{
TypeDefinitionHandle declaringTypeHandle;
if ((declaringTypeHandle = td.GetDeclaringType()).IsNil) {
string @namespace = td.Namespace.IsNil ? "" : reader.GetString(td.Namespace);
return new FullTypeName(new TopLevelTypeName(@namespace, reader.GetString(td.Name)));
} else {
return declaringTypeHandle.GetFullTypeName(reader).NestedType(reader.GetString(td.Name), 0);
}
}
public static string ToILNameString(this FullTypeName typeName)
{
var escapedName = Disassembler.DisassemblerHelpers.Escape(typeName.Name);
@ -204,16 +91,6 @@ namespace ICSharpCode.Decompiler @@ -204,16 +91,6 @@ namespace ICSharpCode.Decompiler
}
}
public static TypeReferenceHandle GetDeclaringType(this TypeReference tr)
{
switch (tr.ResolutionScope.Kind) {
case HandleKind.TypeReference:
return (TypeReferenceHandle)tr.ResolutionScope;
default:
return default(TypeReferenceHandle);
}
}
public static AssemblyReferenceHandle GetDeclaringAssembly(this TypeReferenceHandle handle, MetadataReader reader)
{
var tr = reader.GetTypeReference(handle);
@ -227,29 +104,47 @@ namespace ICSharpCode.Decompiler @@ -227,29 +104,47 @@ namespace ICSharpCode.Decompiler
}
}
public static bool IsValueType(this TypeDefinition typeDefinition, MetadataReader reader)
{
if (typeDefinition.BaseType.IsNil)
return false;
var baseType = typeDefinition.BaseType.GetFullTypeName(reader).ToString();
if (baseType == "System.Enum")
return true;
var thisType = typeDefinition.GetFullTypeName(reader).ToString();
return baseType == "System.ValueType" && thisType != "System.Enum";
}
public static bool IsConstructor(this MethodDefinition methodDefinition, MetadataReader reader)
public static bool IsConstructor(this SRM.MethodDefinition methodDefinition, MetadataReader reader)
{
string name = reader.GetString(methodDefinition.Name);
return (methodDefinition.Attributes & (MethodAttributes.RTSpecialName | MethodAttributes.SpecialName)) != 0
&& (name == ".cctor" || name == ".ctor");
}
public static bool IsEnum(this TypeDefinition typeDefinition, MetadataReader reader)
public static bool HasMatchingDefaultMemberAttribute(this PropertyDefinitionHandle handle, PEFile module, out CustomAttributeHandle defaultMemberAttribute)
{
if (typeDefinition.BaseType.IsNil)
return false;
return typeDefinition.BaseType.GetFullTypeName(reader).ToString() == "System.Enum";
defaultMemberAttribute = default(CustomAttributeHandle);
var metadata = module.GetMetadataReader();
var propertyDefinition = metadata.GetPropertyDefinition(handle);
var accessorHandle = propertyDefinition.GetAccessors().GetAny();
var accessor = metadata.GetMethodDefinition(accessorHandle);
if (accessor.GetParameters().Count > 0) {
var basePropDef = propertyDefinition;
var firstOverrideHandle = accessorHandle.GetMethodImplementations(metadata).FirstOrDefault();
if (!firstOverrideHandle.IsNil) {
// if the property is explicitly implementing an interface, look up the property in the interface:
var firstOverride = metadata.GetMethodImplementation(firstOverrideHandle);
var baseAccessor = new Metadata.Entity(module, firstOverride.MethodDeclaration).ResolveAsMethod();
if (!baseAccessor.IsNil) {
var declaringType = metadata.GetTypeDefinition(metadata.GetMethodDefinition(baseAccessor.Handle).GetDeclaringType());
foreach (var basePropHandle in declaringType.GetProperties()) {
var baseProp = metadata.GetPropertyDefinition(basePropHandle);
var accessors = baseProp.GetAccessors();
if (accessors.Getter == baseAccessor.Handle || accessors.Setter == baseAccessor.Handle) {
basePropDef = baseProp;
break;
}
}
} else
return false;
}
var defaultMemberName = accessor.GetDeclaringType().GetDefaultMemberName(metadata, out var attr);
if (defaultMemberName == metadata.GetString(basePropDef.Name)) {
defaultMemberAttribute = attr;
return true;
}
}
return false;
}
public static string GetDefaultMemberName(this TypeDefinitionHandle type, MetadataReader reader)

40
ICSharpCode.Decompiler/Dom/MetadataResolver.cs → ICSharpCode.Decompiler/Metadata/MetadataResolver.cs

@ -9,7 +9,7 @@ using System.Text; @@ -9,7 +9,7 @@ using System.Text;
using System.Threading.Tasks;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.Dom
namespace ICSharpCode.Decompiler.Metadata
{
public interface IMetadataResolveContext
{
@ -43,10 +43,33 @@ namespace ICSharpCode.Decompiler.Dom @@ -43,10 +43,33 @@ namespace ICSharpCode.Decompiler.Dom
public static class MetadataResolver
{
public static TypeDefinition ResolveType(EntityHandle handle, IMetadataResolveContext context)
{
switch (handle.Kind) {
case HandleKind.TypeDefinition:
return new TypeDefinition(context.CurrentModule, (TypeDefinitionHandle)handle);
case HandleKind.TypeReference:
return Resolve((TypeReferenceHandle)handle, context);
case HandleKind.TypeSpecification:
return Resolve((TypeSpecificationHandle)handle, context);
default:
throw new NotSupportedException();
}
}
public static MethodDefinition ResolveMember(EntityHandle handle, IMetadataResolveContext context)
{
switch (handle.Kind) {
case HandleKind.MemberReference:
break;
}
throw new NotImplementedException();
}
/// <summary>
/// Implements resolving of TypeReferences to TypeDefinitions as decribed in II.7.3 of ECMA-335 6th edition.
/// </summary>
public static TypeDefinition Resolve(TypeReferenceHandle handle, IMetadataResolveContext context)
public static TypeDefinition Resolve(this TypeReferenceHandle handle, IMetadataResolveContext context)
{
var metadata = context.CurrentModule.GetMetadataReader();
var tr = metadata.GetTypeReference(handle);
@ -101,7 +124,7 @@ namespace ICSharpCode.Decompiler.Dom @@ -101,7 +124,7 @@ namespace ICSharpCode.Decompiler.Dom
return default(TypeDefinitionHandle);
}
public static IMemberDefinition Resolve(MemberReferenceHandle handle, IMetadataResolveContext context)
public static IMetadataEntity Resolve(MemberReferenceHandle handle, IMetadataResolveContext context)
{
var metadata = context.CurrentModule.GetMetadataReader();
var mr = metadata.GetMemberReference(handle);
@ -120,23 +143,24 @@ namespace ICSharpCode.Decompiler.Dom @@ -120,23 +143,24 @@ namespace ICSharpCode.Decompiler.Dom
default:
throw new NotSupportedException();
}
var name = metadata.GetString(mr.Name);
/*var name = metadata.GetString(mr.Name);
switch (mr.GetKind()) {
case MemberReferenceKind.Field:
return declaringType.Fields.FirstOrDefault(fd => fd.Name == name);
case MemberReferenceKind.Method:
var signature = mr.DecodeMethodSignature(new TypeSystem.Implementation.TypeReferenceSignatureDecoder(), default(Unit));
return declaringType.Methods.SingleOrDefault(md => MatchMethodDefinition(name, signature, md));
}
}*/
throw new NotSupportedException();
}
static bool MatchMethodDefinition(string name, MethodSignature<TypeSystem.ITypeReference> signature, MethodDefinition md)
{
if (name != md.Name || md.GenericParameters.Count != signature.GenericParameterCount || signature.RequiredParameterCount != md.Parameters.Count)
return false;
throw new NotImplementedException();
//if (name != md.Name || md.GenericParameters.Count != signature.GenericParameterCount || signature.RequiredParameterCount != md.Parameters.Count)
// return false;
// TODO overload resolution... OMG
return true;
//return true;
}
public static TypeDefinition Resolve(TypeSpecificationHandle handle, IMetadataResolveContext context)

114
ICSharpCode.Decompiler/Metadata/OperandType.cs

@ -0,0 +1,114 @@ @@ -0,0 +1,114 @@
// Copyright (c) 2014 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System.Collections.Generic;
using System.Reflection.Metadata;
namespace ICSharpCode.Decompiler.Metadata
{
public enum OperandType
{
BrTarget,
Field,
I,
I8,
Method,
None,
R = 7,
Sig = 9,
String,
Switch,
Tok,
Type,
Variable,
ShortBrTarget,
ShortI,
ShortR,
ShortVariable
}
static partial class ILOpCodeExtensions
{
public static OperandType GetOperandType(this ILOpCode opCode)
{
ushort index = (ushort)((((int)opCode & 0x200) >> 1) | ((int)opCode & 0xff));
if (index >= operandTypes.Length)
return (OperandType)255;
return (OperandType)operandTypes[index];
}
public static string GetDisplayName(this ILOpCode opCode)
{
ushort index = (ushort)((((int)opCode & 0x200) >> 1) | ((int)opCode & 0xff));
if (index >= operandNames.Length)
return "";
return operandNames[index];
}
public static bool IsDefined(this ILOpCode opCode)
{
return !string.IsNullOrEmpty(GetDisplayName(opCode));
}
static ILOpCodeExtensions()
{
ILKeywords = BuildKeywordList(
"abstract", "algorithm", "alignment", "ansi", "any", "arglist",
"array", "as", "assembly", "assert", "at", "auto", "autochar", "beforefieldinit",
"blob", "blob_object", "bool", "brnull", "brnull.s", "brzero", "brzero.s", "bstr",
"bytearray", "byvalstr", "callmostderived", "carray", "catch", "cdecl", "cf",
"char", "cil", "class", "clsid", "const", "currency", "custom", "date", "decimal",
"default", "demand", "deny", "endmac", "enum", "error", "explicit", "extends", "extern",
"false", "famandassem", "family", "famorassem", "fastcall", "fault", "field", "filetime",
"filter", "final", "finally", "fixed", "float", "float32", "float64", "forwardref",
"fromunmanaged", "handler", "hidebysig", "hresult", "idispatch", "il", "illegal",
"implements", "implicitcom", "implicitres", "import", "in", "inheritcheck", "init",
"initonly", "instance", "int", "int16", "int32", "int64", "int8", "interface", "internalcall",
"iunknown", "lasterr", "lcid", "linkcheck", "literal", "localloc", "lpstr", "lpstruct", "lptstr",
"lpvoid", "lpwstr", "managed", "marshal", "method", "modopt", "modreq", "native", "nested",
"newslot", "noappdomain", "noinlining", "nomachine", "nomangle", "nometadata", "noncasdemand",
"noncasinheritance", "noncaslinkdemand", "noprocess", "not", "not_in_gc_heap", "notremotable",
"notserialized", "null", "nullref", "object", "objectref", "opt", "optil", "out",
"permitonly", "pinned", "pinvokeimpl", "prefix1", "prefix2", "prefix3", "prefix4", "prefix5", "prefix6",
"prefix7", "prefixref", "prejitdeny", "prejitgrant", "preservesig", "private", "privatescope", "protected",
"public", "record", "refany", "reqmin", "reqopt", "reqrefuse", "reqsecobj", "request", "retval",
"rtspecialname", "runtime", "safearray", "sealed", "sequential", "serializable", "special", "specialname",
"static", "stdcall", "storage", "stored_object", "stream", "streamed_object", "string", "struct",
"synchronized", "syschar", "sysstring", "tbstr", "thiscall", "tls", "to", "true", "typedref",
"unicode", "unmanaged", "unmanagedexp", "unsigned", "unused", "userdefined", "value", "valuetype",
"vararg", "variant", "vector", "virtual", "void", "wchar", "winapi", "with", "wrapper",
// These are not listed as keywords in spec, but ILAsm treats them as such
"property", "type", "flags", "callconv", "strict"
);
}
public static readonly HashSet<string> ILKeywords;
static HashSet<string> BuildKeywordList(params string[] keywords)
{
HashSet<string> s = new HashSet<string>(keywords);
foreach (var inst in operandNames) {
if (string.IsNullOrEmpty(inst))
continue;
s.Add(inst);
}
return s;
}
}
}

2
ICSharpCode.Decompiler/Dom/SequencePoint.cs → ICSharpCode.Decompiler/Metadata/SequencePoint.cs

@ -4,7 +4,7 @@ using System.Reflection.Metadata; @@ -4,7 +4,7 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Text;
namespace ICSharpCode.Decompiler.Dom
namespace ICSharpCode.Decompiler.Metadata
{
using SRMDocument = System.Reflection.Metadata.Document;

4
ICSharpCode.Decompiler/DotNetCore/UniversalAssemblyResolver.cs → ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs

@ -3,10 +3,8 @@ using System.Collections.Generic; @@ -3,10 +3,8 @@ using System.Collections.Generic;
using System.IO;
using System.Reflection.PortableExecutable;
using System.Text;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler
namespace ICSharpCode.Decompiler.Metadata
{
public class UniversalAssemblyResolver : IAssemblyResolver
{

2
ICSharpCode.Decompiler/DotNetCore/UnresolvedAssemblyNameReference.cs → ICSharpCode.Decompiler/Metadata/UnresolvedAssemblyNameReference.cs

@ -4,7 +4,7 @@ using System.Linq; @@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ICSharpCode.Decompiler
namespace ICSharpCode.Decompiler.Metadata
{
public sealed class UnresolvedAssemblyNameReference
{

204
ICSharpCode.Decompiler/SRMExtensions.cs

@ -0,0 +1,204 @@ @@ -0,0 +1,204 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler
{
public static partial class SRMExtensions
{
public static bool HasFlag(this TypeDefinition typeDefinition, TypeAttributes attribute) => (typeDefinition.Attributes & attribute) == attribute;
public static bool HasFlag(this MethodDefinition methodDefinition, MethodAttributes attribute) => (methodDefinition.Attributes & attribute) == attribute;
public static bool HasFlag(this FieldDefinition fieldDefinition, FieldAttributes attribute) => (fieldDefinition.Attributes & attribute) == attribute;
public static bool HasFlag(this PropertyDefinition propertyDefinition, PropertyAttributes attribute) => (propertyDefinition.Attributes & attribute) == attribute;
public static bool HasFlag(this EventDefinition eventDefinition, EventAttributes attribute) => (eventDefinition.Attributes & attribute) == attribute;
public static bool IsValueType(this TypeDefinitionHandle handle, MetadataReader reader)
{
return reader.GetTypeDefinition(handle).IsValueType(reader);
}
public static bool IsValueType(this TypeDefinition typeDefinition, MetadataReader reader)
{
if (typeDefinition.BaseType.IsNil)
return false;
var baseType = typeDefinition.BaseType.GetFullTypeName(reader).ToString();
if (baseType == "System.Enum")
return true;
var thisType = typeDefinition.GetFullTypeName(reader).ToString();
return baseType == "System.ValueType" && thisType != "System.Enum";
}
public static bool IsEnum(this TypeDefinitionHandle handle, MetadataReader reader)
{
return reader.GetTypeDefinition(handle).IsEnum(reader);
}
public static bool IsEnum(this TypeDefinition typeDefinition, MetadataReader reader)
{
if (typeDefinition.BaseType.IsNil)
return false;
return typeDefinition.BaseType.GetFullTypeName(reader).ToString() == "System.Enum";
}
public static bool IsDelegate(this TypeDefinitionHandle handle, MetadataReader reader)
{
return reader.GetTypeDefinition(handle).IsDelegate(reader);
}
public static bool IsDelegate(this TypeDefinition typeDefinition, MetadataReader reader)
{
var baseType = typeDefinition.BaseType;
return !baseType.IsNil && baseType.GetFullTypeName(reader).ToString() == typeof(MulticastDelegate).FullName;
}
public static bool IsExtensionMethod(this MethodDefinition methodDefinition, MetadataReader reader)
{
if (methodDefinition.HasFlag(MethodAttributes.Static)) {
foreach (var attribute in methodDefinition.GetCustomAttributes()) {
string typeName = reader.GetCustomAttribute(attribute).GetAttributeType(reader).GetFullTypeName(reader).ToString();
if (typeName == "System.Runtime.CompilerServices.ExtensionAttribute")
return true;
}
}
return false;
}
public static bool HasBody(this MethodDefinitionHandle handle, MetadataReader reader)
{
var methodDefinition = reader.GetMethodDefinition(handle);
return (methodDefinition.Attributes & MethodAttributes.Abstract) == 0 &&
(methodDefinition.Attributes & MethodAttributes.PinvokeImpl) == 0 &&
(methodDefinition.ImplAttributes & MethodImplAttributes.InternalCall) == 0 &&
(methodDefinition.ImplAttributes & MethodImplAttributes.Native) == 0 &&
(methodDefinition.ImplAttributes & MethodImplAttributes.Unmanaged) == 0 &&
(methodDefinition.ImplAttributes & MethodImplAttributes.Runtime) == 0;
}
public static bool HasBody(this MethodDefinition methodDefinition)
{
return (methodDefinition.Attributes & MethodAttributes.Abstract) == 0 &&
(methodDefinition.Attributes & MethodAttributes.PinvokeImpl) == 0 &&
(methodDefinition.ImplAttributes & MethodImplAttributes.InternalCall) == 0 &&
(methodDefinition.ImplAttributes & MethodImplAttributes.Native) == 0 &&
(methodDefinition.ImplAttributes & MethodImplAttributes.Unmanaged) == 0 &&
(methodDefinition.ImplAttributes & MethodImplAttributes.Runtime) == 0;
}
public static MethodDefinitionHandle GetAny(this PropertyAccessors accessors)
{
if (!accessors.Getter.IsNil)
return accessors.Getter;
return accessors.Setter;
}
public static MethodDefinitionHandle GetAny(this EventAccessors accessors)
{
if (!accessors.Adder.IsNil)
return accessors.Adder;
if (!accessors.Remover.IsNil)
return accessors.Remover;
return accessors.Raiser;
}
/// <summary>
/// Gets the type of the attribute.
/// </summary>
public static EntityHandle GetAttributeType(this CustomAttribute attribute, MetadataReader reader)
{
switch (attribute.Constructor.Kind) {
case HandleKind.MethodDefinition:
var md = reader.GetMethodDefinition((MethodDefinitionHandle)attribute.Constructor);
return md.GetDeclaringType();
case HandleKind.MemberReference:
var mr = reader.GetMemberReference((MemberReferenceHandle)attribute.Constructor);
return mr.Parent;
default:
throw new NotSupportedException();
}
}
public static TypeReferenceHandle GetDeclaringType(this TypeReference tr)
{
switch (tr.ResolutionScope.Kind) {
case HandleKind.TypeReference:
return (TypeReferenceHandle)tr.ResolutionScope;
default:
return default(TypeReferenceHandle);
}
}
public static FullTypeName GetFullTypeName(this EntityHandle handle, MetadataReader reader)
{
if (handle.IsNil)
throw new ArgumentNullException(nameof(handle));
switch (handle.Kind) {
case HandleKind.TypeDefinition:
return ((TypeDefinitionHandle)handle).GetFullTypeName(reader);
case HandleKind.TypeReference:
return ((TypeReferenceHandle)handle).GetFullTypeName(reader);
case HandleKind.TypeSpecification:
return ((TypeSpecificationHandle)handle).GetFullTypeName(reader);
default:
throw new NotSupportedException();
}
}
public static FullTypeName GetFullTypeName(this TypeSpecificationHandle handle, MetadataReader reader, bool omitGenericParamCount = false)
{
if (handle.IsNil)
throw new ArgumentNullException(nameof(handle));
var ts = reader.GetTypeSpecification(handle);
return ts.DecodeSignature(new Metadata.FullTypeNameSignatureDecoder(reader), default(Unit));
}
public static FullTypeName GetFullTypeName(this TypeReferenceHandle handle, MetadataReader reader, bool omitGenericParamCount = false)
{
if (handle.IsNil)
throw new ArgumentNullException(nameof(handle));
var tr = reader.GetTypeReference(handle);
TypeReferenceHandle declaringTypeHandle;
if ((declaringTypeHandle = tr.GetDeclaringType()).IsNil) {
string @namespace = tr.Namespace.IsNil ? "" : reader.GetString(tr.Namespace);
return new FullTypeName(new TopLevelTypeName(@namespace, reader.GetString(tr.Name)));
} else {
return declaringTypeHandle.GetFullTypeName(reader, omitGenericParamCount).NestedType(reader.GetString(tr.Name), 0);
}
}
public static FullTypeName GetFullTypeName(this TypeDefinitionHandle handle, MetadataReader reader)
{
if (handle.IsNil)
throw new ArgumentNullException(nameof(handle));
return reader.GetTypeDefinition(handle).GetFullTypeName(reader);
}
public static FullTypeName GetFullTypeName(this TypeDefinition td, MetadataReader reader)
{
TypeDefinitionHandle declaringTypeHandle;
if ((declaringTypeHandle = td.GetDeclaringType()).IsNil) {
string @namespace = td.Namespace.IsNil ? "" : reader.GetString(td.Namespace);
return new FullTypeName(new TopLevelTypeName(@namespace, reader.GetString(td.Name)));
} else {
return declaringTypeHandle.GetFullTypeName(reader).NestedType(reader.GetString(td.Name), 0);
}
}
public static TType DecodeSignature<TType, TGenericContext>(this EventDefinition ev, MetadataReader reader, ISignatureTypeProvider<TType, TGenericContext> provider, TGenericContext genericContext)
{
switch (ev.Type.Kind) {
case HandleKind.TypeDefinition:
return provider.GetTypeFromDefinition(reader, (TypeDefinitionHandle)ev.Type, 0);
case HandleKind.TypeReference:
return provider.GetTypeFromReference(reader, (TypeReferenceHandle)ev.Type, 0);
case HandleKind.TypeSpecification:
return provider.GetTypeFromSpecification(reader, genericContext, (TypeSpecificationHandle)ev.Type, 0);
default:
throw new NotSupportedException();
}
}
}
}

62
ICSharpCode.Decompiler/SRMHacks.cs

@ -0,0 +1,62 @@ @@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Text;
using System.Threading.Tasks;
using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.Decompiler
{
public static partial class SRMExtensions
{
public static unsafe MethodSemanticsAttributes GetMethodSemanticsAttributes(this MethodDefinitionHandle handle, MetadataReader reader)
{
byte* startPointer = reader.MetadataPointer;
int offset = reader.GetTableMetadataOffset(TableIndex.MethodSemantics);
int rowSize = reader.GetTableRowSize(TableIndex.MethodSemantics);
int rowCount = reader.GetTableRowCount(TableIndex.MethodSemantics);
var small = reader.IsSmallReference(TableIndex.MethodDef);
int methodRowNo = reader.GetRowNumber(handle);
for (int row = rowCount - 1; row >= 0; row--) {
byte* ptr = startPointer + offset + rowSize * row;
uint rowNo = small ? *(ushort*)(ptr + 2) : *(uint*)(ptr + 2);
if (methodRowNo == rowNo) {
return (MethodSemanticsAttributes)(*(ushort*)ptr);
}
}
return 0;
}
public static unsafe ImmutableArray<MethodImplementationHandle> GetMethodImplementations(this MethodDefinitionHandle handle, MetadataReader reader)
{
byte* startPointer = reader.MetadataPointer;
int offset = reader.GetTableMetadataOffset(TableIndex.MethodImpl);
int rowSize = reader.GetTableRowSize(TableIndex.MethodImpl);
int rowCount = reader.GetTableRowCount(TableIndex.MethodImpl);
var methodDefSize = reader.GetReferenceSize(TableIndex.MethodDef);
var typeDefSize = reader.GetReferenceSize(TableIndex.TypeDef);
var containingTypeRow = reader.GetRowNumber(reader.GetMethodDefinition(handle).GetDeclaringType());
var methodDefRow = reader.GetRowNumber(handle);
var list = new List<MethodImplementationHandle>();
// TODO : if sorted -> binary search?
for (int row = 0; row < reader.GetTableRowCount(TableIndex.MethodImpl); row++) {
byte* ptr = startPointer + offset + rowSize * row;
uint currentTypeRow = typeDefSize == 2 ? *(ushort*)ptr : *(uint*)ptr;
if (currentTypeRow != containingTypeRow) continue;
uint currentMethodRowCoded = methodDefSize == 2 ? *(ushort*)(ptr + typeDefSize) : *(uint*)(ptr + typeDefSize);
if ((currentMethodRowCoded >> 1) != methodDefRow) continue;
list.Add(MetadataTokens.MethodImplementationHandle(row + 1));
}
return list.ToImmutableArray();
}
}
}

3
ICSharpCode.Decompiler/TypeSystem/CecilLoader.cs

@ -23,7 +23,6 @@ using System.IO; @@ -23,7 +23,6 @@ using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Reflection.PortableExecutable;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@ -31,6 +30,8 @@ using System.Threading; @@ -31,6 +30,8 @@ using System.Threading;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.Decompiler.Util;
using static ICSharpCode.Decompiler.Metadata.MetadataExtensions;
namespace ICSharpCode.Decompiler.TypeSystem
{
/// <summary>

42
ICSharpCode.Decompiler/TypeSystem/Implementation/TypeSpecification.cs

@ -17,22 +17,20 @@ @@ -17,22 +17,20 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using SRM = System.Reflection.Metadata;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.TypeSystem.Implementation
{
class SignatureTypeReference : ITypeReference
{
readonly TypeSpecification typeSpecification;
readonly MetadataReader reader;
readonly SRM.TypeSpecification typeSpecification;
readonly SRM.MetadataReader reader;
public SignatureTypeReference(TypeSpecificationHandle handle, MetadataReader reader)
public SignatureTypeReference(SRM.TypeSpecificationHandle handle, SRM.MetadataReader reader)
{
this.typeSpecification = reader.GetTypeSpecification(handle);
this.reader = reader;
@ -105,9 +103,9 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -105,9 +103,9 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
}
}
class TypeReferenceSignatureDecoder : ISignatureTypeProvider<ITypeReference, Unit>
class TypeReferenceSignatureDecoder : SRM.ISignatureTypeProvider<ITypeReference, Unit>
{
public ITypeReference GetArrayType(ITypeReference elementType, ArrayShape shape)
public ITypeReference GetArrayType(ITypeReference elementType, SRM.ArrayShape shape)
{
return new ArrayTypeReference(elementType, shape.Rank);
}
@ -117,7 +115,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -117,7 +115,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return new ByReferenceTypeReference(elementType);
}
public ITypeReference GetFunctionPointerType(MethodSignature<ITypeReference> signature)
public ITypeReference GetFunctionPointerType(SRM.MethodSignature<ITypeReference> signature)
{
return KnownTypeReference.IntPtr;
}
@ -152,7 +150,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -152,7 +150,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return new PointerTypeReference(elementType);
}
public ITypeReference GetPrimitiveType(PrimitiveTypeCode typeCode)
public ITypeReference GetPrimitiveType(SRM.PrimitiveTypeCode typeCode)
{
return KnownTypeReference.Get(typeCode.ToKnownTypeCode());
}
@ -162,12 +160,12 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -162,12 +160,12 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return new ArrayTypeReference(elementType);
}
public ITypeReference GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)
public ITypeReference GetTypeFromDefinition(SRM.MetadataReader reader, SRM.TypeDefinitionHandle handle, byte rawTypeKind)
{
return new GetClassTypeReference(handle.GetFullTypeName(reader), DefaultAssemblyReference.CurrentAssembly);
}
public ITypeReference GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)
public ITypeReference GetTypeFromReference(SRM.MetadataReader reader, SRM.TypeReferenceHandle handle, byte rawTypeKind)
{
var asmref = handle.GetDeclaringAssembly(reader);
if (asmref.IsNil)
@ -176,13 +174,13 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -176,13 +174,13 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return new GetClassTypeReference(handle.GetFullTypeName(reader), new DefaultAssemblyReference(reader.GetString(asm.Name)));
}
public ITypeReference GetTypeFromSpecification(MetadataReader reader, Unit genericContext, TypeSpecificationHandle handle, byte rawTypeKind)
public ITypeReference GetTypeFromSpecification(SRM.MetadataReader reader, Unit genericContext, SRM.TypeSpecificationHandle handle, byte rawTypeKind)
{
return new SignatureTypeReference(handle, reader);
}
}
public class TypeSystemAttributeTypeProvider : ICustomAttributeTypeProvider<IType>
public class TypeSystemAttributeTypeProvider : SRM.ICustomAttributeTypeProvider<IType>
{
readonly ITypeResolveContext context;
@ -193,7 +191,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -193,7 +191,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
this.context = context;
}
public IType GetPrimitiveType(PrimitiveTypeCode typeCode)
public IType GetPrimitiveType(SRM.PrimitiveTypeCode typeCode)
{
return context.Compilation.FindType(typeCode.ToKnownTypeCode());
}
@ -208,13 +206,13 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -208,13 +206,13 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return new ArrayType(context.Compilation, elementType);
}
public IType GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)
public IType GetTypeFromDefinition(SRM.MetadataReader reader, SRM.TypeDefinitionHandle handle, byte rawTypeKind)
{
var type = reader.GetTypeDefinition(handle);
return new DefaultUnresolvedTypeDefinition(type.GetFullTypeName(reader).ToString()).Resolve(context);
}
public IType GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)
public IType GetTypeFromReference(SRM.MetadataReader reader, SRM.TypeReferenceHandle handle, byte rawTypeKind)
{
return new DefaultUnresolvedTypeDefinition(handle.GetFullTypeName(reader).ToString()).Resolve(context);
}
@ -224,7 +222,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -224,7 +222,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return new GetClassTypeReference(new FullTypeName(name)).Resolve(context);
}
public PrimitiveTypeCode GetUnderlyingEnumType(IType type)
public SRM.PrimitiveTypeCode GetUnderlyingEnumType(IType type)
{
var def = type.GetEnumUnderlyingType().GetDefinition();
if (def == null)
@ -240,11 +238,11 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -240,11 +238,11 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public class MetadataUnresolvedAttributeBlob : IUnresolvedAttribute, ISupportsInterning
{
MetadataReader reader;
SRM.MetadataReader reader;
ITypeReference attributeType;
CustomAttribute attribute;
SRM.CustomAttribute attribute;
public MetadataUnresolvedAttributeBlob(MetadataReader reader, ITypeReference attributeType, CustomAttribute attribute)
public MetadataUnresolvedAttributeBlob(SRM.MetadataReader reader, ITypeReference attributeType, SRM.CustomAttribute attribute)
{
this.reader = reader;
this.attributeType = attributeType;

8
ILSpy/ExtensionMethods.cs

@ -102,6 +102,14 @@ namespace ICSharpCode.ILSpy @@ -102,6 +102,14 @@ namespace ICSharpCode.ILSpy
return false;
}
public static string ToSuffixString(this System.Reflection.Metadata.EntityHandle token)
{
if (!DisplaySettingsPanel.CurrentDisplaySettings.ShowMetadataTokens)
return string.Empty;
return " @" + System.Reflection.Metadata.Ecma335.MetadataTokens.GetToken(token).ToString("x8");
}
public static string ToSuffixString(this System.Reflection.Metadata.MethodDefinitionHandle token)
{
if (!DisplaySettingsPanel.CurrentDisplaySettings.ShowMetadataTokens)

1
ILSpy/ILSpy.csproj

@ -126,7 +126,6 @@ @@ -126,7 +126,6 @@
<Compile Include="Images\Images.cs" />
<Compile Include="Languages\ILLanguage.cs" />
<Compile Include="Languages\IResourceFileHandler.cs" />
<Compile Include="Languages\ITypeProvider.cs" />
<Compile Include="Languages\Language.cs" />
<Compile Include="Languages\Languages.cs" />
<Compile Include="LoadedAssembly.cs" />

2
ILSpy/Languages/ILAstLanguage.cs

@ -23,7 +23,7 @@ using System.Linq; @@ -23,7 +23,7 @@ using System.Linq;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.IL.Transforms;
using ICSharpCode.Decompiler.TypeSystem;

47
ILSpy/Languages/ILLanguage.cs

@ -25,7 +25,7 @@ using System.Reflection.Metadata; @@ -25,7 +25,7 @@ using System.Reflection.Metadata;
using System.IO;
using System.Reflection.Metadata.Ecma335;
using System.Linq;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy
{
@ -57,62 +57,69 @@ namespace ICSharpCode.ILSpy @@ -57,62 +57,69 @@ namespace ICSharpCode.ILSpy
};
}
public override void DecompileMethod(Decompiler.Dom.MethodDefinition method, ITextOutput output, DecompilationOptions options)
public override void DecompileMethod(Decompiler.Metadata.MethodDefinition method, ITextOutput output, DecompilationOptions options)
{
var dis = CreateDisassembler(output, options);
dis.DisassembleMethod(method);
}
public override void DecompileField(Decompiler.Dom.FieldDefinition field, ITextOutput output, DecompilationOptions options)
public override void DecompileField(Decompiler.Metadata.FieldDefinition field, ITextOutput output, DecompilationOptions options)
{
var dis = CreateDisassembler(output, options);
dis.DisassembleField(field);
}
public override void DecompileProperty(Decompiler.Dom.PropertyDefinition property, ITextOutput output, DecompilationOptions options)
public override void DecompileProperty(Decompiler.Metadata.PropertyDefinition property, ITextOutput output, DecompilationOptions options)
{
var dis = CreateDisassembler(output, options);
dis.DisassembleProperty(property);
if (!property.GetMethod.IsNil) {
var accessors = property.This().GetAccessors();
if (!accessors.Getter.IsNil) {
output.WriteLine();
dis.DisassembleMethod(property.GetMethod);
dis.DisassembleMethod(new Decompiler.Metadata.MethodDefinition(property.Module, accessors.Getter));
}
if (!property.SetMethod.IsNil) {
if (!accessors.Setter.IsNil) {
output.WriteLine();
dis.DisassembleMethod(property.SetMethod);
dis.DisassembleMethod(new Decompiler.Metadata.MethodDefinition(property.Module, accessors.Setter));
}
foreach (var m in property.OtherMethods) {
/*foreach (var m in property.OtherMethods) {
output.WriteLine();
dis.DisassembleMethod(m);
}
}*/
}
public override void DecompileEvent(Decompiler.Dom.EventDefinition ev, ITextOutput output, DecompilationOptions options)
public override void DecompileEvent(Decompiler.Metadata.EventDefinition ev, ITextOutput output, DecompilationOptions options)
{
var dis = CreateDisassembler(output, options);
dis.DisassembleEvent(ev);
if (!ev.AddMethod.IsNil) {
var accessors = ev.This().GetAccessors();
if (!accessors.Adder.IsNil) {
output.WriteLine();
dis.DisassembleMethod(ev.AddMethod);
dis.DisassembleMethod(new Decompiler.Metadata.MethodDefinition(ev.Module, accessors.Adder));
}
if (!ev.RemoveMethod.IsNil) {
if (!accessors.Remover.IsNil) {
output.WriteLine();
dis.DisassembleMethod(ev.RemoveMethod);
dis.DisassembleMethod(new Decompiler.Metadata.MethodDefinition(ev.Module, accessors.Remover));
}
foreach (var m in ev.OtherMethods) {
if (!accessors.Raiser.IsNil) {
output.WriteLine();
dis.DisassembleMethod(m);
dis.DisassembleMethod(new Decompiler.Metadata.MethodDefinition(ev.Module, accessors.Raiser));
}
/*foreach (var m in ev.OtherMethods) {
output.WriteLine();
dis.DisassembleMethod(m);
}*/
}
public override void DecompileType(Decompiler.Dom.TypeDefinition type, ITextOutput output, DecompilationOptions options)
public override void DecompileType(Decompiler.Metadata.TypeDefinition type, ITextOutput output, DecompilationOptions options)
{
var dis = CreateDisassembler(output, options);
dis.DisassembleType(type);
}
public override void DecompileNamespace(string nameSpace, IEnumerable<Decompiler.Dom.TypeDefinition> types, ITextOutput output, DecompilationOptions options)
public override void DecompileNamespace(string nameSpace, IEnumerable<Decompiler.Metadata.TypeDefinition> types, ITextOutput output, DecompilationOptions options)
{
var dis = CreateDisassembler(output, options);
dis.DisassembleNamespace(nameSpace, types);
@ -138,7 +145,7 @@ namespace ICSharpCode.ILSpy @@ -138,7 +145,7 @@ namespace ICSharpCode.ILSpy
}
}
public override string TypeToString(Decompiler.Dom.ITypeReference type, bool includeNamespace, Decompiler.Dom.ICustomAttributeProvider typeAttributes = null)
public override string TypeToString(Entity type, bool includeNamespace, CustomAttributeHandleCollection typeAttributes = default(CustomAttributeHandleCollection))
{
PlainTextOutput output = new PlainTextOutput();
type.WriteTo(output, GenericContext.Empty, includeNamespace ? ILNameSyntax.TypeName : ILNameSyntax.ShortTypeName);

86
ILSpy/Languages/ITypeProvider.cs

@ -1,86 +0,0 @@ @@ -1,86 +0,0 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection.Metadata;
using System.Text;
using System.Threading.Tasks;
using ICSharpCode.Decompiler.Dom;
namespace ICSharpCode.ILSpy
{
public sealed class CSharpSignatureTypeProvider : ISignatureTypeProvider<string, GenericContext>
{
public string GetArrayType(string elementType, ArrayShape shape)
{
throw new NotImplementedException();
}
public string GetByReferenceType(string elementType)
{
throw new NotImplementedException();
}
public string GetFunctionPointerType(MethodSignature<string> signature)
{
throw new NotImplementedException();
}
public string GetGenericInstantiation(string genericType, ImmutableArray<string> typeArguments)
{
throw new NotImplementedException();
}
public string GetGenericMethodParameter(GenericContext genericContext, int index)
{
throw new NotImplementedException();
}
public string GetGenericTypeParameter(GenericContext genericContext, int index)
{
throw new NotImplementedException();
}
public string GetModifiedType(string modifier, string unmodifiedType, bool isRequired)
{
throw new NotImplementedException();
}
public string GetPinnedType(string elementType)
{
throw new NotImplementedException();
}
public string GetPointerType(string elementType)
{
throw new NotImplementedException();
}
public string GetPrimitiveType(PrimitiveTypeCode typeCode)
{
throw new NotImplementedException();
}
public string GetSZArrayType(string elementType)
{
throw new NotImplementedException();
}
public string GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)
{
throw new NotImplementedException();
}
public string GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)
{
throw new NotImplementedException();
}
public string GetTypeFromSpecification(MetadataReader reader, GenericContext genericContext, TypeSpecificationHandle handle, byte rawTypeKind)
{
throw new NotImplementedException();
}
}
}

80
ILSpy/Languages/Language.cs

@ -21,7 +21,8 @@ using System.Collections.Generic; @@ -21,7 +21,8 @@ using System.Collections.Generic;
using System.Collections.Immutable;
using System.Reflection.PortableExecutable;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.Metadata;
using static System.Reflection.Metadata.PEReaderExtensions;
using SRM = System.Reflection.Metadata;
@ -61,22 +62,30 @@ namespace ICSharpCode.ILSpy @@ -61,22 +62,30 @@ namespace ICSharpCode.ILSpy
public virtual void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options)
{
WriteCommentLine(output, TypeToString(method.DeclaringType, true) + "." + method.Name);
WriteCommentLine(output, TypeToString(new Entity(method.Module, method.This().GetDeclaringType()), true) + "." + method.Name);
}
public virtual void DecompileProperty(PropertyDefinition property, ITextOutput output, DecompilationOptions options)
{
WriteCommentLine(output, TypeToString(property.DeclaringType, true) + "." + property.Name);
var metadata = property.Module.GetMetadataReader();
var propertyDefinition = metadata.GetPropertyDefinition(property.Handle);
var declaringType = metadata.GetMethodDefinition(propertyDefinition.GetAccessors().GetAny()).GetDeclaringType();
WriteCommentLine(output, TypeToString(new Entity(property.Module, declaringType), true) + "." + metadata.GetString(propertyDefinition.Name));
}
public virtual void DecompileField(FieldDefinition field, ITextOutput output, DecompilationOptions options)
{
WriteCommentLine(output, TypeToString(field.DeclaringType, true) + "." + field.Name);
var metadata = field.Module.GetMetadataReader();
var fieldDefinition = metadata.GetFieldDefinition(field.Handle);
WriteCommentLine(output, TypeToString(new Entity(field.Module, fieldDefinition.GetDeclaringType()), true) + "." + metadata.GetString(fieldDefinition.Name));
}
public virtual void DecompileEvent(EventDefinition ev, ITextOutput output, DecompilationOptions options)
{
WriteCommentLine(output, TypeToString(ev.DeclaringType, true) + "." + ev.Name);
var metadata = ev.Module.GetMetadataReader();
var eventDefinition = metadata.GetEventDefinition(ev.Handle);
var declaringType = metadata.GetMethodDefinition(eventDefinition.GetAccessors().GetAny()).GetDeclaringType();
WriteCommentLine(output, TypeToString(new Entity(ev.Module, declaringType), true) + "." + metadata.GetString(eventDefinition.Name));
}
public virtual void DecompileType(TypeDefinition type, ITextOutput output, DecompilationOptions options)
@ -115,12 +124,14 @@ namespace ICSharpCode.ILSpy @@ -115,12 +124,14 @@ namespace ICSharpCode.ILSpy
/// <summary>
/// Converts a type reference into a string. This method is used by the member tree node for parameter and return types.
/// </summary>
public virtual string TypeToString(ITypeReference type, bool includeNamespace, ICustomAttributeProvider typeAttributes = null)
public virtual string TypeToString(Entity type, bool includeNamespace, SRM.CustomAttributeHandleCollection typeAttributes = default(SRM.CustomAttributeHandleCollection))
{
var metadata = type.Module.GetMetadataReader();
var fullName = type.Handle.GetFullTypeName(metadata);
if (includeNamespace)
return type.FullName.ToString();
return fullName.ToString();
else
return type.Name;
return fullName.Name;
}
public virtual SRM.ISignatureTypeProvider<string, GenericContext> CreateSignatureTypeProvider(bool includeNamespace)
@ -132,54 +143,67 @@ namespace ICSharpCode.ILSpy @@ -132,54 +143,67 @@ namespace ICSharpCode.ILSpy
/// Converts a member signature to a string.
/// This is used for displaying the tooltip on a member reference.
/// </summary>
public virtual string GetTooltip(IMemberReference member)
{
return member.Name;
}
/// <summary>
/// Converts a member signature to a string.
/// This is used for displaying the tooltip on a member reference.
/// </summary>
public virtual string GetTooltip(ITypeReference type)
{
return TypeToString(type, true);
public virtual string GetTooltip(Entity entity)
{
var metadata = entity.Module.GetMetadataReader();
switch (entity.Handle.Kind) {
case SRM.HandleKind.TypeReference:
case SRM.HandleKind.TypeDefinition:
case SRM.HandleKind.TypeSpecification:
return entity.Handle.GetFullTypeName(metadata).ToString();
case SRM.HandleKind.FieldDefinition:
var fieldDefinition = metadata.GetFieldDefinition((SRM.FieldDefinitionHandle)entity.Handle);
string fieldType = fieldDefinition.DecodeSignature(CreateSignatureTypeProvider(false), new GenericContext(fieldDefinition.GetDeclaringType(), entity.Module));
return fieldType + " " + fieldDefinition.GetDeclaringType().GetFullTypeName(metadata) + "." + metadata.GetString(fieldDefinition.Name);
case SRM.HandleKind.MethodDefinition:
return TreeNodes.MethodTreeNode.GetText(entity, this).ToString();
case SRM.HandleKind.EventDefinition:
return TreeNodes.EventTreeNode.GetText(entity, this).ToString();
case SRM.HandleKind.PropertyDefinition:
return TreeNodes.PropertyTreeNode.GetText(entity, this).ToString();
default:
throw new NotSupportedException();
}
}
public virtual string FormatFieldName(FieldDefinition field)
{
if (field.Handle.IsNil)
throw new ArgumentNullException(nameof(field));
return field.Name;
var metadata = field.Module.GetMetadataReader();
return metadata.GetString(metadata.GetFieldDefinition(field.Handle).Name);
}
public virtual string FormatPropertyName(PropertyDefinition property, bool? isIndexer = null)
{
if (property.Handle.IsNil)
throw new ArgumentNullException(nameof(property));
return property.Name;
var metadata = property.Module.GetMetadataReader();
return metadata.GetString(metadata.GetPropertyDefinition(property.Handle).Name);
}
public virtual string FormatMethodName(MethodDefinition method)
{
if (method.Handle.IsNil)
throw new ArgumentNullException(nameof(method));
return method.Name;
var metadata = method.Module.GetMetadataReader();
return metadata.GetString(metadata.GetMethodDefinition(method.Handle).Name);
}
public virtual string FormatEventName(EventDefinition @event)
{
if (@event.Handle.IsNil)
throw new ArgumentNullException(nameof(@event));
return @event.Name;
var metadata = @event.Module.GetMetadataReader();
return metadata.GetString(metadata.GetEventDefinition(@event.Handle).Name);
}
public virtual string FormatTypeName(TypeDefinition type)
{
if (type.Handle.IsNil)
throw new ArgumentNullException(nameof(type));
return type.Name;
var metadata = type.Module.GetMetadataReader();
return metadata.GetString(metadata.GetTypeDefinition(type.Handle).Name);
}
/// <summary>
@ -190,7 +214,7 @@ namespace ICSharpCode.ILSpy @@ -190,7 +214,7 @@ namespace ICSharpCode.ILSpy
return Name;
}
public virtual bool ShowMember(IMemberReference member)
public virtual bool ShowMember(IMetadataEntity member)
{
return true;
}
@ -198,7 +222,7 @@ namespace ICSharpCode.ILSpy @@ -198,7 +222,7 @@ namespace ICSharpCode.ILSpy
/// <summary>
/// Used by the analyzer to map compiler generated code back to the original code's location
/// </summary>
public virtual IMemberReference GetOriginalCodeLocation(IMemberReference member)
public virtual IMetadataEntity GetOriginalCodeLocation(IMetadataEntity member)
{
return member;
}

2
ILSpy/LoadedAssembly.cs

@ -23,7 +23,7 @@ using System.Reflection.PortableExecutable; @@ -23,7 +23,7 @@ using System.Reflection.PortableExecutable;
using System.Threading;
using System.Threading.Tasks;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.Options;
using static System.Reflection.Metadata.PEReaderExtensions;

6
ILSpy/MainWindow.xaml.cs

@ -274,12 +274,12 @@ namespace ICSharpCode.ILSpy @@ -274,12 +274,12 @@ namespace ICSharpCode.ILSpy
foreach (LoadedAssembly asm in commandLineLoadedAssemblies) {
var def = asm.GetPEFileOrNull();
if (def != null) {
/*MemberReference mr = XmlDocKeyProvider.FindMemberByKey(def, args.NavigateTo);
if (mr != null) {
var mr = XmlDocKeyProvider.FindMemberByKey(def, args.NavigateTo);
if (!mr.IsNil) {
found = true;
JumpToReference(mr);
break;
}*/
}
}
}
}

4
ILSpy/SearchPane.cs

@ -26,7 +26,7 @@ using System.Windows.Controls; @@ -26,7 +26,7 @@ using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.TreeNodes;
using Mono.Cecil;
@ -333,7 +333,7 @@ namespace ICSharpCode.ILSpy @@ -333,7 +333,7 @@ namespace ICSharpCode.ILSpy
public static readonly System.Collections.Generic.IComparer<SearchResult> Comparer = new SearchResultComparer();
public IMemberReference Member { get; set; }
public IMetadataEntity Member { get; set; }
public float Fitness { get; set; }
public string Location { get; set; }

106
ILSpy/SearchStrategies.cs

@ -5,10 +5,14 @@ using System.Text.RegularExpressions; @@ -5,10 +5,14 @@ using System.Text.RegularExpressions;
using System.Windows.Media;
using ICSharpCode.Decompiler.Util;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
using System.Reflection;
using ICSharpCode.Decompiler.Disassembler;
using SRM = System.Reflection.Metadata;
using ILOpCode = System.Reflection.Metadata.ILOpCode;
using ICSharpCode.Decompiler;
using static System.Reflection.Metadata.PEReaderExtensions;
namespace ICSharpCode.ILSpy
{
@ -38,9 +42,29 @@ namespace ICSharpCode.ILSpy @@ -38,9 +42,29 @@ namespace ICSharpCode.ILSpy
searchTerm = terms;
}
protected float CalculateFitness(IMemberReference member)
protected float CalculateFitness(IMetadataEntity member)
{
string text = member.Name;
var metadata = member.Module.GetMetadataReader();
string text;
switch (member) {
case TypeDefinition td:
text = metadata.GetString(metadata.GetTypeDefinition(td.Handle).Name);
break;
case FieldDefinition fd:
text = metadata.GetString(metadata.GetFieldDefinition(fd.Handle).Name);
break;
case MethodDefinition md:
text = metadata.GetString(metadata.GetMethodDefinition(md.Handle).Name);
break;
case PropertyDefinition pd:
text = metadata.GetString(metadata.GetPropertyDefinition(pd.Handle).Name);
break;
case EventDefinition ed:
text = metadata.GetString(metadata.GetEventDefinition(ed.Handle).Name);
break;
default:
throw new NotSupportedException();
}
// Probably compiler generated types without meaningful names, show them last
if (text.StartsWith("<")) {
@ -79,7 +103,7 @@ namespace ICSharpCode.ILSpy @@ -79,7 +103,7 @@ namespace ICSharpCode.ILSpy
return false;
}
protected virtual bool MatchName(IMemberDefinition m, Language language)
protected virtual bool MatchName(IMetadataEntity m, Language language)
{
return IsMatch(t => GetLanguageSpecificName(language, m, regex != null ? fullNameSearch : t.Contains(".")));
}
@ -122,25 +146,26 @@ namespace ICSharpCode.ILSpy @@ -122,25 +146,26 @@ namespace ICSharpCode.ILSpy
return true;
}
string GetLanguageSpecificName(Language language, IMemberDefinition member, bool fullName = false)
string GetLanguageSpecificName(Language language, IMetadataEntity member, bool fullName = false)
{
var metadata = member.Module.GetMetadataReader();
switch (member) {
case TypeDefinition t:
return language.TypeToString(t, fullName);
case FieldDefinition f:
return fullName ? language.TypeToString(f.DeclaringType, fullName) + "." + language.FormatFieldName(f) : language.FormatFieldName(f);
return fullName ? language.TypeToString(new TypeDefinition(member.Module, metadata.GetFieldDefinition(f.Handle).GetDeclaringType()), fullName) + "." + language.FormatFieldName(f) : language.FormatFieldName(f);
case PropertyDefinition p:
return fullName ? language.TypeToString(p.DeclaringType, fullName) + "." + language.FormatPropertyName(p) : language.FormatPropertyName(p);
return fullName ? language.TypeToString(new TypeDefinition(member.Module, metadata.GetMethodDefinition(metadata.GetPropertyDefinition(p.Handle).GetAccessors().GetAny()).GetDeclaringType()), fullName) + "." + language.FormatPropertyName(p) : language.FormatPropertyName(p);
case MethodDefinition m:
return fullName ? language.TypeToString(m.DeclaringType, fullName) + "." + language.FormatMethodName(m) : language.FormatMethodName(m);
return fullName ? language.TypeToString(new TypeDefinition(member.Module, metadata.GetMethodDefinition(m.Handle).GetDeclaringType()), fullName) + "." + language.FormatMethodName(m) : language.FormatMethodName(m);
case EventDefinition e:
return fullName ? language.TypeToString(e.DeclaringType, fullName) + "." + language.FormatEventName(e) : language.FormatEventName(e);
return fullName ? language.TypeToString(new TypeDefinition(member.Module, metadata.GetMethodDefinition(metadata.GetEventDefinition(e.Handle).GetAccessors().GetAny()).GetDeclaringType()), fullName) + "." + language.FormatEventName(e) : language.FormatEventName(e);
default:
throw new NotSupportedException(member?.GetType() + " not supported!");
}
}
void Add<T>(IEnumerable<T> items, TypeDefinition type, Language language, Action<SearchResult> addResult, Func<T, Language, bool> matcher, Func<T, ImageSource> image) where T : IMemberReference
void Add<T>(IEnumerable<T> items, TypeDefinition type, Language language, Action<SearchResult> addResult, Func<T, Language, bool> matcher, Func<T, ImageSource> image) where T : IMetadataEntity
{
foreach (var item in items) {
if (matcher(item, language)) {
@ -149,7 +174,7 @@ namespace ICSharpCode.ILSpy @@ -149,7 +174,7 @@ namespace ICSharpCode.ILSpy
Member = item,
Fitness = CalculateFitness(item),
Image = image(item),
Name = GetLanguageSpecificName(language, (IMemberDefinition)item),
Name = GetLanguageSpecificName(language, item),
LocationImage = TypeTreeNode.GetIcon(type),
Location = language.TypeToString(type, includeNamespace: true)
});
@ -159,19 +184,21 @@ namespace ICSharpCode.ILSpy @@ -159,19 +184,21 @@ namespace ICSharpCode.ILSpy
public virtual void Search(TypeDefinition type, Language language, Action<SearchResult> addResult)
{
Add(type.Fields, type, language, addResult, IsMatch, FieldTreeNode.GetIcon);
Add(type.Properties, type, language, addResult, IsMatch, p => PropertyTreeNode.GetIcon(p));
Add(type.Events, type, language, addResult, IsMatch, EventTreeNode.GetIcon);
Add(type.Methods.Where(NotSpecialMethod), type, language, addResult, IsMatch, MethodTreeNode.GetIcon);
var td = type.This();
var metadata = type.Module.GetMetadataReader();
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.GetEvents().Select(e => new EventDefinition(type.Module, e)), type, language, addResult, IsMatch, EventTreeNode.GetIcon);
Add(td.GetMethods().Where(m => NotSpecialMethod(m, metadata)).Select(m => new MethodDefinition(type.Module, m)), type, language, addResult, IsMatch, MethodTreeNode.GetIcon);
foreach (TypeDefinition nestedType in type.NestedTypes) {
Search(nestedType, language, addResult);
foreach (var nestedType in td.GetNestedTypes()) {
Search(new TypeDefinition(type.Module, nestedType), language, addResult);
}
}
bool NotSpecialMethod(MethodDefinition arg)
bool NotSpecialMethod(SRM.MethodDefinitionHandle method, SRM.MetadataReader metadata)
{
return (arg.GetMethodSemanticsAttributes() & (
return (method.GetMethodSemanticsAttributes(metadata) & (
MethodSemanticsAttributes.Setter
| MethodSemanticsAttributes.Getter
| MethodSemanticsAttributes.Adder
@ -233,17 +260,19 @@ namespace ICSharpCode.ILSpy @@ -233,17 +260,19 @@ namespace ICSharpCode.ILSpy
protected override bool IsMatch(PropertyDefinition property, Language language)
{
return MethodIsLiteralMatch(property.GetMethod) || MethodIsLiteralMatch(property.SetMethod);
var accessors = property.This().GetAccessors();
return MethodIsLiteralMatch(accessors.Getter, property.Module) || MethodIsLiteralMatch(accessors.Setter, property.Module);
}
protected override bool IsMatch(EventDefinition ev, Language language)
{
return MethodIsLiteralMatch(ev.AddMethod) || MethodIsLiteralMatch(ev.RemoveMethod) || MethodIsLiteralMatch(ev.InvokeMethod);
var accessors = ev.This().GetAccessors();
return MethodIsLiteralMatch(accessors.Adder, ev.Module) || MethodIsLiteralMatch(accessors.Remover, ev.Module) || MethodIsLiteralMatch(accessors.Raiser, ev.Module);
}
protected override bool IsMatch(MethodDefinition m, Language language)
{
return MethodIsLiteralMatch(m);
return MethodIsLiteralMatch(m.Handle, m.Module);
}
bool IsLiteralMatch(object val)
@ -267,11 +296,15 @@ namespace ICSharpCode.ILSpy @@ -267,11 +296,15 @@ namespace ICSharpCode.ILSpy
}
}
bool MethodIsLiteralMatch(MethodDefinition m)
bool MethodIsLiteralMatch(SRM.MethodDefinitionHandle m, PEFile module)
{
if (m == null || !m.HasBody)
if (module == null)
return false;
var metadata = module.GetMetadataReader();
if (m.IsNil || !m.HasBody(metadata))
return false;
var blob = m.Body.GetILReader();
var methodDefinition = metadata.GetMethodDefinition(m);
var blob = module.Reader.GetMethodBody(methodDefinition.RelativeVirtualAddress).GetILReader();
if (searchTermLiteralType == TypeCode.Int64) {
long val = (long)searchTermLiteralValue;
while (blob.RemainingBytes > 0) {
@ -365,7 +398,7 @@ namespace ICSharpCode.ILSpy @@ -365,7 +398,7 @@ namespace ICSharpCode.ILSpy
return true;
break;
case ILOpCode.Ldstr:
if ((string)searchTermLiteralValue == ILParser.DecodeUserString(ref blob, m.Module))
if ((string)searchTermLiteralValue == ILParser.DecodeUserString(ref blob, module))
return true;
break;
}
@ -377,7 +410,7 @@ namespace ICSharpCode.ILSpy @@ -377,7 +410,7 @@ namespace ICSharpCode.ILSpy
ILParser.SkipOperand(ref blob, code);
continue;
}
if (IsMatch(t => ILParser.DecodeUserString(ref blob, m.Module)))
if (IsMatch(t => ILParser.DecodeUserString(ref blob, module)))
return true;
}
}
@ -441,18 +474,20 @@ namespace ICSharpCode.ILSpy @@ -441,18 +474,20 @@ namespace ICSharpCode.ILSpy
{
if (MatchName(type, language)) {
string name = language.TypeToString(type, includeNamespace: false);
var metadata = type.Module.GetMetadataReader();
var declaringType = type.This().GetDeclaringType();
addResult(new SearchResult {
Member = type,
Fitness = CalculateFitness(type),
Image = TypeTreeNode.GetIcon(type),
Name = name,
LocationImage = type.DeclaringType != null ? TypeTreeNode.GetIcon(type.DeclaringType) : Images.Namespace,
Location = type.DeclaringType != null ? language.TypeToString(type.DeclaringType, includeNamespace: true) : type.Namespace
LocationImage = !declaringType.IsNil ? TypeTreeNode.GetIcon(new TypeDefinition(type.Module, declaringType)) : Images.Namespace,
Location = !declaringType.IsNil ? language.TypeToString(new TypeDefinition(type.Module, declaringType), includeNamespace: true) : type.Handle.GetFullTypeName(metadata).TopLevelTypeName.Namespace
});
}
foreach (TypeDefinition nestedType in type.NestedTypes) {
Search(nestedType, language, addResult);
foreach (var nestedType in type.This().GetNestedTypes()) {
Search(new TypeDefinition(type.Module, nestedType), language, addResult);
}
}
}
@ -469,14 +504,15 @@ namespace ICSharpCode.ILSpy @@ -469,14 +504,15 @@ namespace ICSharpCode.ILSpy
if (MatchName(type, language))
{
string name = language.TypeToString(type, includeNamespace: false);
addResult(new SearchResult
{
var metadata = type.Module.GetMetadataReader();
var declaringType = type.This().GetDeclaringType();
addResult(new SearchResult {
Member = type,
Image = TypeTreeNode.GetIcon(type),
Fitness = CalculateFitness(type),
Name = name,
LocationImage = !type.DeclaringType.IsNil ? TypeTreeNode.GetIcon(type.DeclaringType) : Images.Namespace,
Location = !type.DeclaringType.IsNil ? language.TypeToString(type.DeclaringType, includeNamespace: true) : type.Namespace
LocationImage = !declaringType.IsNil ? TypeTreeNode.GetIcon(new TypeDefinition(type.Module, declaringType)) : Images.Namespace,
Location = !declaringType.IsNil ? language.TypeToString(new TypeDefinition(type.Module, declaringType), includeNamespace: true) : type.Handle.GetFullTypeName(metadata).TopLevelTypeName.Namespace
});
}

18
ILSpy/TextView/DecompilerTextView.cs

@ -45,11 +45,11 @@ using ICSharpCode.AvalonEdit.Search; @@ -45,11 +45,11 @@ using ICSharpCode.AvalonEdit.Search;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.Documentation;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.AvalonEdit;
using ICSharpCode.ILSpy.Options;
using ICSharpCode.ILSpy.TreeNodes;
using Microsoft.Win32;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.TextView
{
@ -206,20 +206,18 @@ namespace ICSharpCode.ILSpy.TextView @@ -206,20 +206,18 @@ namespace ICSharpCode.ILSpy.TextView
}
}
return $"{code.Name} (0x{code.Code:x})";
} else if (segment.Reference is MemberReference) {
MemberReference mr = (MemberReference)segment.Reference;
} else if (segment.Reference is Entity entity) {
// if possible, resolve the reference
if (mr is TypeReference) {
mr = ((TypeReference)mr).Resolve() ?? mr;
} else if (mr is MethodReference) {
mr = ((MethodReference)mr).Resolve() ?? mr;
if (entity.IsType()) {
var td = entity.ResolveAsType();
if (!td.IsNil) entity = td;
}
XmlDocRenderer renderer = new XmlDocRenderer();
//renderer.AppendText(MainWindow.Instance.CurrentLanguage.GetTooltip(mr));
renderer.AppendText(MainWindow.Instance.CurrentLanguage.GetTooltip(entity));
try {
XmlDocumentationProvider docProvider = XmlDocLoader.LoadDocumentation(mr.Module);
var docProvider = entity.Module.DocumentationResolver.GetProvider(); // TODO implement proper API
if (docProvider != null) {
string documentation = docProvider.GetDocumentation(XmlDocKeyProvider.GetKey(mr));
string documentation = docProvider.GetDocumentation(XmlDocKeyProvider.GetKey(entity));
if (documentation != null) {
renderer.AppendText(Environment.NewLine);
renderer.AddXmlDocumentation(documentation);

1
ILSpy/TreeNodes/Analyzer/AnalyzedPropertyOverridesTreeNode.cs

@ -55,7 +55,6 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -55,7 +55,6 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
yield break;
foreach (PropertyDefinition property in type.Properties) {
analyzedProperty.
if (TypesHierarchyHelpers.IsBaseProperty(analyzedProperty, property)) {
MethodDefinition anyAccessor = property.GetMethod ?? property.SetMethod;
bool hidesParent = !anyAccessor.IsVirtual ^ anyAccessor.IsNewSlot;

4
ILSpy/TreeNodes/Analyzer/AnalyzerEntityTreeNode.cs

@ -17,7 +17,7 @@ @@ -17,7 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System.Collections.Generic;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.TreeView;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
@ -27,7 +27,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -27,7 +27,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
/// </summary>
public abstract class AnalyzerEntityTreeNode : AnalyzerTreeNode, IMemberTreeNode
{
public abstract IMemberReference Member { get; }
public abstract IMetadataEntity Member { get; }
public override void ActivateItem(System.Windows.RoutedEventArgs e)
{

19
ILSpy/TreeNodes/AssemblyListTreeNode.cs

@ -25,7 +25,7 @@ using System.Linq; @@ -25,7 +25,7 @@ using System.Linq;
using System.Reflection.PortableExecutable;
using System.Windows;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.TreeView;
namespace ICSharpCode.ILSpy.TreeNodes
@ -210,8 +210,9 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -210,8 +210,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// </summary>
public TypeTreeNode FindTypeNode(TypeDefinition def)
{
if (!def.DeclaringType.IsNil) {
TypeTreeNode decl = FindTypeNode(def.DeclaringType);
var declaringType = def.This().GetDeclaringType();
if (!declaringType.IsNil) {
TypeTreeNode decl = FindTypeNode(new TypeDefinition(def.Module, declaringType));
if (decl != null) {
decl.EnsureLazyChildren();
return decl.Children.OfType<TypeTreeNode>().FirstOrDefault(t => t.TypeDefinition == def && !t.IsHidden);
@ -231,7 +232,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -231,7 +232,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// </summary>
public ILSpyTreeNode FindMethodNode(MethodDefinition def)
{
TypeTreeNode typeNode = FindTypeNode(def.DeclaringType);
TypeTreeNode typeNode = FindTypeNode(new TypeDefinition(def.Module, def.This().GetDeclaringType()));
if (typeNode == null)
return null;
typeNode.EnsureLazyChildren();
@ -266,7 +267,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -266,7 +267,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// </summary>
public FieldTreeNode FindFieldNode(FieldDefinition def)
{
TypeTreeNode typeNode = FindTypeNode(def.DeclaringType);
TypeTreeNode typeNode = FindTypeNode(new TypeDefinition(def.Module, def.This().GetDeclaringType()));
if (typeNode == null)
return null;
typeNode.EnsureLazyChildren();
@ -279,7 +280,9 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -279,7 +280,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// </summary>
public PropertyTreeNode FindPropertyNode(PropertyDefinition def)
{
TypeTreeNode typeNode = FindTypeNode(def.DeclaringType);
var metadata = def.Module.GetMetadataReader();
var accessor = metadata.GetMethodDefinition(metadata.GetPropertyDefinition(def.Handle).GetAccessors().GetAny());
TypeTreeNode typeNode = FindTypeNode(new TypeDefinition(def.Module, accessor.GetDeclaringType()));
if (typeNode == null)
return null;
typeNode.EnsureLazyChildren();
@ -292,7 +295,9 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -292,7 +295,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// </summary>
public EventTreeNode FindEventNode(EventDefinition def)
{
TypeTreeNode typeNode = FindTypeNode(def.DeclaringType);
var metadata = def.Module.GetMetadataReader();
var accessor = metadata.GetMethodDefinition(metadata.GetEventDefinition(def.Handle).GetAccessors().GetAny());
TypeTreeNode typeNode = FindTypeNode(new TypeDefinition(def.Module, accessor.GetDeclaringType()));
if (typeNode == null)
return null;
typeNode.EnsureLazyChildren();

12
ILSpy/TreeNodes/AssemblyTreeNode.cs

@ -26,7 +26,7 @@ using System.Windows; @@ -26,7 +26,7 @@ using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.TreeView;
using Microsoft.Win32;
@ -163,11 +163,13 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -163,11 +163,13 @@ namespace ICSharpCode.ILSpy.TreeNodes
foreach (NamespaceTreeNode ns in namespaces.Values) {
ns.Children.Clear();
}
foreach (TypeDefinition type in metadata.GetTopLevelTypeDefinitions().Select(td => new TypeDefinition(module, td)).OrderBy(t => t.FullName.ToString(), NaturalStringComparer.Instance)) {
foreach (var typeHandle in metadata.GetTopLevelTypeDefinitions().OrderBy(t => t.GetFullTypeName(metadata).ToString(), NaturalStringComparer.Instance)) {
NamespaceTreeNode ns;
if (!namespaces.TryGetValue(type.Namespace, out ns)) {
ns = new NamespaceTreeNode(type.Namespace);
namespaces[type.Namespace] = ns;
var type = new TypeDefinition(module, typeHandle);
var namespaceString = metadata.GetString(metadata.GetTypeDefinition(typeHandle).Namespace);
if (!namespaces.TryGetValue(namespaceString, out ns)) {
ns = new NamespaceTreeNode(namespaceString);
namespaces[namespaceString] = ns;
}
TypeTreeNode node = new TypeTreeNode(type, this);
typeDict[type] = node;

41
ILSpy/TreeNodes/BaseTypesEntryNode.cs

@ -19,41 +19,46 @@ @@ -19,41 +19,46 @@
using System;
using System.Linq;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.TreeView;
namespace ICSharpCode.ILSpy.TreeNodes
{
sealed class BaseTypesEntryNode : ILSpyTreeNode, IMemberTreeNode
{
private readonly ITypeReference tr;
private TypeDefinition def;
private readonly bool isInterface;
readonly Entity tr;
TypeDefinition td;
readonly bool isInterface;
public BaseTypesEntryNode(ITypeReference tr, bool isInterface)
public BaseTypesEntryNode(Entity entity, bool isInterface)
{
this.tr = tr ?? throw new ArgumentNullException(nameof(tr));
this.def = tr.GetDefinition();
if (entity.IsNil) throw new ArgumentNullException(nameof(entity));
this.tr = entity;
this.td = tr.ResolveAsType();
this.isInterface = isInterface;
this.LazyLoading = true;
}
public override bool ShowExpander
{
get { return !def.IsNil && (def.BaseType != null || def.HasInterfaces); }
get {
if (td.IsNil) return false;
var typeDef = td.This();
return !typeDef.BaseType.IsNil || typeDef.GetInterfaceImplementations().Any();
}
}
public override object Text
{
get { return def.FullName + def.Handle.ToSuffixString(); }
get { return tr.Handle.GetFullTypeName(tr.Module.GetMetadataReader()) + tr.Handle.ToSuffixString(); }
}
public override object Icon
{
get
{
if (def != null)
return TypeTreeNode.GetIcon(def);
if (td != null)
return TypeTreeNode.GetIcon(td);
else
return isInterface ? Images.Interface : Images.Class;
}
@ -61,20 +66,20 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -61,20 +66,20 @@ namespace ICSharpCode.ILSpy.TreeNodes
protected override void LoadChildren()
{
if (def != null)
BaseTypesTreeNode.AddBaseTypes(this.Children, def);
if (td != null)
BaseTypesTreeNode.AddBaseTypes(this.Children, td);
}
public override void ActivateItem(System.Windows.RoutedEventArgs e)
{
// on item activation, try to resolve once again (maybe the user loaded the assembly in the meantime)
if (def == null) {
def = tr.GetDefinition();
if (def != null)
if (td.IsNil) {
td = tr.ResolveAsType();
if (!td.IsNil)
this.LazyLoading = true;
// re-load children
}
e.Handled = ActivateItem(this, def);
e.Handled = ActivateItem(this, td);
}
internal static bool ActivateItem(SharpTreeNode node, TypeDefinition def)
@ -94,6 +99,6 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -94,6 +99,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
language.WriteCommentLine(output, language.TypeToString(tr, true));
}
IMemberReference IMemberTreeNode.Member => tr;
IMetadataEntity IMemberTreeNode.Member => tr;
}
}

13
ILSpy/TreeNodes/BaseTypesTreeNode.cs

@ -19,7 +19,7 @@ @@ -19,7 +19,7 @@
using System;
using System.Windows.Threading;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.TreeView;
namespace ICSharpCode.ILSpy.TreeNodes
@ -48,10 +48,13 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -48,10 +48,13 @@ namespace ICSharpCode.ILSpy.TreeNodes
internal static void AddBaseTypes(SharpTreeNodeCollection children, TypeDefinition type)
{
if (type.BaseType != null)
children.Add(new BaseTypesEntryNode(type.BaseType, false));
foreach (var i in type.Interfaces) {
children.Add(new BaseTypesEntryNode(i, true));
var metadata = type.Module.GetMetadataReader();
var def = type.This();
if (!def.BaseType.IsNil)
children.Add(new BaseTypesEntryNode(new Entity(type.Module, def.BaseType), false));
foreach (var i in def.GetInterfaceImplementations()) {
var interfaceImpl = metadata.GetInterfaceImplementation(i);
children.Add(new BaseTypesEntryNode(new Entity(type.Module, interfaceImpl.Interface), true));
}
}

16
ILSpy/TreeNodes/DerivedTypesEntryNode.cs

@ -21,7 +21,7 @@ using System.Reflection; @@ -21,7 +21,7 @@ using System.Reflection;
using System.Reflection.PortableExecutable;
using System.Threading;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.TreeNodes
{
@ -41,12 +41,12 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -41,12 +41,12 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override bool ShowExpander
{
get { return !type.HasFlag(TypeAttributes.Sealed) && base.ShowExpander; }
get { return !type.This().HasFlag(TypeAttributes.Sealed) && base.ShowExpander; }
}
public override object Text
{
get { return type.FullName + type.Handle.ToSuffixString(); }
get { return type.Handle.GetFullTypeName(type.Module.GetMetadataReader()) + type.Handle.ToSuffixString(); }
}
public override object Icon
@ -58,8 +58,10 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -58,8 +58,10 @@ namespace ICSharpCode.ILSpy.TreeNodes
{
if (!settings.ShowInternalApi && !IsPublicAPI)
return FilterResult.Hidden;
if (settings.SearchTermMatches(type.Name)) {
if (!type.DeclaringType.IsNil && !settings.Language.ShowMember(type))
var metadata = type.Module.GetMetadataReader();
var typeDefinition = metadata.GetTypeDefinition(type.Handle);
if (settings.SearchTermMatches(metadata.GetString(typeDefinition.Name))) {
if (!typeDefinition.GetDeclaringType().IsNil && !settings.Language.ShowMember(type))
return FilterResult.Hidden;
else
return FilterResult.Match;
@ -69,7 +71,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -69,7 +71,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override bool IsPublicAPI {
get {
switch (type.Attributes & TypeAttributes.VisibilityMask) {
switch (type.This().Attributes & TypeAttributes.VisibilityMask) {
case TypeAttributes.Public:
case TypeAttributes.NestedPublic:
case TypeAttributes.NestedFamily:
@ -102,6 +104,6 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -102,6 +104,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
language.WriteCommentLine(output, language.TypeToString(type, true));
}
IMemberReference IMemberTreeNode.Member => type;
IMetadataEntity IMemberTreeNode.Member => type;
}
}

23
ILSpy/TreeNodes/DerivedTypesTreeNode.cs

@ -18,13 +18,14 @@ @@ -18,13 +18,14 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.PortableExecutable;
using System.Threading;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.Util;
using static System.Reflection.Metadata.PEReaderExtensions;
using SRM = System.Reflection.Metadata;
namespace ICSharpCode.ILSpy.TreeNodes
{
@ -70,16 +71,18 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -70,16 +71,18 @@ namespace ICSharpCode.ILSpy.TreeNodes
internal static IEnumerable<DerivedTypesEntryNode> FindDerivedTypes(TypeDefinition type, PEFile[] assemblies, CancellationToken cancellationToken)
{
foreach (var module in assemblies) {
var reader = module.GetMetadataReader();
foreach (var h in TreeTraversal.PreOrder(reader.GetTopLevelTypeDefinitions(), t => reader.GetTypeDefinition(t).GetNestedTypes())) {
var metadata = module.GetMetadataReader();
foreach (var h in TreeTraversal.PreOrder(metadata.GetTopLevelTypeDefinitions(), t => metadata.GetTypeDefinition(t).GetNestedTypes())) {
cancellationToken.ThrowIfCancellationRequested();
var td = new TypeDefinition(module, h);
if (type.IsInterface && td.HasInterfaces) {
foreach (var iface in td.Interfaces) {
if (IsSameType(iface, type))
var typeDefinition = metadata.GetTypeDefinition(h);
if ((typeDefinition.Attributes & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface) {
foreach (var iface in typeDefinition.GetInterfaceImplementations()) {
var ifaceImpl = metadata.GetInterfaceImplementation(iface);
if (IsSameType(metadata, ifaceImpl.Interface, type.Handle))
yield return new DerivedTypesEntryNode(td, assemblies);
}
} else if (!type.IsInterface && td.BaseType != null && IsSameType(td.BaseType, type)) {
} else if (!typeDefinition.BaseType.IsNil && IsSameType(metadata, typeDefinition.BaseType, type.Handle)) {
yield return new DerivedTypesEntryNode(td, assemblies);
}
}
@ -87,10 +90,10 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -87,10 +90,10 @@ namespace ICSharpCode.ILSpy.TreeNodes
yield break;
}
static bool IsSameType(ITypeReference typeRef, TypeDefinition type)
static bool IsSameType(SRM.MetadataReader metadata, SRM.EntityHandle typeRef, SRM.TypeDefinitionHandle type)
{
// FullName contains only namespace, name and type parameter count, therefore this should suffice.
return typeRef.FullName == type.FullName;
return typeRef.GetFullTypeName(metadata) == type.GetFullTypeName(metadata);
}
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)

65
ILSpy/TreeNodes/EventTreeNode.cs

@ -19,9 +19,10 @@ @@ -19,9 +19,10 @@
using System;
using System.Linq;
using System.Reflection;
using SRM = System.Reflection.Metadata;
using System.Windows.Media;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.TreeNodes
{
@ -35,36 +36,51 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -35,36 +36,51 @@ namespace ICSharpCode.ILSpy.TreeNodes
if (ev.IsNil)
throw new ArgumentNullException(nameof(ev));
this.EventDefinition = ev;
if (!ev.AddMethod.IsNil)
this.Children.Add(new MethodTreeNode(ev.AddMethod));
if (!ev.RemoveMethod.IsNil)
this.Children.Add(new MethodTreeNode(ev.RemoveMethod));
if (!ev.InvokeMethod.IsNil)
this.Children.Add(new MethodTreeNode(ev.InvokeMethod));
foreach (var m in ev.OtherMethods)
this.Children.Add(new MethodTreeNode(m));
var metadata = ev.Module.GetMetadataReader();
var eventDefinition = metadata.GetEventDefinition(ev.Handle);
var accessors = eventDefinition.GetAccessors();
if (!accessors.Adder.IsNil)
this.Children.Add(new MethodTreeNode(new MethodDefinition(ev.Module, accessors.Adder)));
if (!accessors.Remover.IsNil)
this.Children.Add(new MethodTreeNode(new MethodDefinition(ev.Module, accessors.Remover)));
if (!accessors.Raiser.IsNil)
this.Children.Add(new MethodTreeNode(new MethodDefinition(ev.Module, accessors.Raiser)));
//foreach (var m in ev.OtherMethods)
// this.Children.Add(new MethodTreeNode(m));
}
public EventDefinition EventDefinition { get; }
public override object Text => GetText(EventDefinition, this.Language) + EventDefinition.Handle.ToSuffixString();
public static object GetText(EventDefinition eventDef, Language language)
public static object GetText(EventDefinition ev, Language language)
{
var eventType = eventDef.DecodeSignature(language.CreateSignatureTypeProvider(false), new GenericContext(eventDef.DeclaringType));
return HighlightSearchMatch(eventDef.Name, " : " + eventType);
var metadata = ev.Module.GetMetadataReader();
var eventDefinition = metadata.GetEventDefinition(ev.Handle);
var accessors = eventDefinition.GetAccessors();
SRM.TypeDefinitionHandle declaringType;
if (!accessors.Adder.IsNil) {
declaringType = metadata.GetMethodDefinition(accessors.Adder).GetDeclaringType();
} else if (!accessors.Remover.IsNil) {
declaringType = metadata.GetMethodDefinition(accessors.Remover).GetDeclaringType();
} else {
declaringType = metadata.GetMethodDefinition(accessors.Raiser).GetDeclaringType();
}
var eventType = eventDefinition.DecodeSignature(metadata, language.CreateSignatureTypeProvider(false), new GenericContext(declaringType, ev.Module));
return HighlightSearchMatch(metadata.GetString(eventDefinition.Name), " : " + eventType);
}
public override object Icon => GetIcon(EventDefinition);
public static ImageSource GetIcon(EventDefinition eventDef)
public static ImageSource GetIcon(EventDefinition @event)
{
MethodDefinition accessor = eventDef.GetAccessors().FirstOrDefault().Method;
if (!accessor.IsNil)
return Images.GetIcon(MemberIcon.Event, GetOverlayIcon(accessor.Attributes), accessor.HasFlag(MethodAttributes.Static));
else
return Images.GetIcon(MemberIcon.Event, AccessOverlayIcon.Public, false);
var metadata = @event.Module.GetMetadataReader();
var accessor = metadata.GetEventDefinition(@event.Handle).GetAccessors().GetAny();
if (!accessor.IsNil) {
var accessorMethod = metadata.GetMethodDefinition(accessor);
return Images.GetIcon(MemberIcon.Event, GetOverlayIcon(accessorMethod.Attributes), accessorMethod.HasFlag(MethodAttributes.Static));
}
return Images.GetIcon(MemberIcon.Event, AccessOverlayIcon.Public, false);
}
private static AccessOverlayIcon GetOverlayIcon(MethodAttributes methodAttributes)
@ -93,7 +109,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -93,7 +109,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
{
if (!settings.ShowInternalApi && !IsPublicAPI)
return FilterResult.Hidden;
if (settings.SearchTermMatches(EventDefinition.Name) && settings.Language.ShowMember(EventDefinition))
var metadata = EventDefinition.Module.GetMetadataReader();
if (settings.SearchTermMatches(metadata.GetString(metadata.GetEventDefinition(EventDefinition.Handle).Name)) && settings.Language.ShowMember(EventDefinition))
return FilterResult.Match;
else
return FilterResult.Hidden;
@ -106,9 +123,11 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -106,9 +123,11 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override bool IsPublicAPI {
get {
MethodDefinition accessor = EventDefinition.GetAccessors().FirstOrDefault().Method;
var metadata = EventDefinition.Module.GetMetadataReader();
var accessor = metadata.GetEventDefinition(EventDefinition.Handle).GetAccessors().GetAny();
if (accessor.IsNil) return false;
switch (accessor.Attributes & MethodAttributes.MemberAccessMask) {
var accessorMethod = metadata.GetMethodDefinition(accessor);
switch (accessorMethod.Attributes & MethodAttributes.MemberAccessMask) {
case MethodAttributes.Public:
case MethodAttributes.FamORAssem:
case MethodAttributes.Family:
@ -119,6 +138,6 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -119,6 +138,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
}
}
IMemberReference IMemberTreeNode.Member => EventDefinition;
IMetadataEntity IMemberTreeNode.Member => EventDefinition;
}
}

62
ILSpy/TreeNodes/FieldTreeNode.cs

@ -20,7 +20,8 @@ using System; @@ -20,7 +20,8 @@ using System;
using System.Reflection;
using System.Windows.Media;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.ILSpy.TreeNodes
{
@ -33,7 +34,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -33,7 +34,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public FieldTreeNode(FieldDefinition field)
{
if (field == null)
if (field.IsNil)
throw new ArgumentNullException(nameof(field));
this.FieldDefinition = field;
}
@ -42,41 +43,47 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -42,41 +43,47 @@ namespace ICSharpCode.ILSpy.TreeNodes
public static object GetText(FieldDefinition field, Language language)
{
string fieldType = field.DecodeSignature(language.CreateSignatureTypeProvider(false), new GenericContext(field.DeclaringType));
return HighlightSearchMatch(field.Name, " : " + fieldType);
var metadata = field.Module.GetMetadataReader();
var fieldDefinition = metadata.GetFieldDefinition(field.Handle);
string fieldType = fieldDefinition.DecodeSignature(language.CreateSignatureTypeProvider(false), new GenericContext(fieldDefinition.GetDeclaringType(), field.Module));
return HighlightSearchMatch(metadata.GetString(fieldDefinition.Name), " : " + fieldType);
}
public override object Icon => GetIcon(FieldDefinition);
public static ImageSource GetIcon(FieldDefinition field)
{
if (field.DeclaringType.IsEnum && !field.HasFlag(FieldAttributes.SpecialName))
return Images.GetIcon(MemberIcon.EnumValue, GetOverlayIcon(field.Attributes), false);
var metadata = field.Module.GetMetadataReader();
var fieldDefinition = metadata.GetFieldDefinition(field.Handle);
if (fieldDefinition.GetDeclaringType().IsEnum(metadata) && !fieldDefinition.HasFlag(FieldAttributes.SpecialName))
return Images.GetIcon(MemberIcon.EnumValue, GetOverlayIcon(fieldDefinition.Attributes), false);
if (field.HasFlag(FieldAttributes.Literal))
return Images.GetIcon(MemberIcon.Literal, GetOverlayIcon(field.Attributes), false);
else if (field.HasFlag(FieldAttributes.InitOnly)) {
if (fieldDefinition.HasFlag(FieldAttributes.Literal))
return Images.GetIcon(MemberIcon.Literal, GetOverlayIcon(fieldDefinition.Attributes), false);
else if (fieldDefinition.HasFlag(FieldAttributes.InitOnly)) {
if (IsDecimalConstant(field))
return Images.GetIcon(MemberIcon.Literal, GetOverlayIcon(field.Attributes), false);
return Images.GetIcon(MemberIcon.Literal, GetOverlayIcon(fieldDefinition.Attributes), false);
else
return Images.GetIcon(MemberIcon.FieldReadOnly, GetOverlayIcon(field.Attributes), field.HasFlag(FieldAttributes.Static));
return Images.GetIcon(MemberIcon.FieldReadOnly, GetOverlayIcon(fieldDefinition.Attributes), fieldDefinition.HasFlag(FieldAttributes.Static));
} else
return Images.GetIcon(MemberIcon.Field, GetOverlayIcon(field.Attributes), field.HasFlag(FieldAttributes.Static));
return Images.GetIcon(MemberIcon.Field, GetOverlayIcon(fieldDefinition.Attributes), fieldDefinition.HasFlag(FieldAttributes.Static));
}
private static bool IsDecimalConstant(FieldDefinition field)
{
/*var fieldType = field.FieldType;
if (fieldType.Name == "Decimal" && fieldType.Namespace == "System") {
if (field.HasCustomAttributes) {
var attrs = field.CustomAttributes;
for (int i = 0; i < attrs.Count; i++) {
var attrType = attrs[i].AttributeType;
if (attrType.Name == "DecimalConstantAttribute" && attrType.Namespace == "System.Runtime.CompilerServices")
return true;
}
var metadata = field.Module.GetMetadataReader();
var fieldDefinition = metadata.GetFieldDefinition(field.Handle);
var fieldType = fieldDefinition.DecodeSignature(new FullTypeNameSignatureDecoder(metadata), default(Unit));
if (fieldType.ToString() == "System.Decimal") {
var attrs = fieldDefinition.GetCustomAttributes();
foreach (var h in attrs) {
var attr = metadata.GetCustomAttribute(h);
var attrType = attr.GetAttributeType(metadata).GetFullTypeName(metadata);
if (attrType.ToString() == "System.Runtime.CompilerServices.DecimalConstantAttribute")
return true;
}
}*/
}
return false;
}
@ -106,7 +113,9 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -106,7 +113,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
{
if (!settings.ShowInternalApi && !IsPublicAPI)
return FilterResult.Hidden;
if (settings.SearchTermMatches(FieldDefinition.Name) && settings.Language.ShowMember(FieldDefinition))
var metadata = FieldDefinition.Module.GetMetadataReader();
var fieldDefinition = metadata.GetFieldDefinition(FieldDefinition.Handle);
if (settings.SearchTermMatches(metadata.GetString(fieldDefinition.Name)) && settings.Language.ShowMember(FieldDefinition))
return FilterResult.Match;
else
return FilterResult.Hidden;
@ -119,7 +128,10 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -119,7 +128,10 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override bool IsPublicAPI {
get {
switch (FieldDefinition.Attributes & FieldAttributes.FieldAccessMask) {
var metadata = FieldDefinition.Module.GetMetadataReader();
var fieldDefinition = metadata.GetFieldDefinition(FieldDefinition.Handle);
switch (fieldDefinition.Attributes & FieldAttributes.FieldAccessMask) {
case FieldAttributes.Public:
case FieldAttributes.FamORAssem:
case FieldAttributes.Family:
@ -130,6 +142,6 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -130,6 +142,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
}
}
IMemberReference IMemberTreeNode.Member => FieldDefinition;
IMetadataEntity IMemberTreeNode.Member => FieldDefinition;
}
}

4
ILSpy/TreeNodes/IMemberTreeNode.cs

@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.TreeNodes
{
@ -27,6 +27,6 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -27,6 +27,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// </summary>
public interface IMemberTreeNode
{
IMemberReference Member { get; }
IMetadataEntity Member { get; }
}
}

39
ILSpy/TreeNodes/MethodTreeNode.cs

@ -24,7 +24,7 @@ using System.Text; @@ -24,7 +24,7 @@ using System.Text;
using System.Windows.Media;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
using SRM = System.Reflection.Metadata;
namespace ICSharpCode.ILSpy.TreeNodes
@ -48,8 +48,10 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -48,8 +48,10 @@ namespace ICSharpCode.ILSpy.TreeNodes
public static object GetText(MethodDefinition method, Language language)
{
var b = new StringBuilder();
var metadata = method.Module.GetMetadataReader();
var methodDefinition = metadata.GetMethodDefinition(method.Handle);
var signatureProvider = language.CreateSignatureTypeProvider(false);
var signature = method.DecodeSignature(signatureProvider, new GenericContext(method));
var signature = methodDefinition.DecodeSignature(signatureProvider, new GenericContext(method));
b.Append('(');
for (int i = 0; i < signature.ParameterTypes.Length; i++) {
@ -62,7 +64,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -62,7 +64,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
b.Append(", ");
b.Append("...");
}
if (method.IsConstructor) {
if (methodDefinition.IsConstructor(metadata)) {
b.Append(')');
} else {
b.Append(") : ");
@ -75,28 +77,33 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -75,28 +77,33 @@ namespace ICSharpCode.ILSpy.TreeNodes
public static ImageSource GetIcon(MethodDefinition method)
{
if (method.HasFlag(MethodAttributes.SpecialName) && method.Name.StartsWith("op_", StringComparison.Ordinal)) {
return Images.GetIcon(MemberIcon.Operator, GetOverlayIcon(method.Attributes), false);
var metadata = method.Module.GetMetadataReader();
var methodDefinition = metadata.GetMethodDefinition(method.Handle);
if (methodDefinition.HasFlag(MethodAttributes.SpecialName) && method.Name.StartsWith("op_", StringComparison.Ordinal)) {
return Images.GetIcon(MemberIcon.Operator, GetOverlayIcon(methodDefinition.Attributes), false);
}
if (method.IsExtensionMethod) {
return Images.GetIcon(MemberIcon.ExtensionMethod, GetOverlayIcon(method.Attributes), false);
if (methodDefinition.IsExtensionMethod(metadata)) {
return Images.GetIcon(MemberIcon.ExtensionMethod, GetOverlayIcon(methodDefinition.Attributes), false);
}
if (method.HasFlag(MethodAttributes.SpecialName) &&
if (methodDefinition.HasFlag(MethodAttributes.SpecialName) &&
(method.Name == ".ctor" || method.Name == ".cctor")) {
return Images.GetIcon(MemberIcon.Constructor, GetOverlayIcon(method.Attributes), method.HasFlag(MethodAttributes.Static));
return Images.GetIcon(MemberIcon.Constructor, GetOverlayIcon(methodDefinition.Attributes), methodDefinition.HasFlag(MethodAttributes.Static));
}
if (method.HasPInvokeInfo)
return Images.GetIcon(MemberIcon.PInvokeMethod, GetOverlayIcon(method.Attributes), true);
if (methodDefinition.HasFlag(MethodAttributes.PinvokeImpl) && !methodDefinition.GetImport().Module.IsNil)
return Images.GetIcon(MemberIcon.PInvokeMethod, GetOverlayIcon(methodDefinition.Attributes), true);
bool showAsVirtual = method.HasFlag(MethodAttributes.Virtual) && !(method.HasFlag(MethodAttributes.NewSlot) && method.HasFlag(MethodAttributes.Final)) && !method.DeclaringType.IsInterface;
bool showAsVirtual = methodDefinition.HasFlag(MethodAttributes.Virtual)
&& !(methodDefinition.HasFlag(MethodAttributes.NewSlot) && methodDefinition.HasFlag(MethodAttributes.Final))
&& (metadata.GetTypeDefinition(methodDefinition.GetDeclaringType()).Attributes & TypeAttributes.ClassSemanticsMask) != TypeAttributes.Interface;
return Images.GetIcon(
showAsVirtual ? MemberIcon.VirtualMethod : MemberIcon.Method,
GetOverlayIcon(method.Attributes),
method.HasFlag(MethodAttributes.Static));
GetOverlayIcon(methodDefinition.Attributes),
methodDefinition.HasFlag(MethodAttributes.Static));
}
private static AccessOverlayIcon GetOverlayIcon(MethodAttributes methodAttributes)
@ -138,7 +145,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -138,7 +145,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override bool IsPublicAPI {
get {
switch (MethodDefinition.Attributes & MethodAttributes.MemberAccessMask) {
switch (MethodDefinition.This().Attributes & MethodAttributes.MemberAccessMask) {
case MethodAttributes.Public:
case MethodAttributes.Family:
case MethodAttributes.FamORAssem:
@ -149,6 +156,6 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -149,6 +156,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
}
}
IMemberReference IMemberTreeNode.Member => MethodDefinition;
IMetadataEntity IMemberTreeNode.Member => MethodDefinition;
}
}

68
ILSpy/TreeNodes/PropertyTreeNode.cs

@ -20,7 +20,7 @@ using System; @@ -20,7 +20,7 @@ using System;
using System.Reflection;
using System.Windows.Media;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
using SRM = System.Reflection.Metadata;
@ -38,16 +38,19 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -38,16 +38,19 @@ namespace ICSharpCode.ILSpy.TreeNodes
if (property == null)
throw new ArgumentNullException(nameof(property));
this.PropertyDefinition = property;
var metadata = property.Module.GetMetadataReader();
var propertyDefinition = metadata.GetPropertyDefinition(property.Handle);
var accessors = propertyDefinition.GetAccessors();
using (LoadedAssembly.DisableAssemblyLoad()) {
this.isIndexer = property.IsIndexer;
this.isIndexer = property.Handle.HasMatchingDefaultMemberAttribute(property.Module, out _);
}
if (!property.GetMethod.IsNil)
this.Children.Add(new MethodTreeNode(property.GetMethod));
if (!property.SetMethod.IsNil)
this.Children.Add(new MethodTreeNode(property.SetMethod));
foreach (var m in property.OtherMethods)
this.Children.Add(new MethodTreeNode(m));
if (!accessors.Getter.IsNil)
this.Children.Add(new MethodTreeNode(new MethodDefinition(property.Module, accessors.Getter)));
if (!accessors.Setter.IsNil)
this.Children.Add(new MethodTreeNode(new MethodDefinition(property.Module, accessors.Setter)));
/*foreach (var m in property.OtherMethods)
this.Children.Add(new MethodTreeNode(m));*/
}
public PropertyDefinition PropertyDefinition { get; }
@ -56,29 +59,28 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -56,29 +59,28 @@ namespace ICSharpCode.ILSpy.TreeNodes
public static object GetText(PropertyDefinition property, Language language, bool? isIndexer = null)
{
var metadata = property.Module.GetMetadataReader();
var propertyDefinition = metadata.GetPropertyDefinition(property.Handle);
string name = language.FormatPropertyName(property, isIndexer);
var signature = property.DecodeSignature(language.CreateSignatureTypeProvider(false), new GenericContext(property.DeclaringType));
var signature = propertyDefinition.DecodeSignature(language.CreateSignatureTypeProvider(false), new GenericContext(propertyDefinition.GetAccessors().GetAny(), property.Module));
var b = new System.Text.StringBuilder();
if (property.HasParameters)
{
var hasParameters = property.Handle.HasParameters(metadata);
if (hasParameters) {
b.Append('(');
for (int i = 0; i < signature.ParameterTypes.Length; i++)
{
for (int i = 0; i < signature.ParameterTypes.Length; i++) {
if (i > 0)
b.Append(", ");
b.Append(signature.ParameterTypes[i]);
}
if (signature.Header.CallingConvention == SRM.SignatureCallingConvention.VarArgs)
{
if (property.HasParameters)
if (signature.Header.CallingConvention == SRM.SignatureCallingConvention.VarArgs) {
if (hasParameters)
b.Append(", ");
b.Append("...");
}
b.Append(") : ");
}
else
{
} else {
b.Append(" : ");
}
b.Append(signature.ReturnType);
@ -129,29 +131,35 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -129,29 +131,35 @@ namespace ICSharpCode.ILSpy.TreeNodes
// in numeric order, so we can do an integer comparison of the masked attribute
int accessLevel = 0;
if (!property.GetMethod.IsNil) {
int methodAccessLevel = (int)(property.GetMethod.Attributes & MethodAttributes.MemberAccessMask);
var metadata = property.Module.GetMetadataReader();
var propertyDefinition = metadata.GetPropertyDefinition(property.Handle);
var accessors = propertyDefinition.GetAccessors();
if (!accessors.Getter.IsNil) {
var getter = metadata.GetMethodDefinition(accessors.Getter);
int methodAccessLevel = (int)(getter.Attributes & MethodAttributes.MemberAccessMask);
if (accessLevel < methodAccessLevel) {
accessLevel = methodAccessLevel;
result = property.GetMethod.Attributes;
result = getter.Attributes;
}
}
if (!property.SetMethod.IsNil) {
int methodAccessLevel = (int)(property.SetMethod.Attributes & MethodAttributes.MemberAccessMask);
if (!accessors.Setter.IsNil) {
var setter = metadata.GetMethodDefinition(accessors.Setter);
int methodAccessLevel = (int)(setter.Attributes & MethodAttributes.MemberAccessMask);
if (accessLevel < methodAccessLevel) {
accessLevel = methodAccessLevel;
result = property.SetMethod.Attributes;
result = setter.Attributes;
}
}
foreach (var m in property.OtherMethods) {
/*foreach (var m in property.OtherMethods) {
int methodAccessLevel = (int)(m.Attributes & MethodAttributes.MemberAccessMask);
if (accessLevel < methodAccessLevel) {
accessLevel = methodAccessLevel;
result = m.Attributes;
}
}
}*/
return result;
}
@ -160,7 +168,9 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -160,7 +168,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
{
if (!settings.ShowInternalApi && !IsPublicAPI)
return FilterResult.Hidden;
if (settings.SearchTermMatches(PropertyDefinition.Name) && settings.Language.ShowMember(PropertyDefinition))
var metadata = PropertyDefinition.Module.GetMetadataReader();
var propertyDefinition = metadata.GetPropertyDefinition(PropertyDefinition.Handle);
if (settings.SearchTermMatches(metadata.GetString(propertyDefinition.Name)) && settings.Language.ShowMember(PropertyDefinition))
return FilterResult.Match;
else
return FilterResult.Hidden;
@ -184,6 +194,6 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -184,6 +194,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
}
}
IMemberReference IMemberTreeNode.Member => PropertyDefinition;
IMetadataEntity IMemberTreeNode.Member => PropertyDefinition;
}
}

2
ILSpy/TreeNodes/ResourceListTreeNode.cs

@ -20,7 +20,7 @@ using System; @@ -20,7 +20,7 @@ using System;
using System.Linq;
using System.Windows.Threading;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.TreeNodes
{

2
ILSpy/TreeNodes/ResourceNodes/CursorResourceEntryNode.cs

@ -21,7 +21,7 @@ using System.ComponentModel.Composition; @@ -21,7 +21,7 @@ using System.ComponentModel.Composition;
using System.IO;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.TextView;
namespace ICSharpCode.ILSpy.TreeNodes

2
ILSpy/TreeNodes/ResourceNodes/IResourceNodeFactory.cs

@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.TreeNodes
{

2
ILSpy/TreeNodes/ResourceNodes/IconResourceEntryNode.cs

@ -21,7 +21,7 @@ using System.ComponentModel.Composition; @@ -21,7 +21,7 @@ using System.ComponentModel.Composition;
using System.IO;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.TextView;
namespace ICSharpCode.ILSpy.TreeNodes

2
ILSpy/TreeNodes/ResourceNodes/ImageListResourceEntryNode.cs

@ -20,7 +20,7 @@ using System.ComponentModel.Composition; @@ -20,7 +20,7 @@ using System.ComponentModel.Composition;
using System.Drawing;
using System.Windows.Forms;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.TreeNodes
{

2
ILSpy/TreeNodes/ResourceNodes/ImageResourceEntryNode.cs

@ -21,7 +21,7 @@ using System.ComponentModel.Composition; @@ -21,7 +21,7 @@ using System.ComponentModel.Composition;
using System.IO;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.TextView;
namespace ICSharpCode.ILSpy.TreeNodes

2
ILSpy/TreeNodes/ResourceNodes/ResourceTreeNode.cs

@ -23,7 +23,7 @@ using System.Text; @@ -23,7 +23,7 @@ using System.Text;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Utils;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.TextView;
using Microsoft.Win32;

2
ILSpy/TreeNodes/ResourceNodes/ResourcesFileTreeNode.cs

@ -26,7 +26,7 @@ using System.Linq; @@ -26,7 +26,7 @@ using System.Linq;
using System.Resources;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.Controls;
using ICSharpCode.ILSpy.TextView;
using Microsoft.Win32;

2
ILSpy/TreeNodes/ResourceNodes/XamlResourceNode.cs

@ -22,7 +22,7 @@ using System.IO; @@ -22,7 +22,7 @@ using System.IO;
using System.Threading.Tasks;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes;

2
ILSpy/TreeNodes/ResourceNodes/XmlResourceNode.cs

@ -22,7 +22,7 @@ using System.IO; @@ -22,7 +22,7 @@ using System.IO;
using System.Threading.Tasks;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes;

57
ILSpy/TreeNodes/TypeTreeNode.cs

@ -17,19 +17,21 @@ @@ -17,19 +17,21 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Windows.Media;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Metadata;
using SRM = System.Reflection.Metadata;
namespace ICSharpCode.ILSpy.TreeNodes
{
public sealed class TypeTreeNode : ILSpyTreeNode, IMemberTreeNode
{
readonly TypeDefinition typeDefinition;
readonly SRM.TypeDefinition metadataTypeDefinition;
public TypeTreeNode(TypeDefinition typeDefinition, AssemblyTreeNode parentAssemblyNode)
{
@ -37,6 +39,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -37,6 +39,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
throw new ArgumentNullException(nameof(typeDefinition));
this.ParentAssemblyNode = parentAssemblyNode ?? throw new ArgumentNullException(nameof(parentAssemblyNode));
this.typeDefinition = typeDefinition;
this.metadataTypeDefinition = typeDefinition.This();
this.LazyLoading = true;
}
@ -48,7 +51,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -48,7 +51,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override bool IsPublicAPI {
get {
switch (TypeDefinition.Attributes & TypeAttributes.VisibilityMask) {
switch (metadataTypeDefinition.Attributes & TypeAttributes.VisibilityMask) {
case TypeAttributes.Public:
case TypeAttributes.NestedPublic:
case TypeAttributes.NestedFamily:
@ -64,7 +67,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -64,7 +67,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
{
if (!settings.ShowInternalApi && !IsPublicAPI)
return FilterResult.Hidden;
if (settings.SearchTermMatches(TypeDefinition.Name)) {
if (settings.SearchTermMatches(TypeDefinition.Module.GetMetadataReader().GetString(metadataTypeDefinition.Name))) {
if (settings.Language.ShowMember(TypeDefinition))
return FilterResult.Match;
else
@ -76,26 +79,27 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -76,26 +79,27 @@ namespace ICSharpCode.ILSpy.TreeNodes
protected override void LoadChildren()
{
//if (TypeDefinition.BaseType != null || TypeDefinition.HasInterfaces)
var metadata = TypeDefinition.Module.GetMetadataReader();
if (!metadataTypeDefinition.BaseType.IsNil || metadataTypeDefinition.GetInterfaceImplementations().Any())
this.Children.Add(new BaseTypesTreeNode(TypeDefinition));
if (!TypeDefinition.HasFlag(TypeAttributes.Sealed))
if (!metadataTypeDefinition.HasFlag(TypeAttributes.Sealed))
this.Children.Add(new DerivedTypesTreeNode(ParentAssemblyNode.AssemblyList, TypeDefinition));
foreach (TypeDefinition nestedType in TypeDefinition.NestedTypes.OrderBy(m => m.Name, NaturalStringComparer.Instance)) {
this.Children.Add(new TypeTreeNode(nestedType, ParentAssemblyNode));
foreach (var nestedType in metadataTypeDefinition.GetNestedTypes().OrderBy(m => metadata.GetString(metadata.GetTypeDefinition(m).Name), NaturalStringComparer.Instance)) {
this.Children.Add(new TypeTreeNode(new TypeDefinition(TypeDefinition.Module, nestedType), ParentAssemblyNode));
}
foreach (FieldDefinition field in TypeDefinition.Fields.OrderBy(m => m.Name, NaturalStringComparer.Instance)) {
this.Children.Add(new FieldTreeNode(field));
foreach (var field in metadataTypeDefinition.GetFields().OrderBy(m => metadata.GetString(metadata.GetFieldDefinition(m).Name), NaturalStringComparer.Instance)) {
this.Children.Add(new FieldTreeNode(new FieldDefinition(TypeDefinition.Module, field)));
}
foreach (PropertyDefinition property in TypeDefinition.Properties.OrderBy(m => m.Name, NaturalStringComparer.Instance)) {
this.Children.Add(new PropertyTreeNode(property));
foreach (var property in metadataTypeDefinition.GetProperties().OrderBy(m => metadata.GetString(metadata.GetPropertyDefinition(m).Name), NaturalStringComparer.Instance)) {
this.Children.Add(new PropertyTreeNode(new PropertyDefinition(TypeDefinition.Module, property)));
}
foreach (EventDefinition ev in TypeDefinition.Events.OrderBy(m => m.Name, NaturalStringComparer.Instance)) {
this.Children.Add(new EventTreeNode(ev));
foreach (var ev in metadataTypeDefinition.GetEvents().OrderBy(m => metadata.GetString(metadata.GetEventDefinition(m).Name), NaturalStringComparer.Instance)) {
this.Children.Add(new EventTreeNode(new EventDefinition(TypeDefinition.Module, ev)));
}
foreach (MethodDefinition method in TypeDefinition.Methods.OrderBy(m => m.Name, NaturalStringComparer.Instance)) {
if (method.GetMethodSemanticsAttributes() == 0) {
this.Children.Add(new MethodTreeNode(method));
foreach (var method in metadataTypeDefinition.GetMethods().OrderBy(m => metadata.GetString(metadata.GetMethodDefinition(m).Name), NaturalStringComparer.Instance)) {
if (method.GetMethodSemanticsAttributes(metadata) == 0) {
this.Children.Add(new MethodTreeNode(new MethodDefinition(TypeDefinition.Module, method)));
}
}
}
@ -119,17 +123,19 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -119,17 +123,19 @@ namespace ICSharpCode.ILSpy.TreeNodes
static TypeIcon GetTypeIcon(TypeDefinition type)
{
if (type.IsValueType) {
if (type.IsEnum)
var metadata = type.Module.GetMetadataReader();
var typeDefinition = metadata.GetTypeDefinition(type.Handle);
if (typeDefinition.IsValueType(metadata)) {
if (typeDefinition.IsEnum(metadata))
return TypeIcon.Enum;
else
return TypeIcon.Struct;
} else {
if (type.IsInterface)
if ((typeDefinition.Attributes & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface)
return TypeIcon.Interface;
else if (type.IsDelegate)
else if (typeDefinition.IsDelegate(metadata))
return TypeIcon.Delegate;
else if (IsStaticClass(type))
else if (IsStaticClass(typeDefinition))
return TypeIcon.StaticClass;
else
return TypeIcon.Class;
@ -138,8 +144,9 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -138,8 +144,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
private static AccessOverlayIcon GetOverlayIcon(TypeDefinition type)
{
var def = type.This();
AccessOverlayIcon overlay;
switch (type.Attributes & TypeAttributes.VisibilityMask) {
switch (def.Attributes & TypeAttributes.VisibilityMask) {
case TypeAttributes.Public:
case TypeAttributes.NestedPublic:
overlay = AccessOverlayIcon.Public;
@ -164,11 +171,11 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -164,11 +171,11 @@ namespace ICSharpCode.ILSpy.TreeNodes
return overlay;
}
private static bool IsStaticClass(TypeDefinition type)
static bool IsStaticClass(SRM.TypeDefinition type)
{
return type.HasFlag(TypeAttributes.Sealed) && type.HasFlag(TypeAttributes.Abstract);
}
IMemberReference IMemberTreeNode.Member => TypeDefinition;
IMetadataEntity IMemberTreeNode.Member => TypeDefinition;
}
}

Loading…
Cancel
Save