Browse Source

Finished port of UI (Analyzers still excluded) and Disassembler

pull/1198/head
Siegfried Pammer 7 years ago
parent
commit
cb9787098f
  1. 3
      ICSharpCode.Decompiler.Tests/Helpers/Tester.cs
  2. 4
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  3. 16
      ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs
  4. 1
      ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs
  5. 223
      ICSharpCode.Decompiler/Disassembler/BlobDecoder.cs
  6. 279
      ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs
  7. 373
      ICSharpCode.Decompiler/Disassembler/DomExtensions.cs
  8. 127
      ICSharpCode.Decompiler/Disassembler/ILStructure.cs
  9. 1290
      ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs
  10. 115
      ICSharpCode.Decompiler/Disassembler/OpCodeInfo.cs
  11. 607
      ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs
  12. 1231
      ICSharpCode.Decompiler/Dom/Dom.cs
  13. 239
      ICSharpCode.Decompiler/Dom/MetadataExtensions.cs
  14. 230
      ICSharpCode.Decompiler/Dom/MetadataResolver.cs
  15. 92
      ICSharpCode.Decompiler/Dom/SequencePoint.cs
  16. 6
      ICSharpCode.Decompiler/DotNetCore/DotNetCorePathFinder.cs
  17. 16
      ICSharpCode.Decompiler/DotNetCore/DotNetCorePathFinderExtensions.cs
  18. 66
      ICSharpCode.Decompiler/DotNetCore/UniversalAssemblyResolver.cs
  19. 8
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  20. 335
      ICSharpCode.Decompiler/IL/ILOpCodes.cs
  21. 132
      ICSharpCode.Decompiler/IL/ILOpCodes.tt
  22. 41
      ICSharpCode.Decompiler/IL/SequencePoint.cs
  23. 24
      ICSharpCode.Decompiler/TypeSystem/CecilLoader.cs
  24. 27
      ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs
  25. 6
      ICSharpCode.Decompiler/TypeSystem/Implementation/TypeSpecification.cs
  26. 2
      ICSharpCode.Decompiler/Util/EmptyList.cs
  27. 1
      ILSpy.AddIn/ILSpy.AddIn.csproj
  28. 1
      ILSpy.BamlDecompiler.Tests/ILSpy.BamlDecompiler.Tests.csproj
  29. 8
      ILSpy.BamlDecompiler/BamlResourceEntryNode.cs
  30. 5
      ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs
  31. 35
      ILSpy.BamlDecompiler/CecilDependencyPropertyDescriptor.cs
  32. 60
      ILSpy.BamlDecompiler/CecilType.cs
  33. 54
      ILSpy.BamlDecompiler/CecilTypeResolver.cs
  34. 2
      ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj
  35. 30
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/IType.cs
  36. 6
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/ITypeResolver.cs
  37. 2
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/KnownInfo.cs
  38. 18
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/TypeDeclaration.cs
  39. 6
      ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs
  40. 33
      ILSpy.BamlDecompiler/SRMDependencyPropertyDescriptor.cs
  41. 14
      ILSpy.sln
  42. 2
      ILSpy/Commands/DecompileAllCommand.cs
  43. 10
      ILSpy/DebugSteps.xaml.cs
  44. 36
      ILSpy/ExtensionMethods.cs
  45. 39
      ILSpy/ILSpy.csproj
  46. 49
      ILSpy/Languages/CSharpLanguage.cs
  47. 4
      ILSpy/Languages/ILAstLanguage.cs
  48. 96
      ILSpy/Languages/ILLanguage.cs
  49. 86
      ILSpy/Languages/ITypeProvider.cs
  50. 242
      ILSpy/Languages/Language.cs
  51. 4
      ILSpy/Languages/Languages.cs
  52. 118
      ILSpy/LoadedAssembly.cs
  53. 19
      ILSpy/MainWindow.xaml.cs
  54. 8
      ILSpy/SearchPane.cs
  55. 113
      ILSpy/SearchStrategies.cs
  56. 6
      ILSpy/TextView/DecompilerTextView.cs
  57. 51
      ILSpy/TreeNodes/Analyzer/AnalyzeContextMenuEntry.cs
  58. 24
      ILSpy/TreeNodes/Analyzer/AnalyzedAssemblyTreeNode.cs
  59. 6
      ILSpy/TreeNodes/Analyzer/AnalyzedAttributeAppliedToTreeNode.cs
  60. 2
      ILSpy/TreeNodes/Analyzer/AnalyzedEventAccessorTreeNode.cs
  61. 13
      ILSpy/TreeNodes/Analyzer/AnalyzedEventOverridesTreeNode.cs
  62. 14
      ILSpy/TreeNodes/Analyzer/AnalyzedEventTreeNode.cs
  63. 51
      ILSpy/TreeNodes/Analyzer/AnalyzedFieldAccessTreeNode.cs
  64. 13
      ILSpy/TreeNodes/Analyzer/AnalyzedFieldTreeNode.cs
  65. 11
      ILSpy/TreeNodes/Analyzer/AnalyzedMethodTreeNode.cs
  66. 2
      ILSpy/TreeNodes/Analyzer/AnalyzedMethodUsedByTreeNode.cs
  67. 51
      ILSpy/TreeNodes/Analyzer/AnalyzedMethodUsesTreeNode.cs
  68. 2
      ILSpy/TreeNodes/Analyzer/AnalyzedPropertyAccessorTreeNode.cs
  69. 13
      ILSpy/TreeNodes/Analyzer/AnalyzedPropertyOverridesTreeNode.cs
  70. 23
      ILSpy/TreeNodes/Analyzer/AnalyzedPropertyTreeNode.cs
  71. 11
      ILSpy/TreeNodes/Analyzer/AnalyzedTypeExposedByTreeNode.cs
  72. 39
      ILSpy/TreeNodes/Analyzer/AnalyzedTypeInstantiationsTreeNode.cs
  73. 8
      ILSpy/TreeNodes/Analyzer/AnalyzedTypeTreeNode.cs
  74. 26
      ILSpy/TreeNodes/Analyzer/AnalyzedTypeUsedByTreeNode.cs
  75. 2
      ILSpy/TreeNodes/Analyzer/AnalyzedVirtualMethodUsedByTreeNode.cs
  76. 6
      ILSpy/TreeNodes/Analyzer/AnalyzerEntityTreeNode.cs
  77. 4
      ILSpy/TreeNodes/Analyzer/AnalyzerSearchTreeNode.cs
  78. 6
      ILSpy/TreeNodes/Analyzer/Helpers.cs
  79. 53
      ILSpy/TreeNodes/Analyzer/ScopedWhereUsedAnalyzer.cs
  80. 37
      ILSpy/TreeNodes/AssemblyListTreeNode.cs
  81. 6
      ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs
  82. 43
      ILSpy/TreeNodes/AssemblyTreeNode.cs
  83. 23
      ILSpy/TreeNodes/BaseTypesEntryNode.cs
  84. 14
      ILSpy/TreeNodes/BaseTypesTreeNode.cs
  85. 4
      ILSpy/TreeNodes/CopyFullyQualifiedNameContextMenuEntry.cs
  86. 16
      ILSpy/TreeNodes/DerivedTypesEntryNode.cs
  87. 34
      ILSpy/TreeNodes/DerivedTypesTreeNode.cs
  88. 43
      ILSpy/TreeNodes/EventTreeNode.cs
  89. 42
      ILSpy/TreeNodes/FieldTreeNode.cs
  90. 4
      ILSpy/TreeNodes/IMemberTreeNode.cs
  91. 54
      ILSpy/TreeNodes/MethodTreeNode.cs
  92. 4
      ILSpy/TreeNodes/ModuleReferenceTreeNode.cs
  93. 35
      ILSpy/TreeNodes/PropertyTreeNode.cs
  94. 19
      ILSpy/TreeNodes/ReferenceFolderTreeNode.cs
  95. 6
      ILSpy/TreeNodes/ResourceListTreeNode.cs
  96. 9
      ILSpy/TreeNodes/ResourceNodes/CursorResourceEntryNode.cs
  97. 2
      ILSpy/TreeNodes/ResourceNodes/IResourceNodeFactory.cs
  98. 9
      ILSpy/TreeNodes/ResourceNodes/IconResourceEntryNode.cs
  99. 7
      ILSpy/TreeNodes/ResourceNodes/ImageListResourceEntryNode.cs
  100. 9
      ILSpy/TreeNodes/ResourceNodes/ImageResourceEntryNode.cs
  101. Some files were not shown because too many files have changed in this diff Show More

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

@ -36,7 +36,6 @@ using ICSharpCode.Decompiler.TypeSystem; @@ -36,7 +36,6 @@ using ICSharpCode.Decompiler.TypeSystem;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CSharp;
using Mono.Cecil;
using NUnit.Framework;
namespace ICSharpCode.Decompiler.Tests.Helpers
@ -114,7 +113,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -114,7 +113,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
using (var writer = new StreamWriter(outputFile)) {
//module.Name = Path.GetFileNameWithoutExtension(outputFile);
var output = new PlainTextOutput(writer);
ReflectionDisassembler rd = new ReflectionDisassembler(output, module.GetMetadataReader(), CancellationToken.None);
ReflectionDisassembler rd = new ReflectionDisassembler(output, CancellationToken.None);
rd.DetectControlStructure = false;
//rd.WriteAssemblyReferences(module);
/*if (module.Assembly != null)

4
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -178,7 +178,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -178,7 +178,7 @@ namespace ICSharpCode.Decompiler.CSharp
}
public CSharpDecompiler(string fileName, DecompilerSettings settings)
: this(UniversalAssemblyResolver.LoadMainModule(fileName, settings.ThrowOnAssemblyResolveErrors, settings.LoadInMemory), settings)
//: this(UniversalAssemblyResolver.LoadMainModule(fileName, settings.ThrowOnAssemblyResolveErrors, settings.LoadInMemory), settings)
{
}
@ -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<SequencePoint>> CreateSequencePoints(SyntaxTree syntaxTree)
public Dictionary<ILFunction, List<Dom.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, SequencePoint)> sequencePoints = new List<(ILFunction, SequencePoint)>();
readonly List<(ILFunction, Dom.SequencePoint)> sequencePoints = new List<(ILFunction, Dom.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 SequencePoint {
sequencePoints.Add((current.Function, new Dom.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<SequencePoint>> GetSequencePoints()
internal Dictionary<ILFunction, List<Dom.SequencePoint>> GetSequencePoints()
{
var dict = new Dictionary<ILFunction, List<SequencePoint>>();
var dict = new Dictionary<ILFunction, List<Dom.SequencePoint>>();
foreach (var (function, sequencePoint) in this.sequencePoints) {
if (!dict.TryGetValue(function, out var list)) {
dict.Add(function, list = new List<SequencePoint>());
dict.Add(function, list = new List<Dom.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<SequencePoint>();
var newList = new List<Dom.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 SequencePoint();
var hidden = new Dom.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 SequencePoint();
var hidden = new Dom.SequencePoint();
hidden.Offset = pos;
hidden.EndOffset = function.CecilMethod.Body.CodeSize;
hidden.SetHidden();

1
ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs

@ -25,6 +25,7 @@ using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching; @@ -25,6 +25,7 @@ using ICSharpCode.Decompiler.CSharp.Syntax.PatternMatching;
using ICSharpCode.Decompiler.CSharp.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Semantics;
using Mono.Cecil;
namespace ICSharpCode.Decompiler.CSharp.Transforms
{

223
ICSharpCode.Decompiler/Disassembler/BlobDecoder.cs

@ -0,0 +1,223 @@ @@ -0,0 +1,223 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// 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;
using System.Collections.Generic;
using ICSharpCode.Decompiler.Semantics;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using SRM = System.Reflection.Metadata;
namespace ICSharpCode.Decompiler.Disassembler
{
sealed class BlobDecoder
{
SRM.BlobReader blob;
static readonly ITypeResolveContext context = new SimpleTypeResolveContext(MinimalCorlib.Instance.CreateCompilation());
public BlobDecoder(SRM.BlobReader blob)
{
this.blob = blob;
}
public int Offset => blob.Offset;
public ResolveResult ReadFixedArg(IType argType)
{
if (argType.Kind == TypeKind.Array) {
if (((ArrayType)argType).Dimensions != 1) {
// Only single-dimensional arrays are supported
return ErrorResolveResult.UnknownError;
}
IType elementType = ((ArrayType)argType).ElementType;
uint numElem = blob.ReadUInt32();
if (numElem == 0xffffffff) {
// null reference
return new ConstantResolveResult(argType, null);
} else {
ResolveResult[] elements = new ResolveResult[numElem];
for (int i = 0; i < elements.Length; i++) {
elements[i] = ReadElem(elementType);
// Stop decoding when encountering an error:
if (elements[i].IsError)
return ErrorResolveResult.UnknownError;
}
IType int32 = context.Compilation.FindType(KnownTypeCode.Int32);
ResolveResult[] sizeArgs = { new ConstantResolveResult(int32, elements.Length) };
return new ArrayCreateResolveResult(argType, sizeArgs, elements);
}
} else {
return ReadElem(argType);
}
}
public ResolveResult ReadElem(IType elementType)
{
ITypeDefinition underlyingType;
if (elementType.Kind == TypeKind.Enum) {
underlyingType = elementType.GetDefinition().EnumUnderlyingType.GetDefinition();
} else {
underlyingType = elementType.GetDefinition();
}
if (underlyingType == null)
return ErrorResolveResult.UnknownError;
KnownTypeCode typeCode = underlyingType.KnownTypeCode;
if (typeCode == KnownTypeCode.Object) {
// boxed value type
IType boxedTyped = ReadCustomAttributeFieldOrPropType();
ResolveResult elem = ReadFixedArg(boxedTyped);
if (elem.IsCompileTimeConstant && elem.ConstantValue == null)
return new ConstantResolveResult(elementType, null);
else
return new ConversionResolveResult(elementType, elem, Conversion.BoxingConversion);
} else if (typeCode == KnownTypeCode.Type) {
var type = ReadType();
if (type != null) {
return new TypeOfResolveResult(underlyingType, type);
} else {
return new ConstantResolveResult(underlyingType, null);
}
} else {
return new ConstantResolveResult(elementType, ReadElemValue(typeCode));
}
}
object ReadElemValue(KnownTypeCode typeCode)
{
switch (typeCode) {
case KnownTypeCode.Boolean:
return blob.ReadBoolean();
case KnownTypeCode.Char:
return blob.ReadChar();
case KnownTypeCode.SByte:
return blob.ReadSByte();
case KnownTypeCode.Byte:
return blob.ReadByte();
case KnownTypeCode.Int16:
return blob.ReadInt16();
case KnownTypeCode.UInt16:
return blob.ReadUInt16();
case KnownTypeCode.Int32:
return blob.ReadInt32();
case KnownTypeCode.UInt32:
return blob.ReadUInt32();
case KnownTypeCode.Int64:
return blob.ReadInt64();
case KnownTypeCode.UInt64:
return blob.ReadUInt64();
case KnownTypeCode.Single:
return blob.ReadSingle();
case KnownTypeCode.Double:
return blob.ReadDouble();
case KnownTypeCode.String:
return blob.ReadSerializedString();
default:
throw new NotSupportedException();
}
}
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));
}
IType type = ReadCustomAttributeFieldOrPropType();
string name = blob.ReadSerializedString();
ResolveResult val = ReadFixedArg(type);
return new KeyValuePair<string, ResolveResult>(name, val);
}
IType ReadCustomAttributeFieldOrPropType()
{
ICompilation compilation = context.Compilation;
var b = blob.ReadByte();
switch (b) {
case 0x02:
return compilation.FindType(KnownTypeCode.Boolean);
case 0x03:
return compilation.FindType(KnownTypeCode.Char);
case 0x04:
return compilation.FindType(KnownTypeCode.SByte);
case 0x05:
return compilation.FindType(KnownTypeCode.Byte);
case 0x06:
return compilation.FindType(KnownTypeCode.Int16);
case 0x07:
return compilation.FindType(KnownTypeCode.UInt16);
case 0x08:
return compilation.FindType(KnownTypeCode.Int32);
case 0x09:
return compilation.FindType(KnownTypeCode.UInt32);
case 0x0a:
return compilation.FindType(KnownTypeCode.Int64);
case 0x0b:
return compilation.FindType(KnownTypeCode.UInt64);
case 0x0c:
return compilation.FindType(KnownTypeCode.Single);
case 0x0d:
return compilation.FindType(KnownTypeCode.Double);
case 0x0e:
return compilation.FindType(KnownTypeCode.String);
case 0x1d:
return new ArrayType(compilation, ReadCustomAttributeFieldOrPropType());
case 0x50:
return compilation.FindType(KnownTypeCode.Type);
case 0x51: // boxed value type
return compilation.FindType(KnownTypeCode.Object);
case 0x55: // enum
var type = ReadType();
if (type == null) {
throw new NotSupportedException("Enum type should not be null.");
}
return type;
default:
throw new NotSupportedException(string.Format("Custom attribute type 0x{0:x} is not supported.", b));
}
}
IType ReadType()
{
string typeName = blob.ReadSerializedString();
if (typeName == null) {
return null;
}
ITypeReference typeReference = ReflectionHelper.ParseReflectionName(typeName);
IType typeInCurrentAssembly = typeReference.Resolve(context);
if (typeInCurrentAssembly.Kind != TypeKind.Unknown)
return typeInCurrentAssembly;
// look for the type in mscorlib
ITypeDefinition systemObject = context.Compilation.FindType(KnownTypeCode.Object).GetDefinition();
if (systemObject != null) {
return typeReference.Resolve(new SimpleTypeResolveContext(systemObject.ParentAssembly));
} else {
// couldn't find corlib - return the unknown IType for the current assembly
return typeInCurrentAssembly;
}
}
}
}

279
ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs

@ -18,9 +18,11 @@ @@ -18,9 +18,11 @@
using System;
using System.Collections.Generic;
using Mono.Cecil;
using Mono.Cecil.Cil;
using System.Linq;
using System.Reflection.Metadata;
using System.Text;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Util;
using SRM = System.Reflection.Metadata;
namespace ICSharpCode.Decompiler.Disassembler
@ -57,62 +59,35 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -57,62 +59,35 @@ namespace ICSharpCode.Decompiler.Disassembler
return string.Format("IL_{0:x4}", offset);
}
public static void WriteOffsetReference(ITextOutput writer, Instruction instruction)
public static void WriteOffsetReference(ITextOutput writer, int? offset)
{
if (instruction == null)
if (offset == null)
writer.Write("null");
else
writer.WriteReference(OffsetToString(instruction.Offset), instruction);
writer.WriteReference(OffsetToString(offset.Value), offset);
}
public static void WriteTo(this ExceptionHandler exceptionHandler, ITextOutput writer)
public static void WriteTo(this SRM.ExceptionRegion exceptionHandler, Dom.MethodDefinition method, ITextOutput writer)
{
writer.Write(".try ");
WriteOffsetReference(writer, exceptionHandler.TryStart);
WriteOffsetReference(writer, exceptionHandler.TryOffset);
writer.Write('-');
WriteOffsetReference(writer, exceptionHandler.TryEnd);
WriteOffsetReference(writer, exceptionHandler.TryOffset + exceptionHandler.TryLength);
writer.Write(' ');
writer.Write(exceptionHandler.HandlerType.ToString().ToLowerInvariant());
if (exceptionHandler.FilterStart != null) {
writer.Write(exceptionHandler.Kind.ToString().ToLowerInvariant());
if (exceptionHandler.FilterOffset != -1) {
writer.Write(' ');
WriteOffsetReference(writer, exceptionHandler.FilterStart);
WriteOffsetReference(writer, exceptionHandler.FilterOffset);
writer.Write(" handler ");
}
if (exceptionHandler.CatchType != null) {
if (!exceptionHandler.CatchType.IsNil) {
writer.Write(' ');
exceptionHandler.CatchType.WriteTo(writer);
exceptionHandler.CatchType.CoerceTypeReference(method.Module).WriteTo(writer, new GenericContext(method));
}
writer.Write(' ');
WriteOffsetReference(writer, exceptionHandler.HandlerStart);
WriteOffsetReference(writer, exceptionHandler.HandlerOffset);
writer.Write('-');
WriteOffsetReference(writer, exceptionHandler.HandlerEnd);
}
public static void WriteTo(this Instruction instruction, ITextOutput writer)
{
writer.WriteDefinition(OffsetToString(instruction.Offset), instruction);
writer.Write(": ");
writer.WriteReference(instruction.OpCode.Name, instruction.OpCode);
if (instruction.Operand != null) {
writer.Write(' ');
if (instruction.OpCode == OpCodes.Ldtoken) {
if (instruction.Operand is MethodReference)
writer.Write("method ");
else if (instruction.Operand is FieldReference)
writer.Write("field ");
}
WriteOperand(writer, instruction.Operand);
}
}
static void WriteLabelList(ITextOutput writer, Instruction[] instructions)
{
writer.Write("(");
for (int i = 0; i < instructions.Length; i++) {
if (i != 0) writer.Write(", ");
WriteOffsetReference(writer, instructions[i]);
}
writer.Write(")");
WriteOffsetReference(writer, exceptionHandler.HandlerOffset + exceptionHandler.HandlerLength);
}
static string ToInvariantCultureString(object value)
@ -123,57 +98,6 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -123,57 +98,6 @@ namespace ICSharpCode.Decompiler.Disassembler
: value.ToString();
}
public static void WriteTo(this MethodReference method, ITextOutput writer)
{
if (method.ExplicitThis) {
writer.Write("instance explicit ");
} else if (method.HasThis) {
writer.Write("instance ");
}
if (method.CallingConvention == MethodCallingConvention.VarArg) {
writer.Write("vararg ");
}
method.ReturnType.WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters);
writer.Write(' ');
if (method.DeclaringType != null) {
method.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName);
writer.Write("::");
}
MethodDefinition md = method as MethodDefinition;
if (md != null && md.IsCompilerControlled) {
writer.WriteReference(Escape(method.Name + "$PST" + method.MetadataToken.ToInt32().ToString("X8")), method);
} else {
writer.WriteReference(Escape(method.Name), method);
}
GenericInstanceMethod gim = method as GenericInstanceMethod;
if (gim != null) {
writer.Write('<');
for (int i = 0; i < gim.GenericArguments.Count; i++) {
if (i > 0)
writer.Write(", ");
gim.GenericArguments[i].WriteTo(writer);
}
writer.Write('>');
}
writer.Write("(");
var parameters = method.Parameters;
for (int i = 0; i < parameters.Count; ++i) {
if (i > 0)
writer.Write(", ");
parameters[i].ParameterType.WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters);
}
writer.Write(")");
}
static void WriteTo(this FieldReference field, ITextOutput writer)
{
field.FieldType.WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters);
writer.Write(' ');
field.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName);
writer.Write("::");
writer.WriteReference(Escape(field.Name), field);
}
static bool IsValidIdentifierCharacter(char c)
{
return c == '_' || c == '$' || c == '@' || c == '?' || c == '`';
@ -194,48 +118,9 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -194,48 +118,9 @@ namespace ICSharpCode.Decompiler.Disassembler
return true;
}
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 field in typeof(OpCodes).GetFields()) {
s.Add(((OpCode)field.GetValue(null)).Name);
}
return s;
}
public static string Escape(string identifier)
{
if (IsValidIdentifier(identifier) && !ilKeywords.Contains(identifier)) {
if (IsValidIdentifier(identifier) && !IL.ILOpCodeExtensions.ILKeywords.Contains(identifier)) {
return identifier;
} else {
// The ECMA specification says that ' inside SQString should be ecaped using an octal escape sequence,
@ -244,92 +129,26 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -244,92 +129,26 @@ namespace ICSharpCode.Decompiler.Disassembler
}
}
public static void WriteTo(this TypeReference type, ITextOutput writer, ILNameSyntax syntax = ILNameSyntax.Signature)
public static void WriteParameterReference(ITextOutput writer, Dom.MethodDefinition method, int sequence)
{
ILNameSyntax syntaxForElementTypes = syntax == ILNameSyntax.SignatureNoNamedTypeParameters ? syntax : ILNameSyntax.Signature;
if (type is PinnedType) {
((PinnedType)type).ElementType.WriteTo(writer, syntaxForElementTypes);
writer.Write(" pinned");
} else if (type is ArrayType) {
ArrayType at = (ArrayType)type;
at.ElementType.WriteTo(writer, syntaxForElementTypes);
writer.Write('[');
writer.Write(string.Join(", ", at.Dimensions));
writer.Write(']');
} else if (type is GenericParameter) {
writer.Write('!');
if (((GenericParameter)type).Owner.GenericParameterType == GenericParameterType.Method)
writer.Write('!');
if (string.IsNullOrEmpty(type.Name) || type.Name[0] == '!' || syntax == ILNameSyntax.SignatureNoNamedTypeParameters)
writer.Write(((GenericParameter)type).Position.ToString());
else
writer.Write(Escape(type.Name));
} else if (type is ByReferenceType) {
((ByReferenceType)type).ElementType.WriteTo(writer, syntaxForElementTypes);
writer.Write('&');
} else if (type is PointerType) {
((PointerType)type).ElementType.WriteTo(writer, syntaxForElementTypes);
writer.Write('*');
} else if (type is GenericInstanceType) {
type.GetElementType().WriteTo(writer, syntaxForElementTypes);
writer.Write('<');
var arguments = ((GenericInstanceType)type).GenericArguments;
for (int i = 0; i < arguments.Count; i++) {
if (i > 0)
writer.Write(", ");
arguments[i].WriteTo(writer, syntaxForElementTypes);
}
writer.Write('>');
} else if (type is OptionalModifierType) {
((OptionalModifierType)type).ElementType.WriteTo(writer, syntax);
writer.Write(" modopt(");
((OptionalModifierType)type).ModifierType.WriteTo(writer, ILNameSyntax.TypeName);
writer.Write(") ");
} else if (type is RequiredModifierType) {
((RequiredModifierType)type).ElementType.WriteTo(writer, syntax);
writer.Write(" modreq(");
((RequiredModifierType)type).ModifierType.WriteTo(writer, ILNameSyntax.TypeName);
writer.Write(") ");
} else if (type is FunctionPointerType fpt) {
writer.Write("method ");
fpt.ReturnType.WriteTo(writer, syntax);
writer.Write(" *(");
bool first = true;
foreach (var p in fpt.Parameters) {
if (first)
first = false;
else
writer.Write(", ");
p.ParameterType.WriteTo(writer, syntax);
}
writer.Write(')');
} else if (type is SentinelType) {
writer.Write("..., ");
((SentinelType)type).ElementType.WriteTo(writer, syntax);
} else {
string name = PrimitiveTypeName(type.FullName);
if (syntax == ILNameSyntax.ShortTypeName) {
if (name != null)
writer.Write(name);
else
writer.WriteReference(Escape(type.Name), type);
} else if ((syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) && name != null) {
writer.Write(name);
var metadata = method.Module.GetMetadataReader();
var signatureHeader = method.DecodeSignature(new FullTypeNameSignatureDecoder(metadata), default(Unit)).Header;
int index = signatureHeader.IsInstance && !signatureHeader.HasExplicitThis ? sequence - 1 : sequence;
if (index < 0 || index >= method.Parameters.Count) {
writer.Write(sequence.ToString());
} else {
if (syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters)
writer.Write(type.IsValueType ? "valuetype " : "class ");
if (type.DeclaringType != null) {
type.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName);
writer.Write('/');
writer.WriteReference(Escape(type.Name), type);
var param = metadata.GetParameter(method.Parameters.ElementAt(index));
if (param.Name.IsNil) {
writer.Write(sequence.ToString());
} else {
if (!type.IsDefinition && type.Scope != null && !(type is TypeSpecification))
writer.Write("[{0}]", Escape(type.Scope.Name));
writer.WriteReference(Escape(type.FullName), type);
writer.Write(Escape(metadata.GetString(param.Name)));
}
}
}
public static void WriteVariableReference(ITextOutput writer, Dom.MethodDefinition method, int index)
{
writer.Write(index.ToString());
}
public static void WriteOperand(ITextOutput writer, object operand)
@ -337,19 +156,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -337,19 +156,7 @@ namespace ICSharpCode.Decompiler.Disassembler
if (operand == null)
throw new ArgumentNullException(nameof(operand));
Instruction targetInstruction = operand as Instruction;
if (targetInstruction != null) {
WriteOffsetReference(writer, targetInstruction);
return;
}
Instruction[] targetInstructions = operand as Instruction[];
if (targetInstructions != null) {
WriteLabelList(writer, targetInstructions);
return;
}
VariableReference variableRef = operand as VariableReference;
/*VariableReference variableRef = operand as VariableReference;
if (variableRef != null) {
writer.WriteReference(variableRef.Index.ToString(), variableRef);
return;
@ -363,25 +170,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -363,25 +170,7 @@ namespace ICSharpCode.Decompiler.Disassembler
} else
writer.WriteReference(Escape(paramRef.Name), paramRef);
return;
}
MethodReference methodRef = operand as MethodReference;
if (methodRef != null) {
methodRef.WriteTo(writer);
return;
}
TypeReference typeRef = operand as TypeReference;
if (typeRef != null) {
typeRef.WriteTo(writer, ILNameSyntax.TypeName);
return;
}
FieldReference fieldRef = operand as FieldReference;
if (fieldRef != null) {
fieldRef.WriteTo(writer);
return;
}
}*/
string s = operand as string;
if (s != null) {

373
ICSharpCode.Decompiler/Disassembler/DomExtensions.cs

@ -0,0 +1,373 @@ @@ -0,0 +1,373 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// 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;
using System.Collections.Immutable;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.Disassembler
{
public static class DomExtensions
{
public static void WriteTo(this Dom.FieldDefinition field, ITextOutput output)
{
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);
}
public static void WriteTo(this ITypeReference type, ITextOutput output, GenericContext genericContext, ILNameSyntax syntax = ILNameSyntax.Signature)
{
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;
}
}
public static void WriteTo(this Dom.MethodDefinition method, ITextOutput output)
{
var metadata = method.Module.GetMetadataReader();
var 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));
}
var genericParameters = method.GenericParameters;
if (genericParameters.Count > 0) {
output.Write('<');
for (int i = 0; i < genericParameters.Count; i++) {
if (i > 0)
output.Write(", ");
var gp = metadata.GetGenericParameter(genericParameters[i]);
if ((gp.Attributes & GenericParameterAttributes.ReferenceTypeConstraint) == GenericParameterAttributes.ReferenceTypeConstraint) {
output.Write("class ");
} else if ((gp.Attributes & GenericParameterAttributes.NotNullableValueTypeConstraint) == GenericParameterAttributes.NotNullableValueTypeConstraint) {
output.Write("valuetype ");
}
if ((gp.Attributes & GenericParameterAttributes.DefaultConstructorConstraint) == GenericParameterAttributes.DefaultConstructorConstraint) {
output.Write(".ctor ");
}
var constraints = gp.GetConstraints();
if (constraints.Count > 0) {
output.Write('(');
for (int j = 0; j < constraints.Count; j++) {
if (j > 0)
output.Write(", ");
var constraint = metadata.GetGenericParameterConstraint(constraints[j]);
constraint.Type.CoerceTypeReference(method.Module).WriteTo(output, new GenericContext(method), ILNameSyntax.TypeName);
}
output.Write(") ");
}
if ((gp.Attributes & GenericParameterAttributes.Contravariant) == GenericParameterAttributes.Contravariant) {
output.Write('-');
} else if ((gp.Attributes & GenericParameterAttributes.Covariant) == GenericParameterAttributes.Covariant) {
output.Write('+');
}
output.Write(DisassemblerHelpers.Escape(metadata.GetString(gp.Name)));
}
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(")");
}
public static bool IsBaseTypeOf(this ITypeReference baseType, ITypeReference derivedType)
{
var derivedTypeDefinition = derivedType.GetDefinition();
while (!derivedTypeDefinition.IsNil) {
if (derivedTypeDefinition.FullName == baseType.FullName)
return true;
derivedTypeDefinition = derivedTypeDefinition.BaseType.GetDefinition();
}
return false;
}
}
public class TypeUsedInSignature : ISignatureTypeProvider<bool, Unit>
{
readonly PEFile module;
readonly Dom.TypeDefinition type;
public TypeUsedInSignature(ITypeReference type)
{
this.module = type.Module;
this.type = type.GetDefinition();
}
public bool GetArrayType(bool elementType, ArrayShape shape) => elementType;
public bool GetByReferenceType(bool elementType) => elementType;
public bool GetFunctionPointerType(MethodSignature<bool> signature)
{
throw new NotImplementedException();
}
public bool GetGenericInstantiation(bool genericType, ImmutableArray<bool> typeArguments)
{
throw new NotImplementedException();
}
public bool GetGenericMethodParameter(Unit genericContext, int index) => false;
public bool GetGenericTypeParameter(Unit genericContext, int index) => false;
public bool GetModifiedType(bool modifier, bool unmodifiedType, bool isRequired)
{
throw new NotImplementedException();
}
public bool GetPinnedType(bool elementType) => elementType;
public bool GetPointerType(bool elementType) => elementType;
public bool GetPrimitiveType(PrimitiveTypeCode typeCode)
{
throw new NotImplementedException();
}
public bool GetSZArrayType(bool elementType) => elementType;
public bool GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)
{
return module == type.Module && handle == type.Handle;
}
public bool GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)
{
return new Dom.TypeReference(module, handle).GetDefinition() == type;
}
public bool GetTypeFromSpecification(MetadataReader reader, Unit genericContext, TypeSpecificationHandle handle, byte rawTypeKind)
{
return new Dom.TypeSpecification(module, handle).GetDefinition() == type;
}
}
}

127
ICSharpCode.Decompiler/Disassembler/ILStructure.cs

@ -19,7 +19,9 @@ @@ -19,7 +19,9 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Mono.Cecil.Cil;
using System.Reflection.Metadata;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.Disassembler
{
@ -55,6 +57,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -55,6 +57,7 @@ namespace ICSharpCode.Decompiler.Disassembler
/// </summary>
public class ILStructure
{
public readonly Dom.MethodDefinition Method;
public readonly ILStructureType Type;
/// <summary>
@ -70,82 +73,83 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -70,82 +73,83 @@ namespace ICSharpCode.Decompiler.Disassembler
/// <summary>
/// The exception handler associated with the Try, Filter or Handler block.
/// </summary>
public readonly ExceptionHandler ExceptionHandler;
public readonly ExceptionRegion ExceptionHandler;
/// <summary>
/// The loop's entry point.
/// </summary>
public readonly Instruction LoopEntryPoint;
public readonly int LoopEntryPointOffset;
/// <summary>
/// The list of child structures.
/// </summary>
public readonly List<ILStructure> Children = new List<ILStructure>();
public ILStructure(MethodBody body)
: this(ILStructureType.Root, 0, body.CodeSize)
public ILStructure(Dom.MethodDefinition method, MethodBodyBlock body)
: this(method, ILStructureType.Root, 0, body.GetILReader().Length)
{
// Build the tree of exception structures:
for (int i = 0; i < body.ExceptionHandlers.Count; i++) {
ExceptionHandler eh = body.ExceptionHandlers[i];
if (!body.ExceptionHandlers.Take(i).Any(oldEh => oldEh.TryStart == eh.TryStart && oldEh.TryEnd == eh.TryEnd))
AddNestedStructure(new ILStructure(ILStructureType.Try, eh.TryStart.Offset, eh.TryEnd.Offset, eh));
if (eh.HandlerType == ExceptionHandlerType.Filter)
AddNestedStructure(new ILStructure(ILStructureType.Filter, eh.FilterStart.Offset, eh.HandlerStart.Offset, eh));
AddNestedStructure(new ILStructure(ILStructureType.Handler, eh.HandlerStart.Offset, eh.HandlerEnd == null ? body.CodeSize : eh.HandlerEnd.Offset, eh));
for (int i = 0; i < body.ExceptionRegions.Length; i++) {
ExceptionRegion eh = body.ExceptionRegions[i];
if (!body.ExceptionRegions.Take(i).Any(oldEh => oldEh.TryOffset == eh.TryOffset && oldEh.TryLength == eh.TryLength))
AddNestedStructure(new ILStructure(method, ILStructureType.Try, eh.TryOffset, eh.TryOffset + eh.TryLength, eh));
if (eh.Kind == ExceptionRegionKind.Filter)
AddNestedStructure(new ILStructure(method, ILStructureType.Filter, eh.FilterOffset, eh.HandlerOffset, eh));
AddNestedStructure(new ILStructure(method, ILStructureType.Handler, eh.HandlerOffset, eh.HandlerOffset + eh.HandlerLength, eh));
}
// Very simple loop detection: look for backward branches
List<KeyValuePair<Instruction, Instruction>> allBranches = FindAllBranches(body);
(var allBranches, var isAfterConditionalBranch) = FindAllBranches(body.GetILReader());
// We go through the branches in reverse so that we find the biggest possible loop boundary first (think loops with "continue;")
for (int i = allBranches.Count - 1; i >= 0; i--) {
int loopEnd = allBranches[i].Key.GetEndOffset();
int loopStart = allBranches[i].Value.Offset;
int loopEnd = allBranches[i].Source.End;
int loopStart = allBranches[i].Target;
if (loopStart < loopEnd) {
// We found a backward branch. This is a potential loop.
// Check that is has only one entry point:
Instruction entryPoint = null;
int entryPoint = -1;
// entry point is first instruction in loop if prev inst isn't an unconditional branch
Instruction prev = allBranches[i].Value.Previous;
if (prev != null && !prev.OpCode.IsUnconditionalBranch())
entryPoint = allBranches[i].Value;
if (!isAfterConditionalBranch[loopStart])
entryPoint = allBranches[i].Target;
bool multipleEntryPoints = false;
foreach (var pair in allBranches) {
if (pair.Key.Offset < loopStart || pair.Key.Offset >= loopEnd) {
if (loopStart <= pair.Value.Offset && pair.Value.Offset < loopEnd) {
foreach (var branch in allBranches) {
if (branch.Source.Start < loopStart || branch.Source.Start >= loopEnd) {
if (loopStart <= branch.Target && branch.Target < loopEnd) {
// jump from outside the loop into the loop
if (entryPoint == null)
entryPoint = pair.Value;
else if (pair.Value != entryPoint)
if (entryPoint < 0)
entryPoint = branch.Target;
else if (branch.Target != entryPoint)
multipleEntryPoints = true;
}
}
}
if (!multipleEntryPoints) {
AddNestedStructure(new ILStructure(ILStructureType.Loop, loopStart, loopEnd, entryPoint));
AddNestedStructure(new ILStructure(method, ILStructureType.Loop, loopStart, loopEnd, entryPoint));
}
}
}
SortChildren();
}
public ILStructure(ILStructureType type, int startOffset, int endOffset, ExceptionHandler handler = null)
public ILStructure(Dom.MethodDefinition method, ILStructureType type, int startOffset, int endOffset, ExceptionRegion handler = default(ExceptionRegion))
{
Debug.Assert(startOffset < endOffset);
this.Method = method;
this.Type = type;
this.StartOffset = startOffset;
this.EndOffset = endOffset;
this.ExceptionHandler = handler;
}
public ILStructure(ILStructureType type, int startOffset, int endOffset, Instruction loopEntryPoint)
public ILStructure(Dom.MethodDefinition method, ILStructureType type, int startOffset, int endOffset, int loopEntryPoint)
{
Debug.Assert(startOffset < endOffset);
this.Method = method;
this.Type = type;
this.StartOffset = startOffset;
this.EndOffset = endOffset;
this.LoopEntryPoint = loopEntryPoint;
this.LoopEntryPointOffset = loopEntryPoint;
}
bool AddNestedStructure(ILStructure newStructure)
@ -180,29 +184,68 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -180,29 +184,68 @@ namespace ICSharpCode.Decompiler.Disassembler
return true;
}
struct Branch
{
public Interval Source;
public int Target;
public Branch(int start, int end, int target)
{
this.Source = new Interval(start, end);
this.Target = target;
}
public override string ToString()
{
return $"[Branch Source={Source}, Target={Target}]";
}
}
/// <summary>
/// Finds all branches. Returns list of source offset->target offset mapping.
/// Multiple entries for the same source offset are possible (switch statements).
/// The result is sorted by source offset.
/// </summary>
List<KeyValuePair<Instruction, Instruction>> FindAllBranches(MethodBody body)
(List<Branch> Branches, BitSet IsAfterUnconditionalBranch) FindAllBranches(BlobReader body)
{
var result = new List<KeyValuePair<Instruction, Instruction>>();
foreach (Instruction inst in body.Instructions) {
switch (inst.OpCode.OperandType) {
case OperandType.InlineBrTarget:
case OperandType.ShortInlineBrTarget:
result.Add(new KeyValuePair<Instruction, Instruction>(inst, (Instruction)inst.Operand));
var result = new List<Branch>();
var bitset = new BitSet(body.Length);
body.Reset();
int target;
while (body.RemainingBytes > 0) {
var offset = body.Offset;
int endOffset;
var thisOpCode = ILParser.DecodeOpCode(ref body);
switch (thisOpCode.GetOperandType()) {
case OperandType.BrTarget:
case OperandType.ShortBrTarget:
endOffset = body.Offset + thisOpCode.GetBranchOperandSize();
target = ILParser.DecodeBranchTarget(ref body, thisOpCode);
result.Add(new Branch(offset, endOffset, target));
bitset[endOffset] = IsUnconditionalBranch(thisOpCode);
break;
case OperandType.Switch:
var targets = ILParser.DecodeSwitchTargets(ref body);
foreach (int t in targets)
result.Add(new Branch(offset, offset + 4 * (targets.Length + 1), t));
break;
case OperandType.InlineSwitch:
foreach (Instruction target in (Instruction[])inst.Operand)
result.Add(new KeyValuePair<Instruction, Instruction>(inst, target));
default:
ILParser.SkipOperand(ref body, thisOpCode);
break;
}
}
// ignore the branches where Cecil doesn't decode the target
result.RemoveAll(x => x.Value == null);
return result;
return (result, bitset);
}
static bool IsUnconditionalBranch(ILOpCode opCode)
{
switch (opCode) {
case ILOpCode.Br:
case ILOpCode.Br_s:
return true;
default:
return false;
}
}
void SortChildren()

1290
ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs

File diff suppressed because it is too large Load Diff

115
ICSharpCode.Decompiler/Disassembler/OpCodeInfo.cs

@ -19,22 +19,25 @@ @@ -19,22 +19,25 @@
using System;
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;
namespace ICSharpCode.Decompiler.Disassembler
{
public struct OpCodeInfo : IEquatable<OpCodeInfo>
{
public readonly int Code;
public readonly ILOpCode Code;
public readonly string Name;
string encodedName;
public OpCodeInfo(int code, string name)
public OpCodeInfo(ILOpCode code, string name)
{
this.Code = code;
this.Name = name;
this.Name = name ?? "";
this.encodedName = null;
}
@ -46,6 +49,18 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -46,6 +49,18 @@ namespace ICSharpCode.Decompiler.Disassembler
public static bool operator ==(OpCodeInfo lhs, OpCodeInfo rhs) => lhs.Equals(rhs);
public static bool operator !=(OpCodeInfo lhs, OpCodeInfo rhs) => !(lhs == rhs);
public override bool Equals(object obj)
{
if (obj is OpCodeInfo opCode)
return Equals(opCode);
return false;
}
public override int GetHashCode()
{
return unchecked(982451629 * Code.GetHashCode() + 982451653 * Name.GetHashCode());
}
public string Link => "http://msdn.microsoft.com/library/system.reflection.emit.opcodes." + EncodedName.ToLowerInvariant() + ".aspx";
public string EncodedName {
get {
@ -89,4 +104,98 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -89,4 +104,98 @@ namespace ICSharpCode.Decompiler.Disassembler
}
}
}
public static class ILParser
{
public static ILOpCode DecodeOpCode(ref BlobReader blob)
{
byte opCodeByte = blob.ReadByte();
return (ILOpCode)(opCodeByte == 0xFE ? 0xFE00 + blob.ReadByte() : opCodeByte);
}
public static void SkipOperand(ref BlobReader blob, ILOpCode opCode)
{
switch (opCode.GetOperandType()) {
// 64-bit
case OperandType.I8:
case OperandType.R:
blob.Offset += 8;
break;
// 32-bit
case OperandType.BrTarget:
case OperandType.Field:
case OperandType.Method:
case OperandType.I:
case OperandType.Sig:
case OperandType.String:
case OperandType.Tok:
case OperandType.Type:
case OperandType.ShortR:
blob.Offset += 4;
break;
// (n + 1) * 32-bit
case OperandType.Switch:
uint n = blob.ReadUInt32();
blob.Offset += (int)(n * 4);
break;
// 16-bit
case OperandType.Variable:
blob.Offset += 2;
break;
// 8-bit
case OperandType.ShortVariable:
case OperandType.ShortBrTarget:
case OperandType.ShortI:
blob.Offset++;
break;
}
}
public static int DecodeBranchTarget(ref BlobReader blob, ILOpCode opCode)
{
return (opCode.GetBranchOperandSize() == 4 ? blob.ReadInt32() : blob.ReadSByte()) + blob.Offset;
}
public static int[] DecodeSwitchTargets(ref BlobReader blob)
{
int[] targets = new int[blob.ReadUInt32()];
int offset = blob.Offset + 4 * targets.Length;
for (int i = 0; i < targets.Length; i++)
targets[i] = blob.ReadInt32() + offset;
return targets;
}
public static string DecodeUserString(ref BlobReader blob, Dom.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;
}
}
}

607
ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs

File diff suppressed because it is too large Load Diff

1231
ICSharpCode.Decompiler/Dom/Dom.cs

File diff suppressed because it is too large Load Diff

239
ICSharpCode.Decompiler/TypeSystem/MetadataExtensions.cs → ICSharpCode.Decompiler/Dom/MetadataExtensions.cs

@ -1,17 +1,57 @@ @@ -1,17 +1,57 @@
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.Reflection.PortableExecutable;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.TypeSystem
namespace ICSharpCode.Decompiler
{
static class MetadataExtensions
public static class MetadataExtensions
{
public static Dom.ITypeReference CoerceTypeReference(this EntityHandle handle, Dom.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));
}
}
public static bool IsNil(this Dom.IAssemblyReference reference)
{
return reference == null || (reference is Dom.AssemblyReference ar && ar.IsNil);
}
public static string GetFullAssemblyName(this MetadataReader reader)
{
if (!reader.IsAssembly)
@ -26,6 +66,20 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -26,6 +66,20 @@ namespace ICSharpCode.Decompiler.TypeSystem
return $"{reader.GetString(asm.Name)}, Version={asm.Version}, Culture={reader.GetString(asm.Culture)}, PublicKeyToken={publicKey}";
}
public static string GetFullAssemblyName(this AssemblyReference reference, MetadataReader reader)
{
string publicKey = "null";
if (!reference.PublicKeyOrToken.IsNil && (reference.Flags & AssemblyFlags.PublicKey) != 0) {
SHA1 sha1 = SHA1.Create();
var publicKeyTokenBytes = sha1.ComputeHash(reader.GetBlobBytes(reference.PublicKeyOrToken)).Skip(12).ToArray();
publicKey = publicKeyTokenBytes.ToHexString();
}
string properties = "";
if ((reference.Flags & AssemblyFlags.Retargetable) != 0)
properties = ", Retargetable=true";
return $"{reader.GetString(reference.Name)}, Version={reference.Version}, Culture={reader.GetString(reference.Culture)}, PublicKeyToken={publicKey}{properties}";
}
static string ToHexString(this byte[] bytes)
{
StringBuilder sb = new StringBuilder(bytes.Length * 2);
@ -37,7 +91,24 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -37,7 +91,24 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// <summary>
/// Gets the type of the attribute.
/// </summary>
/// <returns>Either <see cref="TypeDefinitionHandle"/>, <see cref="TypeReferenceHandle"/>,<see cref="TypeSpecificationHandle".</returns>
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) {
@ -52,32 +123,61 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -52,32 +123,61 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
}
public static IEnumerable<TypeDefinitionHandle> GetTopLevelTypeDefinitions(this MetadataReader reader)
{
var queue = new Queue<NamespaceDefinition>();
queue.Enqueue(reader.GetNamespaceDefinitionRoot());
while (queue.Count > 0) {
var ns = queue.Dequeue();
foreach (var td in ns.TypeDefinitions)
yield return td;
foreach (var nestedNS in ns.NamespaceDefinitions)
queue.Enqueue(reader.GetNamespaceDefinition(nestedNS));
}
}
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 TypeReferenceHandle handle, MetadataReader reader)
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).NestedType(reader.GetString(tr.Name), 0);
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);
}
@ -86,9 +186,21 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -86,9 +186,21 @@ namespace ICSharpCode.Decompiler.TypeSystem
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), td.GetGenericParameters().Count));
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);
if (typeName.IsNested) {
return $"{typeName.GetDeclaringType().ToILNameString()}/{escapedName}";
} else if (!string.IsNullOrEmpty(typeName.TopLevelTypeName.Namespace)) {
return $"{typeName.TopLevelTypeName.Namespace}.{escapedName}";
} else {
return declaringTypeHandle.GetFullTypeName(reader).NestedType(reader.GetString(td.Name), td.GetGenericParameters().Count);
return $"{escapedName}";
}
}
@ -115,23 +227,6 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -115,23 +227,6 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
}
public unsafe static 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);
int token = reader.GetToken(handle);
for (int row = rowCount - 1; row >= 0; row--) {
byte* ptr = startPointer + offset + rowSize * row;
ushort methodToken = *(ptr + 2);
if (token == methodToken) {
return (MethodSemanticsAttributes)(*ptr);
}
}
return 0;
}
public static bool IsValueType(this TypeDefinition typeDefinition, MetadataReader reader)
{
if (typeDefinition.BaseType.IsNil)
@ -157,6 +252,32 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -157,6 +252,32 @@ namespace ICSharpCode.Decompiler.TypeSystem
return typeDefinition.BaseType.GetFullTypeName(reader).ToString() == "System.Enum";
}
public static string GetDefaultMemberName(this TypeDefinitionHandle type, MetadataReader reader)
{
return type.GetDefaultMemberName(reader, out var attr);
}
static readonly ITypeResolveContext minimalCorlibContext = new SimpleTypeResolveContext(MinimalCorlib.Instance.CreateCompilation());
public static string GetDefaultMemberName(this TypeDefinitionHandle type, MetadataReader reader, out CustomAttributeHandle defaultMemberAttribute)
{
var td = reader.GetTypeDefinition(type);
foreach (var h in td.GetCustomAttributes()) {
var ca = reader.GetCustomAttribute(h);
if (ca.GetAttributeType(reader).ToString() == "System.Reflection.DefaultMemberAttribute") {
var decodedValues = ca.DecodeValue(new TypeSystemAttributeTypeProvider(minimalCorlibContext));
if (decodedValues.FixedArguments.Length == 1 && decodedValues.FixedArguments[0].Value is string value) {
defaultMemberAttribute = h;
return value;
}
}
}
defaultMemberAttribute = default(CustomAttributeHandle);
return null;
}
public static bool HasOverrides(this MethodDefinitionHandle handle, MetadataReader reader)
{
for (int row = 1; row <= reader.GetTableRowCount(TableIndex.MethodImpl); row++) {
@ -267,5 +388,75 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -267,5 +388,75 @@ namespace ICSharpCode.Decompiler.TypeSystem
return KnownTypeCode.None;
}
}
public static bool IsSmallReference(this MetadataReader reader, TableIndex table)
{
// TODO detect whether #JTD is present (EnC)
return reader.GetTableRowCount(table) <= ushort.MaxValue;
}
public static int GetReferenceSize(this MetadataReader reader, TableIndex table)
{
return IsSmallReference(reader, table) ? 2 : 4;
}
public static unsafe (int startRow, int endRow) BinarySearchRange(this MetadataReader reader, TableIndex table, int valueOffset, uint referenceValue, bool small)
{
int offset = reader.GetTableMetadataOffset(table);
int rowSize = reader.GetTableRowSize(table);
int rowCount = reader.GetTableRowCount(table);
int tableLength = rowSize * rowCount;
byte* startPointer = reader.MetadataPointer;
int result = BinarySearch();
if (result == -1)
return (-1, -1);
int start = result;
while (start > 0 && GetValue(start - 1) == referenceValue)
start--;
int end = result;
while (end + 1 < tableLength && GetValue(end + 1) == referenceValue)
end++;
return (start, end);
uint GetValue(int row)
{
if (small)
return *(ushort*)(startPointer + offset + row * rowSize + valueOffset);
else
return *(uint*)(startPointer + offset + row * rowSize + valueOffset);
}
int BinarySearch()
{
int startRow = 0;
int endRow = rowCount - 1;
while (startRow <= endRow) {
int row = (startRow + endRow) / 2;
uint currentValue = GetValue(row);
if (referenceValue > currentValue) {
startRow = row + 1;
} else if (referenceValue < currentValue) {
endRow = row - 1;
} else {
return row;
}
}
return -1;
}
}
public static AssemblyDefinition? GetAssemblyDefinition(this PEReader reader)
{
var metadata = reader.GetMetadataReader();
if (metadata.IsAssembly)
return metadata.GetAssemblyDefinition();
return null;
}
}
}

230
ICSharpCode.Decompiler/Dom/MetadataResolver.cs

@ -0,0 +1,230 @@ @@ -0,0 +1,230 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Reflection.PortableExecutable;
using System.Text;
using System.Threading.Tasks;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.Dom
{
public interface IMetadataResolveContext
{
PEFile CurrentModule { get; }
PEFile ResolveAssembly(IAssemblyReference reference);
}
public class SimpleMetadataResolveContext : IMetadataResolveContext
{
readonly PEFile mainModule;
readonly IAssemblyResolver assemblyResolver;
readonly Dictionary<IAssemblyReference, PEFile> loadedModules = new Dictionary<IAssemblyReference, PEFile>();
public SimpleMetadataResolveContext(PEFile mainModule)
{
this.mainModule = mainModule;
this.assemblyResolver = mainModule.AssemblyResolver;
}
public PEFile CurrentModule => mainModule;
public PEFile ResolveAssembly(IAssemblyReference reference)
{
if (loadedModules.TryGetValue(reference, out var module))
return module;
var resolved = assemblyResolver.Resolve(reference);
loadedModules.Add(reference, resolved);
return resolved;
}
}
public static class MetadataResolver
{
/// <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)
{
var metadata = context.CurrentModule.GetMetadataReader();
var tr = metadata.GetTypeReference(handle);
if (tr.ResolutionScope.IsNil) {
foreach (var h in metadata.ExportedTypes) {
var exportedType = metadata.GetExportedType(h);
if (exportedType.Name == tr.Name && exportedType.Namespace == tr.Namespace) {
// TODO
}
}
}
switch (tr.ResolutionScope.Kind) {
case HandleKind.TypeReference:
//return Resolve((TypeReferenceHandle)tr.ResolutionScope, context).GetNestedType(new );
break;
case HandleKind.ModuleReference:
break;
case HandleKind.AssemblyReference:
var module = context.ResolveAssembly(new AssemblyReference(context.CurrentModule, (AssemblyReferenceHandle)tr.ResolutionScope));
var moduleMetadata = module.GetMetadataReader();
var @namespace = ResolveNamespace(moduleMetadata, metadata.GetString(tr.Namespace).Split('.'));
if (@namespace == null)
throw new NotSupportedException();
var type = FindTypeInNamespace(moduleMetadata, @namespace.Value, metadata.GetString(tr.Name));
if (type.IsNil)
throw new NotSupportedException();
return new TypeDefinition(module, type);
}
throw new NotSupportedException();
}
static NamespaceDefinition? ResolveNamespace(MetadataReader metadata, string[] namespaceParts)
{
var currentNamespace = metadata.GetNamespaceDefinitionRoot();
for (int i = 0; i < namespaceParts.Length; i++) {
string identifier = namespaceParts[i];
var next = currentNamespace.NamespaceDefinitions.FirstOrDefault(ns => metadata.GetString(metadata.GetNamespaceDefinition(ns).Name) == identifier);
if (next.IsNil)
return null;
currentNamespace = metadata.GetNamespaceDefinition(next);
}
return currentNamespace;
}
static TypeDefinitionHandle FindTypeInNamespace(MetadataReader metadata, NamespaceDefinition @namespace, string name)
{
foreach (var type in @namespace.TypeDefinitions) {
var typeName = metadata.GetString(metadata.GetTypeDefinition(type).Name);
if (name == typeName)
return type;
}
return default(TypeDefinitionHandle);
}
public static IMemberDefinition Resolve(MemberReferenceHandle handle, IMetadataResolveContext context)
{
var metadata = context.CurrentModule.GetMetadataReader();
var mr = metadata.GetMemberReference(handle);
TypeDefinition declaringType;
switch (mr.Parent.Kind) {
case HandleKind.TypeDefinition:
declaringType = new TypeDefinition(context.CurrentModule, (TypeDefinitionHandle)mr.Parent);
break;
case HandleKind.TypeReference:
declaringType = Resolve((TypeReferenceHandle)mr.Parent, context);
break;
case HandleKind.TypeSpecification:
case HandleKind.MethodDefinition:
case HandleKind.ModuleReference:
throw new NotImplementedException();
default:
throw new NotSupportedException();
}
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;
// TODO overload resolution... OMG
return true;
}
public static TypeDefinition Resolve(TypeSpecificationHandle handle, IMetadataResolveContext context)
{
var metadata = context.CurrentModule.GetMetadataReader();
var ts = metadata.GetTypeSpecification(handle);
var unspecialized = ts.DecodeSignature(new Unspecializer(), default(Unit));
switch (unspecialized.Kind) {
case HandleKind.TypeDefinition:
return new TypeDefinition(context.CurrentModule, (TypeDefinitionHandle)unspecialized);
case HandleKind.TypeReference:
return Resolve((TypeReferenceHandle)unspecialized, context);
default:
throw new NotImplementedException();
}
}
class Unspecializer : ISignatureTypeProvider<EntityHandle, Unit>
{
public EntityHandle GetArrayType(EntityHandle elementType, ArrayShape shape)
{
return elementType;
}
public EntityHandle GetByReferenceType(EntityHandle elementType)
{
return elementType;
}
public EntityHandle GetFunctionPointerType(MethodSignature<EntityHandle> signature)
{
throw new NotImplementedException();
}
public EntityHandle GetGenericInstantiation(EntityHandle genericType, ImmutableArray<EntityHandle> typeArguments)
{
return genericType;
}
public EntityHandle GetGenericMethodParameter(Unit genericContext, int index)
{
return MetadataTokens.EntityHandle(0);
}
public EntityHandle GetGenericTypeParameter(Unit genericContext, int index)
{
return MetadataTokens.EntityHandle(0);
}
public EntityHandle GetModifiedType(EntityHandle modifier, EntityHandle unmodifiedType, bool isRequired)
{
return unmodifiedType;
}
public EntityHandle GetPinnedType(EntityHandle elementType)
{
return elementType;
}
public EntityHandle GetPointerType(EntityHandle elementType)
{
return elementType;
}
public EntityHandle GetPrimitiveType(PrimitiveTypeCode typeCode)
{
throw new NotImplementedException();
}
public EntityHandle GetSZArrayType(EntityHandle elementType)
{
throw new NotImplementedException();
}
public EntityHandle GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)
{
return handle;
}
public EntityHandle GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)
{
return handle;
}
public EntityHandle GetTypeFromSpecification(MetadataReader reader, Unit genericContext, TypeSpecificationHandle handle, byte rawTypeKind)
{
return reader.GetTypeSpecification(handle).DecodeSignature(this, genericContext);
}
}
}
}

92
ICSharpCode.Decompiler/Dom/SequencePoint.cs

@ -0,0 +1,92 @@ @@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Text;
namespace ICSharpCode.Decompiler.Dom
{
using SRMDocument = System.Reflection.Metadata.Document;
/// <summary>
/// A sequence point read from a PDB file or produced by the decompiler.
/// </summary>
public struct SequencePoint
{
/// <summary>
/// IL start offset.
/// </summary>
public int Offset { get; set; }
/// <summary>
/// IL end offset.
/// </summary>
/// <remarks>
/// This does not get stored in debug information;
/// it is used internally to create hidden sequence points
/// for the IL fragments not covered by any sequence point.
/// </remarks>
public int EndOffset { get; set; }
public int StartLine { get; set; }
public int StartColumn { get; set; }
public int EndLine { get; set; }
public int EndColumn { get; set; }
public bool IsHidden {
get { return StartLine == 0xfeefee && StartLine == EndLine; }
}
public Document Document { get; set; }
internal void SetHidden()
{
StartLine = EndLine = 0xfeefee;
}
}
public struct Document : IEquatable<Document>
{
public PEFile Module { get; }
public DocumentHandle Handle { get; }
public bool IsNil => Handle.IsNil;
public Document(PEFile module, DocumentHandle handle) : this()
{
this.Module = module ?? throw new ArgumentNullException(nameof(module));
this.Handle = handle;
}
SRMDocument This() => Module.GetMetadataReader().GetDocument(Handle);
public bool Equals(Document other)
{
return Module == other.Module && Handle == other.Handle;
}
public override bool Equals(object obj)
{
if (obj is Document md)
return Equals(md);
return false;
}
public override int GetHashCode()
{
return unchecked(982451629 * Module.GetHashCode() + 982451653 * MetadataTokens.GetToken(Handle));
}
public static bool operator ==(Document lhs, Document rhs) => lhs.Equals(rhs);
public static bool operator !=(Document lhs, Document rhs) => !lhs.Equals(rhs);
public string Url {
get {
if (Handle.IsNil)
return null;
var h = This().Name;
if (h.IsNil) return null;
return Module.GetMetadataReader().GetString(h);
}
}
}
}

6
ICSharpCode.Decompiler/DotNetCore/DotNetCorePathFinder.cs

@ -5,8 +5,8 @@ using System.IO; @@ -5,8 +5,8 @@ using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using ICSharpCode.Decompiler.Dom;
using LightJson.Serialization;
using Mono.Cecil;
namespace ICSharpCode.Decompiler
{
@ -70,7 +70,7 @@ namespace ICSharpCode.Decompiler @@ -70,7 +70,7 @@ namespace ICSharpCode.Decompiler
}
}
public string TryResolveDotNetCore(AssemblyNameReference name)
public string TryResolveDotNetCore(IAssemblyReference name)
{
foreach (var basePath in packageBasePaths) {
if (File.Exists(Path.Combine(basePath, name.Name + ".dll"))) {
@ -106,7 +106,7 @@ namespace ICSharpCode.Decompiler @@ -106,7 +106,7 @@ namespace ICSharpCode.Decompiler
}
}
string FallbackToDotNetSharedDirectory(AssemblyNameReference name, Version version)
string FallbackToDotNetSharedDirectory(IAssemblyReference name, Version version)
{
if (dotnetBasePath == null) return null;
var basePath = Path.Combine(dotnetBasePath, "shared", "Microsoft.NETCore.App");

16
ICSharpCode.Decompiler/DotNetCore/DotNetCorePathFinderExtensions.cs

@ -1,26 +1,28 @@ @@ -1,26 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using Mono.Cecil;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
namespace ICSharpCode.Decompiler
{
public static class DotNetCorePathFinderExtensions
{
public static string DetectTargetFrameworkId(this AssemblyDefinition assembly)
public static string DetectTargetFrameworkId(this PEReader assembly)
{
if (assembly == null)
throw new ArgumentNullException(nameof(assembly));
const string TargetFrameworkAttributeName = "System.Runtime.Versioning.TargetFrameworkAttribute";
var reader = assembly.GetMetadataReader();
foreach (var attribute in assembly.CustomAttributes) {
if (attribute.AttributeType.FullName != TargetFrameworkAttributeName)
foreach (var h in reader.GetCustomAttributes(Handle.AssemblyDefinition)) {
var attribute = reader.GetCustomAttribute(h);
if (attribute.GetAttributeType(reader).ToString() != TargetFrameworkAttributeName)
continue;
var blobReader = new BlobReader(attribute.GetBlob(), null);
var blobReader = reader.GetBlobReader(attribute.Value);
if (blobReader.ReadUInt16() == 0x0001) {
return blobReader.ReadSerString();
return blobReader.ReadSerializedString();
}
}

66
ICSharpCode.Decompiler/DotNetCore/UniversalAssemblyResolver.cs

@ -1,9 +1,10 @@ @@ -1,9 +1,10 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection.PortableExecutable;
using System.Text;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Util;
using Mono.Cecil;
namespace ICSharpCode.Decompiler
{
@ -58,26 +59,18 @@ namespace ICSharpCode.Decompiler @@ -58,26 +59,18 @@ namespace ICSharpCode.Decompiler
AddSearchDirectory(baseDirectory);
}
public static ModuleDefinition LoadMainModule(string mainAssemblyFileName, bool throwOnError = true, bool inMemory = false)
public static PEFile LoadMainModule(string mainAssemblyFileName, bool throwOnError = true, bool inMemory = false)
{
var resolver = new UniversalAssemblyResolver(mainAssemblyFileName, throwOnError);
var module = ModuleDefinition.ReadModule(mainAssemblyFileName, new ReaderParameters {
AssemblyResolver = resolver,
InMemory = inMemory
});
var module = new PEReader(new FileStream(mainAssemblyFileName, FileMode.Open));
resolver.TargetFramework = module.Assembly.DetectTargetFrameworkId();
resolver.TargetFramework = module.DetectTargetFrameworkId();
return module;
return new PEFile(mainAssemblyFileName, module, resolver);
}
public AssemblyDefinition Resolve(AssemblyNameReference name)
{
return Resolve(name, new ReaderParameters());
}
public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters)
public PEFile Resolve(IAssemblyReference name)
{
var file = FindAssemblyFile(name);
if (file == null) {
@ -85,10 +78,10 @@ namespace ICSharpCode.Decompiler @@ -85,10 +78,10 @@ namespace ICSharpCode.Decompiler
throw new AssemblyResolutionException(name);
return null;
}
return GetAssembly(file, parameters);
return new PEFile(file, GetAssembly(file), this);
}
public string FindAssemblyFile(AssemblyNameReference name)
public string FindAssemblyFile(IAssemblyReference name)
{
var targetFramework = TargetFramework.Split(new[] { ",Version=v" }, StringSplitOptions.None);
string file = null;
@ -110,28 +103,21 @@ namespace ICSharpCode.Decompiler @@ -110,28 +103,21 @@ namespace ICSharpCode.Decompiler
}
}
string ResolveInternal(AssemblyNameReference name)
string ResolveInternal(IAssemblyReference name)
{
if (name == null)
if (name.IsNil())
throw new ArgumentNullException(nameof(name));
var assembly = SearchDirectory(name, directories);
if (assembly != null)
return assembly;
if (name.IsRetargetable) {
// if the reference is retargetable, zero it
name = new AssemblyNameReference(name.Name, ZeroVersion) {
PublicKeyToken = Empty<byte>.Array,
};
}
var framework_dir = Path.GetDirectoryName(typeof(object).Module.FullyQualifiedName);
var framework_dirs = DetectMono()
? new[] { framework_dir, Path.Combine(framework_dir, "Facades") }
: new[] { framework_dir };
if (IsZero(name.Version)) {
if (IsZeroVersionOrRetargetable(name)) {
assembly = SearchDirectory(name, framework_dirs);
if (assembly != null)
return assembly;
@ -157,7 +143,7 @@ namespace ICSharpCode.Decompiler @@ -157,7 +143,7 @@ namespace ICSharpCode.Decompiler
}
#region .NET / mono GAC handling
string SearchDirectory(AssemblyNameReference name, IEnumerable<string> directories)
string SearchDirectory(IAssemblyReference name, IEnumerable<string> directories)
{
var extensions = name.IsWindowsRuntime ? new[] { ".winmd", ".dll" } : new[] { ".exe", ".dll" };
foreach (var directory in directories) {
@ -176,19 +162,22 @@ namespace ICSharpCode.Decompiler @@ -176,19 +162,22 @@ namespace ICSharpCode.Decompiler
return null;
}
static bool IsZeroVersionOrRetargetable(IAssemblyReference reference)
{
return IsZero(reference.Version) || reference.IsRetargetable;
}
static bool IsZero(Version version)
{
return version.Major == 0 && version.Minor == 0 && version.Build == 0 && version.Revision == 0;
}
static Version ZeroVersion = new Version(0, 0, 0, 0);
string GetCorlib(AssemblyNameReference reference)
string GetCorlib(IAssemblyReference reference)
{
var version = reference.Version;
var corlib = typeof(object).Assembly.GetName();
if (corlib.Version == version || IsZero(version))
if (corlib.Version == version || IsZeroVersionOrRetargetable(reference))
return typeof(object).Module.FullyQualifiedName;
var path = Directory.GetParent(
@ -286,15 +275,12 @@ namespace ICSharpCode.Decompiler @@ -286,15 +275,12 @@ namespace ICSharpCode.Decompiler
"gac");
}
AssemblyDefinition GetAssembly(string file, ReaderParameters parameters)
PEReader GetAssembly(string file)
{
if (parameters.AssemblyResolver == null)
parameters.AssemblyResolver = this;
return ModuleDefinition.ReadModule(file, parameters).Assembly;
return new PEReader(new FileStream(file, FileMode.Open));
}
string GetAssemblyInGac(AssemblyNameReference reference)
string GetAssemblyInGac(IAssemblyReference reference)
{
if (reference.PublicKeyToken == null || reference.PublicKeyToken.Length == 0)
return null;
@ -305,7 +291,7 @@ namespace ICSharpCode.Decompiler @@ -305,7 +291,7 @@ namespace ICSharpCode.Decompiler
return GetAssemblyInNetGac(reference);
}
string GetAssemblyInMonoGac(AssemblyNameReference reference)
string GetAssemblyInMonoGac(IAssemblyReference reference)
{
for (int i = 0; i < gac_paths.Count; i++) {
var gac_path = gac_paths[i];
@ -317,7 +303,7 @@ namespace ICSharpCode.Decompiler @@ -317,7 +303,7 @@ namespace ICSharpCode.Decompiler
return null;
}
string GetAssemblyInNetGac(AssemblyNameReference reference)
string GetAssemblyInNetGac(IAssemblyReference reference)
{
var gacs = new[] { "GAC_MSIL", "GAC_32", "GAC_64", "GAC" };
var prefixes = new[] { string.Empty, "v4.0_" };
@ -334,7 +320,7 @@ namespace ICSharpCode.Decompiler @@ -334,7 +320,7 @@ namespace ICSharpCode.Decompiler
return null;
}
static string GetAssemblyFile(AssemblyNameReference reference, string prefix, string gac)
static string GetAssemblyFile(IAssemblyReference reference, string prefix, string gac)
{
var gac_folder = new StringBuilder()
.Append(prefix)

8
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -268,6 +268,8 @@ @@ -268,6 +268,8 @@
<Compile Include="CSharp\Transforms\ReplaceMethodCallsWithOperators.cs" />
<Compile Include="CSharp\WholeProjectDecompiler.cs" />
<Compile Include="CSharp\Transforms\AddXmlDocumentationTransform.cs" />
<Compile Include="Disassembler\BlobDecoder.cs" />
<Compile Include="Disassembler\DomExtensions.cs" />
<Compile Include="Disassembler\OpCodeInfo.cs" />
<Compile Include="Documentation\GetPotentiallyNestedClassTypeReference.cs" />
<Compile Include="Documentation\IdStringMemberReference.cs" />
@ -275,6 +277,8 @@ @@ -275,6 +277,8 @@
<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" />
@ -292,7 +296,7 @@ @@ -292,7 +296,7 @@
<Compile Include="IL\ILAstWritingOptions.cs" />
<Compile Include="IL\Instructions\LdFlda.cs" />
<Compile Include="IL\Instructions\StLoc.cs" />
<Compile Include="IL\SequencePoint.cs" />
<Compile Include="Dom\SequencePoint.cs" />
<Compile Include="IL\Instructions\CallIndirect.cs" />
<Compile Include="IL\Instructions\DefaultValue.cs" />
<Compile Include="IL\Transforms\EarlyExpressionTransforms.cs" />
@ -326,7 +330,7 @@ @@ -326,7 +330,7 @@
<Compile Include="IL\Transforms\TransformCollectionAndObjectInitializers.cs" />
<Compile Include="Output\TextTokenWriter.cs" />
<Compile Include="TypeSystem\Implementation\TypeSpecification.cs" />
<Compile Include="TypeSystem\MetadataExtensions.cs" />
<Compile Include="Dom\MetadataExtensions.cs" />
<Compile Include="Util\GraphVizGraph.cs" />
<Compile Include="Util\KeyComparer.cs" />
<Compile Include="Util\LongDict.cs" />

335
ICSharpCode.Decompiler/IL/ILOpCodes.cs

File diff suppressed because one or more lines are too long

132
ICSharpCode.Decompiler/IL/ILOpCodes.tt

@ -21,40 +21,148 @@ @@ -21,40 +21,148 @@
<#@ 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.Reflection.Emit;
using System.Collections.Generic;
using System.Reflection.Metadata;
<#
var operandTypes = new OperandType[0x11f];
var operandTypes = Enumerable.Repeat((OperandType)0xff, 0x11f).ToArray();
var operandNames = new string[0x11f];
#>
namespace ICSharpCode.Decompiler.IL
{
enum ILOpCode : ushort
/// <summary>Describes the operand type of Microsoft intermediate language (MSIL) instruction.</summary>
public enum OperandType
{
<# foreach (var field in typeof(OpCodes).GetFields()) {
var opCode = (OpCode)field.GetValue(null);
ushort val = (ushort)(((opCode.Value & 0x200) >> 1) | (opCode.Value & 0xff));
operandTypes[val] = opCode.OperandType;
#>
<#=field.Name#> = 0x<#=val.ToString("x2")#>,
<# } // end foreach #>
/// <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)
{
return (OperandType)operandTypes[(ushort)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;
}
}
}

41
ICSharpCode.Decompiler/IL/SequencePoint.cs

@ -1,41 +0,0 @@ @@ -1,41 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace ICSharpCode.Decompiler.IL
{
/// <summary>
/// A sequence point produced by the decompiler.
/// </summary>
public struct SequencePoint
{
/// <summary>
/// IL start offset.
/// </summary>
public int Offset { get; set; }
/// <summary>
/// IL end offset.
/// </summary>
/// <remarks>
/// This does not get stored in debug information;
/// it is used internally to create hidden sequence points
/// for the IL fragments not covered by any sequence point.
/// </remarks>
public int EndOffset { get; set; }
public int StartLine { get; set; }
public int StartColumn { get; set; }
public int EndLine { get; set; }
public int EndColumn { get; set; }
public bool IsHidden {
get { return StartLine == 0xfeefee && StartLine == EndLine; }
}
internal void SetHidden()
{
StartLine = EndLine = 0xfeefee;
}
}
}

24
ICSharpCode.Decompiler/TypeSystem/CecilLoader.cs

@ -227,7 +227,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -227,7 +227,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
InitTypeDefinition(cecilTypeDefs[i], typeDefs[i]);
}
AddToTypeSystemTranslationTable(this.currentAssembly, assemblyDefinition);
//AddToTypeSystemTranslationTable(this.currentAssembly, assemblyDefinition);
// Freezing the assembly here is important:
// otherwise it will be frozen when a compilation is first created
// from it. But freezing has the effect of changing some collection instances
@ -911,7 +911,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -911,7 +911,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
{
foreach (MethodDefinitionHandle h in typeDefinition.GetMethods()) {
var method = currentModule.GetMethodDefinition(h);
if (IsVisible(method.Attributes) && !IsAccessor(h.GetMethodSemanticsAttributes(currentModule))) {
/*if (IsVisible(method.Attributes) && !IsAccessor(h.GetMethodSemanticsAttributes(currentModule))) {
SymbolKind type = SymbolKind.Method;
if ((method.Attributes & MethodAttributes.SpecialName) != 0) {
if (method.IsConstructor(currentModule))
@ -920,7 +920,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -920,7 +920,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
type = SymbolKind.Operator;
}
members.Add(ReadMethod(h, td, type));
}
}*/
}
foreach (FieldDefinitionHandle h in typeDefinition.GetFields()) {
var field = currentModule.GetFieldDefinition(h);
@ -1714,7 +1714,8 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -1714,7 +1714,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
public AssemblyDefinition GetCecilObject (IUnresolvedAssembly content)
{
return InternalGetCecilObject<AssemblyDefinition> (content);
throw new NotImplementedException();
//return InternalGetCecilObject<AssemblyDefinition> (content);
}
@ -1722,31 +1723,36 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -1722,31 +1723,36 @@ namespace ICSharpCode.Decompiler.TypeSystem
{
if (type == null)
throw new ArgumentNullException ("type");
return InternalGetCecilObject<TypeDefinition> (type);
throw new NotImplementedException();
//return InternalGetCecilObject<TypeDefinition> (type);
}
public MethodDefinition GetCecilObject (IUnresolvedMethod method)
{
return InternalGetCecilObject<MethodDefinition> (method);
throw new NotImplementedException();
//return InternalGetCecilObject<MethodDefinition> (method);
}
public FieldDefinition GetCecilObject (IUnresolvedField field)
{
return InternalGetCecilObject<FieldDefinition> (field);
throw new NotImplementedException();
//return InternalGetCecilObject<FieldDefinition> (field);
}
public EventDefinition GetCecilObject (IUnresolvedEvent evt)
{
return InternalGetCecilObject<EventDefinition> (evt);
throw new NotImplementedException();
//return InternalGetCecilObject<EventDefinition> (evt);
}
public PropertyDefinition GetCecilObject (IUnresolvedProperty property)
{
return InternalGetCecilObject<PropertyDefinition> (property);
throw new NotImplementedException();
//return InternalGetCecilObject<PropertyDefinition> (property);
}
#endregion
}

27
ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs

@ -41,7 +41,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -41,7 +41,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
if (moduleDefinition == null)
throw new ArgumentNullException(nameof(moduleDefinition));
this.moduleDefinition = moduleDefinition;
MetadataLoader cecilLoader = new MetadataLoader { IncludeInternalMembers = true, LazyLoad = true, OnEntityLoaded = StoreMemberReference, ShortenInterfaceImplNames = false };
/*MetadataLoader cecilLoader = new MetadataLoader { IncludeInternalMembers = true, LazyLoad = true, OnEntityLoaded = StoreMemberReference, ShortenInterfaceImplNames = false };
typeReferenceCecilLoader.SetCurrentModule(moduleDefinition);
IUnresolvedAssembly mainAssembly = cecilLoader.LoadModule(moduleDefinition);
// Load referenced assemblies and type-forwarder references.
@ -69,7 +69,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -69,7 +69,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
referencedAssemblies.Add(MinimalCorlib.Instance);
compilation = new SimpleCompilation(mainAssembly, referencedAssemblies);
}
context = new SimpleTypeResolveContext(compilation.MainAssembly);
context = new SimpleTypeResolveContext(compilation.MainAssembly);*/
}
public ICompilation Compilation {
@ -130,6 +130,8 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -130,6 +130,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
#region Resolve Type
public IType Resolve(TypeReference typeReference)
{
throw new NotImplementedException();
#if false
if (typeReference == null)
return SpecialType.UnknownType;
// We need to skip SentinelType and PinnedType.
@ -137,15 +139,16 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -137,15 +139,16 @@ namespace ICSharpCode.Decompiler.TypeSystem
while (typeReference is OptionalModifierType || typeReference is RequiredModifierType) {
typeReference = ((TypeSpecification)typeReference).ElementType;
}
if (typeReference is SentinelType || typeReference is PinnedType) {
if (typeReference is SentinelType || typeReference is Mono.Cecil.PinnedType) {
typeReference = ((TypeSpecification)typeReference).ElementType;
}
ITypeReference typeRef;
lock (typeReferenceCecilLoader)
typeRef = typeReferenceCecilLoader.ReadTypeReference(typeReference);
return typeRef.Resolve(context);
#endif
}
#endregion
#endregion
#region Resolve Field
public IField Resolve(FieldReference fieldReference)
@ -180,6 +183,8 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -180,6 +183,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
IField CreateFakeField(FieldReference fieldReference)
{
throw new NotImplementedException();
#if false
var declaringType = Resolve(fieldReference.DeclaringType);
var f = new DefaultUnresolvedField();
f.Name = fieldReference.Name;
@ -187,6 +192,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -187,6 +192,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
f.ReturnType = typeReferenceCecilLoader.ReadTypeReference(fieldReference.FieldType);
}
return new ResolvedFakeField(f, context.WithCurrentTypeDefinition(declaringType.GetDefinition()), declaringType);
#endif
}
class ResolvedFakeField : DefaultResolvedField
@ -204,7 +210,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -204,7 +210,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
get { return declaringType; }
}
}
#endregion
#endregion
#region Resolve Method
public IMethod Resolve(MethodReference methodReference)
@ -306,6 +312,8 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -306,6 +312,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// </summary>
IMethod CreateFakeMethod(MethodReference methodReference)
{
throw new NotImplementedException();
#if false
var m = new DefaultUnresolvedMethod();
ITypeReference declaringTypeReference;
lock (typeReferenceCecilLoader) {
@ -324,6 +332,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -324,6 +332,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
var type = declaringTypeReference.Resolve(context);
return new ResolvedFakeMethod(m, context.WithCurrentTypeDefinition(type.GetDefinition()), type);
#endif
}
class ResolvedFakeMethod : DefaultResolvedMethod
@ -343,7 +352,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -343,7 +352,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
#endregion
#region Resolve Property
#region Resolve Property
public IProperty Resolve(PropertyReference propertyReference)
{
if (propertyReference == null)
@ -378,9 +387,9 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -378,9 +387,9 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
return null;
}
#endregion
#endregion
#region Resolve Event
#region Resolve Event
public IEvent Resolve(EventReference eventReference)
{
if (eventReference == null)
@ -412,6 +421,6 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -412,6 +421,6 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
return null;
}
#endregion
#endregion
}
}

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

@ -105,8 +105,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -105,8 +105,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
}
}
public struct Unit { }
class TypeReferenceSignatureDecoder : ISignatureTypeProvider<ITypeReference, Unit>
{
public ITypeReference GetArrayType(ITypeReference elementType, ArrayShape shape)
@ -184,10 +182,12 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -184,10 +182,12 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
}
}
class TypeSystemAttributeTypeProvider : ICustomAttributeTypeProvider<IType>
public class TypeSystemAttributeTypeProvider : ICustomAttributeTypeProvider<IType>
{
readonly ITypeResolveContext context;
public static TypeSystemAttributeTypeProvider CreateDefault() => new TypeSystemAttributeTypeProvider(new SimpleTypeResolveContext(MinimalCorlib.Instance.CreateCompilation()));
public TypeSystemAttributeTypeProvider(ITypeResolveContext context)
{
this.context = context;

2
ICSharpCode.Decompiler/Util/EmptyList.cs

@ -116,4 +116,6 @@ namespace ICSharpCode.Decompiler.Util @@ -116,4 +116,6 @@ namespace ICSharpCode.Decompiler.Util
{
public static readonly T[] Array = new T[0];
}
public struct Unit { }
}

1
ILSpy.AddIn/ILSpy.AddIn.csproj

@ -49,7 +49,6 @@ @@ -49,7 +49,6 @@
<ItemGroup>
<ProjectReference Include="..\ICSharpCode.Decompiler\ICSharpCode.Decompiler.csproj" />
<ProjectReference Include="..\ILSpy.BamlDecompiler\ILSpy.BamlDecompiler.csproj" />
<ProjectReference Include="..\ILSpy\ILSpy.csproj" />
<ProjectReference Include="..\SharpTreeView\ICSharpCode.TreeView.csproj" />
</ItemGroup>

1
ILSpy.BamlDecompiler.Tests/ILSpy.BamlDecompiler.Tests.csproj

@ -40,7 +40,6 @@ @@ -40,7 +40,6 @@
<ProjectReference Include="..\ICSharpCode.Decompiler.Tests\ICSharpCode.Decompiler.Tests.csproj" />
<ProjectReference Include="..\ILSpy\ILSpy.csproj" />
<ProjectReference Include="..\SharpTreeView\ICSharpCode.TreeView.csproj" />
<ProjectReference Include="..\ILSpy.BamlDecompiler\ILSpy.BamlDecompiler.csproj" />
</ItemGroup>
<ItemGroup>

8
ILSpy.BamlDecompiler/BamlResourceEntryNode.cs

@ -10,11 +10,11 @@ using System.Threading.Tasks; @@ -10,11 +10,11 @@ using System.Threading.Tasks;
using System.Xml.Linq;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Util;
using ICSharpCode.ILSpy;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes;
using Mono.Cecil;
using Ricciolo.StylesExplorer.MarkupReflection;
namespace ILSpy.BamlDecompiler
@ -50,16 +50,16 @@ namespace ILSpy.BamlDecompiler @@ -50,16 +50,16 @@ namespace ILSpy.BamlDecompiler
{
var asm = this.Ancestors().OfType<AssemblyTreeNode>().FirstOrDefault().LoadedAssembly;
Data.Position = 0;
XDocument xamlDocument = LoadIntoDocument(asm.GetAssemblyResolver(), asm.GetAssemblyDefinitionAsync().Result, Data, cancellationToken);
XDocument xamlDocument = LoadIntoDocument(asm.GetAssemblyResolver(), asm.GetPEFileOrNull(), Data, cancellationToken);
output.Write(xamlDocument.ToString());
return true;
}
internal static XDocument LoadIntoDocument(IAssemblyResolver resolver, AssemblyDefinition asm, Stream stream, CancellationToken cancellationToken)
internal static XDocument LoadIntoDocument(PEFile module, Stream stream, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
XDocument xamlDocument;
using (XmlBamlReader reader = new XmlBamlReader(stream, new CecilTypeResolver(resolver, asm))) {
using (XmlBamlReader reader = new XmlBamlReader(stream, new NRTypeResolver(resolver, asm))) {
xamlDocument = XDocument.Load(reader);
ConvertConnectionIds(xamlDocument, asm, cancellationToken);
ConvertToEmptyElements(xamlDocument.Root);

5
ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs

@ -7,13 +7,14 @@ using System.IO; @@ -7,13 +7,14 @@ using System.IO;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy;
using ICSharpCode.Decompiler.Dom;
namespace ILSpy.BamlDecompiler
{
[Export(typeof(IResourceNodeFactory))]
public sealed class BamlResourceNodeFactory : IResourceNodeFactory
{
public ILSpyTreeNode CreateNode(Mono.Cecil.Resource resource)
public ILSpyTreeNode CreateNode(Resource resource)
{
return null;
}
@ -35,7 +36,7 @@ namespace ILSpy.BamlDecompiler @@ -35,7 +36,7 @@ namespace ILSpy.BamlDecompiler
public string WriteResourceToFile(LoadedAssembly assembly, string fileName, Stream stream, DecompilationOptions options)
{
var document = BamlResourceEntryNode.LoadIntoDocument(assembly.GetAssemblyResolver(), assembly.GetAssemblyDefinitionAsync().Result, stream, options.CancellationToken);
var document = BamlResourceEntryNode.LoadIntoDocument(assembly.GetAssemblyResolver(), assembly.GetPEFileOrNull(), stream, options.CancellationToken);
fileName = Path.ChangeExtension(fileName, ".xaml");
document.Save(Path.Combine(options.SaveAsProjectDirectory, fileName));
return fileName;

35
ILSpy.BamlDecompiler/CecilDependencyPropertyDescriptor.cs

@ -1,35 +0,0 @@ @@ -1,35 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
using System;
using System.Linq;
using Mono.Cecil;
using Ricciolo.StylesExplorer.MarkupReflection;
namespace ILSpy.BamlDecompiler
{
public class CecilDependencyPropertyDescriptor : IDependencyPropertyDescriptor
{
string member;
TypeDefinition type;
public CecilDependencyPropertyDescriptor(string member, TypeDefinition type)
{
if (type == null)
throw new ArgumentNullException("type");
this.member = member;
this.type = type;
}
public bool IsAttached {
get {
return type.Methods.Any(m => m.Name == "Get" + member);
}
}
public override string ToString()
{
return string.Format("[CecilDependencyPropertyDescriptor Member={0}, Type={1}]", member, type);
}
}
}

60
ILSpy.BamlDecompiler/CecilType.cs

@ -2,68 +2,49 @@ @@ -2,68 +2,49 @@
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
using System;
using System.Linq;
using ICSharpCode.Decompiler.TypeSystem;
using Mono.Cecil;
using Ricciolo.StylesExplorer.MarkupReflection;
namespace ILSpy.BamlDecompiler
{
public class CecilType : IType
public class NRType : IDotNetType
{
internal readonly TypeDefinition type;
readonly ITypeDefinition type;
public CecilType(TypeDefinition type)
public ITypeDefinition Type => type;
public NRType(ITypeDefinition type)
{
if (type == null)
throw new ArgumentNullException("type");
this.type = type;
this.type = type ?? throw new ArgumentNullException(nameof(type));
}
public string AssemblyQualifiedName {
get {
return type.FullName +
", " + type.Module.Assembly.FullName;
", " + type.ParentAssembly.FullAssemblyName;
}
}
public bool IsSubclassOf(IType type)
public bool IsSubclassOf(IDotNetType type)
{
if (type == null)
throw new ArgumentNullException("type");
if (!(type is CecilType))
throw new ArgumentNullException(nameof(type));
if (!(type is NRType baseType))
return false;
CecilType ct = (CecilType)type;
var t = this.type;
if (t == ct.type)
return false;
while (t != null) {
if (t == ct.type)
return true;
foreach (var @interface in t.Interfaces) {
var resolved = @interface.InterfaceType.Resolve();
if (resolved == ct.type)
return true;
}
if (t.BaseType == null)
break;
t = t.BaseType.Resolve();
}
return false;
return this.type.GetAllBaseTypeDefinitions().Any(t => t.Equals(baseType.type));
}
public bool Equals(IType type)
public bool Equals(IDotNetType type)
{
if (type == null)
throw new ArgumentNullException("type");
if (!(type is CecilType))
if (!(type is NRType))
return false;
return this.type == ((CecilType)type).type;
return this.type.Equals(((NRType)type).type);
}
public override string ToString()
@ -71,13 +52,14 @@ namespace ILSpy.BamlDecompiler @@ -71,13 +52,14 @@ namespace ILSpy.BamlDecompiler
return string.Format("[CecilType Type={0}]", type);
}
public IType BaseType {
public IDotNetType BaseType {
get {
TypeDefinition td = type.BaseType.Resolve();
var t = type.DirectBaseTypes.First();
var td = t.GetDefinition();
if (td == null)
throw new Exception("could not resolve '" + type.BaseType.FullName + "'!");
throw new Exception($"Could not resolve '{t.FullName}'!");
return new CecilType(td);
return new NRType(td);
}
}
}

54
ILSpy.BamlDecompiler/CecilTypeResolver.cs

@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
using System;
using ICSharpCode.Decompiler.TypeSystem;
using Mono.Cecil;
using Ricciolo.StylesExplorer.MarkupReflection;
@ -10,20 +11,18 @@ namespace ILSpy.BamlDecompiler @@ -10,20 +11,18 @@ namespace ILSpy.BamlDecompiler
/// <summary>
/// Description of CecilTypeResolver.
/// </summary>
public class CecilTypeResolver : ITypeResolver
public class NRTypeResolver : IDotNetTypeResolver
{
IAssemblyResolver resolver;
AssemblyDefinition thisAssembly;
readonly ICompilation compilation;
public CecilTypeResolver(IAssemblyResolver resolver, AssemblyDefinition asm)
public NRTypeResolver(ICompilation compilation)
{
this.resolver = resolver;
this.thisAssembly = asm;
this.compilation = compilation;
}
public bool IsLocalAssembly(string name)
{
return MakeShort(name) == this.thisAssembly.Name.Name;
return MakeShort(name) == compilation.MainAssembly.AssemblyName;
}
string MakeShort(string name)
@ -35,7 +34,7 @@ namespace ILSpy.BamlDecompiler @@ -35,7 +34,7 @@ namespace ILSpy.BamlDecompiler
return name.Substring(0, endOffset);
}
public IType GetTypeByAssemblyQualifiedName(string name)
public IDotNetType GetTypeByAssemblyQualifiedName(string name)
{
int bracket = name.LastIndexOf(']');
int comma = bracket > -1 ? name.IndexOf(',', bracket) : name.IndexOf(',');
@ -46,47 +45,21 @@ namespace ILSpy.BamlDecompiler @@ -46,47 +45,21 @@ namespace ILSpy.BamlDecompiler
string fullName = bracket > -1 ? name.Substring(0, name.IndexOf('[')) : name.Substring(0, comma);
string assemblyName = name.Substring(comma + 1).Trim();
var type = thisAssembly.MainModule.GetType(fullName);
if (type == null) {
type = TryFindInExportedTypes(fullName, thisAssembly);
}
if (type == null) {
var otherAssembly = resolver.Resolve(AssemblyNameReference.Parse(assemblyName));
if (otherAssembly == null)
return new UnresolvableType(name);
type = otherAssembly.MainModule.GetType(fullName.Replace('+', '/'));
if (type == null) {
type = TryFindInExportedTypes(fullName, otherAssembly);
}
}
var type = compilation.FindType(new FullTypeName(fullName)).GetDefinition();
if (type == null)
return new UnresolvableType(name);
return new CecilType(type);
}
TypeDefinition TryFindInExportedTypes(string fullName, AssemblyDefinition asm)
{
foreach (var exportedType in asm.MainModule.ExportedTypes) {
if (exportedType.IsForwarder && exportedType.FullName == fullName) {
return exportedType.Resolve();
}
}
return null;
return new NRType(type);
}
public IDependencyPropertyDescriptor GetDependencyPropertyDescriptor(string name, IType ownerType, IType targetType)
public IDependencyPropertyDescriptor GetDependencyPropertyDescriptor(string name, IDotNetType ownerType, IDotNetType targetType)
{
if (ownerType == null)
throw new ArgumentNullException("ownerType");
if (ownerType is CecilType)
return new CecilDependencyPropertyDescriptor(name, ((CecilType)ownerType).type);
if (ownerType is NRType)
return new NRTypeDependencyPropertyDescriptor(((NRType)ownerType).Type, name);
if (ownerType is UnresolvableType)
return new UnresolvableDependencyPropertyDescriptor();
@ -95,7 +68,8 @@ namespace ILSpy.BamlDecompiler @@ -95,7 +68,8 @@ namespace ILSpy.BamlDecompiler
public string RuntimeVersion {
get {
return thisAssembly.MainModule.Runtime.ToString();
throw new NotImplementedException();
//return thisAssembly.MainModule.Runtime.ToString();
}
}
}

2
ILSpy.BamlDecompiler/ILSpy.BamlDecompiler.csproj

@ -54,7 +54,7 @@ @@ -54,7 +54,7 @@
<ItemGroup>
<Compile Include="BamlResourceNodeFactory.cs" />
<Compile Include="BamlResourceEntryNode.cs" />
<Compile Include="CecilDependencyPropertyDescriptor.cs" />
<Compile Include="SRMDependencyPropertyDescriptor.cs" />
<Compile Include="CecilType.cs" />
<Compile Include="CecilTypeResolver.cs" />
<Compile Include="ConnectMethodDecompiler.cs" />

30
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/IType.cs

@ -7,41 +7,31 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -7,41 +7,31 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
/// <summary>
/// Interface representing a DotNet type
/// </summary>
public interface IType
public interface IDotNetType
{
IType BaseType { get; }
IDotNetType BaseType { get; }
string AssemblyQualifiedName { get; }
bool IsSubclassOf(IType type);
bool Equals(IType type);
bool IsSubclassOf(IDotNetType type);
bool Equals(IDotNetType type);
}
public class UnresolvableType : IType
public class UnresolvableType : IDotNetType
{
string assemblyQualifiedName;
public UnresolvableType(string assemblyQualifiedName)
{
this.assemblyQualifiedName = assemblyQualifiedName;
this.AssemblyQualifiedName = assemblyQualifiedName;
}
public IType BaseType {
get {
return null;
}
}
public IDotNetType BaseType => null;
public string AssemblyQualifiedName {
get {
return assemblyQualifiedName;
}
}
public string AssemblyQualifiedName { get; }
public bool IsSubclassOf(IType type)
public bool IsSubclassOf(IDotNetType type)
{
return Equals(type);
}
public bool Equals(IType type)
public bool Equals(IDotNetType type)
{
return type is UnresolvableType && type.AssemblyQualifiedName == AssemblyQualifiedName;
}

6
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/ITypeResolver.cs

@ -4,11 +4,11 @@ @@ -4,11 +4,11 @@
namespace Ricciolo.StylesExplorer.MarkupReflection
{
public interface ITypeResolver
public interface IDotNetTypeResolver
{
string RuntimeVersion { get; }
bool IsLocalAssembly(string name);
IType GetTypeByAssemblyQualifiedName(string name);
IDependencyPropertyDescriptor GetDependencyPropertyDescriptor(string name, IType ownerType, IType targetType);
IDotNetType GetTypeByAssemblyQualifiedName(string name);
IDependencyPropertyDescriptor GetDependencyPropertyDescriptor(string name, IDotNetType ownerType, IDotNetType targetType);
}
}

2
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/KnownInfo.cs

@ -31,7 +31,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -31,7 +31,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
{
}
public KnownInfo(ITypeResolver resolver)
public KnownInfo(IDotNetTypeResolver resolver)
{
switch (resolver.RuntimeVersion) {
case "Net_2_0":

18
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/TypeDeclaration.cs

@ -9,33 +9,33 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -9,33 +9,33 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
{
readonly XmlBamlReader reader;
readonly bool _isExtension;
IType _type;
IDotNetType _type;
bool _typeLoaded;
readonly ITypeResolver resolver;
readonly IDotNetTypeResolver resolver;
protected TypeDeclaration(ITypeResolver resolver)
protected TypeDeclaration(IDotNetTypeResolver resolver)
{
this.resolver = resolver;
}
public TypeDeclaration(ITypeResolver resolver, string name, string namespaceName, short assemblyId)
public TypeDeclaration(IDotNetTypeResolver resolver, string name, string namespaceName, short assemblyId)
: this(null, resolver, name, namespaceName, assemblyId)
{
}
public TypeDeclaration(ITypeResolver resolver, string name, string enclosingTypeName, string namespaceName, short assemblyId)
public TypeDeclaration(IDotNetTypeResolver resolver, string name, string enclosingTypeName, string namespaceName, short assemblyId)
: this(null, resolver, name, namespaceName, assemblyId)
{
this.EnclosingTypeName = enclosingTypeName;
}
public TypeDeclaration(ITypeResolver resolver, string name, string namespaceName, short assemblyId, bool isExtension)
public TypeDeclaration(IDotNetTypeResolver resolver, string name, string namespaceName, short assemblyId, bool isExtension)
: this(null, resolver, name, namespaceName, assemblyId)
{
_isExtension = isExtension;
}
public TypeDeclaration(XmlBamlReader reader, ITypeResolver resolver, string name, string namespaceName, short assemblyId)
public TypeDeclaration(XmlBamlReader reader, IDotNetTypeResolver resolver, string name, string namespaceName, short assemblyId)
{
this.reader = reader;
this.resolver = resolver;
@ -73,7 +73,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -73,7 +73,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
public virtual string Name { get; protected set; }
public IType Type {
public IDotNetType Type {
get {
if (!_typeLoaded) {
if (this.Name.Length > 0)
@ -119,7 +119,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -119,7 +119,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
protected set { throw new NotSupportedException(); }
}
public ResolverTypeDeclaration(ITypeResolver resolver, string assemblyQualifiedName)
public ResolverTypeDeclaration(IDotNetTypeResolver resolver, string assemblyQualifiedName)
: base(resolver)
{
string name, @namespace, assembly;

6
ILSpy.BamlDecompiler/Ricciolo.StylesExplorer.MarkupReflection/XmlBamlReader.cs

@ -22,7 +22,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -22,7 +22,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
Dictionary<short, TypeDeclaration> typeTable = new Dictionary<short, TypeDeclaration>();
Dictionary<short, PropertyDeclaration> propertyTable = new Dictionary<short, PropertyDeclaration>();
readonly ITypeResolver _resolver;
readonly IDotNetTypeResolver _resolver;
BamlRecordType currentType;
@ -99,7 +99,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -99,7 +99,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
public ISet<XmlNamespace> XmlnsDefinitions { get; } = new HashSet<XmlNamespace>();
public XmlBamlReader(Stream stream, ITypeResolver resolver)
public XmlBamlReader(Stream stream, IDotNetTypeResolver resolver)
{
if (stream == null)
throw new ArgumentNullException(nameof(stream));
@ -1626,7 +1626,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection @@ -1626,7 +1626,7 @@ namespace Ricciolo.StylesExplorer.MarkupReflection
/// <summary>
/// Returns object used to resolve types
/// </summary>
public ITypeResolver Resolver
public IDotNetTypeResolver Resolver
{
get { return _resolver; }
}

33
ILSpy.BamlDecompiler/SRMDependencyPropertyDescriptor.cs

@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
// This code is distributed under the MS-PL (for details please see \doc\MS-PL.txt)
using System;
using System.Linq;
using ICSharpCode.Decompiler.TypeSystem;
using Ricciolo.StylesExplorer.MarkupReflection;
namespace ILSpy.BamlDecompiler
{
public class NRTypeDependencyPropertyDescriptor : IDependencyPropertyDescriptor
{
readonly ITypeDefinition typeDefinition;
readonly string member;
public NRTypeDependencyPropertyDescriptor(ITypeDefinition type, string name)
{
this.typeDefinition = type;
this.member = name;
}
public bool IsAttached {
get {
return typeDefinition.GetMethods(m => m.Name == "Get" + member, GetMemberOptions.IgnoreInheritedMembers).Any();
}
}
public override string ToString()
{
return string.Format("[CecilDependencyPropertyDescriptor Member={0}, Type={1}]", member, typeDefinition);
}
}
}

14
ILSpy.sln

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26730.12
VisualStudioVersion = 15.0.27130.2026
MinimumVisualStudioVersion = 15.0
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "doc", "doc", "{F45DB999-7E72-4000-B5AD-3A7B485A0896}"
ProjectSection(SolutionItems) = preProject
@ -24,10 +24,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestPlugin", "TestPlugin\Te @@ -24,10 +24,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestPlugin", "TestPlugin\Te
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil.Pdb", "cecil\symbols\pdb\Mono.Cecil.Pdb.csproj", "{63E6915C-7EA4-4D76-AB28-0D7191EEA626}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILSpy.BamlDecompiler", "ILSpy.BamlDecompiler\ILSpy.BamlDecompiler.csproj", "{A6BAD2BA-76BA-461C-8B6D-418607591247}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILSpy.BamlDecompiler.Tests", "ILSpy.BamlDecompiler.Tests\ILSpy.BamlDecompiler.Tests.csproj", "{1169E6D1-1899-43D4-A500-07CE4235B388}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILSpy.AddIn", "ILSpy.AddIn\ILSpy.AddIn.csproj", "{9D7BE6C0-B7B3-4A50-A54E-18A2D84A3384}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0A344E19-D1FC-4F4C-8883-0844AC669113}"
@ -69,14 +65,6 @@ Global @@ -69,14 +65,6 @@ Global
{63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Debug|Any CPU.Build.0 = net_4_0_Debug|Any CPU
{63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Release|Any CPU.ActiveCfg = net_4_0_Release|Any CPU
{63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Release|Any CPU.Build.0 = net_4_0_Release|Any CPU
{A6BAD2BA-76BA-461C-8B6D-418607591247}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A6BAD2BA-76BA-461C-8B6D-418607591247}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A6BAD2BA-76BA-461C-8B6D-418607591247}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A6BAD2BA-76BA-461C-8B6D-418607591247}.Release|Any CPU.Build.0 = Release|Any CPU
{1169E6D1-1899-43D4-A500-07CE4235B388}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1169E6D1-1899-43D4-A500-07CE4235B388}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1169E6D1-1899-43D4-A500-07CE4235B388}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1169E6D1-1899-43D4-A500-07CE4235B388}.Release|Any CPU.Build.0 = Release|Any CPU
{9D7BE6C0-B7B3-4A50-A54E-18A2D84A3384}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9D7BE6C0-B7B3-4A50-A54E-18A2D84A3384}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9D7BE6C0-B7B3-4A50-A54E-18A2D84A3384}.Release|Any CPU.ActiveCfg = Release|Any CPU

2
ILSpy/Commands/DecompileAllCommand.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.
#if DEBUG
#if false && DEBUG
using System;
using System.Diagnostics;

10
ILSpy/DebugSteps.xaml.cs

@ -20,7 +20,7 @@ namespace ICSharpCode.ILSpy @@ -20,7 +20,7 @@ namespace ICSharpCode.ILSpy
public static ILAstWritingOptions Options => writingOptions;
#if DEBUG
#if false && DEBUG
ILAstLanguage language;
#endif
@ -28,7 +28,7 @@ namespace ICSharpCode.ILSpy @@ -28,7 +28,7 @@ namespace ICSharpCode.ILSpy
{
InitializeComponent();
#if DEBUG
#if false && DEBUG
MainWindow.Instance.SessionSettings.FilterSettings.PropertyChanged += FilterSettings_PropertyChanged;
MainWindow.Instance.SelectionChanged += SelectionChanged;
writingOptions.PropertyChanged += WritingOptions_PropertyChanged;
@ -56,7 +56,7 @@ namespace ICSharpCode.ILSpy @@ -56,7 +56,7 @@ namespace ICSharpCode.ILSpy
private void FilterSettings_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
#if DEBUG
#if false && DEBUG
if (e.PropertyName == "Language") {
if (language != null) {
language.StepperUpdated -= ILAstStepperUpdated;
@ -72,7 +72,7 @@ namespace ICSharpCode.ILSpy @@ -72,7 +72,7 @@ namespace ICSharpCode.ILSpy
private void ILAstStepperUpdated(object sender, EventArgs e)
{
#if DEBUG
#if false && DEBUG
if (language == null) return;
Dispatcher.Invoke(() => {
tree.ItemsSource = language.Stepper.Steps;
@ -88,7 +88,7 @@ namespace ICSharpCode.ILSpy @@ -88,7 +88,7 @@ namespace ICSharpCode.ILSpy
void IPane.Closed()
{
#if DEBUG
#if false && DEBUG
MainWindow.Instance.SessionSettings.FilterSettings.PropertyChanged -= FilterSettings_PropertyChanged;
MainWindow.Instance.SelectionChanged -= SelectionChanged;
writingOptions.PropertyChanged -= WritingOptions_PropertyChanged;

36
ILSpy/ExtensionMethods.cs

@ -102,12 +102,44 @@ namespace ICSharpCode.ILSpy @@ -102,12 +102,44 @@ namespace ICSharpCode.ILSpy
return false;
}
public static string ToSuffixString(this MetadataToken token)
public static string ToSuffixString(this System.Reflection.Metadata.MethodDefinitionHandle token)
{
if (!DisplaySettingsPanel.CurrentDisplaySettings.ShowMetadataTokens)
return string.Empty;
return " @" + token.ToInt32().ToString("x8");
return " @" + System.Reflection.Metadata.Ecma335.MetadataTokens.GetToken(token).ToString("x8");
}
public static string ToSuffixString(this System.Reflection.Metadata.PropertyDefinitionHandle 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.EventDefinitionHandle 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.FieldDefinitionHandle 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.TypeDefinitionHandle token)
{
if (!DisplaySettingsPanel.CurrentDisplaySettings.ShowMetadataTokens)
return string.Empty;
return " @" + System.Reflection.Metadata.Ecma335.MetadataTokens.GetToken(token).ToString("x8");
}
/// <summary>

39
ILSpy/ILSpy.csproj

@ -76,7 +76,6 @@ @@ -76,7 +76,6 @@
<Compile Include="AvalonEdit\ITextMarker.cs" />
<Compile Include="AvalonEdit\TextMarkerService.cs" />
<Compile Include="Cecil\CecilExtensions.cs" />
<Compile Include="Cecil\TypesHierarchyHelpers.cs" />
<Compile Include="Commands\CheckForUpdatesCommand.cs" />
<Compile Include="Commands\BrowseBackCommand.cs" />
<Compile Include="Commands\BrowseForwardCommand.cs" />
@ -127,6 +126,7 @@ @@ -127,6 +126,7 @@
<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" />
@ -181,28 +181,8 @@ @@ -181,28 +181,8 @@
<Compile Include="TextView\EditorCommands.cs" />
<Compile Include="TextView\FoldingCommands.cs" />
<Compile Include="TextView\XmlDocRenderer.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzeContextMenuEntry.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedAssemblyTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedAttributeAppliedToTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedEventOverridesTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedEventTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedInterfacePropertyImplementedByTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedInterfaceMethodImplementedByTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedInterfaceEventImplementedByTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedEventFiredByTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedPropertyAccessorTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedTypeExposedByTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedTypeExtensionMethodsTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedTypeInstantiationsTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedTypeTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedEventAccessorTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedTypeUsedByTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedVirtualMethodUsedByTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzerEntityTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzerSearchTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\RemoveAnalyzeContextMenuEntry.cs" />
<Compile Include="TreeNodes\Analyzer\Helpers.cs" />
<Compile Include="TreeNodes\Analyzer\ScopedWhereUsedAnalyzer.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzerTreeNode.cs" />
<Compile Include="TreeNodes\BaseTypesEntryNode.cs" />
<Compile Include="TreeNodes\CopyFullyQualifiedNameContextMenuEntry.cs" />
<Compile Include="TreeNodes\DerivedTypesEntryNode.cs" />
@ -213,12 +193,12 @@ @@ -213,12 +193,12 @@
<Compile Include="TreeNodes\ResourceNodes\IconResourceEntryNode.cs" />
<Compile Include="TreeNodes\ResourceNodes\ImageListResourceEntryNode.cs" />
<Compile Include="TreeNodes\ResourceNodes\ImageResourceEntryNode.cs" />
<Compile Include="TreeNodes\ResourceNodes\XmlResourceNode.cs" />
<Compile Include="TreeNodes\ResourceNodes\IResourceNodeFactory.cs" />
<Compile Include="TreeNodes\ResourceNodes\ResourceEntryNode.cs" />
<Compile Include="TreeNodes\ResourceNodes\ResourcesFileTreeNode.cs" />
<Compile Include="TreeNodes\ResourceNodes\ResourceTreeNode.cs" />
<Compile Include="TreeNodes\ResourceNodes\XamlResourceNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedPropertyOverridesTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedPropertyTreeNode.cs" />
<Compile Include="TreeNodes\ResourceNodes\XmlResourceNode.cs" />
<Compile Include="TreeNodes\SearchMsdnContextMenuEntry.cs" />
<EmbeddedResource Include="..\doc\LGPL.txt">
<Link>LGPL.txt</Link>
@ -264,13 +244,6 @@ @@ -264,13 +244,6 @@
<Compile Include="TextView\ReferenceElementGenerator.cs" />
<Compile Include="TextView\AvalonEditTextOutput.cs" />
<Compile Include="TextView\UIElementGenerator.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedFieldAccessTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedFieldTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedMethodTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedMethodUsedByTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedMethodUsesTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzerTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedMethodOverridesTreeNode.cs" />
<Compile Include="TreeNodes\AssemblyListTreeNode.cs" />
<Compile Include="TreeNodes\AssemblyReferenceTreeNode.cs" />
<Compile Include="TreeNodes\AssemblyTreeNode.cs" />
@ -284,9 +257,7 @@ @@ -284,9 +257,7 @@
<Compile Include="TreeNodes\NamespaceTreeNode.cs" />
<Compile Include="TreeNodes\PropertyTreeNode.cs" />
<Compile Include="TreeNodes\ReferenceFolderTreeNode.cs" />
<Compile Include="TreeNodes\ResourceNodes\ResourceEntryNode.cs" />
<Compile Include="TreeNodes\ResourceListTreeNode.cs" />
<Compile Include="TreeNodes\ResourceNodes\ResourceTreeNode.cs" />
<Compile Include="TreeNodes\ThreadingSupport.cs" />
<Compile Include="TreeNodes\TypeTreeNode.cs" />
<EmbeddedResource Include="README.txt" />

49
ILSpy/Languages/CSharpLanguage.cs

@ -23,23 +23,21 @@ using System.ComponentModel.Composition; @@ -23,23 +23,21 @@ using System.ComponentModel.Composition;
using System.IO;
using System.Linq;
using System.Resources;
using System.Windows;
using System.Windows.Controls;
using ICSharpCode.Decompiler;
using ICSharpCode.ILSpy.Options;
using Mono.Cecil;
using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.CSharp.OutputVisitor;
using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.CSharp.Transforms;
using ICSharpCode.Decompiler.TypeSystem;
using System.Windows;
using System.Windows.Controls;
using ICSharpCode.ILSpy.Options;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.Decompiler.CSharp.Transforms;
using ICSharpCode.AvalonEdit.Highlighting;
using System.Windows.Media;
using Mono.Cecil;
namespace ICSharpCode.ILSpy
{
#if false
/// <summary>
/// C# decompiler integration into ILSpy.
/// Note: if you're interested in using the decompiler without the ILSpy UI,
@ -252,40 +250,6 @@ namespace ICSharpCode.ILSpy @@ -252,40 +250,6 @@ namespace ICSharpCode.ILSpy
WriteCode(output, options.DecompilerSettings, decompiler.Decompile(type), decompiler.TypeSystem);
}
public static string GetPlatformDisplayName(ModuleDefinition module)
{
switch (module.Architecture) {
case TargetArchitecture.I386:
if ((module.Attributes & ModuleAttributes.Preferred32Bit) == ModuleAttributes.Preferred32Bit)
return "AnyCPU (32-bit preferred)";
else if ((module.Attributes & ModuleAttributes.Required32Bit) == ModuleAttributes.Required32Bit)
return "x86";
else
return "AnyCPU (64-bit preferred)";
case TargetArchitecture.AMD64:
return "x64";
case TargetArchitecture.IA64:
return "Itanium";
default:
return module.Architecture.ToString();
}
}
public static string GetRuntimeDisplayName(ModuleDefinition module)
{
switch (module.Runtime) {
case TargetRuntime.Net_1_0:
return ".NET 1.0";
case TargetRuntime.Net_1_1:
return ".NET 1.1";
case TargetRuntime.Net_2_0:
return ".NET 2.0";
case TargetRuntime.Net_4_0:
return ".NET 4.0";
}
return null;
}
void AddReferenceWarningMessage(AssemblyDefinition assembly, ITextOutput output)
{
var loadedAssembly = MainWindow.Instance.CurrentAssemblyList.GetAssemblies().FirstOrDefault(la => la.GetAssemblyDefinitionOrNull() == assembly);
@ -519,4 +483,5 @@ namespace ICSharpCode.ILSpy @@ -519,4 +483,5 @@ namespace ICSharpCode.ILSpy
return new CSharpAmbience() { ConversionFlags = flags }.ConvertSymbol(symbol);
}
}
#endif
}

4
ILSpy/Languages/ILAstLanguage.cs

@ -23,14 +23,14 @@ using System.Linq; @@ -23,14 +23,14 @@ using System.Linq;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.IL.Transforms;
using ICSharpCode.Decompiler.TypeSystem;
using Mono.Cecil;
namespace ICSharpCode.ILSpy
{
#if DEBUG
#if false && DEBUG
/// <summary>
/// Represents the ILAst "language" used for debugging purposes.
/// </summary>

96
ILSpy/Languages/ILLanguage.cs

@ -25,6 +25,7 @@ using System.Reflection.Metadata; @@ -25,6 +25,7 @@ using System.Reflection.Metadata;
using System.IO;
using System.Reflection.Metadata.Ecma335;
using System.Linq;
using ICSharpCode.Decompiler.Dom;
namespace ICSharpCode.ILSpy
{
@ -48,114 +49,99 @@ namespace ICSharpCode.ILSpy @@ -48,114 +49,99 @@ namespace ICSharpCode.ILSpy
get { return ".il"; }
}
protected virtual ReflectionDisassembler CreateDisassembler(ITextOutput output, PEReader reader, DecompilationOptions options)
protected virtual ReflectionDisassembler CreateDisassembler(ITextOutput output, DecompilationOptions options)
{
return new ReflectionDisassembler(output, reader, options.CancellationToken) {
return new ReflectionDisassembler(output, options.CancellationToken) {
DetectControlStructure = detectControlStructure,
ShowSequencePoints = options.DecompilerSettings.ShowDebugInfo
};
}
public override void DecompileMethod(Mono.Cecil.MethodDefinition method, ITextOutput output, DecompilationOptions options)
public override void DecompileMethod(Decompiler.Dom.MethodDefinition method, ITextOutput output, DecompilationOptions options)
{
using (var reader = new PEReader(new FileStream(method.Module.FileName, FileMode.Open, FileAccess.Read))) {
var dis = CreateDisassembler(output, reader, options);
dis.DisassembleMethod(MetadataTokens.MethodDefinitionHandle(method.MetadataToken.ToInt32()));
}
var dis = CreateDisassembler(output, options);
dis.DisassembleMethod(method);
}
public override void DecompileField(Mono.Cecil.FieldDefinition field, ITextOutput output, DecompilationOptions options)
public override void DecompileField(Decompiler.Dom.FieldDefinition field, ITextOutput output, DecompilationOptions options)
{
using (var reader = new PEReader(new FileStream(field.Module.FileName, FileMode.Open, FileAccess.Read))) {
var dis = CreateDisassembler(output, reader, options);
dis.DisassembleField(MetadataTokens.FieldDefinitionHandle(field.MetadataToken.ToInt32()));
}
var dis = CreateDisassembler(output, options);
dis.DisassembleField(field);
}
public override void DecompileProperty(Mono.Cecil.PropertyDefinition property, ITextOutput output, DecompilationOptions options)
public override void DecompileProperty(Decompiler.Dom.PropertyDefinition property, ITextOutput output, DecompilationOptions options)
{
using (var reader = new PEReader(new FileStream(property.Module.FileName, FileMode.Open, FileAccess.Read))) {
var dis = CreateDisassembler(output, reader, options);
dis.DisassembleProperty(MetadataTokens.PropertyDefinitionHandle(property.MetadataToken.ToInt32()));
var dis = CreateDisassembler(output, options);
dis.DisassembleProperty(property);
if (property.GetMethod != null) {
if (!property.GetMethod.IsNil) {
output.WriteLine();
dis.DisassembleMethod(MetadataTokens.MethodDefinitionHandle(property.GetMethod.MetadataToken.ToInt32()));
dis.DisassembleMethod(property.GetMethod);
}
if (property.SetMethod != null) {
if (!property.SetMethod.IsNil) {
output.WriteLine();
dis.DisassembleMethod(MetadataTokens.MethodDefinitionHandle(property.SetMethod.MetadataToken.ToInt32()));
dis.DisassembleMethod(property.SetMethod);
}
foreach (var m in property.OtherMethods) {
output.WriteLine();
dis.DisassembleMethod(MetadataTokens.MethodDefinitionHandle(m.MetadataToken.ToInt32()));
}
dis.DisassembleMethod(m);
}
}
public override void DecompileEvent(Mono.Cecil.EventDefinition ev, ITextOutput output, DecompilationOptions options)
public override void DecompileEvent(Decompiler.Dom.EventDefinition ev, ITextOutput output, DecompilationOptions options)
{
using (var reader = new PEReader(new FileStream(ev.Module.FileName, FileMode.Open, FileAccess.Read))) {
var dis = CreateDisassembler(output, reader, options);
dis.DisassembleEvent(MetadataTokens.EventDefinitionHandle(ev.MetadataToken.ToInt32()));
if (ev.AddMethod != null) {
var dis = CreateDisassembler(output, options);
dis.DisassembleEvent(ev);
if (!ev.AddMethod.IsNil) {
output.WriteLine();
dis.DisassembleMethod(MetadataTokens.MethodDefinitionHandle(ev.AddMethod.MetadataToken.ToInt32()));
dis.DisassembleMethod(ev.AddMethod);
}
if (ev.RemoveMethod != null) {
if (!ev.RemoveMethod.IsNil) {
output.WriteLine();
dis.DisassembleMethod(MetadataTokens.MethodDefinitionHandle(ev.RemoveMethod.MetadataToken.ToInt32()));
dis.DisassembleMethod(ev.RemoveMethod);
}
foreach (var m in ev.OtherMethods) {
output.WriteLine();
dis.DisassembleMethod(MetadataTokens.MethodDefinitionHandle(m.MetadataToken.ToInt32()));
}
dis.DisassembleMethod(m);
}
}
public override void DecompileType(Mono.Cecil.TypeDefinition type, ITextOutput output, DecompilationOptions options)
public override void DecompileType(Decompiler.Dom.TypeDefinition type, ITextOutput output, DecompilationOptions options)
{
using (var reader = new PEReader(new FileStream(type.Module.FileName, FileMode.Open, FileAccess.Read))) {
var dis = CreateDisassembler(output, reader, options);
dis.DisassembleType(MetadataTokens.TypeDefinitionHandle(type.MetadataToken.ToInt32()));
}
var dis = CreateDisassembler(output, options);
dis.DisassembleType(type);
}
public override void DecompileNamespace(string nameSpace, IEnumerable<Mono.Cecil.TypeDefinition> types, ITextOutput output, DecompilationOptions options)
public override void DecompileNamespace(string nameSpace, IEnumerable<Decompiler.Dom.TypeDefinition> types, ITextOutput output, DecompilationOptions options)
{
if (!types.Any())
return;
using (var reader = new PEReader(new FileStream(types.First().Module.FileName, FileMode.Open, FileAccess.Read))) {
var dis = CreateDisassembler(output, reader, options);
dis.DisassembleNamespace(nameSpace, types.Select(t => MetadataTokens.TypeDefinitionHandle(t.MetadataToken.ToInt32())));
}
var dis = CreateDisassembler(output, options);
dis.DisassembleNamespace(nameSpace, types);
}
public override void DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options)
{
output.WriteLine("// " + assembly.FileName);
output.WriteLine();
using (var reader = new PEReader(new FileStream(assembly.FileName, FileMode.Open, FileAccess.Read))) {
var dis = CreateDisassembler(output, reader, options);
var module = assembly.GetModuleDefinitionAsync().Result;
var module = assembly.GetPEFileOrNull();
var metadata = module.GetMetadataReader();
var dis = CreateDisassembler(output, options);
if (options.FullDecompilation)
dis.WriteAssemblyReferences();
if (module.Assembly != null)
dis.WriteAssemblyHeader();
dis.WriteAssemblyReferences(module);
if (metadata.IsAssembly)
dis.WriteAssemblyHeader(module);
output.WriteLine();
dis.WriteModuleHeader();
dis.WriteModuleHeader(module);
if (options.FullDecompilation) {
output.WriteLine();
output.WriteLine();
dis.WriteModuleContents(reader.GetMetadataReader().GetModuleDefinition());
}
dis.WriteModuleContents(module);
}
}
public override string TypeToString(Mono.Cecil.TypeReference type, bool includeNamespace, Mono.Cecil.ICustomAttributeProvider typeAttributes = null)
public override string TypeToString(Decompiler.Dom.ITypeReference type, bool includeNamespace, Decompiler.Dom.ICustomAttributeProvider typeAttributes = null)
{
PlainTextOutput output = new PlainTextOutput();
type.WriteTo(output, includeNamespace ? ILNameSyntax.TypeName : ILNameSyntax.ShortTypeName);
type.WriteTo(output, GenericContext.Empty, includeNamespace ? ILNameSyntax.TypeName : ILNameSyntax.ShortTypeName);
return output.ToString();
}
}

86
ILSpy/Languages/ITypeProvider.cs

@ -0,0 +1,86 @@ @@ -0,0 +1,86 @@
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();
}
}
}

242
ILSpy/Languages/Language.cs

@ -18,8 +18,13 @@ @@ -18,8 +18,13 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Reflection.PortableExecutable;
using ICSharpCode.Decompiler;
using Mono.Cecil;
using ICSharpCode.Decompiler.Dom;
using static System.Reflection.Metadata.PEReaderExtensions;
using SRM = System.Reflection.Metadata;
namespace ICSharpCode.ILSpy
{
@ -87,16 +92,18 @@ namespace ICSharpCode.ILSpy @@ -87,16 +92,18 @@ namespace ICSharpCode.ILSpy
public virtual void DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options)
{
WriteCommentLine(output, assembly.FileName);
var asm = assembly.GetAssemblyDefinitionOrNull();
if (asm != null) {
var name = asm.Name;
if (name.IsWindowsRuntime) {
var asm = assembly.GetPEFileOrNull();
if (asm == null) return;
var reader = asm.GetMetadataReader();
if (reader.IsAssembly) {
var name = reader.GetAssemblyDefinition();
if ((name.Flags & System.Reflection.AssemblyFlags.WindowsRuntime) != 0) {
WriteCommentLine(output, name.Name + " [WinRT]");
} else {
WriteCommentLine(output, name.FullName);
WriteCommentLine(output, reader.GetFullAssemblyName());
}
} else {
WriteCommentLine(output, assembly.GetModuleDefinitionAsync().Result.Name);
WriteCommentLine(output, reader.GetString(reader.GetModuleDefinition().Name));
}
}
@ -108,57 +115,69 @@ namespace ICSharpCode.ILSpy @@ -108,57 +115,69 @@ 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(TypeReference type, bool includeNamespace, ICustomAttributeProvider typeAttributes = null)
public virtual string TypeToString(ITypeReference type, bool includeNamespace, ICustomAttributeProvider typeAttributes = null)
{
if (includeNamespace)
return type.FullName;
return type.FullName.ToString();
else
return type.Name;
}
public virtual SRM.ISignatureTypeProvider<string, GenericContext> CreateSignatureTypeProvider(bool includeNamespace)
{
return new ILSignatureProvider(includeNamespace);
}
/// <summary>
/// Converts a member signature to a string.
/// This is used for displaying the tooltip on a member reference.
/// </summary>
public virtual string GetTooltip(MemberReference member)
public virtual string GetTooltip(IMemberReference member)
{
if (member is TypeReference)
return TypeToString((TypeReference)member, true);
else
return member.ToString();
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 FormatFieldName(FieldDefinition field)
{
if (field == null)
if (field.Handle.IsNil)
throw new ArgumentNullException(nameof(field));
return field.Name;
}
public virtual string FormatPropertyName(PropertyDefinition property, bool? isIndexer = null)
{
if (property == null)
if (property.Handle.IsNil)
throw new ArgumentNullException(nameof(property));
return property.Name;
}
public virtual string FormatMethodName(MethodDefinition method)
{
if (method == null)
if (method.Handle.IsNil)
throw new ArgumentNullException(nameof(method));
return method.Name;
}
public virtual string FormatEventName(EventDefinition @event)
{
if (@event == null)
if (@event.Handle.IsNil)
throw new ArgumentNullException(nameof(@event));
return @event.Name;
}
public virtual string FormatTypeName(TypeDefinition type)
{
if (type == null)
if (type.Handle.IsNil)
throw new ArgumentNullException(nameof(type));
return type.Name;
}
@ -171,7 +190,7 @@ namespace ICSharpCode.ILSpy @@ -171,7 +190,7 @@ namespace ICSharpCode.ILSpy
return Name;
}
public virtual bool ShowMember(MemberReference member)
public virtual bool ShowMember(IMemberReference member)
{
return true;
}
@ -179,9 +198,190 @@ namespace ICSharpCode.ILSpy @@ -179,9 +198,190 @@ namespace ICSharpCode.ILSpy
/// <summary>
/// Used by the analyzer to map compiler generated code back to the original code's location
/// </summary>
public virtual MemberReference GetOriginalCodeLocation(MemberReference member)
public virtual IMemberReference GetOriginalCodeLocation(IMemberReference member)
{
return member;
}
public static string GetPlatformDisplayName(PEFile module)
{
var architecture = module.Reader.PEHeaders.CoffHeader.Machine;
var flags = module.Reader.PEHeaders.CorHeader.Flags;
switch (architecture) {
case Machine.I386:
if ((flags & CorFlags.Prefers32Bit) != 0)
return "AnyCPU (32-bit preferred)";
else if ((flags & CorFlags.Requires32Bit) != 0)
return "x86";
else
return "AnyCPU (64-bit preferred)";
case Machine.Amd64:
return "x64";
case Machine.IA64:
return "Itanium";
default:
return architecture.ToString();
}
}
public static string GetRuntimeDisplayName(PEFile module)
{
string version = module.GetMetadataReader().MetadataVersion;
switch (version[1]) {
case '1':
if (version[3] == 1)
return ".NET 1.1";
else
return ".NET 1.0";
case '2':
return ".NET 2.0";
case '4':
return ".NET 4.0";
}
return null;
}
}
class ILSignatureProvider : SRM.ISignatureTypeProvider<string, GenericContext>
{
bool includeNamespace;
public ILSignatureProvider(bool includeNamespace)
{
this.includeNamespace = includeNamespace;
}
public string GetArrayType(string elementType, SRM.ArrayShape shape)
{
string printedShape = "";
for (int i = 0; i < shape.Rank; i++) {
if (i > 0)
printedShape += ", ";
if (i < shape.LowerBounds.Length || i < shape.Sizes.Length) {
int lower = 0;
if (i < shape.LowerBounds.Length) {
lower = shape.LowerBounds[i];
printedShape += lower.ToString();
}
printedShape += "...";
if (i < shape.Sizes.Length)
printedShape += (lower + shape.Sizes[i] - 1).ToString();
}
}
return $"{elementType}[{printedShape}]";
}
public string GetByReferenceType(string elementType)
{
return elementType + "&";
}
public string GetFunctionPointerType(SRM.MethodSignature<string> signature)
{
throw new NotImplementedException();
}
public string GetGenericInstantiation(string genericType, ImmutableArray<string> typeArguments)
{
return genericType + "<" + string.Join(", ", typeArguments) + ">";
}
public string GetGenericMethodParameter(GenericContext genericContext, int index)
{
return "!!" + genericContext.GetGenericMethodTypeParameterName(index);
}
public string GetGenericTypeParameter(GenericContext genericContext, int index)
{
return "!" + genericContext.GetGenericTypeParameterName(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)
{
switch (typeCode) {
case SRM.PrimitiveTypeCode.Boolean:
return "bool";
case SRM.PrimitiveTypeCode.Byte:
return "uint8";
case SRM.PrimitiveTypeCode.SByte:
return "int8";
case SRM.PrimitiveTypeCode.Char:
return "char";
case SRM.PrimitiveTypeCode.Int16:
return "int16";
case SRM.PrimitiveTypeCode.UInt16:
return "uint16";
case SRM.PrimitiveTypeCode.Int32:
return "int32";
case SRM.PrimitiveTypeCode.UInt32:
return "uint32";
case SRM.PrimitiveTypeCode.Int64:
return "int64";
case SRM.PrimitiveTypeCode.UInt64:
return "uint64";
case SRM.PrimitiveTypeCode.Single:
return "float32";
case SRM.PrimitiveTypeCode.Double:
return "float64";
case SRM.PrimitiveTypeCode.IntPtr:
return "native int";
case SRM.PrimitiveTypeCode.UIntPtr:
break;
case SRM.PrimitiveTypeCode.Object:
return "object";
case SRM.PrimitiveTypeCode.String:
return "string";
case SRM.PrimitiveTypeCode.TypedReference:
break;
case SRM.PrimitiveTypeCode.Void:
return "void";
default:
break;
}
throw new NotImplementedException();
}
public string GetSZArrayType(string elementType)
{
return elementType + "[]";
}
public string GetTypeFromDefinition(SRM.MetadataReader reader, SRM.TypeDefinitionHandle handle, byte rawTypeKind)
{
if (!includeNamespace) {
return Decompiler.Disassembler.DisassemblerHelpers.Escape(handle.GetFullTypeName(reader).Name);
}
return handle.GetFullTypeName(reader).ToILNameString();
}
public string GetTypeFromReference(SRM.MetadataReader reader, SRM.TypeReferenceHandle handle, byte rawTypeKind)
{
if (!includeNamespace) {
return Decompiler.Disassembler.DisassemblerHelpers.Escape(handle.GetFullTypeName(reader).Name);
}
return handle.GetFullTypeName(reader).ToILNameString();
}
public string GetTypeFromSpecification(SRM.MetadataReader reader, GenericContext genericContext, SRM.TypeSpecificationHandle handle, byte rawTypeKind)
{
return reader.GetTypeSpecification(handle).DecodeSignature(this, genericContext);
}
}
}

4
ILSpy/Languages/Languages.cs

@ -45,8 +45,8 @@ namespace ICSharpCode.ILSpy @@ -45,8 +45,8 @@ namespace ICSharpCode.ILSpy
languages.AddRange(composition.GetExportedValues<Language>());
languages.Sort((a, b) => a.Name.CompareTo(b.Name));
#if DEBUG
languages.AddRange(ILAstLanguage.GetDebugLanguages());
languages.AddRange(CSharpLanguage.GetDebugLanguages());
//languages.AddRange(ILAstLanguage.GetDebugLanguages());
//languages.AddRange(CSharpLanguage.GetDebugLanguages());
#endif
allLanguages = languages.AsReadOnly();
}

118
ILSpy/LoadedAssembly.cs

@ -19,13 +19,14 @@ @@ -19,13 +19,14 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection.PortableExecutable;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Threading;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.ILSpy.Options;
using Mono.Cecil;
using static System.Reflection.Metadata.PEReaderExtensions;
namespace ICSharpCode.ILSpy
{
@ -34,21 +35,17 @@ namespace ICSharpCode.ILSpy @@ -34,21 +35,17 @@ namespace ICSharpCode.ILSpy
/// </summary>
public sealed class LoadedAssembly
{
readonly Task<ModuleDefinition> assemblyTask;
readonly Task<PEFile> assemblyTask;
readonly AssemblyList assemblyList;
readonly string fileName;
readonly string shortName;
public LoadedAssembly(AssemblyList assemblyList, string fileName, Stream stream = null)
{
if (assemblyList == null)
throw new ArgumentNullException(nameof(assemblyList));
if (fileName == null)
throw new ArgumentNullException(nameof(fileName));
this.assemblyList = assemblyList;
this.fileName = fileName;
this.assemblyTask = Task.Factory.StartNew<ModuleDefinition>(LoadAssembly, stream); // requires that this.fileName is set
this.assemblyList = assemblyList ?? throw new ArgumentNullException(nameof(assemblyList));
this.fileName = fileName ?? throw new ArgumentNullException(nameof(fileName));
this.assemblyTask = Task.Factory.StartNew(LoadAssembly, stream); // requires that this.fileName is set
this.shortName = Path.GetFileNameWithoutExtension(fileName);
}
@ -58,8 +55,8 @@ namespace ICSharpCode.ILSpy @@ -58,8 +55,8 @@ namespace ICSharpCode.ILSpy
/// </summary>
public async Task<string> GetTargetFrameworkIdAsync()
{
var assembly = await GetAssemblyDefinitionAsync().ConfigureAwait(false);
return assembly?.DetectTargetFrameworkId() ?? string.Empty;
var assembly = await GetPEFileAsync().ConfigureAwait(false);
return assembly.Reader.DetectTargetFrameworkId() ?? string.Empty;
}
public ReferenceLoadInfo LoadedAssemblyReferencesInfo { get; } = new ReferenceLoadInfo();
@ -67,7 +64,7 @@ namespace ICSharpCode.ILSpy @@ -67,7 +64,7 @@ namespace ICSharpCode.ILSpy
/// <summary>
/// Gets the Cecil ModuleDefinition.
/// </summary>
public Task<ModuleDefinition> GetModuleDefinitionAsync()
public Task<PEFile> GetPEFileAsync()
{
return assemblyTask;
}
@ -76,33 +73,10 @@ namespace ICSharpCode.ILSpy @@ -76,33 +73,10 @@ namespace ICSharpCode.ILSpy
/// Gets the Cecil ModuleDefinition.
/// Returns null in case of load errors.
/// </summary>
public ModuleDefinition GetModuleDefinitionOrNull()
public PEFile GetPEFileOrNull()
{
try {
return GetModuleDefinitionAsync().Result;
} catch (Exception ex) {
System.Diagnostics.Trace.TraceError(ex.ToString());
return null;
}
}
/// <summary>
/// Gets the Cecil AssemblyDefinition.
/// </summary>
public async Task<AssemblyDefinition> GetAssemblyDefinitionAsync()
{
var module = await assemblyTask.ConfigureAwait(false);
return module != null ? module.Assembly : null;
}
/// <summary>
/// Gets the Cecil AssemblyDefinition.
/// Returns null when there was a load error; or when opening a netmodule.
/// </summary>
public AssemblyDefinition GetAssemblyDefinitionOrNull()
{
try {
return GetAssemblyDefinitionAsync().Result;
return GetPEFileAsync().Result;
} catch (Exception ex) {
System.Diagnostics.Trace.TraceError(ex.ToString());
return null;
@ -118,7 +92,7 @@ namespace ICSharpCode.ILSpy @@ -118,7 +92,7 @@ namespace ICSharpCode.ILSpy
public string Text {
get {
if (IsLoaded && !HasLoadError) {
string version = GetAssemblyDefinitionOrNull()?.Name.Version.ToString();
string version = GetPEFileOrNull()?.Reader.GetAssemblyDefinition()?.Version.ToString();
if (version == null)
return ShortName;
return String.Format("{0} ({1})", ShortName, version);
@ -134,25 +108,26 @@ namespace ICSharpCode.ILSpy @@ -134,25 +108,26 @@ namespace ICSharpCode.ILSpy
public bool IsAutoLoaded { get; set; }
ModuleDefinition LoadAssembly(object state)
PEFile LoadAssembly(object state)
{
var stream = state as Stream;
ModuleDefinition module;
PEReader module;
// runs on background thread
ReaderParameters p = new ReaderParameters();
p.AssemblyResolver = new MyAssemblyResolver(this);
p.InMemory = true;
if (stream != null)
{
// Read the module from a precrafted stream
module = ModuleDefinition.ReadModule(stream, p);
module = new PEReader(stream);
}
else
{
// Read the module from disk (by default)
module = ModuleDefinition.ReadModule(fileName, p);
using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read)) {
var ms = new MemoryStream();
fs.CopyTo(ms);
ms.Position = 0;
module = new PEReader(ms, PEStreamOptions.PrefetchEntireImage);
}
}
if (DecompilerSettingsPanel.CurrentDecompilerSettings.UseDebugSymbols) {
@ -164,17 +139,18 @@ namespace ICSharpCode.ILSpy @@ -164,17 +139,18 @@ namespace ICSharpCode.ILSpy
// ignore any errors during symbol loading
}
}
return module;
return new PEFile(fileName, module, new MyAssemblyResolver(this));
}
private void LoadSymbols(ModuleDefinition module)
private void LoadSymbols(PEReader reader)
{
if (!module.HasDebugHeader) {
/*string pdbDirectory = Path.GetDirectoryName(fileName);
if (!reader.TryOpenAssociatedPortablePdb(pdbDirectory, OpenStream, out var provider, out var pdbFileName) {
return;
}
// search for pdb in same directory as dll
string pdbName = Path.Combine(Path.GetDirectoryName(fileName), Path.GetFileNameWithoutExtension(fileName) + ".pdb");
string pdbName = Path.Combine(, Path.GetFileNameWithoutExtension(fileName) + ".pdb");
if (File.Exists(pdbName)) {
using (Stream s = File.OpenRead(pdbName)) {
module.ReadSymbols(new Mono.Cecil.Pdb.PdbReaderProvider().GetSymbolReader(module, s));
@ -183,6 +159,11 @@ namespace ICSharpCode.ILSpy @@ -183,6 +159,11 @@ namespace ICSharpCode.ILSpy
}
// TODO: use symbol cache, get symbols from microsoft
Stream OpenStream(string pdbFileName)
{
}*/
}
[ThreadStatic]
@ -218,18 +199,9 @@ namespace ICSharpCode.ILSpy @@ -218,18 +199,9 @@ namespace ICSharpCode.ILSpy
this.parent = parent;
}
public AssemblyDefinition Resolve(AssemblyNameReference name)
{
return parent.LookupReferencedAssembly(name)?.GetAssemblyDefinitionOrNull();
}
public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters)
{
return parent.LookupReferencedAssembly(name)?.GetAssemblyDefinitionOrNull();
}
public void Dispose()
public PEFile Resolve(IAssemblyReference reference)
{
return parent.LookupReferencedAssembly(reference)?.GetPEFileOrNull();
}
}
@ -238,14 +210,12 @@ namespace ICSharpCode.ILSpy @@ -238,14 +210,12 @@ namespace ICSharpCode.ILSpy
return new MyAssemblyResolver(this);
}
public LoadedAssembly LookupReferencedAssembly(AssemblyNameReference name)
public LoadedAssembly LookupReferencedAssembly(IAssemblyReference reference)
{
if (name == null)
throw new ArgumentNullException(nameof(name));
if (name.IsWindowsRuntime) {
return assemblyList.assemblyLookupCache.GetOrAdd((name.Name, true), LookupReferencedAssemblyInternal);
if (reference.IsWindowsRuntime) {
return assemblyList.assemblyLookupCache.GetOrAdd((reference.Name, true), LookupReferencedAssemblyInternal);
} else {
return assemblyList.assemblyLookupCache.GetOrAdd((name.FullName, false), LookupReferencedAssemblyInternal);
return assemblyList.assemblyLookupCache.GetOrAdd((reference.FullName, false), LookupReferencedAssemblyInternal);
}
}
@ -265,8 +235,10 @@ namespace ICSharpCode.ILSpy @@ -265,8 +235,10 @@ namespace ICSharpCode.ILSpy
LoadedAssembly asm;
lock (loadingAssemblies) {
foreach (LoadedAssembly loaded in assemblyList.GetAssemblies()) {
var asmDef = loaded.GetAssemblyDefinitionOrNull();
if (asmDef != null && data.fullName.Equals(data.isWinRT ? asmDef.Name.Name : asmDef.FullName, StringComparison.OrdinalIgnoreCase)) {
var reader = loaded.GetPEFileOrNull()?.GetMetadataReader();
if (reader == null || !reader.IsAssembly) continue;
var asmDef = reader.GetAssemblyDefinition();
if (data.fullName.Equals(data.isWinRT ? reader.GetString(asmDef.Name) : reader.GetFullAssemblyName(), StringComparison.OrdinalIgnoreCase)) {
LoadedAssemblyReferencesInfo.AddMessageOnce(data.fullName, MessageKind.Info, "Success - Found in Assembly List");
return loaded;
}
@ -312,7 +284,7 @@ namespace ICSharpCode.ILSpy @@ -312,7 +284,7 @@ namespace ICSharpCode.ILSpy
return asm;
}
public Task ContinueWhenLoaded(Action<Task<ModuleDefinition>> onAssemblyLoaded, TaskScheduler taskScheduler)
public Task ContinueWhenLoaded(Action<Task<PEFile>> onAssemblyLoaded, TaskScheduler taskScheduler)
{
return this.assemblyTask.ContinueWith(onAssemblyLoaded, default(CancellationToken), TaskContinuationOptions.RunContinuationsAsynchronously, taskScheduler);
}

19
ILSpy/MainWindow.xaml.cs

@ -38,7 +38,6 @@ using ICSharpCode.ILSpy.TextView; @@ -38,7 +38,6 @@ using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.TreeView;
using Microsoft.Win32;
using Mono.Cecil;
namespace ICSharpCode.ILSpy
{
@ -273,14 +272,14 @@ namespace ICSharpCode.ILSpy @@ -273,14 +272,14 @@ namespace ICSharpCode.ILSpy
}
} else {
foreach (LoadedAssembly asm in commandLineLoadedAssemblies) {
ModuleDefinition def = asm.GetModuleDefinitionOrNull();
var def = asm.GetPEFileOrNull();
if (def != null) {
MemberReference mr = XmlDocKeyProvider.FindMemberByKey(def, args.NavigateTo);
/*MemberReference mr = XmlDocKeyProvider.FindMemberByKey(def, args.NavigateTo);
if (mr != null) {
found = true;
JumpToReference(mr);
break;
}
}*/
}
}
}
@ -292,7 +291,7 @@ namespace ICSharpCode.ILSpy @@ -292,7 +291,7 @@ namespace ICSharpCode.ILSpy
} else if (commandLineLoadedAssemblies.Count == 1) {
// NavigateTo == null and an assembly was given on the command-line:
// Select the newly loaded assembly
JumpToReference(commandLineLoadedAssemblies[0].GetModuleDefinitionOrNull());
JumpToReference(commandLineLoadedAssemblies[0].GetPEFileOrNull());
}
if (args.Search != null)
{
@ -577,7 +576,7 @@ namespace ICSharpCode.ILSpy @@ -577,7 +576,7 @@ namespace ICSharpCode.ILSpy
public ILSpyTreeNode FindTreeNode(object reference)
{
if (reference is TypeReference)
/*if (reference is TypeReference)
{
return assemblyListTreeNode.FindTypeNode(((TypeReference)reference).Resolve());
}
@ -597,7 +596,7 @@ namespace ICSharpCode.ILSpy @@ -597,7 +596,7 @@ namespace ICSharpCode.ILSpy
{
return assemblyListTreeNode.FindEventNode(((EventReference)reference).Resolve());
}
else if (reference is AssemblyDefinition)
else if (reference is PEFile)
{
return assemblyListTreeNode.FindAssemblyNode((AssemblyDefinition)reference);
}
@ -607,12 +606,14 @@ namespace ICSharpCode.ILSpy @@ -607,12 +606,14 @@ namespace ICSharpCode.ILSpy
}
else if (reference is Resource)
{
return assemblyListTreeNode.FindResourceNode((Resource)reference);
return null;
//return assemblyListTreeNode.FindResourceNode((Resource)reference);
}
else
{
return null;
}
}*/
return null;
}
public void JumpToReference(object reference)

8
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.ILSpy.TreeNodes;
using Mono.Cecil;
@ -216,12 +216,12 @@ namespace ICSharpCode.ILSpy @@ -216,12 +216,12 @@ namespace ICSharpCode.ILSpy
try {
var searcher = GetSearchStrategy(searchMode, searchTerm);
foreach (var loadedAssembly in assemblies) {
ModuleDefinition module = loadedAssembly.GetModuleDefinitionOrNull();
var module = loadedAssembly.GetPEFileOrNull();
if (module == null)
continue;
CancellationToken cancellationToken = cts.Token;
foreach (TypeDefinition type in module.Types) {
foreach (var type in module.TypeDefinitions) {
cancellationToken.ThrowIfCancellationRequested();
searcher.Search(type, language, AddResult);
}
@ -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 MemberReference Member { get; set; }
public IMemberReference Member { get; set; }
public float Fitness { get; set; }
public string Location { get; set; }

113
ILSpy/SearchStrategies.cs

@ -3,11 +3,12 @@ using System.Collections.Generic; @@ -3,11 +3,12 @@ using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Media;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
using ICSharpCode.ILSpy.TreeNodes;
using Mono.Cecil;
using Code = Mono.Cecil.Cil.Code;
using ICSharpCode.Decompiler.Dom;
using System.Reflection;
using ICSharpCode.Decompiler.Disassembler;
using ILOpCode = System.Reflection.Metadata.ILOpCode;
namespace ICSharpCode.ILSpy
{
@ -37,7 +38,7 @@ namespace ICSharpCode.ILSpy @@ -37,7 +38,7 @@ namespace ICSharpCode.ILSpy
searchTerm = terms;
}
protected float CalculateFitness(MemberReference member)
protected float CalculateFitness(IMemberReference member)
{
string text = member.Name;
@ -49,11 +50,11 @@ namespace ICSharpCode.ILSpy @@ -49,11 +50,11 @@ namespace ICSharpCode.ILSpy
// Constructors always have the same name in IL:
// Use type name instead
if (text == ".cctor" || text == ".ctor") {
text = member.DeclaringType.Name;
//text = member.DeclaringType.Name;
}
// Ignore generic arguments, it not possible to search based on them either
text = ReflectionHelper.SplitTypeParameterCountFromReflectionName(text);
text = Decompiler.TypeSystem.ReflectionHelper.SplitTypeParameterCountFromReflectionName(text);
return 1.0f / text.Length;
}
@ -139,7 +140,7 @@ namespace ICSharpCode.ILSpy @@ -139,7 +140,7 @@ namespace ICSharpCode.ILSpy
}
}
void Add<T>(IEnumerable<T> items, TypeDefinition type, Language language, Action<SearchResult> addResult, Func<T, Language, bool> matcher, Func<T, ImageSource> image) where T : MemberReference
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
{
foreach (var item in items) {
if (matcher(item, language)) {
@ -170,12 +171,12 @@ namespace ICSharpCode.ILSpy @@ -170,12 +171,12 @@ namespace ICSharpCode.ILSpy
bool NotSpecialMethod(MethodDefinition arg)
{
return (arg.SemanticsAttributes & (
return (arg.GetMethodSemanticsAttributes() & (
MethodSemanticsAttributes.Setter
| MethodSemanticsAttributes.Getter
| MethodSemanticsAttributes.AddOn
| MethodSemanticsAttributes.RemoveOn
| MethodSemanticsAttributes.Fire)) == 0;
| MethodSemanticsAttributes.Adder
| MethodSemanticsAttributes.Remover
| MethodSemanticsAttributes.Raiser)) == 0;
}
Regex SafeNewRegex(string unsafePattern)
@ -227,7 +228,7 @@ namespace ICSharpCode.ILSpy @@ -227,7 +228,7 @@ namespace ICSharpCode.ILSpy
protected override bool IsMatch(FieldDefinition field, Language language)
{
return IsLiteralMatch(field.Constant);
return IsLiteralMatch(field.DecodeConstant());
}
protected override bool IsMatch(PropertyDefinition property, Language language)
@ -268,91 +269,115 @@ namespace ICSharpCode.ILSpy @@ -268,91 +269,115 @@ namespace ICSharpCode.ILSpy
bool MethodIsLiteralMatch(MethodDefinition m)
{
if (m == null)
return false;
var body = m.Body;
if (body == null)
if (m == null || !m.HasBody)
return false;
var blob = m.Body.GetILReader();
if (searchTermLiteralType == TypeCode.Int64) {
long val = (long)searchTermLiteralValue;
foreach (var inst in body.Instructions) {
switch (inst.OpCode.Code) {
case Code.Ldc_I8:
if (val == (long)inst.Operand)
while (blob.RemainingBytes > 0) {
ILOpCode code;
switch (code = ILParser.DecodeOpCode(ref blob)) {
case ILOpCode.Ldc_i8:
if (val == blob.ReadInt64())
return true;
break;
case Code.Ldc_I4:
if (val == (int)inst.Operand)
case ILOpCode.Ldc_i4:
if (val == blob.ReadInt32())
return true;
break;
case Code.Ldc_I4_S:
if (val == (sbyte)inst.Operand)
case ILOpCode.Ldc_i4_s:
if (val == blob.ReadSByte())
return true;
break;
case Code.Ldc_I4_M1:
case ILOpCode.Ldc_i4_m1:
if (val == -1)
return true;
break;
case Code.Ldc_I4_0:
case ILOpCode.Ldc_i4_0:
if (val == 0)
return true;
break;
case Code.Ldc_I4_1:
case ILOpCode.Ldc_i4_1:
if (val == 1)
return true;
break;
case Code.Ldc_I4_2:
case ILOpCode.Ldc_i4_2:
if (val == 2)
return true;
break;
case Code.Ldc_I4_3:
case ILOpCode.Ldc_i4_3:
if (val == 3)
return true;
break;
case Code.Ldc_I4_4:
case ILOpCode.Ldc_i4_4:
if (val == 4)
return true;
break;
case Code.Ldc_I4_5:
case ILOpCode.Ldc_i4_5:
if (val == 5)
return true;
break;
case Code.Ldc_I4_6:
case ILOpCode.Ldc_i4_6:
if (val == 6)
return true;
break;
case Code.Ldc_I4_7:
case ILOpCode.Ldc_i4_7:
if (val == 7)
return true;
break;
case Code.Ldc_I4_8:
case ILOpCode.Ldc_i4_8:
if (val == 8)
return true;
break;
default:
ILParser.SkipOperand(ref blob, code);
break;
}
}
} else if (searchTermLiteralType != TypeCode.Empty) {
Code expectedCode;
ILOpCode expectedCode;
switch (searchTermLiteralType) {
case TypeCode.Single:
expectedCode = Code.Ldc_R4;
expectedCode = ILOpCode.Ldc_r4;
break;
case TypeCode.Double:
expectedCode = Code.Ldc_R8;
expectedCode = ILOpCode.Ldc_r8;
break;
case TypeCode.String:
expectedCode = Code.Ldstr;
expectedCode = ILOpCode.Ldstr;
break;
default:
throw new InvalidOperationException();
}
foreach (var inst in body.Instructions) {
if (inst.OpCode.Code == expectedCode && searchTermLiteralValue.Equals(inst.Operand))
while (blob.RemainingBytes > 0) {
var code = ILParser.DecodeOpCode(ref blob);
if (code != expectedCode) {
ILParser.SkipOperand(ref blob, code);
continue;
}
switch (code) {
case ILOpCode.Ldc_r4:
if ((float)searchTermLiteralValue == blob.ReadSingle())
return true;
break;
case ILOpCode.Ldc_r8:
if ((double)searchTermLiteralValue == blob.ReadDouble())
return true;
break;
case ILOpCode.Ldstr:
if ((string)searchTermLiteralValue == ILParser.DecodeUserString(ref blob, m.Module))
return true;
break;
}
}
} else {
foreach (var inst in body.Instructions) {
if (inst.OpCode.Code == Code.Ldstr && IsMatch(t => (string)inst.Operand))
while (blob.RemainingBytes > 0) {
var code = ILParser.DecodeOpCode(ref blob);
if (code != ILOpCode.Ldstr) {
ILParser.SkipOperand(ref blob, code);
continue;
}
if (IsMatch(t => ILParser.DecodeUserString(ref blob, m.Module)))
return true;
}
}
@ -450,8 +475,8 @@ namespace ICSharpCode.ILSpy @@ -450,8 +475,8 @@ namespace ICSharpCode.ILSpy
Image = TypeTreeNode.GetIcon(type),
Fitness = CalculateFitness(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 = !type.DeclaringType.IsNil ? TypeTreeNode.GetIcon(type.DeclaringType) : Images.Namespace,
Location = !type.DeclaringType.IsNil ? language.TypeToString(type.DeclaringType, includeNamespace: true) : type.Namespace
});
}

6
ILSpy/TextView/DecompilerTextView.cs

@ -200,12 +200,12 @@ namespace ICSharpCode.ILSpy.TextView @@ -200,12 +200,12 @@ namespace ICSharpCode.ILSpy.TextView
string documentation = docProvider.GetDocumentation("F:System.Reflection.Emit.OpCodes." + code.EncodedName);
if (documentation != null) {
XmlDocRenderer renderer = new XmlDocRenderer();
renderer.AppendText($"{code.Name} (0x{code.Code:x2}) - ");
renderer.AppendText($"{code.Name} (0x{code.Code:x}) - ");
renderer.AddXmlDocumentation(documentation);
return renderer.CreateTextBlock();
}
}
return $"{code.Name} (0x{code.Code:x2})";
return $"{code.Name} (0x{code.Code:x})";
} else if (segment.Reference is MemberReference) {
MemberReference mr = (MemberReference)segment.Reference;
// if possible, resolve the reference
@ -215,7 +215,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -215,7 +215,7 @@ namespace ICSharpCode.ILSpy.TextView
mr = ((MethodReference)mr).Resolve() ?? mr;
}
XmlDocRenderer renderer = new XmlDocRenderer();
renderer.AppendText(MainWindow.Instance.CurrentLanguage.GetTooltip(mr));
//renderer.AppendText(MainWindow.Instance.CurrentLanguage.GetTooltip(mr));
try {
XmlDocumentationProvider docProvider = XmlDocLoader.LoadDocumentation(mr.Module);
if (docProvider != null) {

51
ILSpy/TreeNodes/Analyzer/AnalyzeContextMenuEntry.cs

@ -17,7 +17,7 @@ @@ -17,7 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System.Linq;
using Mono.Cecil;
using ICSharpCode.Decompiler.Dom;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
@ -62,32 +62,31 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -62,32 +62,31 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
}
}
public static void Analyze(MemberReference member)
public static void Analyze(IMemberReference member)
{
if (member is TypeReference) {
TypeDefinition type = ((TypeReference)member).Resolve();
if (type != null)
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedTypeTreeNode(type));
}
else if (member is FieldReference) {
FieldDefinition field = ((FieldReference)member).Resolve();
if (field != null)
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedFieldTreeNode(field));
}
else if (member is MethodReference) {
MethodDefinition method = ((MethodReference)member).Resolve();
if (method != null)
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedMethodTreeNode(method));
}
else if (member is PropertyReference) {
PropertyDefinition property = ((PropertyReference)member).Resolve();
if (property != null)
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedPropertyTreeNode(property));
}
else if (member is EventReference) {
EventDefinition @event = ((EventReference)member).Resolve();
if (@event != null)
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedEventTreeNode(@event));
var definition = member.GetDefinition();
if (definition == null) return;
switch (definition) {
case TypeDefinition td:
if (!td.IsNil)
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedTypeTreeNode(td));
break;
case FieldDefinition fd:
if (!fd.IsNil)
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedFieldTreeNode(fd));
break;
case MethodDefinition md:
if (!md.IsNil)
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedMethodTreeNode(md));
break;
case PropertyDefinition pd:
if (!pd.IsNil)
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedPropertyTreeNode(pd));
break;
case EventDefinition ed:
if (!ed.IsNil)
AnalyzerTreeView.Instance.ShowOrFocus(new AnalyzedEventTreeNode(ed));
break;
}
}
}

24
ILSpy/TreeNodes/Analyzer/AnalyzedAssemblyTreeNode.cs

@ -17,15 +17,15 @@ @@ -17,15 +17,15 @@
// DEALINGS IN THE SOFTWARE.
using System;
using Mono.Cecil;
using ICSharpCode.Decompiler.Dom;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
internal class AnalyzedAssemblyTreeNode : AnalyzerEntityTreeNode
{
private readonly ModuleDefinition analyzedAssembly;
private readonly PEFile analyzedAssembly;
public AnalyzedAssemblyTreeNode(ModuleDefinition analyzedAssembly)
public AnalyzedAssemblyTreeNode(PEFile analyzedAssembly)
{
if (analyzedAssembly == null)
throw new ArgumentNullException(nameof(analyzedAssembly));
@ -33,27 +33,15 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -33,27 +33,15 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
//this.LazyLoading = true;
}
public override object Icon
{
get { return Images.Assembly; }
}
public override object Icon => Images.Assembly;
public override object Text
{
get
{
return analyzedAssembly.Name;
}
}
public override object Text => analyzedAssembly.Name;
protected override void LoadChildren()
{
//this.Children.Add(new AnalyzedAssemblyReferencedByTreeNode(analyzedAssembly));
}
public override MemberReference Member
{
get { return null; }
}
public override IMemberReference Member => null;
}
}

6
ILSpy/TreeNodes/Analyzer/AnalyzedAttributeAppliedToTreeNode.cs

@ -20,9 +20,9 @@ using System; @@ -20,9 +20,9 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Mono.Cecil;
using System.Collections.Concurrent;
using ICSharpCode.Decompiler.Util;
using ICSharpCode.Decompiler.Dom;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
@ -43,7 +43,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -43,7 +43,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
public AnalyzedAttributeAppliedToTreeNode(TypeDefinition analyzedType)
{
if (analyzedType == null)
if (analyzedType.IsNil)
throw new ArgumentNullException(nameof(analyzedType));
this.analyzedType = analyzedType;
@ -103,7 +103,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -103,7 +103,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
#region standard custom attributes
private IEnumerable<AnalyzerTreeNode> FindReferencesInAssembly(ModuleDefinition module, TypeReference tr, CancellationToken ct)
private IEnumerable<AnalyzerTreeNode> FindReferencesInAssembly(PEFile module, TypeReference tr, CancellationToken ct)
{
//since we do not display modules as separate entities, coalesce the assembly and module searches
bool foundInAssyOrModule = false;

2
ILSpy/TreeNodes/Analyzer/AnalyzedEventAccessorTreeNode.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 Mono.Cecil;
using ICSharpCode.Decompiler.Dom;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{

13
ILSpy/TreeNodes/Analyzer/AnalyzedEventOverridesTreeNode.cs

@ -19,9 +19,10 @@ @@ -19,9 +19,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
using ICSharpCode.Decompiler.TypeSystem;
using Mono.Cecil;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.Dom;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
@ -31,7 +32,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -31,7 +32,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
public AnalyzedEventOverridesTreeNode(EventDefinition analyzedEvent)
{
if (analyzedEvent == null)
if (analyzedEvent.IsNil)
throw new ArgumentNullException(nameof(analyzedEvent));
this.analyzedEvent = analyzedEvent;
@ -50,7 +51,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -50,7 +51,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
private IEnumerable<AnalyzerTreeNode> FindReferencesInType(TypeDefinition type)
{
if (!TypesHierarchyHelpers.IsBaseType(analyzedEvent.DeclaringType, type, resolveTypeArguments: false))
if (!analyzedEvent.DeclaringType.IsBaseTypeOf(type))
yield break;
foreach (EventDefinition eventDef in type.Events) {
@ -66,8 +67,8 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -66,8 +67,8 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
public static bool CanShow(EventDefinition property)
{
var accessor = property.AddMethod ?? property.RemoveMethod;
return accessor.IsVirtual && !accessor.IsFinal && !accessor.DeclaringType.IsInterface;
var accessor = property.GetAccessors().First().Method;
return accessor.HasFlag(MethodAttributes.Virtual) && !accessor.HasFlag(MethodAttributes.Final) && !accessor.DeclaringType.IsInterface;
}
}
}

14
ILSpy/TreeNodes/Analyzer/AnalyzedEventTreeNode.cs

@ -17,7 +17,8 @@ @@ -17,7 +17,8 @@
// DEALINGS IN THE SOFTWARE.
using System;
using Mono.Cecil;
using System.Linq;
using ICSharpCode.Decompiler.Dom;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
@ -35,9 +36,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -35,9 +36,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
this.LazyLoading = true;
}
public override MemberReference Member {
get { return analyzedEvent; }
}
public override IMemberReference Member => analyzedEvent;
public override object Icon
{
@ -82,13 +81,12 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -82,13 +81,12 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
return null;
}
public static bool CanShow(MemberReference member)
public static bool CanShow(IMemberReference member)
{
var eventDef = member as EventDefinition;
if (eventDef == null)
if (!(member is EventDefinition eventDef))
return false;
return !MainWindow.Instance.CurrentLanguage.ShowMember(eventDef.AddMethod ?? eventDef.RemoveMethod)
return !MainWindow.Instance.CurrentLanguage.ShowMember(eventDef.GetAccessors().First().Method)
|| AnalyzedEventOverridesTreeNode.CanShow(eventDef);
}
}

51
ILSpy/TreeNodes/Analyzer/AnalyzedFieldAccessTreeNode.cs

@ -21,8 +21,10 @@ using System.Collections; @@ -21,8 +21,10 @@ using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Mono.Cecil;
using Mono.Cecil.Cil;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.Dom;
using ILOpCode = System.Reflection.Metadata.ILOpCode;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
@ -35,7 +37,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -35,7 +37,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
public AnalyzedFieldAccessTreeNode(FieldDefinition analyzedField, bool showWrites)
{
if (analyzedField == null)
if (analyzedField.IsNil)
throw new ArgumentNullException(nameof(analyzedField));
this.analyzedField = analyzedField;
@ -67,24 +69,27 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -67,24 +69,27 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
bool found = false;
if (!method.HasBody)
continue;
foreach (Instruction instr in method.Body.Instructions) {
if (CanBeReference(instr.OpCode.Code)) {
FieldReference fr = instr.Operand as FieldReference;
if (fr != null && fr.Name == name &&
Helpers.IsReferencedBy(analyzedField.DeclaringType, fr.DeclaringType) &&
fr.Resolve() == analyzedField) {
var blob = method.Body.GetILReader();
while (blob.RemainingBytes > 0) {
var opCode = ILParser.DecodeOpCode(ref blob);
if (!CanBeReference(opCode)) {
ILParser.SkipOperand(ref blob, opCode);
continue;
}
var field = ILParser.DecodeMemberToken(ref blob, method.Module);
if (field == null || field.Name != name)
continue;
var definition = field.GetDefinition() as FieldDefinition?;
if (definition?.DeclaringType.FullName != analyzedField.DeclaringType.FullName)
continue;
found = true;
break;
}
}
}
method.Body = null;
if (found) {
MethodDefinition codeLocation = this.Language.GetOriginalCodeLocation(method) as MethodDefinition;
if (codeLocation != null && !HasAlreadyBeenFound(codeLocation)) {
var node = new AnalyzedMethodTreeNode(codeLocation);
MethodDefinition? codeLocation = this.Language.GetOriginalCodeLocation(method) as MethodDefinition?;
if (codeLocation != null && !HasAlreadyBeenFound(codeLocation.Value)) {
var node = new AnalyzedMethodTreeNode(codeLocation.Value);
node.Language = this.Language;
yield return node;
}
@ -92,17 +97,17 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -92,17 +97,17 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
}
}
private bool CanBeReference(Code code)
private bool CanBeReference(ILOpCode code)
{
switch (code) {
case Code.Ldfld:
case Code.Ldsfld:
case ILOpCode.Ldfld:
case ILOpCode.Ldsfld:
return !showWrites;
case Code.Stfld:
case Code.Stsfld:
case ILOpCode.Stfld:
case ILOpCode.Stsfld:
return showWrites;
case Code.Ldflda:
case Code.Ldsflda:
case ILOpCode.Ldflda:
case ILOpCode.Ldsflda:
return true; // always show address-loading
default:
return false;

13
ILSpy/TreeNodes/Analyzer/AnalyzedFieldTreeNode.cs

@ -17,7 +17,7 @@ @@ -17,7 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System;
using Mono.Cecil;
using ICSharpCode.Decompiler.Dom;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
@ -27,16 +27,13 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -27,16 +27,13 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
public AnalyzedFieldTreeNode(FieldDefinition analyzedField)
{
if (analyzedField == null)
if (analyzedField.IsNil)
throw new ArgumentNullException(nameof(analyzedField));
this.analyzedField = analyzedField;
this.LazyLoading = true;
}
public override object Icon
{
get { return FieldTreeNode.GetIcon(analyzedField); }
}
public override object Icon => FieldTreeNode.GetIcon(analyzedField);
public override object Text
{
@ -54,8 +51,6 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -54,8 +51,6 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
this.Children.Add(new AnalyzedFieldAccessTreeNode(analyzedField, true));
}
public override MemberReference Member {
get { return analyzedField; }
}
public override IMemberReference Member => analyzedField;
}
}

11
ILSpy/TreeNodes/Analyzer/AnalyzedMethodTreeNode.cs

@ -17,7 +17,8 @@ @@ -17,7 +17,8 @@
// DEALINGS IN THE SOFTWARE.
using System;
using Mono.Cecil;
using System.Reflection;
using ICSharpCode.Decompiler.Dom;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
@ -28,7 +29,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -28,7 +29,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
public AnalyzedMethodTreeNode(MethodDefinition analyzedMethod, string prefix = "")
{
if (analyzedMethod == null)
if (analyzedMethod.IsNil)
throw new ArgumentNullException(nameof(analyzedMethod));
this.analyzedMethod = analyzedMethod;
this.prefix = prefix;
@ -53,7 +54,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -53,7 +54,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
if (analyzedMethod.HasBody)
this.Children.Add(new AnalyzedMethodUsesTreeNode(analyzedMethod));
if (analyzedMethod.IsVirtual && !(analyzedMethod.IsNewSlot && analyzedMethod.IsFinal))
if (analyzedMethod.HasFlag(MethodAttributes.Virtual) && !(analyzedMethod.HasFlag(MethodAttributes.NewSlot) && analyzedMethod.HasFlag(MethodAttributes.Final)))
this.Children.Add(new AnalyzedVirtualMethodUsedByTreeNode(analyzedMethod));
else
this.Children.Add(new AnalyzedMethodUsedByTreeNode(analyzedMethod));
@ -65,8 +66,6 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -65,8 +66,6 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
this.Children.Add(new AnalyzedInterfaceMethodImplementedByTreeNode(analyzedMethod));
}
public override MemberReference Member {
get { return analyzedMethod; }
}
public override IMemberReference Member => analyzedMethod;
}
}

2
ILSpy/TreeNodes/Analyzer/AnalyzedMethodUsedByTreeNode.cs

@ -66,7 +66,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -66,7 +66,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
foreach (Instruction instr in method.Body.Instructions) {
MethodReference mr = instr.Operand as MethodReference;
if (mr != null && mr.Name == name &&
Helpers.IsReferencedBy(analyzedMethod.DeclaringType, mr.DeclaringType) &&
Helpers.IsSameType(analyzedMethod.DeclaringType, mr.DeclaringType) &&
mr.Resolve() == analyzedMethod) {
found = true;
break;

51
ILSpy/TreeNodes/Analyzer/AnalyzedMethodUsesTreeNode.cs

@ -20,8 +20,9 @@ using System; @@ -20,8 +20,9 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Mono.Cecil;
using Mono.Cecil.Cil;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.IL;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
@ -34,7 +35,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -34,7 +35,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
public AnalyzedMethodUsesTreeNode(MethodDefinition analyzedMethod)
{
if (analyzedMethod == null)
if (analyzedMethod.IsNil)
throw new ArgumentNullException(nameof(analyzedMethod));
this.analyzedMethod = analyzedMethod;
@ -61,24 +62,42 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -61,24 +62,42 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
private IEnumerable<MethodDefinition> GetUsedMethods()
{
foreach (Instruction instr in analyzedMethod.Body.Instructions) {
MethodReference mr = instr.Operand as MethodReference;
if (mr != null) {
MethodDefinition def = mr.Resolve();
if (def != null)
yield return def;
if (!analyzedMethod.HasBody) yield break;
var blob = analyzedMethod.Body.GetILReader();
while (blob.RemainingBytes > 0) {
var opCode = ILParser.DecodeOpCode(ref blob);
switch (opCode.GetOperandType()) {
case OperandType.Method:
case OperandType.Sig:
case OperandType.Tok:
var member = ILParser.DecodeMemberToken(ref blob, analyzedMethod.Module).GetDefinition();
if (member is MethodDefinition md)
yield return md;
break;
default:
ILParser.SkipOperand(ref blob, opCode);
break;
}
}
}
private IEnumerable<FieldDefinition> GetUsedFields()
IEnumerable<FieldDefinition> GetUsedFields()
{
foreach (Instruction instr in analyzedMethod.Body.Instructions) {
FieldReference fr = instr.Operand as FieldReference;
if (fr != null) {
FieldDefinition def = fr.Resolve();
if (def != null)
yield return def;
if (!analyzedMethod.HasBody) yield break;
var blob = analyzedMethod.Body.GetILReader();
while (blob.RemainingBytes > 0) {
var opCode = ILParser.DecodeOpCode(ref blob);
switch (opCode.GetOperandType()) {
case OperandType.Field:
case OperandType.Sig:
case OperandType.Tok:
var member = ILParser.DecodeMemberToken(ref blob, analyzedMethod.Module).GetDefinition();
if (member is FieldDefinition fd)
yield return fd;
break;
default:
ILParser.SkipOperand(ref blob, opCode);
break;
}
}
}

2
ILSpy/TreeNodes/Analyzer/AnalyzedPropertyAccessorTreeNode.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 Mono.Cecil;
using ICSharpCode.Decompiler.Dom;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{

13
ILSpy/TreeNodes/Analyzer/AnalyzedPropertyOverridesTreeNode.cs

@ -19,9 +19,10 @@ @@ -19,9 +19,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
using ICSharpCode.Decompiler.TypeSystem;
using Mono.Cecil;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.Dom;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
@ -50,11 +51,11 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -50,11 +51,11 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
private IEnumerable<AnalyzerTreeNode> FindReferencesInType(TypeDefinition type)
{
if (!TypesHierarchyHelpers.IsBaseType(analyzedProperty.DeclaringType, type, resolveTypeArguments: false))
if (!analyzedProperty.DeclaringType.IsBaseTypeOf(type))
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;
@ -67,8 +68,8 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -67,8 +68,8 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
public static bool CanShow(PropertyDefinition property)
{
var accessor = property.GetMethod ?? property.SetMethod;
return accessor.IsVirtual && !accessor.IsFinal && !accessor.DeclaringType.IsInterface;
var accessor = property.GetAccessors().First().Method;
return accessor.HasFlag(MethodAttributes.Virtual) && !accessor.HasFlag(MethodAttributes.Final) && !accessor.DeclaringType.IsInterface;
}
}
}

23
ILSpy/TreeNodes/Analyzer/AnalyzedPropertyTreeNode.cs

@ -18,7 +18,7 @@ @@ -18,7 +18,7 @@
using System;
using ICSharpCode.Decompiler;
using Mono.Cecil;
using ICSharpCode.Decompiler.Dom;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
@ -32,7 +32,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -32,7 +32,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
if (analyzedProperty == null)
throw new ArgumentNullException(nameof(analyzedProperty));
this.isIndexer = analyzedProperty.IsIndexer();
this.isIndexer = analyzedProperty.IsIndexer;
this.analyzedProperty = analyzedProperty;
this.prefix = prefix;
this.LazyLoading = true;
@ -54,9 +54,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -54,9 +54,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
protected override void LoadChildren()
{
if (analyzedProperty.GetMethod != null)
if (!analyzedProperty.GetMethod.IsNil)
this.Children.Add(new AnalyzedPropertyAccessorTreeNode(analyzedProperty.GetMethod, "get"));
if (analyzedProperty.SetMethod != null)
if (!analyzedProperty.SetMethod.IsNil)
this.Children.Add(new AnalyzedPropertyAccessorTreeNode(analyzedProperty.SetMethod, "set"));
foreach (var accessor in analyzedProperty.OtherMethods)
this.Children.Add(new AnalyzedPropertyAccessorTreeNode(accessor, null));
@ -67,26 +67,23 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -67,26 +67,23 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
this.Children.Add(new AnalyzedInterfacePropertyImplementedByTreeNode(analyzedProperty));
}
public static AnalyzerTreeNode TryCreateAnalyzer(MemberReference member)
public static AnalyzerTreeNode TryCreateAnalyzer(IMemberReference member)
{
if (CanShow(member))
return new AnalyzedPropertyTreeNode(member as PropertyDefinition);
return new AnalyzedPropertyTreeNode((PropertyDefinition)member);
else
return null;
}
public static bool CanShow(MemberReference member)
public static bool CanShow(IMemberReference member)
{
var property = member as PropertyDefinition;
if (property == null)
if (!(member is PropertyDefinition property))
return false;
return !MainWindow.Instance.CurrentLanguage.ShowMember(property.GetMethod ?? property.SetMethod)
return !MainWindow.Instance.CurrentLanguage.ShowMember(property.GetMethod.IsNil ? property.SetMethod : property.GetMethod)
|| AnalyzedPropertyOverridesTreeNode.CanShow(property);
}
public override MemberReference Member {
get { return analyzedProperty; }
}
public override IMemberReference Member => analyzedProperty;
}
}

11
ILSpy/TreeNodes/Analyzer/AnalyzedTypeExposedByTreeNode.cs

@ -19,8 +19,9 @@ @@ -19,8 +19,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
using Mono.Cecil;
using ICSharpCode.Decompiler.Dom;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
@ -30,7 +31,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -30,7 +31,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
public AnalyzedTypeExposedByTreeNode(TypeDefinition analyzedType)
{
if (analyzedType == null)
if (analyzedType.IsNil)
throw new ArgumentNullException(nameof(analyzedType));
this.analyzedType = analyzedType;
@ -135,7 +136,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -135,7 +136,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
// exclude methods with 'semantics'. for example, property getters & setters.
// HACK: this is a potentially fragile implementation, as the MethodSemantics may be extended to other uses at a later date.
if (method.SemanticsAttributes != MethodSemanticsAttributes.None)
if (method.GetMethodSemanticsAttributes() != 0)
return false;
if (method.ReturnType.Resolve() == analyzedType)
@ -153,8 +154,8 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -153,8 +154,8 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
private static bool IsPrivate(PropertyDefinition property)
{
bool isGetterPublic = (property.GetMethod != null && !property.GetMethod.IsPrivate);
bool isSetterPublic = (property.SetMethod != null && !property.SetMethod.IsPrivate);
bool isGetterPublic = (!property.GetMethod.IsNil && !property.GetMethod.IsPrivate);
bool isSetterPublic = (!property.SetMethod.IsNil && !property.SetMethod.IsPrivate);
return !(isGetterPublic || isSetterPublic);
}

39
ILSpy/TreeNodes/Analyzer/AnalyzedTypeInstantiationsTreeNode.cs

@ -19,10 +19,11 @@ @@ -19,10 +19,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
using ICSharpCode.Decompiler.TypeSystem;
using Mono.Cecil;
using Mono.Cecil.Cil;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.IL;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
@ -33,12 +34,12 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -33,12 +34,12 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
public AnalyzedTypeInstantiationsTreeNode(TypeDefinition analyzedType)
{
if (analyzedType == null)
if (analyzedType.IsNil)
throw new ArgumentNullException(nameof(analyzedType));
this.analyzedType = analyzedType;
this.isSystemObject = (analyzedType.FullName == "System.Object");
this.isSystemObject = (analyzedType.FullName.ToString() == "System.Object");
}
public override object Text
@ -61,22 +62,30 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -61,22 +62,30 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
// ignore chained constructors
// (since object is the root of everything, we can short circuit the test in this case)
if (method.Name == ".ctor" &&
(isSystemObject || analyzedType == type || TypesHierarchyHelpers.IsBaseType(analyzedType, type, false)))
if (method.IsConstructor && (isSystemObject || analyzedType == type || analyzedType.IsBaseTypeOf(type)))
continue;
foreach (Instruction instr in method.Body.Instructions) {
MethodReference mr = instr.Operand as MethodReference;
if (mr != null && mr.Name == ".ctor") {
if (Helpers.IsReferencedBy(analyzedType, mr.DeclaringType)) {
var blob = method.Body.GetILReader();
while (!found && blob.RemainingBytes > 0) {
var opCode = ILParser.DecodeOpCode(ref blob);
switch (opCode.GetOperandType()) {
case OperandType.Method:
case OperandType.Sig:
case OperandType.Tok:
var member = ILParser.DecodeMemberToken(ref blob, method.Module);
if (member.Name == ".ctor") {
if (member.DeclaringType.FullName == analyzedType.FullName) {
found = true;
break;
}
}
break;
default:
ILParser.SkipOperand(ref blob, opCode);
break;
}
}
method.Body = null;
if (found) {
var node = new AnalyzedMethodTreeNode(method);
node.Language = this.Language;
@ -87,7 +96,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -87,7 +96,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
public static bool CanShow(TypeDefinition type)
{
return (type.IsClass && !(type.IsAbstract && type.IsSealed) && !type.IsEnum);
return (type.IsClass && !(type.HasFlag(TypeAttributes.Abstract) && type.HasFlag(TypeAttributes.Sealed)) && !type.IsEnum);
}
}
}

8
ILSpy/TreeNodes/Analyzer/AnalyzedTypeTreeNode.cs

@ -17,7 +17,7 @@ @@ -17,7 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System;
using Mono.Cecil;
using ICSharpCode.Decompiler.Dom;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
@ -27,7 +27,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -27,7 +27,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
public AnalyzedTypeTreeNode(TypeDefinition analyzedType)
{
if (analyzedType == null)
if (analyzedType.IsNil)
throw new ArgumentNullException(nameof(analyzedType));
this.analyzedType = analyzedType;
this.LazyLoading = true;
@ -64,8 +64,6 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -64,8 +64,6 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
this.Children.Add(new AnalyzedTypeExtensionMethodsTreeNode(analyzedType));
}
public override MemberReference Member {
get { return analyzedType; }
}
public override IMemberReference Member => analyzedType;
}
}

26
ILSpy/TreeNodes/Analyzer/AnalyzedTypeUsedByTreeNode.cs

@ -20,7 +20,9 @@ using System; @@ -20,7 +20,9 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Mono.Cecil;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
@ -30,7 +32,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -30,7 +32,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
public AnalyzedTypeUsedByTreeNode(TypeDefinition analyzedType)
{
if (analyzedType == null)
if (analyzedType.IsNil)
throw new ArgumentNullException(nameof(analyzedType));
this.analyzedType = analyzedType;
@ -46,7 +48,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -46,7 +48,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
var analyzer = new ScopedWhereUsedAnalyzer<AnalyzerTreeNode>(analyzedType, FindTypeUsage);
return analyzer.PerformAnalysis(ct)
.Cast<AnalyzerEntityTreeNode>()
.Where(n => n.Member.DeclaringType != analyzedType)
.Where(n => n.Member.DeclaringType.FullName != analyzedType.FullName)
.Distinct(new AnalyzerEntityTreeNodeComparer())
.OrderBy(n => n.Text);
}
@ -59,7 +61,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -59,7 +61,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
if (IsUsedInTypeDefinition(type))
yield return new AnalyzedTypeTreeNode(type) { Language = Language };
foreach (var field in type.Fields.Where(IsUsedInFieldReference))
foreach (var field in type.Fields.Where(IsUsedInField))
yield return new AnalyzedFieldTreeNode(field) { Language = Language };
foreach (var method in type.Methods.Where(IsUsedInMethodDefinition))
@ -80,7 +82,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -80,7 +82,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
return types.Any(IsUsedInTypeReference);
}
private bool IsUsedInTypeReference(TypeReference type)
private bool IsUsedInTypeReference(ITypeReference type)
{
if (type == null)
return false;
@ -96,16 +98,14 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -96,16 +98,14 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
|| IsUsedInTypeReferences(type.Interfaces.Select(i => i.InterfaceType));
}
private bool IsUsedInFieldReference(FieldReference field)
private bool IsUsedInField(FieldDefinition field)
{
if (field == null)
return false;
if (field.IsNil) return false;
return TypeMatches(field.DeclaringType)
|| TypeMatches(field.FieldType);
return TypeMatches(field.DeclaringType) || field.DecodeSignature(new TypeUsedInSignature(analyzedType), default(Unit));
}
private bool IsUsedInMethodReference(MethodReference method)
private bool IsUsedInMethod(MethodDefinition method)
{
if (method == null)
return false;
@ -161,10 +161,10 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -161,10 +161,10 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
return TypeMatches(parameter.ParameterType);
}
private bool TypeMatches(TypeReference tref)
private bool TypeMatches(ITypeReference tref)
{
if (tref != null && tref.Name == analyzedType.Name) {
var tdef = tref.Resolve();
var tdef = tref.GetDefinition();
if (tdef != null) {
return (tdef == analyzedType);
}

2
ILSpy/TreeNodes/Analyzer/AnalyzedVirtualMethodUsedByTreeNode.cs

@ -97,7 +97,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -97,7 +97,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
if (mr != null && mr.Name == name) {
// explicit call to the requested method
if (instr.OpCode.Code == Code.Call
&& Helpers.IsReferencedBy(analyzedMethod.DeclaringType, mr.DeclaringType)
&& Helpers.IsSameType(analyzedMethod.DeclaringType, mr.DeclaringType)
&& mr.Resolve() == analyzedMethod) {
found = true;
prefix = "(as base) ";

6
ILSpy/TreeNodes/Analyzer/AnalyzerEntityTreeNode.cs

@ -17,8 +17,8 @@ @@ -17,8 +17,8 @@
// DEALINGS IN THE SOFTWARE.
using System.Collections.Generic;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.TreeView;
using Mono.Cecil;
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 MemberReference Member { get; }
public abstract IMemberReference Member { get; }
public override void ActivateItem(System.Windows.RoutedEventArgs e)
{
@ -38,7 +38,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -38,7 +38,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
public override bool HandleAssemblyListChanged(ICollection<LoadedAssembly> removedAssemblies, ICollection<LoadedAssembly> addedAssemblies)
{
foreach (LoadedAssembly asm in removedAssemblies) {
if (this.Member.Module == asm.GetModuleDefinitionOrNull())
if (this.Member.Module == asm.GetPEFileOrNull())
return false; // remove this node
}
this.Children.RemoveAll(

4
ILSpy/TreeNodes/Analyzer/AnalyzerSearchTreeNode.cs

@ -16,8 +16,12 @@ @@ -16,8 +16,12 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Reflection.Metadata;
using System.Threading;
using ICSharpCode.Decompiler.Disassembler;
using Dom = ICSharpCode.Decompiler.Dom;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{

6
ILSpy/TreeNodes/Analyzer/Helpers.cs

@ -26,7 +26,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -26,7 +26,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
internal static class Helpers
{
public static bool IsReferencedBy(TypeDefinition type, TypeReference typeRef)
public static bool IsSameType(TypeDefinition type, TypeReference typeRef)
{
// TODO: move it to a better place after adding support for more cases.
if (type == null)
@ -44,7 +44,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -44,7 +44,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
if (type.DeclaringType != null || typeRef.DeclaringType != null) {
if (type.DeclaringType == null || typeRef.DeclaringType == null)
return false;
if (!IsReferencedBy(type.DeclaringType, typeRef.DeclaringType))
if (!IsSameType(type.DeclaringType, typeRef.DeclaringType))
return false;
}
@ -105,7 +105,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -105,7 +105,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
foreach (Instruction instr in method.Body.Instructions) {
MethodReference mr = instr.Operand as MethodReference;
if (mr != null && mr.Name == name &&
IsReferencedBy(analyzedMethod.DeclaringType, mr.DeclaringType) &&
IsSameType(analyzedMethod.DeclaringType, mr.DeclaringType) &&
mr.Resolve() == analyzedMethod) {
found = true;
break;

53
ILSpy/TreeNodes/Analyzer/ScopedWhereUsedAnalyzer.cs

@ -19,9 +19,12 @@ @@ -19,9 +19,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.Decompiler.Util;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
@ -30,8 +33,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -30,8 +33,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
/// </summary>
internal class ScopedWhereUsedAnalyzer<T>
{
private readonly AssemblyDefinition assemblyScope;
private readonly PEFile assemblyScope;
private TypeDefinition typeScope;
private static readonly TypeSystemAttributeTypeProvider typeProvider = TypeSystemAttributeTypeProvider.CreateDefault();
private readonly Accessibility memberAccessibility = Accessibility.Public;
private Accessibility typeAccessibility = Accessibility.Public;
@ -40,7 +44,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -40,7 +44,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
public ScopedWhereUsedAnalyzer(TypeDefinition type, Func<TypeDefinition, IEnumerable<T>> typeAnalysisFunction)
{
this.typeScope = type;
this.assemblyScope = type.Module.Assembly;
this.assemblyScope = type.Module;
this.typeAnalysisFunction = typeAnalysisFunction;
}
@ -53,8 +57,8 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -53,8 +57,8 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
public ScopedWhereUsedAnalyzer(PropertyDefinition property, Func<TypeDefinition, IEnumerable<T>> typeAnalysisFunction)
: this(property.DeclaringType, typeAnalysisFunction)
{
Accessibility getterAccessibility = (property.GetMethod == null) ? Accessibility.Private : GetMethodAccessibility(property.GetMethod);
Accessibility setterAccessibility = (property.SetMethod == null) ? Accessibility.Private : GetMethodAccessibility(property.SetMethod);
Accessibility getterAccessibility = (property.GetMethod.IsNil) ? Accessibility.Private : GetMethodAccessibility(property.GetMethod);
Accessibility setterAccessibility = (property.SetMethod.IsNil) ? Accessibility.Private : GetMethodAccessibility(property.SetMethod);
this.memberAccessibility = (Accessibility)Math.Max((int)getterAccessibility, (int)setterAccessibility);
}
@ -142,7 +146,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -142,7 +146,7 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
private void DetermineTypeAccessibility()
{
while (typeScope.IsNested) {
while (!typeScope.DeclaringType.IsNil) {
Accessibility accessibility = GetNestedTypeAccessibility(typeScope);
if ((int)typeAccessibility > (int)accessibility) {
typeAccessibility = accessibility;
@ -215,9 +219,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -215,9 +219,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
return assemblies.AsParallel().WithCancellation(ct).SelectMany(asm => FindReferencesInAssembly(asm, ct));
}
private IEnumerable<T> FindReferencesInAssembly(AssemblyDefinition asm, CancellationToken ct)
private IEnumerable<T> FindReferencesInAssembly(PEFile asm, CancellationToken ct)
{
foreach (TypeDefinition type in TreeTraversal.PreOrder(asm.MainModule.Types, t => t.NestedTypes)) {
foreach (TypeDefinition type in TreeTraversal.PreOrder(asm.TypeDefinitions, t => t.NestedTypes)) {
ct.ThrowIfCancellationRequested();
foreach (var result in typeAnalysisFunction(type)) {
ct.ThrowIfCancellationRequested();
@ -248,41 +252,41 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -248,41 +252,41 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
}
}
private IEnumerable<AssemblyDefinition> GetReferencingAssemblies(AssemblyDefinition asm, CancellationToken ct)
private IEnumerable<PEFile> GetReferencingAssemblies(PEFile asm, CancellationToken ct)
{
yield return asm;
string requiredAssemblyFullName = asm.FullName;
IEnumerable<LoadedAssembly> assemblies = MainWindow.Instance.CurrentAssemblyList.GetAssemblies().Where(assy => assy.GetAssemblyDefinitionOrNull() != null);
IEnumerable<LoadedAssembly> assemblies = MainWindow.Instance.CurrentAssemblyList.GetAssemblies().Where(assy => assy.GetPEFileOrNull()?.IsAssembly == true);
foreach (var assembly in assemblies) {
ct.ThrowIfCancellationRequested();
bool found = false;
var module = assembly.GetModuleDefinitionOrNull();
var module = assembly.GetPEFileOrNull();
if (module == null)
continue;
var metadata = module.GetMetadataReader();
foreach (var reference in module.AssemblyReferences) {
if (requiredAssemblyFullName == reference.FullName) {
found = true;
break;
}
}
if (found && AssemblyReferencesScopeType(module.Assembly))
yield return module.Assembly;
if (found && AssemblyReferencesScopeType(module))
yield return module;
}
}
private IEnumerable<AssemblyDefinition> GetAssemblyAndAnyFriends(AssemblyDefinition asm, CancellationToken ct)
private IEnumerable<PEFile> GetAssemblyAndAnyFriends(PEFile asm, CancellationToken ct)
{
yield return asm;
var reader = asm.GetMetadataReader();
if (asm.HasCustomAttributes) {
var attributes = asm.CustomAttributes
.Where(attr => attr.AttributeType.FullName == "System.Runtime.CompilerServices.InternalsVisibleToAttribute");
var attributes = reader.CustomAttributes.Select(h => reader.GetCustomAttribute(h)).Where(ca => ca.GetAttributeType(asm).FullName.ToString() == "System.Runtime.CompilerServices.InternalsVisibleToAttribute");
var friendAssemblies = new HashSet<string>();
foreach (var attribute in attributes) {
string assemblyName = attribute.ConstructorArguments[0].Value as string;
string assemblyName = attribute.DecodeValue(typeProvider).FixedArguments[0].Value as string;
assemblyName = assemblyName.Split(',')[0]; // strip off any public key info
friendAssemblies.Add(assemblyName);
}
@ -293,22 +297,21 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer @@ -293,22 +297,21 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
foreach (var assembly in assemblies) {
ct.ThrowIfCancellationRequested();
if (friendAssemblies.Contains(assembly.ShortName)) {
var module = assembly.GetModuleDefinitionOrNull();
var module = assembly.GetPEFileOrNull();
if (module == null)
continue;
if (AssemblyReferencesScopeType(module.Assembly))
yield return module.Assembly;
}
if (AssemblyReferencesScopeType(module))
yield return module;
}
}
}
}
private bool AssemblyReferencesScopeType(AssemblyDefinition asm)
private bool AssemblyReferencesScopeType(PEFile asm)
{
bool hasRef = false;
foreach (var typeref in asm.MainModule.GetTypeReferences()) {
if (typeref.Name == typeScope.Name && typeref.Namespace == typeScope.Namespace) {
foreach (var typeRef in asm.TypeReferences) {
if (typeRef.Name == typeScope.Name && typeRef.Namespace == typeScope.Namespace) {
hasRef = true;
break;
}

37
ILSpy/TreeNodes/AssemblyListTreeNode.cs

@ -22,10 +22,11 @@ using System.Collections.ObjectModel; @@ -22,10 +22,11 @@ using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Reflection.PortableExecutable;
using System.Windows;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.TreeView;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes
{
@ -153,7 +154,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -153,7 +154,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
}
#region Find*Node
/*
public ILSpyTreeNode FindResourceNode(Resource resource)
{
if (resource == null)
@ -177,27 +178,15 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -177,27 +178,15 @@ namespace ICSharpCode.ILSpy.TreeNodes
}
return null;
}
*/
public AssemblyTreeNode FindAssemblyNode(ModuleDefinition module)
public AssemblyTreeNode FindAssemblyNode(PEFile module)
{
if (module == null)
return null;
App.Current.Dispatcher.VerifyAccess();
foreach (AssemblyTreeNode node in this.Children) {
if (node.LoadedAssembly.IsLoaded && node.LoadedAssembly.GetModuleDefinitionOrNull() == module)
return node;
}
return null;
}
public AssemblyTreeNode FindAssemblyNode(AssemblyDefinition asm)
{
if (asm == null)
return null;
App.Current.Dispatcher.VerifyAccess();
foreach (AssemblyTreeNode node in this.Children) {
if (node.LoadedAssembly.IsLoaded && node.LoadedAssembly.GetAssemblyDefinitionOrNull() == asm)
if (node.LoadedAssembly.IsLoaded && node.LoadedAssembly.GetPEFileOrNull() == module)
return node;
}
return null;
@ -221,16 +210,14 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -221,16 +210,14 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// </summary>
public TypeTreeNode FindTypeNode(TypeDefinition def)
{
if (def == null)
return null;
if (def.DeclaringType != null) {
if (!def.DeclaringType.IsNil) {
TypeTreeNode decl = FindTypeNode(def.DeclaringType);
if (decl != null) {
decl.EnsureLazyChildren();
return decl.Children.OfType<TypeTreeNode>().FirstOrDefault(t => t.TypeDefinition == def && !t.IsHidden);
}
} else {
AssemblyTreeNode asm = FindAssemblyNode(def.Module.Assembly);
AssemblyTreeNode asm = FindAssemblyNode(def.Module);
if (asm != null) {
return asm.FindTypeNode(def);
}
@ -244,8 +231,6 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -244,8 +231,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// </summary>
public ILSpyTreeNode FindMethodNode(MethodDefinition def)
{
if (def == null)
return null;
TypeTreeNode typeNode = FindTypeNode(def.DeclaringType);
if (typeNode == null)
return null;
@ -281,8 +266,6 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -281,8 +266,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// </summary>
public FieldTreeNode FindFieldNode(FieldDefinition def)
{
if (def == null)
return null;
TypeTreeNode typeNode = FindTypeNode(def.DeclaringType);
if (typeNode == null)
return null;
@ -296,8 +279,6 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -296,8 +279,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// </summary>
public PropertyTreeNode FindPropertyNode(PropertyDefinition def)
{
if (def == null)
return null;
TypeTreeNode typeNode = FindTypeNode(def.DeclaringType);
if (typeNode == null)
return null;
@ -311,8 +292,6 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -311,8 +292,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// </summary>
public EventTreeNode FindEventNode(EventDefinition def)
{
if (def == null)
return null;
TypeTreeNode typeNode = FindTypeNode(def.DeclaringType);
if (typeNode == null)
return null;

6
ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs

@ -25,7 +25,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -25,7 +25,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// <summary>
/// Node within assembly reference list.
/// </summary>
public sealed class AssemblyReferenceTreeNode : ILSpyTreeNode
/*public sealed class AssemblyReferenceTreeNode : ILSpyTreeNode
{
readonly AssemblyNameReference r;
readonly AssemblyTreeNode parentAssembly;
@ -77,7 +77,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -77,7 +77,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
if (assemblyListNode != null) {
var refNode = assemblyListNode.FindAssemblyNode(parentAssembly.LoadedAssembly.LookupReferencedAssembly(r));
if (refNode != null) {
ModuleDefinition module = refNode.LoadedAssembly.GetModuleDefinitionOrNull();
ModuleDefinition module = refNode.LoadedAssembly.GetPEFileOrNull();
if (module != null) {
foreach (var childRef in module.AssemblyReferences)
this.Children.Add(new AssemblyReferenceTreeNode(childRef, refNode));
@ -106,5 +106,5 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -106,5 +106,5 @@ namespace ICSharpCode.ILSpy.TreeNodes
output.WriteLine();
}
}
}
}*/
}

43
ILSpy/TreeNodes/AssemblyTreeNode.cs

@ -20,15 +20,19 @@ using System; @@ -20,15 +20,19 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection.PortableExecutable;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.TreeView;
using Microsoft.Win32;
using Mono.Cecil;
using SRM = System.Reflection.Metadata;
using static System.Reflection.Metadata.PEReaderExtensions;
namespace ICSharpCode.ILSpy.TreeNodes
{
@ -97,18 +101,19 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -97,18 +101,19 @@ namespace ICSharpCode.ILSpy.TreeNodes
if (tooltip == null && assembly.IsLoaded) {
tooltip = new TextBlock();
var module = assembly.GetModuleDefinitionOrNull();
if (module.Assembly != null) {
var module = assembly.GetPEFileOrNull();
var metadata = module?.GetMetadataReader();
if (metadata?.IsAssembly == true) {
tooltip.Inlines.Add(new Bold(new Run("Name: ")));
tooltip.Inlines.Add(new Run(module.Assembly.FullName));
tooltip.Inlines.Add(new Run(metadata.GetFullAssemblyName()));
tooltip.Inlines.Add(new LineBreak());
}
tooltip.Inlines.Add(new Bold(new Run("Location: ")));
tooltip.Inlines.Add(new Run(assembly.FileName));
tooltip.Inlines.Add(new LineBreak());
tooltip.Inlines.Add(new Bold(new Run("Architecture: ")));
tooltip.Inlines.Add(new Run(CSharpLanguage.GetPlatformDisplayName(module)));
string runtimeName = CSharpLanguage.GetRuntimeDisplayName(module);
tooltip.Inlines.Add(new Run(Language.GetPlatformDisplayName(module)));
string runtimeName = Language.GetRuntimeDisplayName(module);
if (runtimeName != null) {
tooltip.Inlines.Add(new LineBreak());
tooltip.Inlines.Add(new Bold(new Run("Runtime: ")));
@ -125,7 +130,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -125,7 +130,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
get { return !assembly.HasLoadError; }
}
void OnAssemblyLoaded(Task<ModuleDefinition> moduleTask)
void OnAssemblyLoaded(Task<PEFile> moduleTask)
{
// change from "Loading" icon to final icon
RaisePropertyChanged("Icon");
@ -145,19 +150,20 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -145,19 +150,20 @@ namespace ICSharpCode.ILSpy.TreeNodes
protected override void LoadChildren()
{
ModuleDefinition moduleDefinition = assembly.GetModuleDefinitionOrNull();
if (moduleDefinition == null) {
var module = assembly.GetPEFileOrNull();
if (module == null) {
// if we crashed on loading, then we don't have any children
return;
}
var metadata = module.GetMetadataReader();
this.Children.Add(new ReferenceFolderTreeNode(moduleDefinition, this));
if (moduleDefinition.HasResources)
this.Children.Add(new ResourceListTreeNode(moduleDefinition));
this.Children.Add(new ReferenceFolderTreeNode(metadata, this));
if (module.Resources.Any())
this.Children.Add(new ResourceListTreeNode(module));
foreach (NamespaceTreeNode ns in namespaces.Values) {
ns.Children.Clear();
}
foreach (TypeDefinition type in moduleDefinition.Types.OrderBy(t => t.FullName, NaturalStringComparer.Instance)) {
foreach (TypeDefinition type in metadata.GetTopLevelTypeDefinitions().Select(td => new TypeDefinition(module, td)).OrderBy(t => t.FullName.ToString(), NaturalStringComparer.Instance)) {
NamespaceTreeNode ns;
if (!namespaces.TryGetValue(type.Namespace, out ns)) {
ns = new NamespaceTreeNode(type.Namespace);
@ -173,9 +179,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -173,9 +179,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
}
}
public override bool CanExpandRecursively {
get { return true; }
}
public override bool CanExpandRecursively => true;
/// <summary>
/// Finds the node for a top-level type.
@ -396,10 +400,11 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -396,10 +400,11 @@ namespace ICSharpCode.ILSpy.TreeNodes
return;
foreach (var node in context.SelectedTreeNodes) {
var la = ((AssemblyTreeNode)node).LoadedAssembly;
var module = la.GetModuleDefinitionOrNull();
var module = la.GetPEFileOrNull();
if (module != null) {
foreach (var assyRef in module.AssemblyReferences) {
la.LookupReferencedAssembly(assyRef);
var metadata = module.GetMetadataReader();
foreach (var assyRef in metadata.AssemblyReferences) {
la.LookupReferencedAssembly(new AssemblyReference(module, assyRef));
}
}
}

23
ILSpy/TreeNodes/BaseTypesEntryNode.cs

@ -19,35 +19,33 @@ @@ -19,35 +19,33 @@
using System;
using System.Linq;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.TreeView;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes
{
sealed class BaseTypesEntryNode : ILSpyTreeNode, IMemberTreeNode
{
private readonly TypeReference tr;
private readonly ITypeReference tr;
private TypeDefinition def;
private readonly bool isInterface;
public BaseTypesEntryNode(TypeReference tr, bool isInterface)
public BaseTypesEntryNode(ITypeReference tr, bool isInterface)
{
if (tr == null)
throw new ArgumentNullException(nameof(tr));
this.tr = tr;
this.def = tr.Resolve();
this.tr = tr ?? throw new ArgumentNullException(nameof(tr));
this.def = tr.GetDefinition();
this.isInterface = isInterface;
this.LazyLoading = true;
}
public override bool ShowExpander
{
get { return def != null && (def.BaseType != null || def.HasInterfaces); }
get { return !def.IsNil && (def.BaseType != null || def.HasInterfaces); }
}
public override object Text
{
get { return this.Language.TypeToString(tr, true) + tr.MetadataToken.ToSuffixString(); }
get { return def.FullName + def.Handle.ToSuffixString(); }
}
public override object Icon
@ -71,7 +69,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -71,7 +69,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
{
// on item activation, try to resolve once again (maybe the user loaded the assembly in the meantime)
if (def == null) {
def = tr.Resolve();
def = tr.GetDefinition();
if (def != null)
this.LazyLoading = true;
// re-load children
@ -96,9 +94,6 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -96,9 +94,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
language.WriteCommentLine(output, language.TypeToString(tr, true));
}
MemberReference IMemberTreeNode.Member
{
get { return tr; }
}
IMemberReference IMemberTreeNode.Member => tr;
}
}

14
ILSpy/TreeNodes/BaseTypesTreeNode.cs

@ -19,8 +19,8 @@ @@ -19,8 +19,8 @@
using System;
using System.Windows.Threading;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.TreeView;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes
{
@ -37,15 +37,9 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -37,15 +37,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
this.LazyLoading = true;
}
public override object Text
{
get { return "Base Types"; }
}
public override object Text => "Base Types";
public override object Icon
{
get { return Images.SuperTypes; }
}
public override object Icon => Images.SuperTypes;
protected override void LoadChildren()
{
@ -57,7 +51,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -57,7 +51,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
if (type.BaseType != null)
children.Add(new BaseTypesEntryNode(type.BaseType, false));
foreach (var i in type.Interfaces) {
children.Add(new BaseTypesEntryNode(i.InterfaceType, true));
children.Add(new BaseTypesEntryNode(i, true));
}
}

4
ILSpy/TreeNodes/CopyFullyQualifiedNameContextMenuEntry.cs

@ -15,9 +15,9 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -15,9 +15,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
public void Execute(TextViewContext context)
{
var member = GetMemberNodeFromContext(context)?.Member;
/*var member = GetMemberNodeFromContext(context)?.Member;
if (member == null) return;
Clipboard.SetText(GetFullyQualifiedName(member));
Clipboard.SetText(GetFullyQualifiedName(member));*/
}
private IMemberTreeNode GetMemberNodeFromContext(TextViewContext context)

16
ILSpy/TreeNodes/DerivedTypesEntryNode.cs

@ -17,19 +17,21 @@ @@ -17,19 +17,21 @@
// DEALINGS IN THE SOFTWARE.
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.PortableExecutable;
using System.Threading;
using ICSharpCode.Decompiler;
using Mono.Cecil;
using ICSharpCode.Decompiler.Dom;
namespace ICSharpCode.ILSpy.TreeNodes
{
class DerivedTypesEntryNode : ILSpyTreeNode, IMemberTreeNode
{
private readonly TypeDefinition type;
private readonly ModuleDefinition[] assemblies;
private readonly PEFile[] assemblies;
private readonly ThreadingSupport threading;
public DerivedTypesEntryNode(TypeDefinition type, ModuleDefinition[] assemblies)
public DerivedTypesEntryNode(TypeDefinition type, PEFile[] assemblies)
{
this.type = type;
this.assemblies = assemblies;
@ -39,12 +41,12 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -39,12 +41,12 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override bool ShowExpander
{
get { return !type.IsSealed && base.ShowExpander; }
get { return !type.HasFlag(TypeAttributes.Sealed) && base.ShowExpander; }
}
public override object Text
{
get { return this.Language.TypeToString(type, true) + type.MetadataToken.ToSuffixString(); }
get { return type.FullName + type.Handle.ToSuffixString(); }
}
public override object Icon
@ -57,7 +59,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -57,7 +59,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
if (!settings.ShowInternalApi && !IsPublicAPI)
return FilterResult.Hidden;
if (settings.SearchTermMatches(type.Name)) {
if (type.IsNested && !settings.Language.ShowMember(type))
if (!type.DeclaringType.IsNil && !settings.Language.ShowMember(type))
return FilterResult.Hidden;
else
return FilterResult.Match;
@ -100,6 +102,6 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -100,6 +102,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
language.WriteCommentLine(output, language.TypeToString(type, true));
}
MemberReference IMemberTreeNode.Member => type;
IMemberReference IMemberTreeNode.Member => type;
}
}

34
ILSpy/TreeNodes/DerivedTypesTreeNode.cs

@ -18,10 +18,13 @@ @@ -18,10 +18,13 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection.PortableExecutable;
using System.Threading;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.Decompiler.Util;
using Mono.Cecil;
using static System.Reflection.Metadata.PEReaderExtensions;
namespace ICSharpCode.ILSpy.TreeNodes
{
@ -60,18 +63,20 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -60,18 +63,20 @@ namespace ICSharpCode.ILSpy.TreeNodes
IEnumerable<ILSpyTreeNode> FetchChildren(CancellationToken cancellationToken)
{
// FetchChildren() runs on the main thread; but the enumerator will be consumed on a background thread
var assemblies = list.GetAssemblies().Select(node => node.GetModuleDefinitionOrNull()).Where(asm => asm != null).ToArray();
var assemblies = list.GetAssemblies().Select(node => node.GetPEFileOrNull()).Where(asm => asm != null).ToArray();
return FindDerivedTypes(type, assemblies, cancellationToken);
}
internal static IEnumerable<DerivedTypesEntryNode> FindDerivedTypes(TypeDefinition type, ModuleDefinition[] assemblies, CancellationToken cancellationToken)
internal static IEnumerable<DerivedTypesEntryNode> FindDerivedTypes(TypeDefinition type, PEFile[] assemblies, CancellationToken cancellationToken)
{
foreach (ModuleDefinition module in assemblies) {
foreach (TypeDefinition td in TreeTraversal.PreOrder(module.Types, t => t.NestedTypes)) {
foreach (var module in assemblies) {
var reader = module.GetMetadataReader();
foreach (var h in TreeTraversal.PreOrder(reader.GetTopLevelTypeDefinitions(), t => reader.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.InterfaceType, type))
if (IsSameType(iface, type))
yield return new DerivedTypesEntryNode(td, assemblies);
}
} else if (!type.IsInterface && td.BaseType != null && IsSameType(td.BaseType, type)) {
@ -79,22 +84,13 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -79,22 +84,13 @@ namespace ICSharpCode.ILSpy.TreeNodes
}
}
}
yield break;
}
static bool IsSameType(TypeReference typeRef, TypeDefinition type)
static bool IsSameType(ITypeReference typeRef, TypeDefinition type)
{
if (typeRef.FullName == type.FullName)
return true;
if (typeRef.Name != type.Name || type.Namespace != typeRef.Namespace)
return false;
if (typeRef.IsNested || type.IsNested)
if (!typeRef.IsNested || !type.IsNested || !IsSameType(typeRef.DeclaringType, type.DeclaringType))
return false;
var gTypeRef = typeRef as GenericInstanceType;
if (gTypeRef != null || type.HasGenericParameters)
if (gTypeRef == null || !type.HasGenericParameters || gTypeRef.GenericArguments.Count != type.GenericParameters.Count)
return false;
return true;
// FullName contains only namespace, name and type parameter count, therefore this should suffice.
return typeRef.FullName == type.FullName;
}
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)

43
ILSpy/TreeNodes/EventTreeNode.cs

@ -17,9 +17,11 @@ @@ -17,9 +17,11 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using System.Reflection;
using System.Windows.Media;
using ICSharpCode.Decompiler;
using Mono.Cecil;
using ICSharpCode.Decompiler.Dom;
namespace ICSharpCode.ILSpy.TreeNodes
{
@ -28,41 +30,39 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -28,41 +30,39 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// </summary>
public sealed class EventTreeNode : ILSpyTreeNode, IMemberTreeNode
{
public EventTreeNode(EventDefinition ev)
{
if (ev == null)
if (ev.IsNil)
throw new ArgumentNullException(nameof(ev));
this.EventDefinition = ev;
if (ev.AddMethod != null)
if (!ev.AddMethod.IsNil)
this.Children.Add(new MethodTreeNode(ev.AddMethod));
if (ev.RemoveMethod != null)
if (!ev.RemoveMethod.IsNil)
this.Children.Add(new MethodTreeNode(ev.RemoveMethod));
if (ev.InvokeMethod != null)
if (!ev.InvokeMethod.IsNil)
this.Children.Add(new MethodTreeNode(ev.InvokeMethod));
if (ev.HasOtherMethods) {
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.MetadataToken.ToSuffixString();
public override object Text => GetText(EventDefinition, this.Language) + EventDefinition.Handle.ToSuffixString();
public static object GetText(EventDefinition eventDef, Language language)
{
return HighlightSearchMatch(eventDef.Name, " : " + language.TypeToString(eventDef.EventType, false, eventDef));
var eventType = eventDef.DecodeSignature(language.CreateSignatureTypeProvider(false), new GenericContext(eventDef.DeclaringType));
return HighlightSearchMatch(eventDef.Name, " : " + eventType);
}
public override object Icon => GetIcon(EventDefinition);
public static ImageSource GetIcon(EventDefinition eventDef)
{
MethodDefinition accessor = eventDef.AddMethod ?? eventDef.RemoveMethod;
if (accessor != null)
return Images.GetIcon(MemberIcon.Event, GetOverlayIcon(eventDef.AddMethod.Attributes), eventDef.AddMethod.IsStatic);
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);
}
@ -82,7 +82,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -82,7 +82,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
return AccessOverlayIcon.ProtectedInternal;
case MethodAttributes.Private:
return AccessOverlayIcon.Private;
case MethodAttributes.CompilerControlled:
case 0:
return AccessOverlayIcon.CompilerControlled;
default:
throw new NotSupportedException();
@ -104,14 +104,21 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -104,14 +104,21 @@ namespace ICSharpCode.ILSpy.TreeNodes
language.DecompileEvent(EventDefinition, output, options);
}
public override bool IsPublicAPI {
get {
MethodDefinition accessor = EventDefinition.AddMethod ?? EventDefinition.RemoveMethod;
return accessor != null && (accessor.IsPublic || accessor.IsFamilyOrAssembly || accessor.IsFamily);
MethodDefinition accessor = EventDefinition.GetAccessors().FirstOrDefault().Method;
if (accessor.IsNil) return false;
switch (accessor.Attributes & MethodAttributes.MemberAccessMask) {
case MethodAttributes.Public:
case MethodAttributes.FamORAssem:
case MethodAttributes.Family:
return true;
default:
return false;
}
}
}
MemberReference IMemberTreeNode.Member => EventDefinition;
IMemberReference IMemberTreeNode.Member => EventDefinition;
}
}

42
ILSpy/TreeNodes/FieldTreeNode.cs

@ -17,9 +17,10 @@ @@ -17,9 +17,10 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Reflection;
using System.Windows.Media;
using ICSharpCode.Decompiler;
using Mono.Cecil;
using ICSharpCode.Decompiler.Dom;
namespace ICSharpCode.ILSpy.TreeNodes
{
@ -37,37 +38,35 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -37,37 +38,35 @@ namespace ICSharpCode.ILSpy.TreeNodes
this.FieldDefinition = field;
}
public override object Text
public override object Text => GetText(FieldDefinition, Language) + FieldDefinition.Handle.ToSuffixString();
public static object GetText(FieldDefinition field, Language language)
{
get {
return HighlightSearchMatch(
FieldDefinition.Name,
" : " + this.Language.TypeToString(FieldDefinition.FieldType, false, FieldDefinition) + FieldDefinition.MetadataToken.ToSuffixString()
);
}
string fieldType = field.DecodeSignature(language.CreateSignatureTypeProvider(false), new GenericContext(field.DeclaringType));
return HighlightSearchMatch(field.Name, " : " + fieldType);
}
public override object Icon => GetIcon(FieldDefinition);
public static ImageSource GetIcon(FieldDefinition field)
{
if (field.DeclaringType.IsEnum && !field.Attributes.HasFlag(FieldAttributes.SpecialName))
if (field.DeclaringType.IsEnum && !field.HasFlag(FieldAttributes.SpecialName))
return Images.GetIcon(MemberIcon.EnumValue, GetOverlayIcon(field.Attributes), false);
if (field.IsLiteral)
if (field.HasFlag(FieldAttributes.Literal))
return Images.GetIcon(MemberIcon.Literal, GetOverlayIcon(field.Attributes), false);
else if (field.IsInitOnly) {
else if (field.HasFlag(FieldAttributes.InitOnly)) {
if (IsDecimalConstant(field))
return Images.GetIcon(MemberIcon.Literal, GetOverlayIcon(field.Attributes), false);
else
return Images.GetIcon(MemberIcon.FieldReadOnly, GetOverlayIcon(field.Attributes), field.IsStatic);
return Images.GetIcon(MemberIcon.FieldReadOnly, GetOverlayIcon(field.Attributes), field.HasFlag(FieldAttributes.Static));
} else
return Images.GetIcon(MemberIcon.Field, GetOverlayIcon(field.Attributes), field.IsStatic);
return Images.GetIcon(MemberIcon.Field, GetOverlayIcon(field.Attributes), field.HasFlag(FieldAttributes.Static));
}
private static bool IsDecimalConstant(FieldDefinition field)
{
var fieldType = field.FieldType;
/*var fieldType = field.FieldType;
if (fieldType.Name == "Decimal" && fieldType.Namespace == "System") {
if (field.HasCustomAttributes) {
var attrs = field.CustomAttributes;
@ -77,7 +76,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -77,7 +76,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
return true;
}
}
}
}*/
return false;
}
@ -96,7 +95,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -96,7 +95,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
return AccessOverlayIcon.ProtectedInternal;
case FieldAttributes.Private:
return AccessOverlayIcon.Private;
case FieldAttributes.CompilerControlled:
case 0:
return AccessOverlayIcon.CompilerControlled;
default:
throw new NotSupportedException();
@ -120,10 +119,17 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -120,10 +119,17 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override bool IsPublicAPI {
get {
return FieldDefinition.IsPublic || FieldDefinition.IsFamily || FieldDefinition.IsFamilyOrAssembly;
switch (FieldDefinition.Attributes & FieldAttributes.FieldAccessMask) {
case FieldAttributes.Public:
case FieldAttributes.FamORAssem:
case FieldAttributes.Family:
return true;
default:
return false;
}
}
}
MemberReference IMemberTreeNode.Member => FieldDefinition;
IMemberReference 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 Mono.Cecil;
using ICSharpCode.Decompiler.Dom;
namespace ICSharpCode.ILSpy.TreeNodes
{
@ -27,6 +27,6 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -27,6 +27,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// </summary>
public interface IMemberTreeNode
{
MemberReference Member { get; }
IMemberReference Member { get; }
}
}

54
ILSpy/TreeNodes/MethodTreeNode.cs

@ -17,13 +17,15 @@ @@ -17,13 +17,15 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Controls;
using System.Windows.Media;
using ICSharpCode.Decompiler;
using Mono.Cecil;
using ICSharpCode.Decompiler.Dom;
using SRM = System.Reflection.Metadata;
namespace ICSharpCode.ILSpy.TreeNodes
{
@ -36,24 +38,27 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -36,24 +38,27 @@ namespace ICSharpCode.ILSpy.TreeNodes
public MethodTreeNode(MethodDefinition method)
{
if (method == null)
if (method.IsNil)
throw new ArgumentNullException(nameof(method));
this.MethodDefinition = method;
}
public override object Text => GetText(MethodDefinition, Language) + MethodDefinition.MetadataToken.ToSuffixString();
public override object Text => GetText(MethodDefinition, Language) + MethodDefinition.Handle.ToSuffixString();
public static object GetText(MethodDefinition method, Language language)
{
StringBuilder b = new StringBuilder();
var b = new StringBuilder();
var signatureProvider = language.CreateSignatureTypeProvider(false);
var signature = method.DecodeSignature(signatureProvider, new GenericContext(method));
b.Append('(');
for (int i = 0; i < method.Parameters.Count; i++) {
for (int i = 0; i < signature.ParameterTypes.Length; i++) {
if (i > 0)
b.Append(", ");
b.Append(language.TypeToString(method.Parameters[i].ParameterType, false, method.Parameters[i]));
b.Append(signature.ParameterTypes[i]);
}
if (method.CallingConvention == MethodCallingConvention.VarArg) {
if (method.HasParameters)
if (signature.Header.CallingConvention == SRM.SignatureCallingConvention.VarArgs) {
if (signature.ParameterTypes.Length > 0)
b.Append(", ");
b.Append("...");
}
@ -61,7 +66,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -61,7 +66,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
b.Append(')');
} else {
b.Append(") : ");
b.Append(language.TypeToString(method.ReturnType, false, method.MethodReturnType));
b.Append(signature.ReturnType);
}
return HighlightSearchMatch(language.FormatMethodName(method), b.ToString());
}
@ -70,32 +75,28 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -70,32 +75,28 @@ namespace ICSharpCode.ILSpy.TreeNodes
public static ImageSource GetIcon(MethodDefinition method)
{
if (method.IsSpecialName && method.Name.StartsWith("op_", StringComparison.Ordinal)) {
if (method.HasFlag(MethodAttributes.SpecialName) && method.Name.StartsWith("op_", StringComparison.Ordinal)) {
return Images.GetIcon(MemberIcon.Operator, GetOverlayIcon(method.Attributes), false);
}
if (method.IsStatic && method.HasCustomAttributes) {
foreach (var ca in method.CustomAttributes) {
if (ca.AttributeType.FullName == "System.Runtime.CompilerServices.ExtensionAttribute") {
if (method.IsExtensionMethod) {
return Images.GetIcon(MemberIcon.ExtensionMethod, GetOverlayIcon(method.Attributes), false);
}
}
}
if (method.IsSpecialName &&
if (method.HasFlag(MethodAttributes.SpecialName) &&
(method.Name == ".ctor" || method.Name == ".cctor")) {
return Images.GetIcon(MemberIcon.Constructor, GetOverlayIcon(method.Attributes), method.IsStatic);
return Images.GetIcon(MemberIcon.Constructor, GetOverlayIcon(method.Attributes), method.HasFlag(MethodAttributes.Static));
}
if (method.HasPInvokeInfo)
return Images.GetIcon(MemberIcon.PInvokeMethod, GetOverlayIcon(method.Attributes), true);
bool showAsVirtual = method.IsVirtual && !(method.IsNewSlot && method.IsFinal) && !method.DeclaringType.IsInterface;
bool showAsVirtual = method.HasFlag(MethodAttributes.Virtual) && !(method.HasFlag(MethodAttributes.NewSlot) && method.HasFlag(MethodAttributes.Final)) && !method.DeclaringType.IsInterface;
return Images.GetIcon(
showAsVirtual ? MemberIcon.VirtualMethod : MemberIcon.Method,
GetOverlayIcon(method.Attributes),
method.IsStatic);
method.HasFlag(MethodAttributes.Static));
}
private static AccessOverlayIcon GetOverlayIcon(MethodAttributes methodAttributes)
@ -113,7 +114,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -113,7 +114,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
return AccessOverlayIcon.ProtectedInternal;
case MethodAttributes.Private:
return AccessOverlayIcon.Private;
case MethodAttributes.CompilerControlled:
case 0:
return AccessOverlayIcon.CompilerControlled;
default:
throw new NotSupportedException();
@ -137,10 +138,17 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -137,10 +138,17 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override bool IsPublicAPI {
get {
return MethodDefinition.IsPublic || MethodDefinition.IsFamily || MethodDefinition.IsFamilyOrAssembly;
switch (MethodDefinition.Attributes & MethodAttributes.MemberAccessMask) {
case MethodAttributes.Public:
case MethodAttributes.Family:
case MethodAttributes.FamORAssem:
return true;
default:
return false;
}
}
}
MemberReference IMemberTreeNode.Member => MethodDefinition;
IMemberReference IMemberTreeNode.Member => MethodDefinition;
}
}

4
ILSpy/TreeNodes/ModuleReferenceTreeNode.cs

@ -25,7 +25,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -25,7 +25,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// <summary>
/// Module reference in ReferenceFolderTreeNode.
/// </summary>
sealed class ModuleReferenceTreeNode : ILSpyTreeNode
/*sealed class ModuleReferenceTreeNode : ILSpyTreeNode
{
readonly ModuleReference r;
@ -48,5 +48,5 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -48,5 +48,5 @@ namespace ICSharpCode.ILSpy.TreeNodes
{
language.WriteCommentLine(output, r.Name);
}
}
}*/
}

35
ILSpy/TreeNodes/PropertyTreeNode.cs

@ -17,9 +17,12 @@ @@ -17,9 +17,12 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Reflection;
using System.Windows.Media;
using ICSharpCode.Decompiler;
using Mono.Cecil;
using ICSharpCode.Decompiler.Dom;
using SRM = System.Reflection.Metadata;
namespace ICSharpCode.ILSpy.TreeNodes
{
@ -36,39 +39,37 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -36,39 +39,37 @@ namespace ICSharpCode.ILSpy.TreeNodes
throw new ArgumentNullException(nameof(property));
this.PropertyDefinition = property;
using (LoadedAssembly.DisableAssemblyLoad()) {
this.isIndexer = property.IsIndexer();
this.isIndexer = property.IsIndexer;
}
if (property.GetMethod != null)
if (!property.GetMethod.IsNil)
this.Children.Add(new MethodTreeNode(property.GetMethod));
if (property.SetMethod != null)
if (!property.SetMethod.IsNil)
this.Children.Add(new MethodTreeNode(property.SetMethod));
if (property.HasOtherMethods) {
foreach (var m in property.OtherMethods)
this.Children.Add(new MethodTreeNode(m));
}
}
public PropertyDefinition PropertyDefinition { get; }
public override object Text => GetText(PropertyDefinition, Language, isIndexer) + PropertyDefinition.MetadataToken.ToSuffixString();
public override object Text => GetText(PropertyDefinition, Language, isIndexer) + PropertyDefinition.Handle.ToSuffixString();
public static object GetText(PropertyDefinition property, Language language, bool? isIndexer = null)
{
string name = language.FormatPropertyName(property, isIndexer);
var signature = property.DecodeSignature(language.CreateSignatureTypeProvider(false), new GenericContext(property.DeclaringType));
var b = new System.Text.StringBuilder();
if (property.HasParameters)
{
b.Append('(');
for (int i = 0; i < property.Parameters.Count; i++)
for (int i = 0; i < signature.ParameterTypes.Length; i++)
{
if (i > 0)
b.Append(", ");
b.Append(language.TypeToString(property.Parameters[i].ParameterType, false, property.Parameters[i]));
b.Append(signature.ParameterTypes[i]);
}
var method = property.GetMethod ?? property.SetMethod;
if (method.CallingConvention == MethodCallingConvention.VarArg)
if (signature.Header.CallingConvention == SRM.SignatureCallingConvention.VarArgs)
{
if (property.HasParameters)
b.Append(", ");
@ -80,7 +81,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -80,7 +81,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
{
b.Append(" : ");
}
b.Append(language.TypeToString(property.PropertyType, false, property));
b.Append(signature.ReturnType);
return HighlightSearchMatch(name, b.ToString());
}
@ -110,7 +111,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -110,7 +111,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
return AccessOverlayIcon.ProtectedInternal;
case MethodAttributes.Private:
return AccessOverlayIcon.Private;
case MethodAttributes.CompilerControlled:
case 0:
return AccessOverlayIcon.CompilerControlled;
default:
throw new NotSupportedException();
@ -128,7 +129,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -128,7 +129,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
// in numeric order, so we can do an integer comparison of the masked attribute
int accessLevel = 0;
if (property.GetMethod != null) {
if (!property.GetMethod.IsNil) {
int methodAccessLevel = (int)(property.GetMethod.Attributes & MethodAttributes.MemberAccessMask);
if (accessLevel < methodAccessLevel) {
accessLevel = methodAccessLevel;
@ -136,7 +137,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -136,7 +137,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
}
}
if (property.SetMethod != null) {
if (!property.SetMethod.IsNil) {
int methodAccessLevel = (int)(property.SetMethod.Attributes & MethodAttributes.MemberAccessMask);
if (accessLevel < methodAccessLevel) {
accessLevel = methodAccessLevel;
@ -144,7 +145,6 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -144,7 +145,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
}
}
if (property.HasOtherMethods) {
foreach (var m in property.OtherMethods) {
int methodAccessLevel = (int)(m.Attributes & MethodAttributes.MemberAccessMask);
if (accessLevel < methodAccessLevel) {
@ -152,7 +152,6 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -152,7 +152,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
result = m.Attributes;
}
}
}
return result;
}
@ -185,6 +184,6 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -185,6 +184,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
}
}
MemberReference IMemberTreeNode.Member => PropertyDefinition;
IMemberReference IMemberTreeNode.Member => PropertyDefinition;
}
}

19
ILSpy/TreeNodes/ReferenceFolderTreeNode.cs

@ -18,9 +18,10 @@ @@ -18,9 +18,10 @@
using System;
using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using System.Windows.Threading;
using ICSharpCode.Decompiler;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes
{
@ -29,10 +30,10 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -29,10 +30,10 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// </summary>
sealed class ReferenceFolderTreeNode : ILSpyTreeNode
{
readonly ModuleDefinition module;
readonly MetadataReader module;
readonly AssemblyTreeNode parentAssembly;
public ReferenceFolderTreeNode(ModuleDefinition module, AssemblyTreeNode parentAssembly)
public ReferenceFolderTreeNode(MetadataReader module, AssemblyTreeNode parentAssembly)
{
this.module = module;
this.parentAssembly = parentAssembly;
@ -53,10 +54,10 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -53,10 +54,10 @@ namespace ICSharpCode.ILSpy.TreeNodes
protected override void LoadChildren()
{
foreach (var r in module.AssemblyReferences.OrderBy(r => r.Name))
this.Children.Add(new AssemblyReferenceTreeNode(r, parentAssembly));
foreach (var r in module.ModuleReferences.OrderBy(r => r.Name))
this.Children.Add(new ModuleReferenceTreeNode(r));
//foreach (var r in module.AssemblyReferences.OrderBy(r => r.Name))
// this.Children.Add(new AssemblyReferenceTreeNode(r, parentAssembly));
//foreach (var r in module.ModuleReferences.OrderBy(r => r.Name))
// this.Children.Add(new ModuleReferenceTreeNode(r));
}
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
@ -66,10 +67,10 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -66,10 +67,10 @@ namespace ICSharpCode.ILSpy.TreeNodes
output.WriteLine();
language.WriteCommentLine(output, "Referenced assemblies (in metadata order):");
// Show metadata order of references
foreach (var r in module.AssemblyReferences)
/*foreach (var r in module.AssemblyReferences)
new AssemblyReferenceTreeNode(r, parentAssembly).Decompile(language, output, options);
foreach (var r in module.ModuleReferences)
language.WriteCommentLine(output, r.Name);
language.WriteCommentLine(output, r.Name);*/
}
}
}

6
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 Mono.Cecil;
using ICSharpCode.Decompiler.Dom;
namespace ICSharpCode.ILSpy.TreeNodes
{
@ -29,9 +29,9 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -29,9 +29,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// </summary>
sealed class ResourceListTreeNode : ILSpyTreeNode
{
readonly ModuleDefinition module;
readonly PEFile module;
public ResourceListTreeNode(ModuleDefinition module)
public ResourceListTreeNode(PEFile module)
{
this.LazyLoading = true;
this.module = module;

9
ILSpy/TreeNodes/ResourceNodes/CursorResourceEntryNode.cs

@ -21,8 +21,8 @@ using System.ComponentModel.Composition; @@ -21,8 +21,8 @@ using System.ComponentModel.Composition;
using System.IO;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.ILSpy.TextView;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes
{
@ -33,11 +33,10 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -33,11 +33,10 @@ namespace ICSharpCode.ILSpy.TreeNodes
public ILSpyTreeNode CreateNode(Resource resource)
{
EmbeddedResource er = resource as EmbeddedResource;
if (er != null) {
return CreateNode(er.Name, er.GetResourceStream());
}
Stream stream = resource.TryOpenStream();
if (stream == null)
return null;
return CreateNode(resource.Name, stream);
}
public ILSpyTreeNode CreateNode(string key, object data)

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 Mono.Cecil;
using ICSharpCode.Decompiler.Dom;
namespace ICSharpCode.ILSpy.TreeNodes
{

9
ILSpy/TreeNodes/ResourceNodes/IconResourceEntryNode.cs

@ -21,8 +21,8 @@ using System.ComponentModel.Composition; @@ -21,8 +21,8 @@ using System.ComponentModel.Composition;
using System.IO;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.ILSpy.TextView;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes
{
@ -31,11 +31,10 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -31,11 +31,10 @@ namespace ICSharpCode.ILSpy.TreeNodes
{
public ILSpyTreeNode CreateNode(Resource resource)
{
EmbeddedResource er = resource as EmbeddedResource;
if (er != null) {
return CreateNode(er.Name, er.GetResourceStream());
}
Stream stream = resource.TryOpenStream();
if (stream == null)
return null;
return CreateNode(resource.Name, stream);
}
public ILSpyTreeNode CreateNode(string key, object data)

7
ILSpy/TreeNodes/ResourceNodes/ImageListResourceEntryNode.cs

@ -20,15 +20,14 @@ using System.ComponentModel.Composition; @@ -20,15 +20,14 @@ using System.ComponentModel.Composition;
using System.Drawing;
using System.Windows.Forms;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Dom;
namespace ICSharpCode.ILSpy.TreeNodes
{
[Export(typeof(IResourceNodeFactory))]
sealed class ImageListResourceEntryNodeFactory : IResourceNodeFactory
{
#region IResourceNodeFactory Members
public ILSpyTreeNode CreateNode(Mono.Cecil.Resource resource)
public ILSpyTreeNode CreateNode(Resource resource)
{
return null;
}
@ -39,8 +38,6 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -39,8 +38,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
return new ImageListResourceEntryNode(key, (ImageListStreamer)data);
return null;
}
#endregion
}
sealed class ImageListResourceEntryNode : ILSpyTreeNode

9
ILSpy/TreeNodes/ResourceNodes/ImageResourceEntryNode.cs

@ -21,8 +21,8 @@ using System.ComponentModel.Composition; @@ -21,8 +21,8 @@ using System.ComponentModel.Composition;
using System.IO;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using ICSharpCode.Decompiler.Dom;
using ICSharpCode.ILSpy.TextView;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes
{
@ -33,11 +33,10 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -33,11 +33,10 @@ namespace ICSharpCode.ILSpy.TreeNodes
public ILSpyTreeNode CreateNode(Resource resource)
{
EmbeddedResource er = resource as EmbeddedResource;
if (er != null) {
return CreateNode(er.Name, er.GetResourceStream());
}
Stream stream = resource.TryOpenStream();
if (stream == null)
return null;
return CreateNode(resource.Name, stream);
}
public ILSpyTreeNode CreateNode(string key, object data)

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save