Browse Source

Merge branch 'master' of https://github.com/icsharpcode/ILSpy into net5take2

pull/2323/head
Siegfried Pammer 4 years ago
parent
commit
6010ae01d5
  1. 6
      .github/workflows/build-ilspy.yml
  2. 2
      DecompilerNuGetDemos.workbook
  3. 4
      ICSharpCode.Decompiler.Console/ICSharpCode.Decompiler.Console.csproj
  4. 2
      ICSharpCode.Decompiler.PowerShell/ICSharpCode.Decompiler.PowerShell.csproj
  5. 6
      ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs
  6. 6
      ICSharpCode.Decompiler.Tests/Helpers/Tester.cs
  7. 1
      ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
  8. 2
      ICSharpCode.Decompiler.Tests/PdbGenerationTestRunner.cs
  9. 2
      ICSharpCode.Decompiler.Tests/TestAssemblyResolver.cs
  10. 35
      ICSharpCode.Decompiler.Tests/TestCases/Correctness/DynamicTests.cs
  11. 2
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/CompoundAssignmentTest.cs
  12. 12
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.cs
  13. 25
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  14. 2
      ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs
  15. 10
      ICSharpCode.Decompiler/CSharp/StatementBuilder.cs
  16. 3
      ICSharpCode.Decompiler/DebugInfo/KnownGuids.cs
  17. 17
      ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs
  18. 6
      ICSharpCode.Decompiler/Documentation/XmlDocumentationProvider.cs
  19. 1
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  20. 6
      ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs
  21. 2
      ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs
  22. 26
      ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs
  23. 20
      ICSharpCode.Decompiler/Metadata/DotNetCorePathFinder.cs
  24. 70
      ICSharpCode.Decompiler/Metadata/DotNetCorePathFinderExtensions.cs
  25. 87
      ICSharpCode.Decompiler/Metadata/ReferenceLoadInfo.cs
  26. 13
      ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs
  27. 14
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs
  28. 2
      ILSpy.BamlDecompiler/Baml/KnownThings.cs
  29. 18
      ILSpy.BamlDecompiler/Baml/KnownThings.g.cs
  30. 52
      ILSpy.BamlDecompiler/Rewrite/ConnectionIdRewritePass.cs
  31. 5
      ILSpy.ReadyToRun/ReadyToRunLanguage.cs
  32. 4
      ILSpy/AboutPage.cs
  33. 14
      ILSpy/Analyzers/AnalyzerScope.cs
  34. 8
      ILSpy/App.xaml
  35. 13
      ILSpy/App.xaml.cs
  36. 45
      ILSpy/AssemblyList.cs
  37. 35
      ILSpy/Commands/SearchMsdnContextMenuEntry.cs
  38. 6
      ILSpy/Controls/ResourceObjectTable.xaml
  39. 31
      ILSpy/Controls/ResourceStringTable.xaml
  40. 5
      ILSpy/Controls/SearchBoxStyle.xaml
  41. 59
      ILSpy/DebugInfo/PortableDebugInfoProvider.cs
  42. 19
      ILSpy/ExtensionMethods.cs
  43. 9
      ILSpy/ILSpy.csproj
  44. 2
      ILSpy/ISmartTextOutput.cs
  45. BIN
      ILSpy/Images/DarkMode.png
  46. 4
      ILSpy/Languages/CSharpLanguage.cs
  47. 34
      ILSpy/LoadedAssembly.cs
  48. 34
      ILSpy/MainWindow.xaml
  49. 8
      ILSpy/MainWindow.xaml.cs
  50. 1
      ILSpy/Metadata/CoffHeaderTreeNode.cs
  51. 2
      ILSpy/Metadata/CorTables/PropertyMapTableTreeNode.cs
  52. 84
      ILSpy/Metadata/DebugMetadataTablesTreeNode.cs
  53. 23
      ILSpy/Metadata/DebugMetadataTreeNode.cs
  54. 257
      ILSpy/Metadata/DebugTables/CustomDebugInformationTableTreeNode.cs
  55. 2
      ILSpy/Metadata/DebugTables/LocalScopeTableTreeNode.cs
  56. 97
      ILSpy/Metadata/Heaps/BlobHeapTreeNode.cs
  57. 86
      ILSpy/Metadata/Heaps/GuidHeapTreeNode.cs
  58. 96
      ILSpy/Metadata/Heaps/StringHeapTreeNode.cs
  59. 97
      ILSpy/Metadata/Heaps/UserStringHeapTreeNode.cs
  60. 21
      ILSpy/Metadata/Helpers.cs
  61. 68
      ILSpy/Metadata/MetadataHeapTreeNode.cs
  62. 22
      ILSpy/Metadata/MetadataProtocolHandler.cs
  63. 2
      ILSpy/Metadata/MetadataTableTreeNode.cs
  64. 23
      ILSpy/Metadata/MetadataTableViews.xaml
  65. 10
      ILSpy/Metadata/MetadataTableViews.xaml.cs
  66. 132
      ILSpy/Metadata/MetadataTablesTreeNode.cs
  67. 85
      ILSpy/Metadata/MetadataTreeNode.cs
  68. 2
      ILSpy/Options/DecompilerSettingsPanel.xaml
  69. 2
      ILSpy/Options/DisplaySettingsPanel.xaml
  70. 2
      ILSpy/Properties/AssemblyInfo.template.cs
  71. 11
      ILSpy/Properties/Resources.Designer.cs
  72. 5
      ILSpy/Properties/Resources.resx
  73. 2
      ILSpy/Properties/app.config.template
  74. 4
      ILSpy/Search/AbstractEntitySearchStrategy.cs
  75. 41
      ILSpy/Search/SearchPane.cs
  76. 2
      ILSpy/Search/SearchPane.xaml
  77. 14
      ILSpy/Search/SearchResult.cs
  78. 10
      ILSpy/SessionSettings.cs
  79. 1211
      ILSpy/TextView/Asm-Mode-Dark.xshd
  80. 149
      ILSpy/TextView/CSharp-Mode-Dark.xshd
  81. 102
      ILSpy/TextView/DecompilerTextView.cs
  82. 41
      ILSpy/TextView/DecompilerTextView.xaml
  83. 530
      ILSpy/TextView/ILAsm-Mode-Dark.xshd
  84. 63
      ILSpy/TextView/XML-Mode-Dark.xshd
  85. 63
      ILSpy/TextView/XML-Mode.xshd
  86. 50
      ILSpy/ThemeManager.cs
  87. 24
      ILSpy/TreeNodes/AssemblyTreeNode.cs
  88. 3
      ILSpy/TreeNodes/DerivedTypesEntryNode.cs
  89. 7
      ILSpy/TreeNodes/DerivedTypesTreeNode.cs
  90. 17
      ILSpy/TreeNodes/ILSpyTreeNode.cs
  91. 4
      ILSpy/TreeNodes/ReferenceFolderTreeNode.cs
  92. 60
      ILSpy/themes/DarkTheme.xaml
  93. 52
      ILSpy/themes/LightTheme.xaml
  94. 11
      ILSpy/themes/ResourceKeys.cs
  95. 6
      ILSpy/themes/generic.xaml
  96. 4
      SharpTreeView/ICSharpCode.TreeView.csproj
  97. 4
      SharpTreeView/SharpTreeNode.cs
  98. 4
      SharpTreeView/SharpTreeView.cs
  99. 35
      SharpTreeView/Themes/Generic.xaml
  100. 331
      decompiler-nuget-demos.ipynb
  101. Some files were not shown because too many files have changed in this diff Show More

6
.github/workflows/build-ilspy.yml

@ -39,15 +39,13 @@ jobs: @@ -39,15 +39,13 @@ jobs:
submodules: true
fetch-depth: 0
- name: Setup .NET Core
- name: Setup .NET Core 3.1
uses: actions/setup-dotnet@v1
with:
dotnet-version: 3.1.x
dotnet-version: '3.1.x'
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.0.2
with:
vs-version: '[16.6,16.9)'
- name: Install dotnet-format
run: dotnet tool install dotnet-format --global --version 4.1.131201

2
DecompilerNuGetDemos.workbook

@ -6,7 +6,7 @@ platforms: @@ -6,7 +6,7 @@ platforms:
- DotNetCore
packages:
- id: ICSharpCode.Decompiler
version: 7.0.0.6291-preview2
version: 7.0.0.6372-preview3
---
Setup: load the references required to work with the decompiler

4
ICSharpCode.Decompiler.Console/ICSharpCode.Decompiler.Console.csproj

@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
<PackAsTool>true</PackAsTool>
<AssemblyName>ilspycmd</AssemblyName>
<ToolCommandName>ilspycmd</ToolCommandName>
<Version>7.0.0.6291-preview2</Version>
<Version>7.0.0.6372-preview3</Version>
<Description>Command-line decompiler using the ILSpy decompilation engine</Description>
<Copyright>Copyright 2011-2021 AlphaSierraPapa</Copyright>
<PackageProjectUrl>https://github.com/icsharpcode/ILSpy/</PackageProjectUrl>
@ -45,7 +45,7 @@ @@ -45,7 +45,7 @@
</ItemGroup>
<ItemGroup Condition="'$(Configuration)' == 'Release'">
<PackageReference Include="ICSharpCode.Decompiler" Version="7.0.0.6291-preview2" />
<PackageReference Include="ICSharpCode.Decompiler" Version="7.0.0.6372-preview3" />
</ItemGroup>
<ItemGroup>

2
ICSharpCode.Decompiler.PowerShell/ICSharpCode.Decompiler.PowerShell.csproj

@ -19,7 +19,7 @@ @@ -19,7 +19,7 @@
</ItemGroup>
<ItemGroup Condition="'$(Configuration)' == 'Release'">
<PackageReference Include="ICSharpCode.Decompiler" Version="7.0.0.6291-preview2" />
<PackageReference Include="ICSharpCode.Decompiler" Version="7.0.0.6372-preview3" />
</ItemGroup>
<ItemGroup>

6
ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs

@ -331,6 +331,12 @@ namespace ICSharpCode.Decompiler.Tests @@ -331,6 +331,12 @@ namespace ICSharpCode.Decompiler.Tests
RunCS(options: options);
}
[Test]
public void DynamicTests([ValueSource(nameof(noMonoOptions))] CompilerOptions options)
{
RunCS(options: options);
}
[Test]
public void MiniJSON([ValueSource(nameof(defaultOptions))] CompilerOptions options)
{

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

@ -219,7 +219,9 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -219,7 +219,9 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
static readonly RoslynToolset roslynToolset = new RoslynToolset();
static readonly string coreRefAsmPath = new DotNetCorePathFinder(TargetFrameworkIdentifier.NETCoreApp, new Version(3, 1)).GetReferenceAssemblyPath(".NETCoreApp, Version = v3.1");
static readonly string coreRefAsmPath = new DotNetCorePathFinder(TargetFrameworkIdentifier.NETCoreApp,
new Version(3, 1), "Microsoft.NETCore.App")
.GetReferenceAssemblyPath(".NETCoreApp, Version = v3.1");
static readonly string refAsmPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86),
@"Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2");
@ -628,7 +630,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -628,7 +630,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
{
var module = new PEFile(assemblyFileName, file, PEStreamOptions.PrefetchEntireImage);
var resolver = new UniversalAssemblyResolver(assemblyFileName, false,
module.Reader.DetectTargetFrameworkId(), PEStreamOptions.PrefetchMetadata);
module.Reader.DetectTargetFrameworkId(), null, PEStreamOptions.PrefetchMetadata);
resolver.AddSearchDirectory(Path.GetDirectoryName(typeof(Span<>).Assembly.Location));
var typeSystem = new DecompilerTypeSystem(module, resolver, settings);
CSharpDecompiler decompiler = new CSharpDecompiler(typeSystem, settings);

1
ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj

@ -105,6 +105,7 @@ @@ -105,6 +105,7 @@
<Compile Include="ProjectDecompiler\TargetFrameworkTests.cs" />
<Compile Include="TestAssemblyResolver.cs" />
<Compile Include="TestCases\Correctness\DeconstructionTests.cs" />
<Compile Include="TestCases\Correctness\DynamicTests.cs" />
<Compile Include="TestCases\Correctness\StringConcat.cs" />
<None Include="TestCases\ILPretty\Issue2260SwitchString.cs" />
<None Include="TestCases\Pretty\Records.cs" />

2
ICSharpCode.Decompiler.Tests/PdbGenerationTestRunner.cs

@ -59,7 +59,7 @@ namespace ICSharpCode.Decompiler.Tests @@ -59,7 +59,7 @@ namespace ICSharpCode.Decompiler.Tests
string peFileName = Path.Combine(TestCasePath, testName + ".expected.dll");
string pdbFileName = Path.Combine(TestCasePath, testName + ".expected.pdb");
var moduleDefinition = new PEFile(peFileName);
var resolver = new UniversalAssemblyResolver(peFileName, false, moduleDefinition.Reader.DetectTargetFrameworkId(), PEStreamOptions.PrefetchEntireImage);
var resolver = new UniversalAssemblyResolver(peFileName, false, moduleDefinition.Reader.DetectTargetFrameworkId(), null, PEStreamOptions.PrefetchEntireImage);
var decompiler = new CSharpDecompiler(moduleDefinition, resolver, new DecompilerSettings());
using (FileStream pdbStream = File.Open(Path.Combine(TestCasePath, testName + ".pdb"), FileMode.OpenOrCreate, FileAccess.ReadWrite))
{

2
ICSharpCode.Decompiler.Tests/TestAssemblyResolver.cs

@ -13,7 +13,7 @@ namespace ICSharpCode.Decompiler.Tests @@ -13,7 +13,7 @@ namespace ICSharpCode.Decompiler.Tests
readonly HashSet<string> localAssemblies = new HashSet<string>();
public TestAssemblyResolver(string mainAssemblyFileName, string baseDir, string targetFramework)
: base(mainAssemblyFileName, false, targetFramework, PEStreamOptions.PrefetchMetadata, MetadataReaderOptions.ApplyWindowsRuntimeProjections)
: base(mainAssemblyFileName, false, targetFramework, null, PEStreamOptions.PrefetchMetadata, MetadataReaderOptions.ApplyWindowsRuntimeProjections)
{
var assemblyNames = new DirectoryInfo(baseDir).EnumerateFiles("*.dll").Select(f => Path.GetFileNameWithoutExtension(f.Name));
foreach (var name in assemblyNames)

35
ICSharpCode.Decompiler.Tests/TestCases/Correctness/DynamicTests.cs

@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
using System;
namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
{
class DynamicTests
{
delegate void RefAction<T>(ref T arg);
static void Main(string[] args)
{
PrintResult((ref dynamic x) => x = x + 2.0, 5.0);
PrintResult((ref dynamic x) => x = x + 2.0, 5);
PrintResult((ref dynamic x) => x = x + 2, 5.0);
PrintResult((ref dynamic x) => x = x + 2, 5);
PrintResult((ref dynamic x) => x = x - 2.0, 5.0);
PrintResult((ref dynamic x) => x = x - 2.0, 5);
PrintResult((ref dynamic x) => x = x - 2, 5.0);
PrintResult((ref dynamic x) => x = x - 2, 5);
PrintResult((ref dynamic x) => x = x * 2.0, 5.0);
PrintResult((ref dynamic x) => x = x * 2.0, 5);
PrintResult((ref dynamic x) => x = x * 2, 5.0);
PrintResult((ref dynamic x) => x = x * 2, 5);
PrintResult((ref dynamic x) => x = x / 2.0, 5.0);
PrintResult((ref dynamic x) => x = x / 2.0, 5);
PrintResult((ref dynamic x) => x = x / 2, 5.0);
PrintResult((ref dynamic x) => x = x / 2, 5);
}
private static void PrintResult(RefAction<dynamic> p, dynamic arg)
{
p(ref arg);
Console.WriteLine(arg);
}
}
}

2
ICSharpCode.Decompiler.Tests/TestCases/Pretty/CompoundAssignmentTest.cs

@ -4529,7 +4529,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -4529,7 +4529,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
return M()[name] -= 2u;
}
public uint CompoundAssignIndexerComplexIndex(string name)
public uint CompoundAssignIndexerComplexIndex()
{
return M()[ToString()] -= 2u;
}

12
ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.cs

@ -137,6 +137,13 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -137,6 +137,13 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
Console.WriteLine("No inlining");
Console.WriteLine(field.GetHashCode());
}
public void RefReadonlyCallVirt(RefLocalsAndReturns provider)
{
ref readonly NormalStruct readonlyRefInstance = ref provider.GetReadonlyRefInstance<NormalStruct>();
Console.WriteLine("No inlining");
readonlyRefInstance.Method();
}
}
private static int[] numbers = new int[10] { 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023 };
@ -156,6 +163,11 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -156,6 +163,11 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
throw new NotImplementedException();
}
public ref readonly T GetReadonlyRefInstance<T>()
{
throw new NotImplementedException();
}
public void CallOnRefReturn()
{
// Both direct calls:

25
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -430,7 +430,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -430,7 +430,7 @@ namespace ICSharpCode.Decompiler.CSharp
settings.LoadInMemory = true;
var file = LoadPEFile(fileName, settings);
var resolver = new UniversalAssemblyResolver(fileName, settings.ThrowOnAssemblyResolveErrors,
file.DetectTargetFrameworkId(),
file.DetectTargetFrameworkId(), file.DetectRuntimePack(),
settings.LoadInMemory ? PEStreamOptions.PrefetchMetadata : PEStreamOptions.Default,
settings.ApplyWindowsRuntimeProjections ? MetadataReaderOptions.ApplyWindowsRuntimeProjections : MetadataReaderOptions.None);
return new DecompilerTypeSystem(file, resolver);
@ -1473,15 +1473,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1473,15 +1473,7 @@ namespace ICSharpCode.Decompiler.CSharp
if (entityDecl != null)
{
int i = 0;
var parameters = function.Variables.Where(v => v.Kind == VariableKind.Parameter).ToDictionary(v => v.Index);
foreach (var parameter in entityDecl.GetChildrenByRole(Roles.Parameter))
{
if (parameters.TryGetValue(i, out var v))
parameter.AddAnnotation(new ILVariableResolveResult(v, method.Parameters[i].Type));
i++;
}
entityDecl.AddAnnotation(function);
AddAnnotationsToDeclaration(method, entityDecl, function);
}
var localSettings = settings.Clone();
@ -1541,6 +1533,19 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1541,6 +1533,19 @@ namespace ICSharpCode.Decompiler.CSharp
}
}
internal static void AddAnnotationsToDeclaration(IMethod method, EntityDeclaration entityDecl, ILFunction function)
{
int i = 0;
var parameters = function.Variables.Where(v => v.Kind == VariableKind.Parameter).ToDictionary(v => v.Index);
foreach (var parameter in entityDecl.GetChildrenByRole(Roles.Parameter))
{
if (parameters.TryGetValue(i, out var v))
parameter.AddAnnotation(new ILVariableResolveResult(v, method.Parameters[i].Type));
i++;
}
entityDecl.AddAnnotation(function);
}
internal static void CleanUpMethodDeclaration(EntityDeclaration entityDecl, BlockStatement body, ILFunction function, bool decompileBody = true)
{
if (function.IsIterator)

2
ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs

@ -462,6 +462,8 @@ namespace ICSharpCode.Decompiler.CSharp @@ -462,6 +462,8 @@ namespace ICSharpCode.Decompiler.CSharp
{
if (inst.ILRangeIsEmpty)
return false;
if (inst.Parent == null)
return false;
return !(inst is BlockContainer || inst is Block);
}

10
ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

@ -390,6 +390,15 @@ namespace ICSharpCode.Decompiler.CSharp @@ -390,6 +390,15 @@ namespace ICSharpCode.Decompiler.CSharp
if (!endContainerLabels.TryGetValue(inst.TargetContainer, out string label))
{
label = "end_" + inst.TargetLabel;
if (!duplicateLabels.TryGetValue(label, out int count))
{
duplicateLabels.Add(label, 1);
}
else
{
duplicateLabels[label]++;
label += "_" + (count + 1);
}
endContainerLabels.Add(inst.TargetContainer, label);
}
return new GotoStatement(label).WithILInstruction(inst);
@ -1359,6 +1368,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1359,6 +1368,7 @@ namespace ICSharpCode.Decompiler.CSharp
method.Modifiers |= Modifiers.Extern;
}
CSharpDecompiler.AddAnnotationsToDeclaration(function.ReducedMethod, method, function);
CSharpDecompiler.CleanUpMethodDeclaration(method, method.Body, function, function.Method.HasBody);
CSharpDecompiler.RemoveAttribute(method, KnownAttribute.CompilerGenerated);
var stmt = new LocalFunctionDeclarationStatement(method);

3
ICSharpCode.Decompiler/DebugInfo/KnownGuids.cs

@ -18,6 +18,9 @@ namespace ICSharpCode.Decompiler.DebugInfo @@ -18,6 +18,9 @@ namespace ICSharpCode.Decompiler.DebugInfo
public static readonly Guid EmbeddedSource = new Guid("0e8a571b-6926-466e-b4ad-8ab04611f5fe");
public static readonly Guid SourceLink = new Guid("CC110556-A091-4D38-9FEC-25AB9A351A6A");
public static readonly Guid MethodSteppingInformation = new Guid("54FD2AC5-E925-401A-9C2A-F94F171072F8");
public static readonly Guid CompilationOptions = new Guid("B5FEEC05-8CD0-4A83-96DA-466284BB4BD8");
public static readonly Guid CompilationMetadataReferences = new Guid("7E4D4708-096E-4C5C-AEDA-CB10BA6A740D");
public static readonly Guid TupleElementNames = new Guid("ED9FDF71-8879-4747-8ED3-FE5EDE3CE710");
public static readonly Guid HashAlgorithmSHA1 = new Guid("ff1816ec-aa5e-4d10-87f7-6f4963833460");
public static readonly Guid HashAlgorithmSHA256 = new Guid("8829d00f-11b8-4213-878b-770e8597ac16");

17
ICSharpCode.Decompiler/DebugInfo/PortablePdbWriter.cs

@ -216,10 +216,21 @@ namespace ICSharpCode.Decompiler.DebugInfo @@ -216,10 +216,21 @@ namespace ICSharpCode.Decompiler.DebugInfo
methodBody = null;
localSignatureRowId = 0;
}
if (sequencePoints?.Count > 0)
sequencePointBlobs.Add(method, (document, EncodeSequencePoints(metadata, localSignatureRowId, sequencePoints)));
// Check if sequence points were already processed - ILFunction gets defined in C# twice:
// This may happen if a compiler-generated function gets transformed into a lambda expression,
// but its method definition is not removed from the syntax tree.
if (!sequencePointBlobs.ContainsKey(method))
{
if (sequencePoints?.Count > 0)
sequencePointBlobs.Add(method, (document, EncodeSequencePoints(metadata, localSignatureRowId, sequencePoints)));
else
sequencePointBlobs.Add(method, (default, default));
}
else
sequencePointBlobs.Add(method, (default, default));
{
Debug.Assert(false, "Duplicate sequence point definition detected: " + MetadataTokens.GetToken(method).ToString("X8"));
}
}
}

6
ICSharpCode.Decompiler/Documentation/XmlDocumentationProvider.cs

@ -271,8 +271,8 @@ namespace ICSharpCode.Decompiler.Documentation @@ -271,8 +271,8 @@ namespace ICSharpCode.Decompiler.Documentation
char prevChar = '\0';
// buffers for use with Decoder:
byte[] input = new byte[1];
char[] output = new char[1];
readonly byte[] input = new byte[1];
readonly char[] output = new char[2];
public LinePositionMapper(FileStream fs, Encoding encoding)
{
@ -289,7 +289,7 @@ namespace ICSharpCode.Decompiler.Documentation @@ -289,7 +289,7 @@ namespace ICSharpCode.Decompiler.Documentation
if (b < 0)
throw new EndOfStreamException();
input[0] = (byte)b;
decoder.Convert(input, 0, 1, output, 0, 1, false, out int bytesUsed, out int charsUsed, out _);
decoder.Convert(input, 0, 1, output, 0, output.Length, false, out int bytesUsed, out int charsUsed, out _);
Debug.Assert(bytesUsed == 1);
if (charsUsed == 1)
{

1
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -91,6 +91,7 @@ @@ -91,6 +91,7 @@
<Compile Include="Documentation\XmlDocumentationElement.cs" />
<Compile Include="IL\ControlFlow\AwaitInFinallyTransform.cs" />
<Compile Include="IL\Transforms\IntroduceNativeIntTypeOnLocals.cs" />
<Compile Include="Metadata\ReferenceLoadInfo.cs" />
<Compile Include="Semantics\OutVarResolveResult.cs" />
<Compile Include="SingleFileBundle.cs" />
<Compile Include="Solution\ProjectId.cs" />

6
ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs

@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata;
@ -473,6 +474,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -473,6 +474,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
reservedVariableNames.Add(proposedName, 0);
}
int count = ++reservedVariableNames[proposedName];
Debug.Assert(!string.IsNullOrWhiteSpace(proposedName));
if (count > 1)
{
return proposedName + count.ToString();
@ -763,6 +765,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -763,6 +765,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
reservedVariableNames.Add(proposedName, 0);
}
int count = ++reservedVariableNames[proposedName];
Debug.Assert(!string.IsNullOrWhiteSpace(proposedName));
if (count > 1)
{
return proposedName + count.ToString();
@ -815,6 +818,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -815,6 +818,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
reservedVariableNames.Add(proposedName, 0);
}
int count = ++reservedVariableNames[proposedName];
Debug.Assert(!string.IsNullOrWhiteSpace(proposedName));
if (count > 1)
{
return proposedName + count.ToString();
@ -828,7 +832,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -828,7 +832,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
private static bool IsPlural(string baseName, ref string proposedName)
{
var newName = Vocabularies.Default.Singularize(baseName, inputIsKnownToBePlural: false);
if (newName == baseName)
if (string.IsNullOrWhiteSpace(newName) || newName == baseName)
return false;
proposedName = newName;
return true;

2
ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs

@ -459,6 +459,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -459,6 +459,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return ldloc.Variable.IsRefReadOnly;
case Call call:
return call.Method.ReturnTypeIsRefReadOnly;
case CallVirt call:
return call.Method.ReturnTypeIsRefReadOnly;
case CallIndirect calli:
return calli.FunctionPointerType.ReturnIsRefReadOnly;
case AddressOf _:

26
ICSharpCode.Decompiler/IL/Transforms/TransformAssignment.cs

@ -19,9 +19,9 @@ @@ -19,9 +19,9 @@
using System;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.IL.Transforms
@ -384,7 +384,29 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -384,7 +384,29 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return false;
context.Step($"Compound assignment (dynamic binary)", compoundStore);
finalizeMatch?.Invoke(context);
newInst = new DynamicCompoundAssign(dynamicBinaryOp.Operation, dynamicBinaryOp.BinderFlags, target, dynamicBinaryOp.LeftArgumentInfo, dynamicBinaryOp.Right, dynamicBinaryOp.RightArgumentInfo, targetKind);
newInst = new DynamicCompoundAssign(ToCompound(dynamicBinaryOp.Operation), dynamicBinaryOp.BinderFlags, target, dynamicBinaryOp.LeftArgumentInfo, dynamicBinaryOp.Right, dynamicBinaryOp.RightArgumentInfo, targetKind);
static ExpressionType ToCompound(ExpressionType from)
{
return from switch
{
ExpressionType.Add => ExpressionType.AddAssign,
ExpressionType.AddChecked => ExpressionType.AddAssignChecked,
ExpressionType.And => ExpressionType.AndAssign,
ExpressionType.Divide => ExpressionType.DivideAssign,
ExpressionType.ExclusiveOr => ExpressionType.ExclusiveOrAssign,
ExpressionType.LeftShift => ExpressionType.LeftShiftAssign,
ExpressionType.Modulo => ExpressionType.ModuloAssign,
ExpressionType.Multiply => ExpressionType.MultiplyAssign,
ExpressionType.MultiplyChecked => ExpressionType.MultiplyAssignChecked,
ExpressionType.Or => ExpressionType.OrAssign,
ExpressionType.Power => ExpressionType.PowerAssign,
ExpressionType.RightShift => ExpressionType.RightShiftAssign,
ExpressionType.Subtract => ExpressionType.SubtractAssign,
ExpressionType.SubtractChecked => ExpressionType.SubtractAssignChecked,
_ => from
};
}
}
else if (setterValue is Call concatCall && UserDefinedCompoundAssign.IsStringConcat(concatCall.Method))
{

20
ICSharpCode.Decompiler/Metadata/DotNetCorePathFinder.cs

@ -75,10 +75,13 @@ namespace ICSharpCode.Decompiler.Metadata @@ -75,10 +75,13 @@ namespace ICSharpCode.Decompiler.Metadata
readonly List<string> packageBasePaths = new List<string>();
readonly Version targetFrameworkVersion;
readonly string dotnetBasePath = FindDotNetExeDirectory();
readonly string preferredRuntimePack;
public DotNetCorePathFinder(TargetFrameworkIdentifier targetFramework, Version targetFrameworkVersion)
public DotNetCorePathFinder(TargetFrameworkIdentifier targetFramework, Version targetFrameworkVersion,
string preferredRuntimePack)
{
this.targetFrameworkVersion = targetFrameworkVersion;
this.preferredRuntimePack = preferredRuntimePack;
if (targetFramework == TargetFrameworkIdentifier.NETStandard)
{
@ -90,8 +93,9 @@ namespace ICSharpCode.Decompiler.Metadata @@ -90,8 +93,9 @@ namespace ICSharpCode.Decompiler.Metadata
}
}
public DotNetCorePathFinder(string parentAssemblyFileName, string targetFrameworkIdString, TargetFrameworkIdentifier targetFramework, Version targetFrameworkVersion, ReferenceLoadInfo loadInfo = null)
: this(targetFramework, targetFrameworkVersion)
public DotNetCorePathFinder(string parentAssemblyFileName, string targetFrameworkIdString, string preferredRuntimePack,
TargetFrameworkIdentifier targetFramework, Version targetFrameworkVersion, ReferenceLoadInfo loadInfo = null)
: this(targetFramework, targetFrameworkVersion, preferredRuntimePack)
{
string assemblyName = Path.GetFileNameWithoutExtension(parentAssemblyFileName);
string basePath = Path.GetDirectoryName(parentAssemblyFileName);
@ -203,7 +207,15 @@ namespace ICSharpCode.Decompiler.Metadata @@ -203,7 +207,15 @@ namespace ICSharpCode.Decompiler.Metadata
runtimePack = null;
return null;
}
foreach (string pack in RuntimePacks)
IEnumerable<string> runtimePacks = RuntimePacks;
if (preferredRuntimePack != null)
{
runtimePacks = new[] { preferredRuntimePack }.Concat(runtimePacks);
}
foreach (string pack in runtimePacks)
{
runtimePack = pack;
string basePath = Path.Combine(dotnetBasePath, "shared", pack);

70
ICSharpCode.Decompiler/Metadata/DotNetCorePathFinderExtensions.cs

@ -17,8 +17,6 @@ @@ -17,8 +17,6 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using System.Text.RegularExpressions;
@ -187,68 +185,42 @@ namespace ICSharpCode.Decompiler.Metadata @@ -187,68 +185,42 @@ namespace ICSharpCode.Decompiler.Metadata
var refPathMatch = Regex.Match(assemblyPath, RefPathPattern, RegexOptions.IgnoreCase | RegexOptions.Compiled);
return refPathMatch.Success;
}
}
public class ReferenceLoadInfo
{
readonly Dictionary<string, UnresolvedAssemblyNameReference> loadedAssemblyReferences = new Dictionary<string, UnresolvedAssemblyNameReference>();
public void AddMessage(string fullName, MessageKind kind, string message)
public static string DetectRuntimePack(this PEFile assembly)
{
lock (loadedAssemblyReferences)
if (assembly is null)
{
if (!loadedAssemblyReferences.TryGetValue(fullName, out var referenceInfo))
{
referenceInfo = new UnresolvedAssemblyNameReference(fullName);
loadedAssemblyReferences.Add(fullName, referenceInfo);
}
referenceInfo.Messages.Add((kind, message));
throw new ArgumentNullException(nameof(assembly));
}
}
public void AddMessageOnce(string fullName, MessageKind kind, string message)
{
lock (loadedAssemblyReferences)
var metadata = assembly.Metadata;
foreach (var r in metadata.AssemblyReferences)
{
if (!loadedAssemblyReferences.TryGetValue(fullName, out var referenceInfo))
{
referenceInfo = new UnresolvedAssemblyNameReference(fullName);
loadedAssemblyReferences.Add(fullName, referenceInfo);
referenceInfo.Messages.Add((kind, message));
}
else
var reference = metadata.GetAssemblyReference(r);
if (reference.PublicKeyOrToken.IsNil)
continue;
if (metadata.StringComparer.Equals(reference.Name, "WindowsBase"))
{
var lastMsg = referenceInfo.Messages.LastOrDefault();
if (kind != lastMsg.Item1 && message != lastMsg.Item2)
referenceInfo.Messages.Add((kind, message));
return "Microsoft.WindowsDesktop.App";
}
}
}
public bool TryGetInfo(string fullName, out UnresolvedAssemblyNameReference info)
{
lock (loadedAssemblyReferences)
{
return loadedAssemblyReferences.TryGetValue(fullName, out info);
}
}
public IReadOnlyList<UnresolvedAssemblyNameReference> Entries {
get {
lock (loadedAssemblyReferences)
if (metadata.StringComparer.Equals(reference.Name, "PresentationFramework"))
{
return loadedAssemblyReferences.Values.ToList();
return "Microsoft.WindowsDesktop.App";
}
}
}
public bool HasErrors {
get {
lock (loadedAssemblyReferences)
if (metadata.StringComparer.Equals(reference.Name, "PresentationCore"))
{
return loadedAssemblyReferences.Any(i => i.Value.HasErrors);
return "Microsoft.WindowsDesktop.App";
}
// TODO add support for ASP.NET Core
}
return "Microsoft.NETCore.App";
}
}
}

87
ICSharpCode.Decompiler/Metadata/ReferenceLoadInfo.cs

@ -0,0 +1,87 @@ @@ -0,0 +1,87 @@
// Copyright (c) 2018 Siegfried Pammer
//
// 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 System.Linq;
namespace ICSharpCode.Decompiler.Metadata
{
public class ReferenceLoadInfo
{
readonly Dictionary<string, UnresolvedAssemblyNameReference> loadedAssemblyReferences = new Dictionary<string, UnresolvedAssemblyNameReference>();
public void AddMessage(string fullName, MessageKind kind, string message)
{
lock (loadedAssemblyReferences)
{
if (!loadedAssemblyReferences.TryGetValue(fullName, out var referenceInfo))
{
referenceInfo = new UnresolvedAssemblyNameReference(fullName);
loadedAssemblyReferences.Add(fullName, referenceInfo);
}
referenceInfo.Messages.Add((kind, message));
}
}
public void AddMessageOnce(string fullName, MessageKind kind, string message)
{
lock (loadedAssemblyReferences)
{
if (!loadedAssemblyReferences.TryGetValue(fullName, out var referenceInfo))
{
referenceInfo = new UnresolvedAssemblyNameReference(fullName);
loadedAssemblyReferences.Add(fullName, referenceInfo);
referenceInfo.Messages.Add((kind, message));
}
else
{
var lastMsg = referenceInfo.Messages.LastOrDefault();
if (kind != lastMsg.Item1 && message != lastMsg.Item2)
referenceInfo.Messages.Add((kind, message));
}
}
}
public bool TryGetInfo(string fullName, out UnresolvedAssemblyNameReference info)
{
lock (loadedAssemblyReferences)
{
return loadedAssemblyReferences.TryGetValue(fullName, out info);
}
}
public IReadOnlyList<UnresolvedAssemblyNameReference> Entries {
get {
lock (loadedAssemblyReferences)
{
return loadedAssemblyReferences.Values.ToList();
}
}
}
public bool HasErrors {
get {
lock (loadedAssemblyReferences)
{
return loadedAssemblyReferences.Any(i => i.Value.HasErrors);
}
}
}
}
}

13
ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs

@ -88,6 +88,7 @@ namespace ICSharpCode.Decompiler.Metadata @@ -88,6 +88,7 @@ namespace ICSharpCode.Decompiler.Metadata
}
readonly string targetFramework;
readonly string runtimePack;
readonly TargetFrameworkIdentifier targetFrameworkIdentifier;
readonly Version targetFrameworkVersion;
@ -109,16 +110,20 @@ namespace ICSharpCode.Decompiler.Metadata @@ -109,16 +110,20 @@ namespace ICSharpCode.Decompiler.Metadata
/// "Silverlight", if the string doesn't match any of these, the resolver falls back to ".NET Framework",
/// which is "classic" .NET &lt;= 4.8.
/// </param>
/// <param name="runtimePack">
/// Identifier of the runtime pack this assembly was compiled for.
/// If omitted, falling back to "Microsoft.NETCore.App" and this is ignored in case of classic .NET</param>
/// <param name="streamOptions">Options used for the <see cref="PEReader"/>.</param>
/// <param name="metadataOptions">Options used for the <see cref="MetadataReader"/>.</param>
public UniversalAssemblyResolver(string mainAssemblyFileName, bool throwOnError, string targetFramework,
PEStreamOptions streamOptions = PEStreamOptions.Default, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default)
string runtimePack = null, PEStreamOptions streamOptions = PEStreamOptions.Default, MetadataReaderOptions metadataOptions = MetadataReaderOptions.Default)
{
this.mainAssemblyFileName = mainAssemblyFileName;
this.throwOnError = throwOnError;
this.streamOptions = streamOptions;
this.metadataOptions = metadataOptions;
this.targetFramework = targetFramework ?? string.Empty;
this.runtimePack = runtimePack ?? "Microsoft.NETCore.App";
(targetFrameworkIdentifier, targetFrameworkVersion) = ParseTargetFramework(this.targetFramework);
if (mainAssemblyFileName != null)
@ -228,7 +233,7 @@ namespace ICSharpCode.Decompiler.Metadata @@ -228,7 +233,7 @@ namespace ICSharpCode.Decompiler.Metadata
return FindWindowsMetadataFile(name);
}
string file = null;
string file;
switch (targetFrameworkIdentifier)
{
case TargetFrameworkIdentifier.NETCoreApp:
@ -238,9 +243,9 @@ namespace ICSharpCode.Decompiler.Metadata @@ -238,9 +243,9 @@ namespace ICSharpCode.Decompiler.Metadata
if (dotNetCorePathFinder == null)
{
if (mainAssemblyFileName == null)
dotNetCorePathFinder = new DotNetCorePathFinder(targetFrameworkIdentifier, targetFrameworkVersion);
dotNetCorePathFinder = new DotNetCorePathFinder(targetFrameworkIdentifier, targetFrameworkVersion, runtimePack);
else
dotNetCorePathFinder = new DotNetCorePathFinder(mainAssemblyFileName, targetFramework, targetFrameworkIdentifier, targetFrameworkVersion);
dotNetCorePathFinder = new DotNetCorePathFinder(mainAssemblyFileName, targetFramework, runtimePack, targetFrameworkIdentifier, targetFrameworkVersion);
foreach (var directory in directories)
{
dotNetCorePathFinder.AddSearchDirectory(directory);

14
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs

@ -66,21 +66,28 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -66,21 +66,28 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
this.symbolKind = SymbolKind.Method;
var (accessorOwner, semanticsAttribute) = module.PEFile.MethodSemanticsLookup.GetSemantics(handle);
const MethodAttributes finalizerAttributes = (MethodAttributes.Virtual | MethodAttributes.Family | MethodAttributes.HideBySig);
this.typeParameters = MetadataTypeParameter.Create(module, this, def.GetGenericParameters());
if (semanticsAttribute != 0)
{
this.symbolKind = SymbolKind.Accessor;
this.accessorOwner = accessorOwner;
this.AccessorKind = semanticsAttribute;
}
else if ((attributes & (MethodAttributes.SpecialName | MethodAttributes.RTSpecialName)) != 0)
else if ((attributes & (MethodAttributes.SpecialName | MethodAttributes.RTSpecialName)) != 0
&& typeParameters.Length == 0)
{
string name = this.Name;
if (name == ".cctor" || name == ".ctor")
{
this.symbolKind = SymbolKind.Constructor;
else if (name.StartsWith("op_", StringComparison.Ordinal))
}
else if (name.StartsWith("op_", StringComparison.Ordinal)
&& CSharp.Syntax.OperatorDeclaration.GetOperatorType(name) != null)
{
this.symbolKind = SymbolKind.Operator;
}
}
else if ((attributes & finalizerAttributes) == finalizerAttributes)
else if ((attributes & finalizerAttributes) == finalizerAttributes && typeParameters.Length == 0)
{
if (Name == "Finalize" && Parameters.Count == 0 && ReturnType.IsKnownType(KnownTypeCode.Void)
&& (DeclaringTypeDefinition as MetadataTypeDefinition)?.Kind == TypeKind.Class)
@ -88,7 +95,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -88,7 +95,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
this.symbolKind = SymbolKind.Destructor;
}
}
this.typeParameters = MetadataTypeParameter.Create(module, this, def.GetGenericParameters());
this.IsExtensionMethod = (attributes & MethodAttributes.Static) == MethodAttributes.Static
&& (module.TypeSystemOptions & TypeSystemOptions.ExtensionMethods) == TypeSystemOptions.ExtensionMethods
&& def.GetCustomAttributes().HasKnownAttribute(metadata, KnownAttribute.Extension);

2
ILSpy.BamlDecompiler/Baml/KnownThings.cs

@ -70,7 +70,7 @@ namespace ILSpy.BamlDecompiler.Baml @@ -70,7 +70,7 @@ namespace ILSpy.BamlDecompiler.Baml
public IModule FrameworkAssembly => assemblies[0];
IModule ResolveAssembly(string name)
{
IModule module = typeSystem.Modules.FirstOrDefault(m => m.FullAssemblyName == name);
IModule module = typeSystem.Modules.FirstOrDefault(m => m.AssemblyName == name);
if (module == null)
throw new Exception("Could not resolve known assembly '" + name + "'!");
return module;

18
ILSpy.BamlDecompiler/Baml/KnownThings.g.cs

@ -22,18 +22,20 @@ @@ -22,18 +22,20 @@
using System;
namespace ILSpy.BamlDecompiler.Baml {
internal partial class KnownThings {
namespace ILSpy.BamlDecompiler.Baml
{
internal partial class KnownThings
{
// Auto-generated. Do not modify.
void InitAssemblies()
{
assemblies[0] = ResolveAssembly("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
assemblies[1] = ResolveAssembly("System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
assemblies[2] = ResolveAssembly("WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
assemblies[3] = ResolveAssembly("PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
assemblies[4] = ResolveAssembly("PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
assemblies[5] = ResolveAssembly("System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
assemblies[0] = ResolveAssembly("mscorlib");
assemblies[1] = ResolveAssembly("System");
assemblies[2] = ResolveAssembly("WindowsBase");
assemblies[3] = ResolveAssembly("PresentationCore");
assemblies[4] = ResolveAssembly("PresentationFramework");
assemblies[5] = ResolveAssembly("System.Xml");
}
void InitTypes()

52
ILSpy.BamlDecompiler/Rewrite/ConnectionIdRewritePass.cs

@ -57,13 +57,15 @@ namespace ILSpy.BamlDecompiler.Rewrite @@ -57,13 +57,15 @@ namespace ILSpy.BamlDecompiler.Rewrite
foreach (var annotation in element.Annotations<BamlConnectionId>())
{
int index;
bool found = false;
if ((index = fieldAssignments.FindIndex(item => item.key.Contains(annotation.Id))) > -1)
{
var xName = ctx.GetKnownNamespace("Name", XamlContext.KnownNamespace_Xaml, element);
if (element.Attribute("Name") is null && element.Attribute(xName) is null)
element.Add(new XAttribute(xName, fieldAssignments[index].value.FieldName));
found = true;
}
else if ((index = eventMappings.FindIndex(item => item.key.Contains(annotation.Id))) > -1)
if ((index = eventMappings.FindIndex(item => item.key.Contains(annotation.Id))) > -1)
{
foreach (var entry in eventMappings[index].value)
{
@ -80,8 +82,9 @@ namespace ILSpy.BamlDecompiler.Rewrite @@ -80,8 +82,9 @@ namespace ILSpy.BamlDecompiler.Rewrite
element.Add(new XAttribute(xmlns + entry.EventName, entry.MethodName));
}
}
found = true;
}
else
if (!found)
{
element.Add(new XComment($"Unknown connection ID: {annotation.Id}"));
}
@ -159,20 +162,7 @@ namespace ILSpy.BamlDecompiler.Rewrite @@ -159,20 +162,7 @@ namespace ILSpy.BamlDecompiler.Rewrite
{
foreach (var section in ilSwitch.Sections)
{
var field = FindField(section.Body);
if (!(field is null))
{
fieldAssignments.Add((section.Labels, field));
}
else
{
events.Clear();
FindEvents(section.Body, events);
if (events.Count > 0)
{
eventMappings.Add((section.Labels, events.ToArray()));
}
}
Add(section.Labels, section.Body);
}
}
else
@ -189,20 +179,22 @@ namespace ILSpy.BamlDecompiler.Rewrite @@ -189,20 +179,22 @@ namespace ILSpy.BamlDecompiler.Rewrite
? ifInst.FalseInst
: ifInst.TrueInst;
var field = FindField(inst);
if (!(field is null))
{
fieldAssignments.Add((new LongSet(id), field));
}
else
{
events.Clear();
FindEvents(inst, events);
if (events.Count > 0)
{
eventMappings.Add((new LongSet(id), events.ToArray()));
}
}
Add(new LongSet(id), inst);
}
}
void Add(LongSet ids, ILInstruction inst)
{
var field = FindField(inst);
if (!(field is null))
{
fieldAssignments.Add((ids, field));
}
events.Clear();
FindEvents(inst, events);
if (events.Count > 0)
{
eventMappings.Add((ids, events.ToArray()));
}
}
}

5
ILSpy.ReadyToRun/ReadyToRunLanguage.cs

@ -104,6 +104,11 @@ namespace ICSharpCode.ILSpy.ReadyToRun @@ -104,6 +104,11 @@ namespace ICSharpCode.ILSpy.ReadyToRun
get { return ".asm"; }
}
public override void WriteCommentLine(ITextOutput output, string comment)
{
output.WriteLine("; " + comment);
}
public override ProjectId DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options)
{
PEFile module = assembly.GetPEFileAsync().GetAwaiter().GetResult();

4
ILSpy/AboutPage.cs

@ -133,7 +133,7 @@ namespace ICSharpCode.ILSpy @@ -133,7 +133,7 @@ namespace ICSharpCode.ILSpy
static void AddUpdateCheckButton(StackPanel stackPanel, DecompilerTextView textView)
{
Button button = new Button();
Button button = ThemeManager.Current.CreateButton();
button.Content = Resources.CheckUpdates;
button.Cursor = Cursors.Arrow;
stackPanel.Children.Add(button);
@ -185,7 +185,7 @@ namespace ICSharpCode.ILSpy @@ -185,7 +185,7 @@ namespace ICSharpCode.ILSpy
});
if (availableVersion.DownloadUrl != null)
{
Button button = new Button();
Button button = ThemeManager.Current.CreateButton();
button.Content = Resources.Download;
button.Cursor = Cursors.Arrow;
button.Click += delegate {

14
ILSpy/Analyzers/AnalyzerScope.cs

@ -76,13 +76,8 @@ namespace ICSharpCode.ILSpy.Analyzers @@ -76,13 +76,8 @@ namespace ICSharpCode.ILSpy.Analyzers
public IEnumerable<PEFile> GetAllModules()
{
foreach (var module in AssemblyList.GetAssemblies())
{
var file = module.GetPEFileOrNull();
if (file == null)
continue;
yield return file;
}
return AssemblyList.GetAllAssemblies().GetAwaiter().GetResult()
.Select(asm => asm.GetPEFileOrNull());
}
public IEnumerable<ITypeDefinition> GetTypesInScope(CancellationToken ct)
@ -139,7 +134,7 @@ namespace ICSharpCode.ILSpy.Analyzers @@ -139,7 +134,7 @@ namespace ICSharpCode.ILSpy.Analyzers
do
{
PEFile curFile = toWalkFiles.Pop();
foreach (var assembly in AssemblyList.GetAssemblies())
foreach (var assembly in AssemblyList.GetAllAssemblies().GetAwaiter().GetResult())
{
ct.ThrowIfCancellationRequested();
bool found = false;
@ -187,7 +182,8 @@ namespace ICSharpCode.ILSpy.Analyzers @@ -187,7 +182,8 @@ namespace ICSharpCode.ILSpy.Analyzers
if (friendAssemblies.Count > 0)
{
IEnumerable<LoadedAssembly> assemblies = AssemblyList.GetAssemblies();
IEnumerable<LoadedAssembly> assemblies = AssemblyList.GetAllAssemblies()
.GetAwaiter().GetResult();
foreach (var assembly in assemblies)
{

8
ILSpy/App.xaml

@ -1,17 +1,19 @@ @@ -1,17 +1,19 @@
<Application x:Class="ICSharpCode.ILSpy.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:styles="urn:TomsToolbox.Wpf.Styles"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style x:Key="DialogWindow" TargetType="{x:Type Window}">
<Style x:Key="DialogWindow" TargetType="{x:Type Window}" BasedOn="{StaticResource {x:Static styles:ResourceKeys.WindowStyle}}">
<Setter Property="ShowInTaskbar" Value="False"/>
<Setter Property="UseLayoutRounding" Value="True"/>
<Setter Property="TextOptions.TextFormattingMode" Value="Display"/>
</Style>
<Style TargetType="{x:Type Button}">
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Static styles:ResourceKeys.ButtonStyle}}">
<Setter Property="MinWidth" Value="73" />
<Setter Property="Padding" Value="9,1,9,1" />
</Style>
</Application.Resources>
</Application>

13
ILSpy/App.xaml.cs

@ -33,6 +33,8 @@ using ICSharpCode.ILSpy.Options; @@ -33,6 +33,8 @@ using ICSharpCode.ILSpy.Options;
using Microsoft.VisualStudio.Composition;
using TomsToolbox.Wpf.Styles;
namespace ICSharpCode.ILSpy
{
/// <summary>
@ -67,6 +69,8 @@ namespace ICSharpCode.ILSpy @@ -67,6 +69,8 @@ namespace ICSharpCode.ILSpy
}
InitializeComponent();
Resources.RegisterDefaultStyles();
if (!System.Diagnostics.Debugger.IsAttached)
{
AppDomain.CurrentDomain.UnhandledException += ShowErrorBox;
@ -128,6 +132,13 @@ namespace ICSharpCode.ILSpy @@ -128,6 +132,13 @@ namespace ICSharpCode.ILSpy
// could be used to log the errors directly. Used at the end so that it does not prevent the export provider setup.
config.ThrowOnErrors();
}
catch (CompositionFailedException ex) when (ex.InnerException is AggregateException agex)
{
foreach (var inner in agex.InnerExceptions)
{
StartupExceptions.Add(new ExceptionData { Exception = inner });
}
}
catch (Exception ex)
{
StartupExceptions.Add(new ExceptionData { Exception = ex });
@ -186,7 +197,7 @@ namespace ICSharpCode.ILSpy @@ -186,7 +197,7 @@ namespace ICSharpCode.ILSpy
[ThreadStatic]
static bool showingError;
static void UnhandledException(Exception exception)
internal static void UnhandledException(Exception exception)
{
Debug.WriteLine(exception.ToString());
for (Exception ex = exception; ex != null; ex = ex.InnerException)

45
ILSpy/AssemblyList.cs

@ -110,6 +110,48 @@ namespace ICSharpCode.ILSpy @@ -110,6 +110,48 @@ namespace ICSharpCode.ILSpy
}
}
/// <summary>
/// Gets all loaded assemblies recursively, including assemblies found in bundles or packages.
/// </summary>
public async Task<IList<LoadedAssembly>> GetAllAssemblies()
{
var assemblies = GetAssemblies();
var results = new List<LoadedAssembly>(assemblies.Length);
foreach (var asm in assemblies)
{
var result = await asm.GetLoadResultAsync();
if (result.Package != null)
{
AddDescendants(result.Package.RootFolder);
}
else if (result.PEFile != null)
{
results.Add(asm);
}
}
void AddDescendants(PackageFolder folder)
{
foreach (var subFolder in folder.Folders)
{
AddDescendants(subFolder);
}
foreach (var entry in folder.Entries)
{
if (!entry.Name.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
continue;
var asm = folder.ResolveFileName(entry.Name);
if (asm == null)
continue;
results.Add(asm);
}
}
return results;
}
public int Count {
get {
lock (lockObj)
@ -233,6 +275,7 @@ namespace ICSharpCode.ILSpy @@ -233,6 +275,7 @@ namespace ICSharpCode.ILSpy
/// </remarks>
public LoadedAssembly OpenAssembly(string file, bool isAutoLoaded = false)
{
file = Path.GetFullPath(file);
return OpenAssembly(file, () => {
var newAsm = new LoadedAssembly(this, file);
newAsm.IsAutoLoaded = isAutoLoaded;
@ -245,6 +288,7 @@ namespace ICSharpCode.ILSpy @@ -245,6 +288,7 @@ namespace ICSharpCode.ILSpy
/// </summary>
public LoadedAssembly OpenAssembly(string file, Stream stream, bool isAutoLoaded = false)
{
file = Path.GetFullPath(file);
return OpenAssembly(file, () => {
var newAsm = new LoadedAssembly(this, file, stream: Task.FromResult(stream));
newAsm.IsAutoLoaded = isAutoLoaded;
@ -254,7 +298,6 @@ namespace ICSharpCode.ILSpy @@ -254,7 +298,6 @@ namespace ICSharpCode.ILSpy
LoadedAssembly OpenAssembly(string file, Func<LoadedAssembly> load)
{
file = Path.GetFullPath(file);
bool isUIThread = App.Current.Dispatcher.Thread == Thread.CurrentThread;
LoadedAssembly asm;

35
ILSpy/Commands/SearchMsdnContextMenuEntry.cs

@ -57,13 +57,13 @@ namespace ICSharpCode.ILSpy @@ -57,13 +57,13 @@ namespace ICSharpCode.ILSpy
if (node is EventTreeNode eventNode && (!eventNode.IsPublicAPI || !IsAccessible(eventNode.EventDefinition)))
return false;
if (node is FieldTreeNode fieldNode && (!fieldNode.IsPublicAPI || !IsAccessible(fieldNode.FieldDefinition)))
if (node is FieldTreeNode fieldNode && (!fieldNode.IsPublicAPI || !IsAccessible(fieldNode.FieldDefinition) || IsDelegateOrEnumMember(fieldNode.FieldDefinition)))
return false;
if (node is PropertyTreeNode propertyNode && (!propertyNode.IsPublicAPI || !IsAccessible(propertyNode.PropertyDefinition)))
return false;
if (node is MethodTreeNode methodNode && (!methodNode.IsPublicAPI || !IsAccessible(methodNode.MethodDefinition)))
if (node is MethodTreeNode methodNode && (!methodNode.IsPublicAPI || !IsAccessible(methodNode.MethodDefinition) || IsDelegateOrEnumMember(methodNode.MethodDefinition)))
return false;
if (node is NamespaceTreeNode namespaceNode && string.IsNullOrEmpty(namespaceNode.Name))
@ -88,6 +88,20 @@ namespace ICSharpCode.ILSpy @@ -88,6 +88,20 @@ namespace ICSharpCode.ILSpy
}
}
bool IsDelegateOrEnumMember(IMember member)
{
if (member.DeclaringTypeDefinition == null)
return false;
switch (member.DeclaringTypeDefinition.Kind)
{
case TypeKind.Delegate:
case TypeKind.Enum:
return true;
default:
return false;
}
}
public void Execute(TextViewContext context)
{
if (context.SelectedTreeNodes != null)
@ -103,19 +117,16 @@ namespace ICSharpCode.ILSpy @@ -103,19 +117,16 @@ namespace ICSharpCode.ILSpy
{
var address = string.Empty;
var namespaceNode = node as NamespaceTreeNode;
if (namespaceNode != null)
if (node is NamespaceTreeNode namespaceNode)
{
address = string.Format(msdnAddress, namespaceNode.Name);
if (node is IMemberTreeNode memberNode)
}
else if (node is IMemberTreeNode memberNode)
{
var member = memberNode.Member;
var memberName = string.Empty;
if (member.DeclaringType == null)
memberName = member.FullName;
else
memberName = string.Format("{0}.{1}", member.DeclaringType.FullName, member.Name);
var memberName = member.ReflectionName.Replace('`', '-').Replace('+', '.');
if (memberName.EndsWith("..ctor", System.StringComparison.Ordinal))
memberName = memberName.Substring(0, memberName.Length - 5) + "-ctor";
address = string.Format(msdnAddress, memberName);
}

6
ILSpy/Controls/ResourceObjectTable.xaml

@ -13,11 +13,11 @@ @@ -13,11 +13,11 @@
<Grid Margin="5,0,0,0">
<Grid.Resources>
<AlternationConverter x:Key="BackgroundConverter">
<SolidColorBrush Color="White"></SolidColorBrush>
<SolidColorBrush Color="Beige"></SolidColorBrush>
<SolidColorBrush Color="Transparent" />
<SolidColorBrush Color="#CCCC33" Opacity="0.15" />
</AlternationConverter>
<Style x:Key="alternatingWithBinding"
TargetType="{x:Type ListBoxItem}">
TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource {x:Type ListBoxItem}}">
<Setter Property="Background"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(ItemsControl.AlternationIndex),

31
ILSpy/Controls/ResourceStringTable.xaml

@ -13,11 +13,11 @@ @@ -13,11 +13,11 @@
<Grid Margin="5,0,0,0">
<Grid.Resources>
<AlternationConverter x:Key="BackgroundConverter">
<SolidColorBrush Color="White"></SolidColorBrush>
<SolidColorBrush Color="Beige"></SolidColorBrush>
<SolidColorBrush Color="Transparent" />
<SolidColorBrush Color="#CCCC33" Opacity="0.15" />
</AlternationConverter>
<Style x:Key="alternatingWithBinding"
TargetType="{x:Type ListBoxItem}">
TargetType="{x:Type ListViewItem}" BasedOn="{StaticResource {x:Type ListViewItem}}">
<Setter Property="Background"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(ItemsControl.AlternationIndex),
@ -35,27 +35,26 @@ @@ -35,27 +35,26 @@
<ListView Name="resourceListView"
FontFamily="Segoe UI"
FontSize="9pt"
Foreground="Black"
Grid.Row="1"
AlternationCount="2"
ItemContainerStyle="{StaticResource alternatingWithBinding}"
local:SortableGridViewColumn.SortMode="Automatic">
<ListView.View>
<GridView AllowsColumnReorder="False">
<GridView.Columns>
<local:SortableGridViewColumn DisplayMemberBinding="{Binding Key}" SortBy="Key">
<GridViewColumnHeader Content="{x:Static properties:Resources.Name}"
<ListView.View>
<GridView AllowsColumnReorder="False">
<GridView.Columns>
<local:SortableGridViewColumn DisplayMemberBinding="{Binding Key}" SortBy="Key">
<GridViewColumnHeader Content="{x:Static properties:Resources.Name}"
HorizontalContentAlignment="Left"
FontWeight="Bold" />
</local:SortableGridViewColumn>
</local:SortableGridViewColumn>
<local:SortableGridViewColumn DisplayMemberBinding="{Binding Value}" SortBy="Value">
<GridViewColumnHeader Content="{x:Static properties:Resources.Value}"
<GridViewColumnHeader Content="{x:Static properties:Resources.Value}"
HorizontalContentAlignment="Left"
FontWeight="Bold" />
</local:SortableGridViewColumn>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
</local:SortableGridViewColumn>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
</Grid>
</UserControl>

5
ILSpy/Controls/SearchBoxStyle.xaml

@ -2,10 +2,7 @@ @@ -2,10 +2,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ICSharpCode.ILSpy.Controls">
<Style x:Key="{x:Type local:SearchBox}" TargetType="{x:Type local:SearchBox}">
<Setter Property="Background" Value="White" />
<Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" />
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
<Style x:Key="{x:Type local:SearchBox}" TargetType="{x:Type local:SearchBox}" BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>

59
ILSpy/DebugInfo/PortableDebugInfoProvider.cs

@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection.Metadata;
using ICSharpCode.Decompiler.DebugInfo;
@ -28,8 +29,8 @@ namespace ICSharpCode.Decompiler.PdbProvider @@ -28,8 +29,8 @@ namespace ICSharpCode.Decompiler.PdbProvider
{
string pdbFileName;
string moduleFileName;
internal MetadataReaderProvider Provider { get; }
readonly MetadataReaderProvider provider;
bool hasError;
internal bool IsEmbedded => pdbFileName == null;
@ -38,20 +39,54 @@ namespace ICSharpCode.Decompiler.PdbProvider @@ -38,20 +39,54 @@ namespace ICSharpCode.Decompiler.PdbProvider
{
this.pdbFileName = pdbFileName;
this.moduleFileName = moduleFileName;
this.Provider = provider ?? throw new ArgumentNullException(nameof(provider));
this.provider = provider ?? throw new ArgumentNullException(nameof(provider));
}
public string Description {
get {
if (pdbFileName == null)
{
if (hasError)
return "Error while loading the PDB stream embedded in this assembly";
return "Embedded in this assembly";
}
else
{
if (hasError)
return $"Error while loading portable PDB: {pdbFileName}";
return $"Loaded from portable PDB: {pdbFileName}";
}
}
}
public string Description => pdbFileName == null
? "Embedded in this assembly"
: $"Loaded from portable PDB: {pdbFileName}";
internal MetadataReader GetMetadataReader()
{
try
{
hasError = false;
return provider.GetMetadataReader();
}
catch (BadImageFormatException)
{
hasError = true;
return null;
}
catch (IOException)
{
hasError = true;
return null;
}
}
public string SourceFileName => pdbFileName ?? moduleFileName;
public IList<DebugInfo.SequencePoint> GetSequencePoints(MethodDefinitionHandle method)
{
var metadata = Provider.GetMetadataReader();
var metadata = GetMetadataReader();
var debugInfo = metadata.GetMethodDebugInformation(method);
var sequencePoints = new List<Decompiler.DebugInfo.SequencePoint>();
var sequencePoints = new List<DebugInfo.SequencePoint>();
if (metadata == null)
return sequencePoints;
foreach (var point in debugInfo.GetSequencePoints())
{
@ -82,8 +117,10 @@ namespace ICSharpCode.Decompiler.PdbProvider @@ -82,8 +117,10 @@ namespace ICSharpCode.Decompiler.PdbProvider
public IList<Variable> GetVariables(MethodDefinitionHandle method)
{
var metadata = Provider.GetMetadataReader();
var metadata = GetMetadataReader();
var variables = new List<Variable>();
if (metadata == null)
return variables;
foreach (var h in metadata.GetLocalScopes(method))
{
@ -100,8 +137,10 @@ namespace ICSharpCode.Decompiler.PdbProvider @@ -100,8 +137,10 @@ namespace ICSharpCode.Decompiler.PdbProvider
public bool TryGetName(MethodDefinitionHandle method, int index, out string name)
{
var metadata = Provider.GetMetadataReader();
var metadata = GetMetadataReader();
name = null;
if (metadata == null)
return false;
foreach (var h in metadata.GetLocalScopes(method))
{

19
ILSpy/ExtensionMethods.cs

@ -93,6 +93,25 @@ namespace ICSharpCode.ILSpy @@ -93,6 +93,25 @@ namespace ICSharpCode.ILSpy
}
return ~start;
}
public static void InsertSorted<T>(this IList<T> list, T item, IComparer<T> comparer)
{
if (list == null)
throw new ArgumentNullException(nameof(list));
if (comparer == null)
throw new ArgumentNullException(nameof(comparer));
if (list.Count == 0)
{
list.Add(item);
}
else
{
int index = list.BinarySearch(item, 0, list.Count, comparer);
list.Insert(index < 0 ? ~index : index, item);
}
}
/*
public static bool IsCustomAttribute(this TypeDefinition type)
{

9
ILSpy/ILSpy.csproj

@ -41,13 +41,14 @@ @@ -41,13 +41,14 @@
<PackageReference Include="System.IO.Compression" Version="4.3.0" />
<PackageReference Include="System.Reflection.Metadata" Version="$(SystemReflectionMetadataVersion)" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="$(SystemCompilerServicesUnsafeVersion)" />
<PackageReference Include="Dirkster.AvalonDock" Version="4.50.1" />
<PackageReference Include="Dirkster.AvalonDock.Themes.VS2013" Version="4.50.1" />
<PackageReference Include="Microsoft.VisualStudio.Composition" Version="16.9.6-alpha" />
<PackageReference Include="System.Composition" Version="$(SystemCompositionVersion)" />
<PackageReference Include="Mono.Cecil" Version="$(MonoCecilVersion)" />
<PackageReference Include="OSVersionHelper" Version="1.1.24" />
<PackageReference Include="DataGridExtensions" Version="2.5.0" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.31" />
<PackageReference Include="TomsToolbox.Wpf.Styles" Version="2.4.2" />
</ItemGroup>
<ItemGroup>
@ -59,10 +60,16 @@ @@ -59,10 +60,16 @@
<Link>license.txt</Link>
</EmbeddedResource>
<Resource Include="Images\NuGet.png" />
<Resource Include="Images\DarkMode.png" />
<Resource Include="Images\ILSpy.ico" />
<EmbeddedResource Include="TextView\CSharp-Mode.xshd" />
<EmbeddedResource Include="TextView\ILAsm-Mode.xshd" />
<EmbeddedResource Include="TextView\Asm-Mode.xshd" />
<EmbeddedResource Include="TextView\XML-Mode.xshd" />
<EmbeddedResource Include="TextView\CSharp-Mode-Dark.xshd" />
<EmbeddedResource Include="TextView\ILAsm-Mode-Dark.xshd" />
<EmbeddedResource Include="TextView\Asm-Mode-Dark.xshd" />
<EmbeddedResource Include="TextView\XML-Mode-Dark.xshd" />
<Compile Remove="Properties\AssemblyInfo.template.cs" />
<None Remove="Properties\launchSettings.json" />
<None Remove="Properties\app.config.template" />

2
ILSpy/ISmartTextOutput.cs

@ -55,7 +55,7 @@ namespace ICSharpCode.ILSpy @@ -55,7 +55,7 @@ namespace ICSharpCode.ILSpy
{
output.AddUIElement(
delegate {
Button button = new Button();
Button button = ThemeManager.Current.CreateButton();
button.Cursor = Cursors.Arrow;
button.Margin = new Thickness(2);
button.Padding = new Thickness(9, 1, 9, 1);

BIN
ILSpy/Images/DarkMode.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 B

4
ILSpy/Languages/CSharpLanguage.cs

@ -688,13 +688,13 @@ namespace ICSharpCode.ILSpy @@ -688,13 +688,13 @@ namespace ICSharpCode.ILSpy
case HandleKind.EventDefinition:
var ed = metadata.GetEventDefinition((EventDefinitionHandle)handle);
declaringType = metadata.GetMethodDefinition(ed.GetAccessors().GetAny()).GetDeclaringType();
if (fullName)
if (fullName && !declaringType.IsNil)
return ToCSharpString(metadata, declaringType, fullName, omitGenerics) + "." + metadata.GetString(ed.Name);
return metadata.GetString(ed.Name);
case HandleKind.PropertyDefinition:
var pd = metadata.GetPropertyDefinition((PropertyDefinitionHandle)handle);
declaringType = metadata.GetMethodDefinition(pd.GetAccessors().GetAny()).GetDeclaringType();
if (fullName)
if (fullName && !declaringType.IsNil)
return ToCSharpString(metadata, declaringType, fullName, omitGenerics) + "." + metadata.GetString(pd.Name);
return metadata.GetString(pd.Name);
default:

34
ILSpy/LoadedAssembly.cs

@ -98,7 +98,7 @@ namespace ICSharpCode.ILSpy @@ -98,7 +98,7 @@ namespace ICSharpCode.ILSpy
this.shortName = Path.GetFileNameWithoutExtension(fileName);
}
public LoadedAssembly(LoadedAssembly bundle, string fileName, Task<Stream?>? stream, IAssemblyResolver assemblyResolver = null)
public LoadedAssembly(LoadedAssembly bundle, string fileName, Task<Stream?>? stream, IAssemblyResolver? assemblyResolver = null)
: this(bundle.assemblyList, fileName, stream, assemblyResolver)
{
this.ParentBundle = bundle;
@ -116,6 +116,12 @@ namespace ICSharpCode.ILSpy @@ -116,6 +116,12 @@ namespace ICSharpCode.ILSpy
return assembly.DetectTargetFrameworkId() ?? string.Empty;
}
public async Task<string> GetRuntimePackAsync()
{
var assembly = await GetPEFileAsync().ConfigureAwait(false);
return assembly.DetectRuntimePack() ?? string.Empty;
}
public ReferenceLoadInfo LoadedAssemblyReferencesInfo { get; } = new ReferenceLoadInfo();
IDebugInfoProvider? debugInfoProvider;
@ -610,9 +616,21 @@ namespace ICSharpCode.ILSpy @@ -610,9 +616,21 @@ namespace ICSharpCode.ILSpy
return new MyAssemblyResolver(this, loadOnDemand);
}
private MyUniversalResolver GetUniversalResolver()
private UniversalAssemblyResolver GetUniversalResolver()
{
return LazyInitializer.EnsureInitialized(ref this.universalResolver, () => new MyUniversalResolver(this))!;
return LazyInitializer.EnsureInitialized(ref this.universalResolver, () => {
var targetFramework = this.GetTargetFrameworkIdAsync().Result;
var runtimePack = this.GetRuntimePackAsync().Result;
var readerOptions = DecompilerSettingsPanel.CurrentDecompilerSettings.ApplyWindowsRuntimeProjections
? MetadataReaderOptions.ApplyWindowsRuntimeProjections
: MetadataReaderOptions.None;
var rootedPath = Path.IsPathRooted(this.FileName) ? this.FileName : null;
return new UniversalAssemblyResolver(rootedPath, throwOnError: false, targetFramework,
runtimePack, PEStreamOptions.PrefetchEntireImage, readerOptions);
})!;
}
public AssemblyReferenceClassifier GetAssemblyReferenceClassifier()
@ -630,15 +648,7 @@ namespace ICSharpCode.ILSpy @@ -630,15 +648,7 @@ namespace ICSharpCode.ILSpy
return debugInfoProvider;
}
class MyUniversalResolver : UniversalAssemblyResolver
{
public MyUniversalResolver(LoadedAssembly assembly)
: base(assembly.FileName, false, assembly.GetTargetFrameworkIdAsync().Result, PEStreamOptions.PrefetchEntireImage, DecompilerSettingsPanel.CurrentDecompilerSettings.ApplyWindowsRuntimeProjections ? MetadataReaderOptions.ApplyWindowsRuntimeProjections : MetadataReaderOptions.None)
{
}
}
MyUniversalResolver? universalResolver;
UniversalAssemblyResolver? universalResolver;
/// <summary>
/// Wait until the assembly is loaded.

34
ILSpy/MainWindow.xaml

@ -16,8 +16,11 @@ @@ -16,8 +16,11 @@
MinHeight="200"
UseLayoutRounding="True"
TextOptions.TextFormattingMode="Display"
Style="{StaticResource {x:Static styles:ResourceKeys.WindowStyle}}"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" d:DesignHeight="500" d:DesignWidth="500"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
xmlns:styles="urn:TomsToolbox.Wpf.Styles"
d:DataContext="{d:DesignInstance local:MainWindowDataContext}"
>
<Window.Resources>
<controls:BoolToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
@ -29,7 +32,7 @@ @@ -29,7 +32,7 @@
ShowRoot="False"
AllowDropOrder="True"
AllowDrop="True"
BorderThickness="0,1,1,1" Visibility="Visible" />
BorderThickness="0" Visibility="Visible" />
<DataTemplate x:Key="AssemblyListPaneTemplate">
<ContentControl Content="{StaticResource AssemblyTreeView}" />
@ -56,6 +59,9 @@ @@ -56,6 +59,9 @@
<DataTemplate x:Key="DefaultContentTemplate">
<ContentPresenter Content="{Binding Content}" />
</DataTemplate>
<styles:InvertGrayEffect x:Key="InvertGrayEffect" />
</Window.Resources>
<Window.CommandBindings>
@ -114,6 +120,20 @@ @@ -114,6 +120,20 @@
</DataTrigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type Image}" x:Key="DarkModeAwareImageStyle">
<Style.Triggers>
<DataTrigger
Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type ButtonBase}, AncestorLevel=1}, Path=IsEnabled}"
Value="False">
<Setter Property="Opacity" Value="0.30" />
</DataTrigger>
<DataTrigger
Binding="{Binding SessionSettings.IsDarkMode}"
Value="True">
<Setter Property="Effect" Value="{StaticResource InvertGrayEffect}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ToolBar.Resources>
<!-- 'Navigation' toolbar category is inserted here -->
<Separator />
@ -123,17 +143,17 @@ @@ -123,17 +143,17 @@
ItemsSource="{Binding AssemblyListManager.AssemblyLists}" ToolTip="{x:Static properties:Resources.SelectAssemblyListDropdownTooltip}"
SelectedItem="{Binding SessionSettings.ActiveAssemblyList}"/>
<Button Command="{x:Static local:ILSpyCommands.ManageAssemblyListsCommand}" ToolTip="{x:Static properties:Resources.ManageAssemblyLists}">
<Image Width="16" Height="16" Source="{controls:XamlResource Images/AssemblyList}" />
<Image Width="16" Height="16" Source="{controls:XamlResource Images/AssemblyList}" Style="{StaticResource DarkModeAwareImageStyle}"/>
</Button>
<Separator />
<CheckBox IsChecked="{Binding SessionSettings.FilterSettings.ApiVisPublicOnly}" ToolTip="{x:Static properties:Resources.ShowPublicOnlyTypesMembers}">
<Image Width="16" Height="16" Source="{controls:XamlResource Images/ShowPublicOnly}" />
<Image Width="16" Height="16" Source="{controls:XamlResource Images/ShowPublicOnly}" Style="{StaticResource DarkModeAwareImageStyle}"/>
</CheckBox>
<CheckBox IsChecked="{Binding SessionSettings.FilterSettings.ApiVisPublicAndInternal}" ToolTip="{x:Static properties:Resources.ShowInternalTypesMembers}">
<Image Width="16" Height="16" Source="{controls:XamlResource Images/ShowPrivateInternal}" />
<Image Width="16" Height="16" Source="{controls:XamlResource Images/ShowPrivateInternal}" Style="{StaticResource DarkModeAwareImageStyle}"/>
</CheckBox>
<CheckBox IsChecked="{Binding SessionSettings.FilterSettings.ApiVisAll}" ToolTip="{x:Static properties:Resources.ShowAllTypesAndMembers}">
<Image Width="16" Height="16" Source="{controls:XamlResource Images/ShowAll}" />
<Image Width="16" Height="16" Source="{controls:XamlResource Images/ShowAll}" Style="{StaticResource DarkModeAwareImageStyle}"/>
</CheckBox>
<Separator />
<ComboBox Name="languageComboBox" DisplayMemberPath="Name" Width="100" MaxDropDownHeight="Auto"
@ -145,6 +165,10 @@ @@ -145,6 +165,10 @@
IsEnabled="{Binding ActiveTabPage.SupportsLanguageSwitching, Source={x:Static docking:DockWorkspace.Instance}}"
ItemsSource="{Binding SelectedItem.LanguageVersions, ElementName=languageComboBox, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SessionSettings.FilterSettings.LanguageVersion, UpdateSourceTrigger=PropertyChanged}"/>
<Separator />
<CheckBox IsChecked="{Binding SessionSettings.IsDarkMode}" ToolTip="{x:Static properties:Resources.DarkMode}">
<Image Source="Images/DarkMode.png" Stretch="None" Style="{StaticResource DarkModeAwareImageStyle}"/>
</CheckBox>
</ToolBar>
<Border DockPanel.Dock="Top" BorderBrush="Black" BorderThickness="1" Name="updatePanel" Visibility="Collapsed">
<DockPanel KeyboardNavigation.TabNavigation="Contained">

8
ILSpy/MainWindow.xaml.cs

@ -140,6 +140,13 @@ namespace ICSharpCode.ILSpy @@ -140,6 +140,13 @@ namespace ICSharpCode.ILSpy
{
ShowAssemblyList(sessionSettings.ActiveAssemblyList);
}
if (e.PropertyName == nameof(SessionSettings.IsDarkMode))
{
// update syntax highlighting and force reload (AvalonEdit does not automatically refresh on highlighting change)
DecompilerTextView.RegisterHighlighting();
DecompileSelectedNodes(DockWorkspace.Instance.ActiveTabPage.GetState() as DecompilerTextViewState);
}
}
void SetWindowBounds(Rect bounds)
@ -189,6 +196,7 @@ namespace ICSharpCode.ILSpy @@ -189,6 +196,7 @@ namespace ICSharpCode.ILSpy
Button MakeToolbarItem(Lazy<ICommand, IToolbarCommandMetadata> command)
{
return new Button {
Style = ThemeManager.Current.CreateToolBarButtonStyle(),
Command = CommandWrapper.Unwrap(command.Value),
ToolTip = Properties.Resources.ResourceManager.GetString(command.Metadata.ToolTip),
Tag = command.Metadata.Tag,

1
ILSpy/Metadata/CoffHeaderTreeNode.cs

@ -111,6 +111,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -111,6 +111,7 @@ namespace ICSharpCode.ILSpy.Metadata
new { Value = (flags & 0x4000) != 0, Meaning = "<4000> File should only be run on a UP machine" },
new { Value = (flags & 0x8000) != 0, Meaning = "<8000> Bytes of machine words are reversed (High)" },
});
dataGridFactory.SetValue(DataGrid.GridLinesVisibilityProperty, DataGridGridLinesVisibility.None);
DataTemplate template = new DataTemplate();
template.VisualTree = dataGridFactory;
return template;

2
ILSpy/Metadata/CorTables/PropertyMapTableTreeNode.cs

@ -111,7 +111,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -111,7 +111,7 @@ namespace ICSharpCode.ILSpy.Metadata
}
[StringFormat("X8")]
public int EventList => MetadataTokens.GetToken(propertyMap.PropertyList);
public int PropertyList => MetadataTokens.GetToken(propertyMap.PropertyList);
public string PropertyListTooltip {
get {

84
ILSpy/Metadata/DebugMetadataTablesTreeNode.cs

@ -0,0 +1,84 @@ @@ -0,0 +1,84 @@
// Copyright (c) 2021 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.Collections.Generic;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.Options;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.ViewModels;
namespace ICSharpCode.ILSpy.Metadata
{
class DebugMetadataTablesTreeNode : ILSpyTreeNode
{
private PEFile module;
private bool isEmbedded;
private MetadataReader provider;
public DebugMetadataTablesTreeNode(PEFile module, bool isEmbedded, MetadataReader provider)
{
this.module = module;
this.isEmbedded = isEmbedded;
this.provider = provider;
this.LazyLoading = true;
}
public override object Text => "Tables";
public override object Icon => Images.Literal;
protected override void LoadChildren()
{
if (ShowTable(TableIndex.Document))
this.Children.Add(new DocumentTableTreeNode(this.module, this.provider, isEmbedded));
if (ShowTable(TableIndex.MethodDebugInformation))
this.Children.Add(new MethodDebugInformationTableTreeNode(this.module, this.provider, isEmbedded));
if (ShowTable(TableIndex.LocalScope))
this.Children.Add(new LocalScopeTableTreeNode(this.module, this.provider, isEmbedded));
if (ShowTable(TableIndex.LocalVariable))
this.Children.Add(new LocalVariableTableTreeNode(this.module, this.provider, isEmbedded));
if (ShowTable(TableIndex.LocalConstant))
this.Children.Add(new LocalConstantTableTreeNode(this.module, this.provider, isEmbedded));
if (ShowTable(TableIndex.ImportScope))
this.Children.Add(new ImportScopeTableTreeNode(this.module, this.provider, isEmbedded));
if (ShowTable(TableIndex.StateMachineMethod))
this.Children.Add(new StateMachineMethodTableTreeNode(this.module, this.provider, isEmbedded));
if (ShowTable(TableIndex.CustomDebugInformation))
this.Children.Add(new CustomDebugInformationTableTreeNode(this.module, this.provider, isEmbedded));
bool ShowTable(TableIndex table) => !DisplaySettingsPanel.CurrentDisplaySettings.HideEmptyMetadataTables || this.provider.GetTableRowCount(table) > 0;
}
public override bool View(TabPageModel tabPage)
{
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
return false;
}
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
{
language.WriteCommentLine(output, "Metadata Tables");
}
}
}

23
ILSpy/Metadata/DebugMetadataTreeNode.cs

@ -64,24 +64,11 @@ namespace ICSharpCode.ILSpy.Metadata @@ -64,24 +64,11 @@ namespace ICSharpCode.ILSpy.Metadata
protected override void LoadChildren()
{
if (ShowTable(TableIndex.Document))
this.Children.Add(new DocumentTableTreeNode(this.module, this.provider, isEmbedded));
if (ShowTable(TableIndex.MethodDebugInformation))
this.Children.Add(new MethodDebugInformationTableTreeNode(this.module, this.provider, isEmbedded));
if (ShowTable(TableIndex.LocalScope))
this.Children.Add(new LocalScopeTableTreeNode(this.module, this.provider, isEmbedded));
if (ShowTable(TableIndex.LocalVariable))
this.Children.Add(new LocalVariableTableTreeNode(this.module, this.provider, isEmbedded));
if (ShowTable(TableIndex.LocalConstant))
this.Children.Add(new LocalConstantTableTreeNode(this.module, this.provider, isEmbedded));
if (ShowTable(TableIndex.ImportScope))
this.Children.Add(new ImportScopeTableTreeNode(this.module, this.provider, isEmbedded));
if (ShowTable(TableIndex.StateMachineMethod))
this.Children.Add(new StateMachineMethodTableTreeNode(this.module, this.provider, isEmbedded));
if (ShowTable(TableIndex.CustomDebugInformation))
this.Children.Add(new CustomDebugInformationTableTreeNode(this.module, this.provider, isEmbedded));
bool ShowTable(TableIndex table) => !DisplaySettingsPanel.CurrentDisplaySettings.HideEmptyMetadataTables || this.provider.GetTableRowCount(table) > 0;
this.Children.Add(new DebugMetadataTablesTreeNode(module, this.isEmbedded, this.provider));
this.Children.Add(new StringHeapTreeNode(module, this.provider));
this.Children.Add(new UserStringHeapTreeNode(module, this.provider));
this.Children.Add(new GuidHeapTreeNode(module, this.provider));
this.Children.Add(new BlobHeapTreeNode(module, this.provider));
}
public MetadataTableTreeNode FindNodeByHandleKind(HandleKind kind)

257
ILSpy/Metadata/DebugTables/CustomDebugInformationTableTreeNode.cs

@ -17,11 +17,15 @@ @@ -17,11 +17,15 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.DebugInfo;
@ -51,6 +55,10 @@ namespace ICSharpCode.ILSpy.Metadata @@ -51,6 +55,10 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
view.RowDetailsVisibilityMode = DataGridRowDetailsVisibilityMode.VisibleWhenSelected;
view.RowDetailsTemplateSelector = new CustomDebugInformationDetailsTemplateSelector();
var list = new List<CustomDebugInformationEntry>();
CustomDebugInformationEntry scrollTargetEntry = default;
@ -68,7 +76,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -68,7 +76,7 @@ namespace ICSharpCode.ILSpy.Metadata
tabPage.Content = view;
if (scrollTargetEntry.RID > 1)
if (scrollTargetEntry?.RID > 1)
{
ScrollItemIntoView(view, scrollTargetEntry);
}
@ -76,17 +84,106 @@ namespace ICSharpCode.ILSpy.Metadata @@ -76,17 +84,106 @@ namespace ICSharpCode.ILSpy.Metadata
return true;
}
struct CustomDebugInformationEntry
class CustomDebugInformationDetailsTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var entry = (CustomDebugInformationEntry)item;
switch (entry.kind)
{
case CustomDebugInformationEntry.CustomDebugInformationKind.StateMachineHoistedLocalScopes:
case CustomDebugInformationEntry.CustomDebugInformationKind.CompilationMetadataReferences:
case CustomDebugInformationEntry.CustomDebugInformationKind.CompilationOptions:
case CustomDebugInformationEntry.CustomDebugInformationKind.TupleElementNames:
return (DataTemplate)MetadataTableViews.Instance["CustomDebugInformationDetailsDataGrid"];
default:
return (DataTemplate)MetadataTableViews.Instance["CustomDebugInformationDetailsTextBlob"];
}
}
}
class CustomDebugInformationEntry
{
readonly int? offset;
readonly PEFile module;
readonly MetadataReader metadata;
readonly CustomDebugInformationHandle handle;
readonly CustomDebugInformation debugInfo;
internal readonly CustomDebugInformationKind kind;
internal enum CustomDebugInformationKind
{
None,
Unknown,
StateMachineHoistedLocalScopes,
DynamicLocalVariables,
DefaultNamespaces,
EditAndContinueLocalSlotMap,
EditAndContinueLambdaAndClosureMap,
EmbeddedSource,
SourceLink,
MethodSteppingInformation,
CompilationOptions,
CompilationMetadataReferences,
TupleElementNames
}
static CustomDebugInformationKind GetKind(MetadataReader metadata, GuidHandle h)
{
if (h.IsNil)
return CustomDebugInformationKind.None;
var guid = metadata.GetGuid(h);
if (KnownGuids.StateMachineHoistedLocalScopes == guid)
{
return CustomDebugInformationKind.StateMachineHoistedLocalScopes;
}
if (KnownGuids.DynamicLocalVariables == guid)
{
return CustomDebugInformationKind.StateMachineHoistedLocalScopes;
}
if (KnownGuids.DefaultNamespaces == guid)
{
return CustomDebugInformationKind.StateMachineHoistedLocalScopes;
}
if (KnownGuids.EditAndContinueLocalSlotMap == guid)
{
return CustomDebugInformationKind.EditAndContinueLocalSlotMap;
}
if (KnownGuids.EditAndContinueLambdaAndClosureMap == guid)
{
return CustomDebugInformationKind.EditAndContinueLambdaAndClosureMap;
}
if (KnownGuids.EmbeddedSource == guid)
{
return CustomDebugInformationKind.EmbeddedSource;
}
if (KnownGuids.SourceLink == guid)
{
return CustomDebugInformationKind.SourceLink;
}
if (KnownGuids.MethodSteppingInformation == guid)
{
return CustomDebugInformationKind.MethodSteppingInformation;
}
if (KnownGuids.CompilationOptions == guid)
{
return CustomDebugInformationKind.CompilationOptions;
}
if (KnownGuids.CompilationMetadataReferences == guid)
{
return CustomDebugInformationKind.CompilationMetadataReferences;
}
if (KnownGuids.TupleElementNames == guid)
{
return CustomDebugInformationKind.TupleElementNames;
}
return CustomDebugInformationKind.Unknown;
}
public int RID => MetadataTokens.GetRowNumber(handle);
public object Offset => offset == null ? "n/a" : (object)offset;
public object Offset => offset == null ? "n/a" : offset;
[StringFormat("X8")]
public int Parent => MetadataTokens.GetToken(debugInfo.Parent);
@ -100,48 +197,66 @@ namespace ICSharpCode.ILSpy.Metadata @@ -100,48 +197,66 @@ namespace ICSharpCode.ILSpy.Metadata
}
}
[StringFormat("X8")]
public int Kind => MetadataTokens.GetHeapOffset(debugInfo.Kind);
string kindString;
public string KindTooltip {
public string Kind {
get {
if (debugInfo.Kind.IsNil)
return null;
var guid = metadata.GetGuid(debugInfo.Kind);
if (KnownGuids.StateMachineHoistedLocalScopes == guid)
{
return "State Machine Hoisted Local Scopes (C# / VB) [" + guid + "]";
}
if (KnownGuids.DynamicLocalVariables == guid)
{
return "Dynamic Local Variables (C#) [" + guid + "]";
}
if (KnownGuids.DefaultNamespaces == guid)
{
return "Default Namespaces (VB) [" + guid + "]";
}
if (KnownGuids.EditAndContinueLocalSlotMap == guid)
{
return "Edit And Continue Local Slot Map (C# / VB) [" + guid + "]";
}
if (KnownGuids.EditAndContinueLambdaAndClosureMap == guid)
{
return "Edit And Continue Lambda And Closure Map (C# / VB) [" + guid + "]";
}
if (KnownGuids.EmbeddedSource == guid)
if (kindString != null)
return kindString;
Guid guid;
if (kind != CustomDebugInformationKind.None)
{
return "Embedded Source (C# / VB) [" + guid + "]";
guid = metadata.GetGuid(debugInfo.Kind);
}
if (KnownGuids.SourceLink == guid)
else
{
return "Source Link (C# / VB) [" + guid + "]";
guid = Guid.Empty;
}
if (KnownGuids.MethodSteppingInformation == guid)
switch (kind)
{
return "Method Stepping Information (C# / VB) [" + guid + "]";
case CustomDebugInformationKind.None:
kindString = "";
break;
case CustomDebugInformationKind.StateMachineHoistedLocalScopes:
kindString = $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - State Machine Hoisted Local Scopes (C# / VB) [{guid}]";
break;
case CustomDebugInformationKind.DynamicLocalVariables:
kindString = $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Dynamic Local Variables (C#) [{guid}]";
break;
case CustomDebugInformationKind.DefaultNamespaces:
kindString = $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Default Namespaces (VB) [{guid}]";
break;
case CustomDebugInformationKind.EditAndContinueLocalSlotMap:
kindString = $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Edit And Continue Local Slot Map (C# / VB) [{guid}]";
break;
case CustomDebugInformationKind.EditAndContinueLambdaAndClosureMap:
kindString = $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Edit And Continue Lambda And Closure Map (C# / VB) [{guid}]";
break;
case CustomDebugInformationKind.EmbeddedSource:
kindString = $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Embedded Source (C# / VB) [{guid}]";
break;
case CustomDebugInformationKind.SourceLink:
kindString = $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Source Link (C# / VB) [{guid}]";
break;
case CustomDebugInformationKind.MethodSteppingInformation:
kindString = $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Method Stepping Information (C# / VB) [{guid}]";
break;
case CustomDebugInformationKind.CompilationOptions:
kindString = $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Compilation Options (C# / VB) [{ guid}]";
break;
case CustomDebugInformationKind.CompilationMetadataReferences:
kindString = $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Compilation Metadata References (C# / VB) [{ guid}]";
break;
case CustomDebugInformationKind.TupleElementNames:
kindString = $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Tuple Element Names (C#) [{ guid}]";
break;
default:
kindString = $"{MetadataTokens.GetHeapOffset(debugInfo.Kind):X8} - Unknown [{guid}]";
break;
}
return $"Unknown [" + guid + "]";
return kindString;
}
}
@ -156,6 +271,75 @@ namespace ICSharpCode.ILSpy.Metadata @@ -156,6 +271,75 @@ namespace ICSharpCode.ILSpy.Metadata
}
}
object rowDetails;
public object RowDetails {
get {
if (rowDetails != null)
return rowDetails;
if (debugInfo.Value.IsNil)
return null;
var reader = metadata.GetBlobReader(debugInfo.Value);
ArrayList list;
switch (kind)
{
case CustomDebugInformationKind.None:
return null;
case CustomDebugInformationKind.StateMachineHoistedLocalScopes:
list = new ArrayList();
while (reader.RemainingBytes > 0)
{
uint offset = reader.ReadUInt32();
uint length = reader.ReadUInt32();
list.Add(new { StartOffset = offset, Length = length });
}
return rowDetails = list;
case CustomDebugInformationKind.SourceLink:
return reader.ReadUTF8(reader.RemainingBytes);
case CustomDebugInformationKind.CompilationOptions:
list = new ArrayList();
while (reader.RemainingBytes > 0)
{
string name = reader.ReadUTF8StringNullTerminated();
string value = reader.ReadUTF8StringNullTerminated();
list.Add(new { Name = name, Value = value });
}
return rowDetails = list;
case CustomDebugInformationKind.CompilationMetadataReferences:
list = new ArrayList();
while (reader.RemainingBytes > 0)
{
string fileName = reader.ReadUTF8StringNullTerminated();
string aliases = reader.ReadUTF8StringNullTerminated();
byte flags = reader.ReadByte();
uint timestamp = reader.ReadUInt32();
uint fileSize = reader.ReadUInt32();
Guid guid = reader.ReadGuid();
list.Add(new { FileName = fileName, Aliases = aliases, Flags = flags, Timestamp = timestamp, FileSize = fileSize, Guid = guid });
}
return rowDetails = list;
case CustomDebugInformationKind.TupleElementNames:
list = new ArrayList();
while (reader.RemainingBytes > 0)
{
list.Add(new { ElementName = reader.ReadUTF8StringNullTerminated() });
}
return rowDetails = list;
default:
return reader.ToHexString();
}
}
}
public CustomDebugInformationEntry(PEFile module, MetadataReader metadata, bool isEmbedded, CustomDebugInformationHandle handle)
{
this.offset = isEmbedded ? null : (int?)metadata.GetTableMetadataOffset(TableIndex.CustomDebugInformation)
@ -164,6 +348,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -164,6 +348,7 @@ namespace ICSharpCode.ILSpy.Metadata
this.metadata = metadata;
this.handle = handle;
this.debugInfo = metadata.GetCustomDebugInformation(handle);
this.kind = GetKind(metadata, debugInfo.Kind);
}
}

2
ILSpy/Metadata/DebugTables/LocalScopeTableTreeNode.cs

@ -108,10 +108,8 @@ namespace ICSharpCode.ILSpy.Metadata @@ -108,10 +108,8 @@ namespace ICSharpCode.ILSpy.Metadata
[StringFormat("X8")]
public int ConstantList => MetadataTokens.GetToken(localScope.GetLocalConstants().FirstOrDefault());
[StringFormat("X8")]
public int StartOffset => localScope.StartOffset;
[StringFormat("X8")]
public int Length => localScope.Length;
public LocalScopeEntry(PEFile module, MetadataReader metadata, bool isEmbedded, LocalScopeHandle handle)

97
ILSpy/Metadata/Heaps/BlobHeapTreeNode.cs

@ -0,0 +1,97 @@ @@ -0,0 +1,97 @@
// 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;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.DebugInfo;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata
{
internal class BlobHeapTreeNode : MetadataHeapTreeNode
{
readonly List<BlobHeapEntry> list;
public BlobHeapTreeNode(PEFile module, MetadataReader metadata)
: base(HandleKind.Blob, module, metadata)
{
list = new List<BlobHeapEntry>();
BlobHandle handle = MetadataTokens.BlobHandle(0);
do
{
BlobHeapEntry entry = new BlobHeapEntry(metadata, handle);
list.Add(entry);
handle = metadata.GetNextHandle(handle);
} while (!handle.IsNil);
}
public override object Text => $"Blob Heap ({list.Count})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage)
{
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
view.ItemsSource = list;
tabPage.Content = view;
return true;
}
class BlobHeapEntry
{
readonly MetadataReader metadata;
readonly BlobHandle handle;
public int Offset => metadata.GetHeapOffset(handle);
public int Length => metadata.GetBlobReader(handle).Length;
public string Value => metadata.GetBlobReader(handle).ToHexString();
public BlobHeapEntry(MetadataReader metadata, BlobHandle handle)
{
this.metadata = metadata;
this.handle = handle;
}
}
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
{
language.WriteCommentLine(output, "Blob Heap");
}
}
}

86
ILSpy/Metadata/Heaps/GuidHeapTreeNode.cs

@ -0,0 +1,86 @@ @@ -0,0 +1,86 @@
// Copyright (c) 2021 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 System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata
{
internal class GuidHeapTreeNode : MetadataHeapTreeNode
{
readonly List<GuidHeapEntry> list;
public GuidHeapTreeNode(PEFile module, MetadataReader metadata)
: base(HandleKind.Guid, module, metadata)
{
list = new List<GuidHeapEntry>();
int count = metadata.GetHeapSize(HeapIndex.Guid) >> 4;
for (int i = 1; i <= count; i++)
{
GuidHeapEntry entry = new GuidHeapEntry(metadata, MetadataTokens.GuidHandle(i));
list.Add(entry);
}
}
public override object Text => $"Guid Heap ({list.Count})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage)
{
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
view.ItemsSource = list;
tabPage.Content = view;
return true;
}
class GuidHeapEntry
{
readonly MetadataReader metadata;
readonly GuidHandle handle;
public int Index => metadata.GetHeapOffset(handle);
public int Length => 16;
public string Value => metadata.GetGuid(handle).ToString();
public GuidHeapEntry(MetadataReader metadata, GuidHandle handle)
{
this.metadata = metadata;
this.handle = handle;
}
}
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
{
language.WriteCommentLine(output, "Guid Heap");
}
}
}

96
ILSpy/Metadata/Heaps/StringHeapTreeNode.cs

@ -0,0 +1,96 @@ @@ -0,0 +1,96 @@
// 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;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.DebugInfo;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata
{
internal class StringHeapTreeNode : MetadataHeapTreeNode
{
readonly List<StringHeapEntry> list;
public StringHeapTreeNode(PEFile module, MetadataReader metadata)
: base(HandleKind.String, module, metadata)
{
list = new List<StringHeapEntry>();
StringHandle handle = MetadataTokens.StringHandle(0);
do
{
StringHeapEntry entry = new StringHeapEntry(metadata, handle);
list.Add(entry);
handle = metadata.GetNextHandle(handle);
} while (!handle.IsNil);
}
public override object Text => $"String Heap ({list.Count})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage)
{
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
view.ItemsSource = list;
tabPage.Content = view;
return true;
}
class StringHeapEntry
{
readonly MetadataReader metadata;
readonly StringHandle handle;
public int Offset => metadata.GetHeapOffset(handle);
public int Length => metadata.GetString(handle).Length;
public string Value => metadata.GetString(handle);
public StringHeapEntry(MetadataReader metadata, StringHandle handle)
{
this.metadata = metadata;
this.handle = handle;
}
}
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
{
language.WriteCommentLine(output, "String Heap");
}
}
}

97
ILSpy/Metadata/Heaps/UserStringHeapTreeNode.cs

@ -0,0 +1,97 @@ @@ -0,0 +1,97 @@
// 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;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.DebugInfo;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.ILSpy.Metadata
{
internal class UserStringHeapTreeNode : MetadataHeapTreeNode
{
readonly List<UserStringHeapEntry> list;
public UserStringHeapTreeNode(PEFile module, MetadataReader metadata)
: base(HandleKind.UserString, module, metadata)
{
list = new List<UserStringHeapEntry>();
UserStringHandle handle = MetadataTokens.UserStringHandle(0);
do
{
UserStringHeapEntry entry = new UserStringHeapEntry(metadata, handle);
list.Add(entry);
handle = metadata.GetNextHandle(handle);
} while (!handle.IsNil);
}
public override object Text => $"UserString Heap ({list.Count})";
public override object Icon => Images.Literal;
public override bool View(ViewModels.TabPageModel tabPage)
{
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
var view = Helpers.PrepareDataGrid(tabPage, this);
view.ItemsSource = list;
tabPage.Content = view;
return true;
}
class UserStringHeapEntry
{
readonly MetadataReader metadata;
readonly UserStringHandle handle;
public int Offset => metadata.GetHeapOffset(handle);
public int Length => metadata.GetUserString(handle).Length;
public string Value => metadata.GetUserString(handle);
public UserStringHeapEntry(MetadataReader metadata, UserStringHandle handle)
{
this.metadata = metadata;
this.handle = handle;
}
}
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
{
language.WriteCommentLine(output, "UserString Heap");
}
}
}

21
ILSpy/Metadata/Helpers.cs

@ -62,13 +62,13 @@ namespace ICSharpCode.ILSpy.Metadata @@ -62,13 +62,13 @@ namespace ICSharpCode.ILSpy.Metadata
SelectionMode = DataGridSelectionMode.Single,
SelectionUnit = DataGridSelectionUnit.FullRow,
SelectedTreeNode = selectedNode,
VerticalContentAlignment = VerticalAlignment.Center,
CellStyle = (Style)MetadataTableViews.Instance["DataGridCellStyle"]
CellStyle = (Style)MetadataTableViews.Instance["DataGridCellStyle"],
};
ContextMenuProvider.Add(view);
DataGridFilter.SetIsAutoFilterEnabled(view, true);
DataGridFilter.SetContentFilterFactory(view, new RegexContentFilterFactory());
}
DataGridFilter.GetFilter(view).Clear();
view.RowDetailsTemplateSelector = null;
view.RowDetailsVisibilityMode = DataGridRowDetailsVisibilityMode.Collapsed;
((MetaDataGrid)view).SelectedTreeNode = selectedNode;
@ -82,13 +82,13 @@ namespace ICSharpCode.ILSpy.Metadata @@ -82,13 +82,13 @@ namespace ICSharpCode.ILSpy.Metadata
return view;
}
private static void View_AutoGeneratedColumns(object sender, EventArgs e)
internal static void View_AutoGeneratedColumns(object sender, EventArgs e)
{
((DataGrid)sender).AutoGeneratedColumns -= View_AutoGeneratedColumns;
((DataGrid)sender).AutoGeneratingColumn -= View_AutoGeneratingColumn;
}
private static void View_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
internal static void View_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
var binding = new Binding(e.PropertyName) { Mode = BindingMode.OneWay };
e.Column = new DataGridTextColumn() {
@ -104,9 +104,14 @@ namespace ICSharpCode.ILSpy.Metadata @@ -104,9 +104,14 @@ namespace ICSharpCode.ILSpy.Metadata
case "Token":
case "Offset":
case "RVA":
case "StartOffset":
case "Length":
binding.StringFormat = "X8";
e.Column.SetTemplate((ControlTemplate)MetadataTableViews.Instance["HexFilter"]);
break;
case "RowDetails":
e.Cancel = true;
break;
default:
e.Cancel = e.PropertyName.Contains("Tooltip");
if (!e.Cancel)
@ -216,6 +221,14 @@ namespace ICSharpCode.ILSpy.Metadata @@ -216,6 +221,14 @@ namespace ICSharpCode.ILSpy.Metadata
throw new NotImplementedException();
}
}
public static string ReadUTF8StringNullTerminated(this ref BlobReader reader)
{
int length = reader.IndexOf(0);
string s = reader.ReadUTF8(length);
reader.ReadByte();
return s;
}
}
class StringFormatAttribute : Attribute

68
ILSpy/Metadata/MetadataHeapTreeNode.cs

@ -0,0 +1,68 @@ @@ -0,0 +1,68 @@
// 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.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Windows.Controls;
using System.Windows.Threading;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.ViewModels;
using ICSharpCode.TreeView;
namespace ICSharpCode.ILSpy.Metadata
{
internal abstract class MetadataHeapTreeNode : ILSpyTreeNode
{
protected PEFile module;
protected MetadataReader metadata;
protected int scrollTarget;
public HandleKind Kind { get; }
public MetadataHeapTreeNode(HandleKind kind, PEFile module, MetadataReader metadata)
{
this.module = module;
this.Kind = kind;
this.metadata = metadata;
}
internal void ScrollTo(Handle handle)
{
//this.scrollTarget = MetadataTokens.GetHeapOffset((EntityHandle)handle);
}
protected void ScrollItemIntoView(DataGrid view, object item)
{
view.Loaded += View_Loaded;
view.Dispatcher.BeginInvoke((Action)(() => view.SelectItem(item)), DispatcherPriority.Background);
}
private void View_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
DataGrid view = (DataGrid)sender;
var sv = view.FindVisualChild<ScrollViewer>();
sv.ScrollToVerticalOffset(scrollTarget - 1);
view.Loaded -= View_Loaded;
this.scrollTarget = default;
}
}
}

22
ILSpy/Metadata/MetadataProtocolHandler.cs

@ -1,10 +1,24 @@ @@ -1,10 +1,24 @@
using System;
using System.Collections.Generic;
// 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.ComponentModel.Composition;
using System.Linq;
using System.Reflection.Metadata;
using System.Text;
using System.Threading.Tasks;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.TreeNodes;

2
ILSpy/Metadata/MetadataTableTreeNode.cs

@ -45,7 +45,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -45,7 +45,7 @@ namespace ICSharpCode.ILSpy.Metadata
internal void ScrollTo(Handle handle)
{
this.scrollTarget = MetadataTokens.GetRowNumber((EntityHandle)handle);
this.scrollTarget = module.Metadata.GetRowNumber((EntityHandle)handle);
}
protected void ScrollItemIntoView(DataGrid view, object item)

23
ILSpy/Metadata/MetadataTableViews.xaml

@ -8,7 +8,7 @@ @@ -8,7 +8,7 @@
xmlns:srm="clr-namespace:System.Reflection;assembly=System.Reflection.Metadata"
xmlns:dgx="urn:tom-englert.de/DataGridExtensions">
<Style x:Key="DataGridCellStyle" TargetType="{x:Type DataGridCell}">
<Style x:Key="DataGridCellStyle" TargetType="{x:Type DataGridCell}" BasedOn="{StaticResource {x:Type DataGridCell}}">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Padding" Value="2" />
<Setter Property="VerticalContentAlignment" Value="Center" />
@ -40,7 +40,7 @@ @@ -40,7 +40,7 @@
Text="{Binding Path=Filter, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</ControlTemplate>
<ControlTemplate x:Key="HexFilter">
<local:HexFilterControl Filter="{Binding Path=Filter, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dgx:DataGridFilterColumnControl}}" />
</ControlTemplate>
@ -98,4 +98,23 @@ @@ -98,4 +98,23 @@
</Style>
<local:ByteWidthConverter x:Key="byteWidthConverter" />
<DataTemplate x:Key="CustomDebugInformationDetailsDataGrid">
<DataGrid ItemsSource="{Binding RowDetails, Mode=OneWay}" GridLinesVisibility="None" CanUserAddRows="False"
CanUserDeleteRows="False" CanUserReorderColumns="False" RowHeaderWidth="0" EnableColumnVirtualization="True"
EnableRowVirtualization="True" RowHeight="20" IsReadOnly="True" SelectionMode="Single" SelectionUnit="FullRow"
AutoGenerateColumns="True" VerticalContentAlignment="Center" AutoGeneratedColumns="DataGrid_AutoGeneratedColumns" AutoGeneratingColumn="DataGrid_AutoGeneratingColumn"
CellStyle="{StaticResource DataGridCellStyle}" MaxHeight="250">
</DataGrid>
</DataTemplate>
<DataTemplate x:Key="CustomDebugInformationDetailsTextBlob">
<Grid MinWidth="800" MaxWidth="800" HorizontalAlignment="Left">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBox IsReadOnly="True" TextWrapping="Wrap" IsReadOnlyCaretVisible="True" Text="{Binding RowDetails, Mode=OneWay}"
MinLines="10" MaxLines="25" />
</Grid>
</DataTemplate>
</ResourceDictionary>

10
ILSpy/Metadata/MetadataTableViews.xaml.cs

@ -36,5 +36,15 @@ namespace ICSharpCode.ILSpy.Metadata @@ -36,5 +36,15 @@ namespace ICSharpCode.ILSpy.Metadata
return instance;
}
}
private void DataGrid_AutoGeneratedColumns(object sender, EventArgs e)
{
Helpers.View_AutoGeneratedColumns(sender, e);
}
private void DataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
Helpers.View_AutoGeneratingColumn(sender, e);
}
}
}

132
ILSpy/Metadata/MetadataTablesTreeNode.cs

@ -0,0 +1,132 @@ @@ -0,0 +1,132 @@
// Copyright (c) 2021 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.Collections.Generic;
using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.Options;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.ViewModels;
namespace ICSharpCode.ILSpy.Metadata
{
class MetadataTablesTreeNode : ILSpyTreeNode
{
private PEFile module;
public MetadataTablesTreeNode(PEFile module)
{
this.module = module;
this.LazyLoading = true;
}
public override object Text => "Tables";
public override object Icon => Images.Literal;
protected override void LoadChildren()
{
if (ShowTable(TableIndex.Module))
this.Children.Add(new ModuleTableTreeNode(module));
if (ShowTable(TableIndex.TypeRef))
this.Children.Add(new TypeRefTableTreeNode(module));
if (ShowTable(TableIndex.TypeDef))
this.Children.Add(new TypeDefTableTreeNode(module));
if (ShowTable(TableIndex.Field))
this.Children.Add(new FieldTableTreeNode(module));
if (ShowTable(TableIndex.MethodDef))
this.Children.Add(new MethodTableTreeNode(module));
if (ShowTable(TableIndex.Param))
this.Children.Add(new ParamTableTreeNode(module));
if (ShowTable(TableIndex.InterfaceImpl))
this.Children.Add(new InterfaceImplTableTreeNode(module));
if (ShowTable(TableIndex.MemberRef))
this.Children.Add(new MemberRefTableTreeNode(module));
if (ShowTable(TableIndex.Constant))
this.Children.Add(new ConstantTableTreeNode(module));
if (ShowTable(TableIndex.CustomAttribute))
this.Children.Add(new CustomAttributeTableTreeNode(module));
if (ShowTable(TableIndex.FieldMarshal))
this.Children.Add(new FieldMarshalTableTreeNode(module));
if (ShowTable(TableIndex.DeclSecurity))
this.Children.Add(new DeclSecurityTableTreeNode(module));
if (ShowTable(TableIndex.ClassLayout))
this.Children.Add(new ClassLayoutTableTreeNode(module));
if (ShowTable(TableIndex.FieldLayout))
this.Children.Add(new FieldLayoutTableTreeNode(module));
if (ShowTable(TableIndex.StandAloneSig))
this.Children.Add(new StandAloneSigTableTreeNode(module));
if (ShowTable(TableIndex.EventMap))
this.Children.Add(new EventMapTableTreeNode(module));
if (ShowTable(TableIndex.Event))
this.Children.Add(new EventTableTreeNode(module));
if (ShowTable(TableIndex.PropertyMap))
this.Children.Add(new PropertyMapTableTreeNode(module));
if (ShowTable(TableIndex.Property))
this.Children.Add(new PropertyTableTreeNode(module));
if (ShowTable(TableIndex.MethodSemantics))
this.Children.Add(new MethodSemanticsTableTreeNode(module));
if (ShowTable(TableIndex.MethodImpl))
this.Children.Add(new MethodImplTableTreeNode(module));
if (ShowTable(TableIndex.ModuleRef))
this.Children.Add(new ModuleRefTableTreeNode(module));
if (ShowTable(TableIndex.TypeSpec))
this.Children.Add(new TypeSpecTableTreeNode(module));
if (ShowTable(TableIndex.ImplMap))
this.Children.Add(new ImplMapTableTreeNode(module));
if (ShowTable(TableIndex.FieldRva))
this.Children.Add(new FieldRVATableTreeNode(module));
if (ShowTable(TableIndex.Assembly))
this.Children.Add(new AssemblyTableTreeNode(module));
if (ShowTable(TableIndex.AssemblyRef))
this.Children.Add(new AssemblyRefTableTreeNode(module));
if (ShowTable(TableIndex.File))
this.Children.Add(new FileTableTreeNode(module));
if (ShowTable(TableIndex.ExportedType))
this.Children.Add(new ExportedTypeTableTreeNode(module));
if (ShowTable(TableIndex.ManifestResource))
this.Children.Add(new ManifestResourceTableTreeNode(module));
if (ShowTable(TableIndex.NestedClass))
this.Children.Add(new NestedClassTableTreeNode(module));
if (ShowTable(TableIndex.GenericParam))
this.Children.Add(new GenericParamTableTreeNode(module));
if (ShowTable(TableIndex.MethodSpec))
this.Children.Add(new MethodSpecTableTreeNode(module));
if (ShowTable(TableIndex.GenericParamConstraint))
this.Children.Add(new GenericParamConstraintTableTreeNode(module));
bool ShowTable(TableIndex table) => !DisplaySettingsPanel.CurrentDisplaySettings.HideEmptyMetadataTables || module.Metadata.GetTableRowCount(table) > 0;
}
public override bool View(TabPageModel tabPage)
{
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
return false;
}
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
{
language.WriteCommentLine(output, "Metadata Tables");
}
}
}

85
ILSpy/Metadata/MetadataTreeNode.cs

@ -17,20 +17,13 @@ @@ -17,20 +17,13 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Reflection.PortableExecutable;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.Options;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.ViewModels;
@ -72,81 +65,17 @@ namespace ICSharpCode.ILSpy.Metadata @@ -72,81 +65,17 @@ namespace ICSharpCode.ILSpy.Metadata
this.Children.Add(new OptionalHeaderTreeNode(module));
this.Children.Add(new DataDirectoriesTreeNode(module));
this.Children.Add(new DebugDirectoryTreeNode(module));
if (ShowTable(TableIndex.Module))
this.Children.Add(new ModuleTableTreeNode(module));
if (ShowTable(TableIndex.TypeRef))
this.Children.Add(new TypeRefTableTreeNode(module));
if (ShowTable(TableIndex.TypeDef))
this.Children.Add(new TypeDefTableTreeNode(module));
if (ShowTable(TableIndex.Field))
this.Children.Add(new FieldTableTreeNode(module));
if (ShowTable(TableIndex.MethodDef))
this.Children.Add(new MethodTableTreeNode(module));
if (ShowTable(TableIndex.Param))
this.Children.Add(new ParamTableTreeNode(module));
if (ShowTable(TableIndex.InterfaceImpl))
this.Children.Add(new InterfaceImplTableTreeNode(module));
if (ShowTable(TableIndex.MemberRef))
this.Children.Add(new MemberRefTableTreeNode(module));
if (ShowTable(TableIndex.Constant))
this.Children.Add(new ConstantTableTreeNode(module));
if (ShowTable(TableIndex.CustomAttribute))
this.Children.Add(new CustomAttributeTableTreeNode(module));
if (ShowTable(TableIndex.FieldMarshal))
this.Children.Add(new FieldMarshalTableTreeNode(module));
if (ShowTable(TableIndex.DeclSecurity))
this.Children.Add(new DeclSecurityTableTreeNode(module));
if (ShowTable(TableIndex.ClassLayout))
this.Children.Add(new ClassLayoutTableTreeNode(module));
if (ShowTable(TableIndex.FieldLayout))
this.Children.Add(new FieldLayoutTableTreeNode(module));
if (ShowTable(TableIndex.StandAloneSig))
this.Children.Add(new StandAloneSigTableTreeNode(module));
if (ShowTable(TableIndex.EventMap))
this.Children.Add(new EventMapTableTreeNode(module));
if (ShowTable(TableIndex.Event))
this.Children.Add(new EventTableTreeNode(module));
if (ShowTable(TableIndex.PropertyMap))
this.Children.Add(new PropertyMapTableTreeNode(module));
if (ShowTable(TableIndex.Property))
this.Children.Add(new PropertyTableTreeNode(module));
if (ShowTable(TableIndex.MethodSemantics))
this.Children.Add(new MethodSemanticsTableTreeNode(module));
if (ShowTable(TableIndex.MethodImpl))
this.Children.Add(new MethodImplTableTreeNode(module));
if (ShowTable(TableIndex.ModuleRef))
this.Children.Add(new ModuleRefTableTreeNode(module));
if (ShowTable(TableIndex.TypeSpec))
this.Children.Add(new TypeSpecTableTreeNode(module));
if (ShowTable(TableIndex.ImplMap))
this.Children.Add(new ImplMapTableTreeNode(module));
if (ShowTable(TableIndex.FieldRva))
this.Children.Add(new FieldRVATableTreeNode(module));
if (ShowTable(TableIndex.Assembly))
this.Children.Add(new AssemblyTableTreeNode(module));
if (ShowTable(TableIndex.AssemblyRef))
this.Children.Add(new AssemblyRefTableTreeNode(module));
if (ShowTable(TableIndex.File))
this.Children.Add(new FileTableTreeNode(module));
if (ShowTable(TableIndex.ExportedType))
this.Children.Add(new ExportedTypeTableTreeNode(module));
if (ShowTable(TableIndex.ManifestResource))
this.Children.Add(new ManifestResourceTableTreeNode(module));
if (ShowTable(TableIndex.NestedClass))
this.Children.Add(new NestedClassTableTreeNode(module));
if (ShowTable(TableIndex.GenericParam))
this.Children.Add(new GenericParamTableTreeNode(module));
if (ShowTable(TableIndex.MethodSpec))
this.Children.Add(new MethodSpecTableTreeNode(module));
if (ShowTable(TableIndex.GenericParamConstraint))
this.Children.Add(new GenericParamConstraintTableTreeNode(module));
bool ShowTable(TableIndex table) => !DisplaySettingsPanel.CurrentDisplaySettings.HideEmptyMetadataTables || module.Metadata.GetTableRowCount(table) > 0;
this.Children.Add(new MetadataTablesTreeNode(module));
this.Children.Add(new StringHeapTreeNode(module, module.Metadata));
this.Children.Add(new UserStringHeapTreeNode(module, module.Metadata));
this.Children.Add(new GuidHeapTreeNode(module, module.Metadata));
this.Children.Add(new BlobHeapTreeNode(module, module.Metadata));
}
public MetadataTableTreeNode FindNodeByHandleKind(HandleKind kind)
{
return this.Children.OfType<MetadataTableTreeNode>().SingleOrDefault(x => x.Kind == kind);
return this.Children.OfType<MetadataTablesTreeNode>().Single()
.Children.OfType<MetadataTableTreeNode>().SingleOrDefault(x => x.Kind == kind);
}
}

2
ILSpy/Options/DecompilerSettingsPanel.xaml

@ -35,7 +35,7 @@ @@ -35,7 +35,7 @@
</ItemsPanelTemplate>
</GroupStyle.Panel>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Style TargetType="{x:Type GroupItem}" BasedOn="{StaticResource {x:Type GroupItem}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>

2
ILSpy/Options/DisplaySettingsPanel.xaml

@ -55,7 +55,7 @@ @@ -55,7 +55,7 @@
<ComboBoxItem>23</ComboBoxItem>
<ComboBoxItem>24</ComboBoxItem>
</ComboBox>
<Border Grid.Row="1" Grid.ColumnSpan="4" BorderBrush="Black" BorderThickness="1" Background="White" Margin="3,5">
<Border Grid.Row="1" Grid.ColumnSpan="4" BorderBrush="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" BorderThickness="1" Margin="3,5">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="AaBbCcXxYyZz" FontFamily="{Binding SelectedFont}" FontSize="{Binding SelectedFontSize}" />
</Border>
</Grid>

2
ILSpy/Properties/AssemblyInfo.template.cs

@ -40,7 +40,7 @@ internal static class RevisionClass @@ -40,7 +40,7 @@ internal static class RevisionClass
public const string Minor = "0";
public const string Build = "0";
public const string Revision = "$INSERTREVISION$";
public const string VersionName = "preview2";
public const string VersionName = "preview3";
public const string FullVersion = Major + "." + Minor + "." + Build + ".$INSERTREVISION$$INSERTBRANCHPOSTFIX$$INSERTVERSIONNAMEPOSTFIX$";
}

11
ILSpy/Properties/Resources.Designer.cs generated

@ -540,6 +540,15 @@ namespace ICSharpCode.ILSpy.Properties { @@ -540,6 +540,15 @@ namespace ICSharpCode.ILSpy.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Dark Mode.
/// </summary>
public static string DarkMode {
get {
return ResourceManager.GetString("DarkMode", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to DEBUG -- Decompile All.
/// </summary>
@ -1587,7 +1596,7 @@ namespace ICSharpCode.ILSpy.Properties { @@ -1587,7 +1596,7 @@ namespace ICSharpCode.ILSpy.Properties {
}
/// <summary>
/// Looks up a localized string similar to Hightlight current line.
/// Looks up a localized string similar to Highlight current line.
/// </summary>
public static string HighlightCurrentLine {
get {

5
ILSpy/Properties/Resources.resx

@ -219,6 +219,9 @@ Are you sure you want to continue?</value> @@ -219,6 +219,9 @@ Are you sure you want to continue?</value>
<data name="DEBUGDumpPDBAsXML" xml:space="preserve">
<value>DEBUG -- Dump PDB as XML</value>
</data>
<data name="DarkMode" xml:space="preserve">
<value>Dark Mode</value>
</data>
<data name="DebugSteps" xml:space="preserve">
<value>Debug Steps</value>
</data>
@ -556,7 +559,7 @@ Are you sure you want to continue?</value> @@ -556,7 +559,7 @@ Are you sure you want to continue?</value>
<value>Hide empty metadata tables from tree view</value>
</data>
<data name="HighlightCurrentLine" xml:space="preserve">
<value>Hightlight current line</value>
<value>Highlight current line</value>
</data>
<data name="HighlightMatchingBraces" xml:space="preserve">
<value>Highlight matching braces</value>

2
ILSpy/Properties/app.config.template

@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="ICSharpCode.AvalonEdit" publicKeyToken="9cc39be672370310" culture="neutral"/>
<bindingRedirect oldVersion="4.1.0.0-99.9.9.9" newVersion="6.1.0.314"/>
<bindingRedirect oldVersion="4.1.0.0-99.9.9.9" newVersion="6.1.1.20"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="ICSharpCode.Decompiler" publicKeyToken="d4bfe873e7598c49" culture="neutral"/>

4
ILSpy/Search/AbstractEntitySearchStrategy.cs

@ -78,9 +78,9 @@ namespace ICSharpCode.ILSpy.Search @@ -78,9 +78,9 @@ namespace ICSharpCode.ILSpy.Search
return 0;
}
// Constructors always have the same name in IL:
// Constructors and destructors always have the same name in IL:
// Use type name instead
if (text == ".cctor" || text == ".ctor")
if (member.SymbolKind == SymbolKind.Constructor || member.SymbolKind == SymbolKind.Destructor)
{
text = member.DeclaringType.Name;
}

41
ILSpy/Search/SearchPane.cs

@ -34,6 +34,7 @@ using System.Windows.Threading; @@ -34,6 +34,7 @@ using System.Windows.Threading;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.Options;
using ICSharpCode.ILSpy.Search;
using ICSharpCode.ILSpy.ViewModels;
@ -48,6 +49,7 @@ namespace ICSharpCode.ILSpy @@ -48,6 +49,7 @@ namespace ICSharpCode.ILSpy
const int MAX_REFRESH_TIME_MS = 10; // More means quicker forward of data, less means better responsibility
RunningSearch currentSearch;
bool runSearchOnNextShow;
IComparer<SearchResult> resultsComparer;
public static readonly DependencyProperty ResultsProperty =
DependencyProperty.Register("Results", typeof(ObservableCollection<SearchResult>), typeof(SearchPane),
@ -210,7 +212,7 @@ namespace ICSharpCode.ILSpy @@ -210,7 +212,7 @@ namespace ICSharpCode.ILSpy
int resultsAdded = 0;
while (Results.Count < MAX_RESULTS && timer.ElapsedMilliseconds < MAX_REFRESH_TIME_MS && currentSearch.resultQueue.TryTake(out var result))
{
InsertResult(Results, result);
Results.InsertSorted(result, resultsComparer);
++resultsAdded;
}
@ -229,6 +231,9 @@ namespace ICSharpCode.ILSpy @@ -229,6 +231,9 @@ namespace ICSharpCode.ILSpy
currentSearch = null;
}
resultsComparer = DisplaySettingsPanel.CurrentDisplaySettings.SortResults ?
SearchResult.ComparerByFitness :
SearchResult.ComparerByName;
Results.Clear();
RunningSearch startedSearch = null;
@ -237,7 +242,7 @@ namespace ICSharpCode.ILSpy @@ -237,7 +242,7 @@ namespace ICSharpCode.ILSpy
MainWindow mainWindow = MainWindow.Instance;
searchProgressBar.IsIndeterminate = true;
startedSearch = new RunningSearch(mainWindow.CurrentAssemblyList.GetAssemblies(), searchTerm,
startedSearch = new RunningSearch(await mainWindow.CurrentAssemblyList.GetAllAssemblies(), searchTerm,
(SearchMode)searchModeComboBox.SelectedIndex, mainWindow.CurrentLanguage,
mainWindow.SessionSettings.FilterSettings.ShowApiLevel);
currentSearch = startedSearch;
@ -251,34 +256,6 @@ namespace ICSharpCode.ILSpy @@ -251,34 +256,6 @@ namespace ICSharpCode.ILSpy
}
}
void InsertResult(IList<SearchResult> results, SearchResult result)
{
if (results.Count == 0)
{
results.Add(result);
}
else if (Options.DisplaySettingsPanel.CurrentDisplaySettings.SortResults)
{
// Keep results collection sorted by "Fitness" by inserting result into correct place
// Inserts in the beginning shifts all elements, but there can be no more than 1000 items.
for (int i = 0; i < results.Count; i++)
{
if (results[i].Fitness < result.Fitness)
{
results.Insert(i, result);
return;
}
}
results.Insert(results.Count - 1, result);
}
else
{
// Original Code
int index = results.BinarySearch(result, 0, results.Count - 1, SearchResult.Comparer);
results.Insert(index < 0 ? ~index : index, result);
}
}
void JumpToSelectedItem()
{
if (listBox.SelectedItem is SearchResult result)
@ -290,14 +267,14 @@ namespace ICSharpCode.ILSpy @@ -290,14 +267,14 @@ namespace ICSharpCode.ILSpy
sealed class RunningSearch
{
readonly CancellationTokenSource cts = new CancellationTokenSource();
readonly LoadedAssembly[] assemblies;
readonly IList<LoadedAssembly> assemblies;
readonly string[] searchTerm;
readonly SearchMode searchMode;
readonly Language language;
readonly ApiVisibility apiVisibility;
public readonly IProducerConsumerCollection<SearchResult> resultQueue = new ConcurrentQueue<SearchResult>();
public RunningSearch(LoadedAssembly[] assemblies, string searchTerm, SearchMode searchMode, Language language, ApiVisibility apiVisibility)
public RunningSearch(IList<LoadedAssembly> assemblies, string searchTerm, SearchMode searchMode, Language language, ApiVisibility apiVisibility)
{
this.assemblies = assemblies;
this.searchTerm = NativeMethods.CommandLineToArgumentArray(searchTerm);

2
ILSpy/Search/SearchPane.xaml

@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
<RowDefinition />
</Grid.RowDefinitions>
<Border BorderBrush="{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" Margin="0">
<Grid Height="23">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />

14
ILSpy/Search/SearchResult.cs

@ -29,7 +29,8 @@ namespace ICSharpCode.ILSpy @@ -29,7 +29,8 @@ namespace ICSharpCode.ILSpy
{
public class SearchResult
{
public static readonly IComparer<SearchResult> Comparer = new SearchResultComparer();
public static readonly IComparer<SearchResult> ComparerByName = new SearchResultNameComparer();
public static readonly IComparer<SearchResult> ComparerByFitness = new SearchResultFitnessComparer();
public virtual object Reference {
get {
@ -57,13 +58,22 @@ namespace ICSharpCode.ILSpy @@ -57,13 +58,22 @@ namespace ICSharpCode.ILSpy
return Name;
}
class SearchResultComparer : IComparer<SearchResult>
class SearchResultNameComparer : IComparer<SearchResult>
{
public int Compare(SearchResult x, SearchResult y)
{
return StringComparer.Ordinal.Compare(x?.Name ?? "", y?.Name ?? "");
}
}
class SearchResultFitnessComparer : IComparer<SearchResult>
{
public int Compare(SearchResult x, SearchResult y)
{
//elements with higher Fitness come first
return Comparer<float>.Default.Compare(y?.Fitness ?? 0, x?.Fitness ?? 0);
}
}
}
public class MemberSearchResult : SearchResult

10
ILSpy/SessionSettings.cs

@ -61,6 +61,7 @@ namespace ICSharpCode.ILSpy @@ -61,6 +61,7 @@ namespace ICSharpCode.ILSpy
this.TopPaneSplitterPosition = FromString((string)doc.Element("TopPaneSplitterPosition"), 0.3);
this.BottomPaneSplitterPosition = FromString((string)doc.Element("BottomPaneSplitterPosition"), 0.3);
this.SelectedSearchMode = FromString((string)doc.Element("SelectedSearchMode"), SearchMode.TypeAndMember);
this.IsDarkMode = FromString((string)doc.Element(nameof(IsDarkMode)), false);
this.DockLayout = new DockLayoutSettings(doc.Element("DockLayout"));
}
@ -75,6 +76,14 @@ namespace ICSharpCode.ILSpy @@ -75,6 +76,14 @@ namespace ICSharpCode.ILSpy
public FilterSettings FilterSettings { get; private set; }
public SearchMode SelectedSearchMode { get; set; }
public bool IsDarkMode {
get => ThemeManager.Current.IsDarkMode;
set {
ThemeManager.Current.IsDarkMode = value;
OnPropertyChanged();
}
}
public string[] ActiveTreeViewPath;
public string ActiveAutoLoadedAssembly;
@ -122,6 +131,7 @@ namespace ICSharpCode.ILSpy @@ -122,6 +131,7 @@ namespace ICSharpCode.ILSpy
doc.Add(new XElement("TopPaneSplitterPosition", ToString(this.TopPaneSplitterPosition)));
doc.Add(new XElement("BottomPaneSplitterPosition", ToString(this.BottomPaneSplitterPosition)));
doc.Add(new XElement("SelectedSearchMode", ToString(this.SelectedSearchMode)));
doc.Add(new XElement(nameof(IsDarkMode), ToString(this.IsDarkMode)));
var dockLayoutElement = new XElement("DockLayout");
if (DockLayout.Valid)

1211
ILSpy/TextView/Asm-Mode-Dark.xshd

File diff suppressed because it is too large Load Diff

149
ILSpy/TextView/CSharp-Mode-Dark.xshd

@ -0,0 +1,149 @@ @@ -0,0 +1,149 @@
<?xml version="1.0"?>
<SyntaxDefinition name="C#" extensions=".cs" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008">
<!-- This is a variant of the AvalonEdit C# highlighting that has several constructs disabled.
The disabled constructs (e.g. contextual keywords) are highlighted using the CSharpLanguage.HighlightingTokenWriter instead.
-->
<!-- The named colors 'Comment' and 'String' are used in SharpDevelop to detect if a line is inside a multiline string/comment -->
<Color name="Comment" foreground="#FF57A64A" exampleText="// comment" />
<Color name="String" foreground="#FFD69D85" exampleText="string text = &quot;Hello, World!&quot;"/>
<Color name="StringInterpolation" foreground="#FFffd68f" exampleText="string text = $&quot;Hello, {name}!&quot;"/>
<Color name="Char" foreground="#FFD69D85" exampleText="char linefeed = '\n';"/>
<Color name="Preprocessor" foreground="#FF9B9B9B" exampleText="#region Title"/>
<Color name="Punctuation" foreground="White" exampleText="a(b.c);"/>
<Color name="ValueTypeKeywords" foreground="#FF00A0FF" exampleText="bool b = true;"/>
<Color name="ReferenceTypeKeywords" foreground="#FF559CD6" exampleText="object o;"/>
<Color name="NumberLiteral" foreground="#FFb5cea8" exampleText="3.1415f"/>
<Color name="ThisOrBaseReference" foreground="#FF3a6a9b" exampleText="this.Do(); base.Do();"/>
<Color name="NullOrValueKeywords" foreground="#FF559CD6" exampleText="if (value == null)"/>
<Color name="Keywords" foreground="#FFd8a0df" exampleText="if (a) {} else {}"/>
<Color name="GotoKeywords" foreground="#FFd8a0df" exampleText="continue; return null;"/>
<Color name="QueryKeywords" foreground="#FFd8a0df" exampleText="var a = from x in y select z;"/>
<Color name="ExceptionKeywords" foreground="#FFd8a0df" exampleText="try {} catch {} finally {}"/>
<Color name="CheckedKeyword" foreground="#FF559CD6" exampleText="checked {}"/>
<Color name="UnsafeKeywords" foreground="#FF559CD6" exampleText="unsafe { fixed (..) {} }"/>
<Color name="OperatorKeywords" foreground="#FFD69D85" exampleText="public static implicit operator..."/>
<Color name="ParameterModifiers" foreground="#FF559CD6" exampleText="(ref int a, params int[] b)"/>
<Color name="Modifiers" foreground="#FF559CD6" exampleText="static readonly int a;"/>
<Color name="Visibility" foreground="#FF559CD6" exampleText="public override void ToString();"/>
<Color name="NamespaceKeywords" foreground="#FF559CD6" exampleText="namespace A.B { using System; }"/>
<Color name="GetSetAddRemove" foreground="#FF559CD6" exampleText="int Prop { get; set; }"/>
<Color name="TrueFalse" foreground="#FF00A0FF" exampleText="b = false; a = true;"/>
<Color name="TypeKeywords" foreground="#FF559CD6" exampleText="if (x is int) { a = x as int; type = typeof(int); size = sizeof(int); c = new object(); }"/>
<Color name="AttributeKeywords" foreground="#FFD69D85" exampleText="[assembly: AssemblyVersion(&quot;1.0.0.*&quot;)]" />
<!-- Colors used for semantic highlighting -->
<Color name="ReferenceTypes" foreground="#569CD6" exampleText="System.#{#Uri#}# uri;"/>
<Color name="InterfaceTypes" foreground="#569CD6" exampleText="System.#{#IDisposable#}# obj;"/>
<Color name="TypeParameters" foreground="#569CD6" exampleText="class MyList&lt;#{#T#}#&gt; { }"/>
<Color name="DelegateTypes" foreground="#569CD6" exampleText="System.#{#Action#}#; action;"/>
<Color name="ValueTypes" fontWeight="bold" foreground="#569CD6" exampleText="System.#{#DateTime#}# date;"/>
<Color name="EnumTypes" fontWeight="bold" foreground="#569CD6" exampleText="System.#{#ConsoleKey#}# key;"/>
<Color name="MethodCall" foreground="#FFdcdcaa" fontWeight="bold" exampleText="o.#{#ToString#}#();"/>
<Color name="FieldAccess" fontStyle="italic" exampleText="return this.#{#name#}#;"/>
<Color name="InactiveCode" foreground="Gray" exampleText="#{#Deactivated by #if#}#"/>
<Color name="SemanticError" foreground="DarkRed" exampleText="o.#{#MissingMethod#}#()"/>
<Property name="DocCommentMarker" value="///" />
<RuleSet name="CommentMarkerSet">
<Keywords fontWeight="bold" foreground="Red">
<Word>TODO</Word>
<Word>FIXME</Word>
</Keywords>
<Keywords fontWeight="bold" foreground="#E0E000">
<Word>HACK</Word>
<Word>UNDONE</Word>
</Keywords>
</RuleSet>
<!-- This is the main ruleset. -->
<RuleSet>
<Span color="Preprocessor">
<Begin>\#</Begin>
<RuleSet name="PreprocessorSet">
<Span> <!-- preprocessor directives that allow comments -->
<Begin fontWeight="bold">
(define|undef|if|elif|else|endif|line)\b
</Begin>
<RuleSet>
<Span color="Comment" ruleSet="CommentMarkerSet">
<Begin>//</Begin>
</Span>
</RuleSet>
</Span>
<Span> <!-- preprocessor directives that don't allow comments -->
<Begin fontWeight="bold">
(region|endregion|error|warning|pragma)\b
</Begin>
</Span>
</RuleSet>
</Span>
<Span color="Comment">
<Begin color="XmlDoc/DocComment">///(?!/)</Begin>
<RuleSet>
<Import ruleSet="XmlDoc/DocCommentSet"/>
<Import ruleSet="CommentMarkerSet"/>
</RuleSet>
</Span>
<Span color="Comment" ruleSet="CommentMarkerSet">
<Begin>//</Begin>
</Span>
<Span color="Comment" ruleSet="CommentMarkerSet" multiline="true">
<Begin>/\*</Begin>
<End>\*/</End>
</Span>
<Span color="String">
<Begin>"</Begin>
<End>"</End>
<RuleSet>
<!-- span for escape sequences -->
<Span begin="\\" end="."/>
</RuleSet>
</Span>
<Span color="Char">
<Begin>'</Begin>
<End>'</End>
<RuleSet>
<!-- span for escape sequences -->
<Span begin="\\" end="."/>
</RuleSet>
</Span>
<Span color="String" multiline="true">
<Begin color="String">@"</Begin>
<End>"</End>
<RuleSet>
<!-- span for escape sequences -->
<Span begin='""' end=""/>
</RuleSet>
</Span>
<Span color="String">
<Begin>\$"</Begin>
<End>"</End>
<RuleSet>
<!-- span for escape sequences -->
<Span begin="\\" end="."/>
<Span begin="\{\{" end=""/>
<!-- string interpolation -->
<Span begin="{" end="}" color="StringInterpolation" ruleSet=""/>
</RuleSet>
</Span>
<!-- Digits -->
<Rule color="NumberLiteral">
\b0[xX][0-9a-fA-F]+ # hex number
|
( \b\d+(\.[0-9]+)? #number with optional floating point
| \.[0-9]+ #or just starting with floating point
)
([eE][+-]?[0-9]+)? # optional exponent
</Rule>
</RuleSet>
</SyntaxDefinition>

102
ILSpy/TextView/DecompilerTextView.cs

@ -59,6 +59,10 @@ using ICSharpCode.ILSpy.ViewModels; @@ -59,6 +59,10 @@ using ICSharpCode.ILSpy.ViewModels;
using Microsoft.Win32;
using TomsToolbox.Wpf;
using ResourceKeys = ICSharpCode.ILSpy.themes.ResourceKeys;
namespace ICSharpCode.ILSpy.TextView
{
/// <summary>
@ -87,41 +91,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -87,41 +91,7 @@ namespace ICSharpCode.ILSpy.TextView
#region Constructor
public DecompilerTextView()
{
HighlightingManager.Instance.RegisterHighlighting(
"ILAsm", new string[] { ".il" },
delegate {
using (Stream s = typeof(DecompilerTextView).Assembly.GetManifestResourceStream(typeof(DecompilerTextView), "ILAsm-Mode.xshd"))
{
using (XmlTextReader reader = new XmlTextReader(s))
{
return HighlightingLoader.Load(reader, HighlightingManager.Instance);
}
}
});
HighlightingManager.Instance.RegisterHighlighting(
"C#", new string[] { ".cs" },
delegate {
using (Stream s = typeof(DecompilerTextView).Assembly.GetManifestResourceStream(typeof(DecompilerTextView), "CSharp-Mode.xshd"))
{
using (XmlTextReader reader = new XmlTextReader(s))
{
return HighlightingLoader.Load(reader, HighlightingManager.Instance);
}
}
});
HighlightingManager.Instance.RegisterHighlighting(
"Asm", new string[] { ".s", ".asm" },
delegate {
using (Stream s = typeof(DecompilerTextView).Assembly.GetManifestResourceStream(typeof(DecompilerTextView), "Asm-Mode.xshd"))
{
using (XmlTextReader reader = new XmlTextReader(s))
{
return HighlightingLoader.Load(reader, HighlightingManager.Instance);
}
}
});
RegisterHighlighting();
InitializeComponent();
@ -153,8 +123,16 @@ namespace ICSharpCode.ILSpy.TextView @@ -153,8 +123,16 @@ namespace ICSharpCode.ILSpy.TextView
DisplaySettingsPanel.CurrentDisplaySettings.PropertyChanged += CurrentDisplaySettings_PropertyChanged;
// SearchPanel
SearchPanel.Install(textEditor.TextArea)
.RegisterCommands(Application.Current.MainWindow.CommandBindings);
SearchPanel searchPanel = SearchPanel.Install(textEditor.TextArea);
searchPanel.RegisterCommands(Application.Current.MainWindow.CommandBindings);
searchPanel.Loaded += (_, _) => {
// HACK: fix the hardcoded but misaligned margin of the search text box.
var textBox = searchPanel.VisualDescendants().OfType<TextBox>().FirstOrDefault();
if (textBox != null)
{
textBox.Margin = new Thickness(3);
}
};
ShowLineMargin();
SetHighlightCurrentLine();
@ -165,6 +143,8 @@ namespace ICSharpCode.ILSpy.TextView @@ -165,6 +143,8 @@ namespace ICSharpCode.ILSpy.TextView
ContextMenuProvider.Add(this);
textEditor.TextArea.TextView.SetResourceReference(ICSharpCode.AvalonEdit.Rendering.TextView.LinkTextForegroundBrushProperty, ResourceKeys.LinkTextForegroundBrush);
this.DataContextChanged += DecompilerTextView_DataContextChanged;
}
@ -494,14 +474,15 @@ namespace ICSharpCode.ILSpy.TextView @@ -494,14 +474,15 @@ namespace ICSharpCode.ILSpy.TextView
};
viewer.Document = document;
Border border = new Border {
Background = SystemColors.ControlBrush,
BorderBrush = SystemColors.ControlDarkBrush,
BorderThickness = new Thickness(1),
MaxHeight = 400,
Child = viewer
};
border.SetResourceReference(Border.BackgroundProperty, SystemColors.ControlBrushKey);
border.SetResourceReference(Border.BorderBrushProperty, SystemColors.ControlDarkBrushKey);
this.Child = border;
viewer.Foreground = SystemColors.InfoTextBrush;
viewer.SetResourceReference(ForegroundProperty, SystemColors.InfoTextBrushKey);
document.TextAlignment = TextAlignment.Left;
document.FontSize = fontSize;
document.FontFamily = SystemFonts.SmallCaptionFontFamily;
@ -960,8 +941,9 @@ namespace ICSharpCode.ILSpy.TextView @@ -960,8 +941,9 @@ namespace ICSharpCode.ILSpy.TextView
{
if (reference.Equals(r.Reference))
{
var mark = textMarkerService.Create(r.StartOffset, r.Length);
mark.BackgroundColor = r.IsDefinition ? Colors.LightSeaGreen : Colors.GreenYellow;
mark.BackgroundColor = (Color)(r.IsDefinition ? FindResource(ResourceKeys.TextMarkerDefinitionBackgroundColor) : FindResource(ResourceKeys.TextMarkerBackgroundColor));
localReferenceMarks.Add(mark);
}
}
@ -1190,6 +1172,15 @@ namespace ICSharpCode.ILSpy.TextView @@ -1190,6 +1172,15 @@ namespace ICSharpCode.ILSpy.TextView
ViewState IHaveState.GetState() => GetState();
public static void RegisterHighlighting()
{
HighlightingManager.Instance.RegisterHighlighting("ILAsm", new[] { ".il" }, "ILAsm-Mode");
HighlightingManager.Instance.RegisterHighlighting("C#", new[] { ".cs" }, "CSharp-Mode");
HighlightingManager.Instance.RegisterHighlighting("Asm", new[] { ".s", ".asm" }, "Asm-Mode");
HighlightingManager.Instance.RegisterHighlighting("xml", new[] { ".xml", ".baml" }, "XML-Mode");
}
public void Dispose()
{
DisplaySettingsPanel.CurrentDisplaySettings.PropertyChanged -= CurrentDisplaySettings_PropertyChanged;
@ -1274,4 +1265,33 @@ namespace ICSharpCode.ILSpy.TextView @@ -1274,4 +1265,33 @@ namespace ICSharpCode.ILSpy.TextView
return false;
}
}
static class ExtensionMethods
{
public static void RegisterHighlighting(
this HighlightingManager manager,
string name,
string[] extensions,
string resourceName)
{
if (ThemeManager.Current.IsDarkMode)
{
resourceName += "-Dark";
}
resourceName += ".xshd";
manager.RegisterHighlighting(
name, extensions,
delegate {
using (Stream s = typeof(DecompilerTextView).Assembly.GetManifestResourceStream(typeof(DecompilerTextView), resourceName))
{
using (XmlTextReader reader = new XmlTextReader(s))
{
return HighlightingLoader.Load(reader, manager);
}
}
});
}
}
}

41
ILSpy/TextView/DecompilerTextView.xaml

@ -2,22 +2,53 @@ @@ -2,22 +2,53 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:properties="clr-namespace:ICSharpCode.ILSpy.Properties"
xmlns:ae="clr-namespace:ICSharpCode.AvalonEdit;assembly=ICSharpCode.AvalonEdit">
xmlns:ae="clr-namespace:ICSharpCode.AvalonEdit;assembly=ICSharpCode.AvalonEdit"
xmlns:folding="clr-namespace:ICSharpCode.AvalonEdit.Folding;assembly=ICSharpCode.AvalonEdit"
xmlns:styles="urn:TomsToolbox.Wpf.Styles">
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="boolToVisibility" />
<SolidColorBrush x:Key="waitAdornerBackgoundBrush" Color="{DynamicResource {x:Static SystemColors.WindowColorKey}}" Opacity=".75"/>
</UserControl.Resources>
<Grid>
<Border BorderThickness="1,1,0,1" BorderBrush="#FF828790">
<Border BorderThickness="1,1,0,1" BorderBrush="{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}">
<Grid>
<ae:TextEditor Name="textEditor" AutomationProperties.Name="Decompilation" FontFamily="Consolas" FontSize="10pt" IsReadOnly="True"
Background="{DynamicResource {x:Static SystemColors.InfoBrushKey}}"
Foreground="{DynamicResource {x:Static SystemColors.InfoTextBrushKey}}">
Foreground="{DynamicResource {x:Static SystemColors.InfoTextBrushKey}}"
folding:FoldingMargin.FoldingMarkerBackgroundBrush="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
folding:FoldingMargin.SelectedFoldingMarkerBackgroundBrush="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
folding:FoldingMargin.FoldingMarkerBrush="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}"
folding:FoldingMargin.SelectedFoldingMarkerBrush="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"
>
<ae:TextEditor.Resources>
<!-- prevent App-wide button style from applying to the buttons in the search box -->
<Style TargetType="{x:Type Button}" />
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
<Setter Property="BorderBrush" Value="{DynamicResource {x:Static styles:ResourceKeys.BorderBrush}}" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border BorderThickness="1"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
Padding="{TemplateBinding Padding}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" />
</Trigger>
</Style.Triggers>
</Style>
</ae:TextEditor.Resources>
</ae:TextEditor>
<Border Name="waitAdorner" Background="#C0FFFFFF" Visibility="Collapsed">
<Border Name="waitAdorner" Background="{StaticResource waitAdornerBackgoundBrush}" Visibility="Collapsed">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock FontSize="14pt" Text="{x:Static properties:Resources.Decompiling}"/>
<ProgressBar Name="progressBar" Height="16" Margin="0, 4" />

530
ILSpy/TextView/ILAsm-Mode-Dark.xshd

@ -0,0 +1,530 @@ @@ -0,0 +1,530 @@
<SyntaxDefinition name="ILAsm" extensions=".il" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008">
<Color name="Comment" foreground="#FF57A64A" exampleText="// comment" />
<Color name="String" foreground="#FFD69D85" exampleText="&quot;Hello, World!&quot;" />
<Color name="Instructions" foreground="#FFD69D85" exampleText="nop;" />
<Color name="Keywords" foreground="#FFD69D85" fontWeight="bold" exampleText="true" />
<Color name="Directives" foreground="#FF57A64A" fontWeight="bold" exampleText=".class" />
<Color name="Security" foreground="#FF559CD6" exampleText="request" />
<RuleSet ignoreCase="false">
<Keywords color="Instructions">
<Word>nop</Word>
<Word>break</Word>
<Word>ldarg.0</Word>
<Word>ldarg.1</Word>
<Word>ldarg.2</Word>
<Word>ldarg.3</Word>
<Word>ldloc.0</Word>
<Word>ldloc.1</Word>
<Word>ldloc.2</Word>
<Word>ldloc.3</Word>
<Word>stloc.0</Word>
<Word>stloc.1</Word>
<Word>stloc.2</Word>
<Word>stloc.3</Word>
<Word>ldarg.s</Word>
<Word>ldarga.s</Word>
<Word>starg.s</Word>
<Word>ldloc.s</Word>
<Word>ldloca.s</Word>
<Word>stloc.s</Word>
<Word>ldnull</Word>
<Word>ldc.i4.m1</Word>
<Word>ldc.i4.0</Word>
<Word>ldc.i4.1</Word>
<Word>ldc.i4.2</Word>
<Word>ldc.i4.3</Word>
<Word>ldc.i4.4</Word>
<Word>ldc.i4.5</Word>
<Word>ldc.i4.6</Word>
<Word>ldc.i4.7</Word>
<Word>ldc.i4.8</Word>
<Word>ldc.i4.s</Word>
<Word>ldc.i4</Word>
<Word>ldc.i8</Word>
<Word>ldc.r4</Word>
<Word>ldc.r8</Word>
<Word>dup</Word>
<Word>pop</Word>
<Word>jmp</Word>
<Word>call</Word>
<Word>calli</Word>
<Word>ret</Word>
<Word>br.s</Word>
<Word>brfalse.s</Word>
<Word>brtrue.s</Word>
<Word>beq.s</Word>
<Word>bge.s</Word>
<Word>bgt.s</Word>
<Word>ble.s</Word>
<Word>blt.s</Word>
<Word>bne.un.s</Word>
<Word>bge.un.s</Word>
<Word>bgt.un.s</Word>
<Word>ble.un.s</Word>
<Word>blt.un.s</Word>
<Word>br</Word>
<Word>brfalse</Word>
<Word>brtrue</Word>
<Word>beq</Word>
<Word>bge</Word>
<Word>bgt</Word>
<Word>ble</Word>
<Word>blt</Word>
<Word>bne.un</Word>
<Word>bge.un</Word>
<Word>bgt.un</Word>
<Word>ble.un</Word>
<Word>blt.un</Word>
<Word>switch</Word>
<Word>ldind.i1</Word>
<Word>ldind.u1</Word>
<Word>ldind.i2</Word>
<Word>ldind.u2</Word>
<Word>ldind.i4</Word>
<Word>ldind.u4</Word>
<Word>ldind.i8</Word>
<Word>ldind.i</Word>
<Word>ldind.r4</Word>
<Word>ldind.r8</Word>
<Word>ldind.ref</Word>
<Word>stind.ref</Word>
<Word>stind.i1</Word>
<Word>stind.i2</Word>
<Word>stind.i4</Word>
<Word>stind.i8</Word>
<Word>stind.r4</Word>
<Word>stind.r8</Word>
<Word>add</Word>
<Word>sub</Word>
<Word>mul</Word>
<Word>div</Word>
<Word>div.un</Word>
<Word>rem</Word>
<Word>rem.un</Word>
<Word>and</Word>
<Word>or</Word>
<Word>xor</Word>
<Word>shl</Word>
<Word>shr</Word>
<Word>shr.un</Word>
<Word>neg</Word>
<Word>not</Word>
<Word>conv.i1</Word>
<Word>conv.i2</Word>
<Word>conv.i4</Word>
<Word>conv.i8</Word>
<Word>conv.r4</Word>
<Word>conv.r8</Word>
<Word>conv.u4</Word>
<Word>conv.u8</Word>
<Word>callvirt</Word>
<Word>cpobj</Word>
<Word>ldobj</Word>
<Word>ldstr</Word>
<Word>newobj</Word>
<Word>castclass</Word>
<Word>isinst</Word>
<Word>conv.r.un</Word>
<Word>unbox</Word>
<Word>throw</Word>
<Word>ldfld</Word>
<Word>ldflda</Word>
<Word>stfld</Word>
<Word>ldsfld</Word>
<Word>ldsflda</Word>
<Word>stsfld</Word>
<Word>stobj</Word>
<Word>conv.ovf.i1.un</Word>
<Word>conv.ovf.i2.un</Word>
<Word>conv.ovf.i4.un</Word>
<Word>conv.ovf.i8.un</Word>
<Word>conv.ovf.u1.un</Word>
<Word>conv.ovf.u2.un</Word>
<Word>conv.ovf.u4.un</Word>
<Word>conv.ovf.u8.un</Word>
<Word>conv.ovf.i.un</Word>
<Word>conv.ovf.u.un</Word>
<Word>box</Word>
<Word>newarr</Word>
<Word>ldlen</Word>
<Word>ldelema</Word>
<Word>ldelem</Word>
<Word>ldelem.i1</Word>
<Word>ldelem.u1</Word>
<Word>ldelem.i2</Word>
<Word>ldelem.u2</Word>
<Word>ldelem.i4</Word>
<Word>ldelem.u4</Word>
<Word>ldelem.i8</Word>
<Word>ldelem.i</Word>
<Word>ldelem.r4</Word>
<Word>ldelem.r8</Word>
<Word>ldelem.ref</Word>
<Word>stelem</Word>
<Word>stelem.i</Word>
<Word>stelem.i1</Word>
<Word>stelem.i2</Word>
<Word>stelem.i4</Word>
<Word>stelem.i8</Word>
<Word>stelem.r4</Word>
<Word>stelem.r8</Word>
<Word>stelem.ref</Word>
<Word>conv.ovf.i1</Word>
<Word>conv.ovf.u1</Word>
<Word>conv.ovf.i2</Word>
<Word>conv.ovf.u2</Word>
<Word>conv.ovf.i4</Word>
<Word>conv.ovf.u4</Word>
<Word>conv.ovf.i8</Word>
<Word>conv.ovf.u8</Word>
<Word>refanyval</Word>
<Word>ckfinite</Word>
<Word>mkrefany</Word>
<Word>ldtoken</Word>
<Word>conv.u2</Word>
<Word>conv.u1</Word>
<Word>conv.i</Word>
<Word>conv.ovf.i</Word>
<Word>conv.ovf.u</Word>
<Word>add.ovf</Word>
<Word>add.ovf.un</Word>
<Word>mul.ovf</Word>
<Word>mul.ovf.un</Word>
<Word>sub.ovf</Word>
<Word>sub.ovf.un</Word>
<Word>endfinally</Word>
<Word>leave</Word>
<Word>leave.s</Word>
<Word>stind.i</Word>
<Word>conv.u</Word>
<Word>prefix7</Word>
<Word>prefix6</Word>
<Word>prefix5</Word>
<Word>prefix4</Word>
<Word>prefix3</Word>
<Word>prefix2</Word>
<Word>prefix1</Word>
<Word>prefixref</Word>
<Word>arglist</Word>
<Word>ceq</Word>
<Word>cgt</Word>
<Word>cgt.un</Word>
<Word>clt</Word>
<Word>clt.un</Word>
<Word>ldftn</Word>
<Word>ldvirtftn</Word>
<Word>ldarg</Word>
<Word>ldarga</Word>
<Word>starg</Word>
<Word>ldloc</Word>
<Word>ldloca</Word>
<Word>stloc</Word>
<Word>localloc</Word>
<Word>endfilter</Word>
<Word>unaligned.</Word>
<Word>volatile.</Word>
<Word>tail.</Word>
<Word>initobj</Word>
<Word>cpblk</Word>
<Word>initblk</Word>
<Word>rethrow</Word>
<Word>sizeof</Word>
<Word>refanytype</Word>
<Word>illegal</Word>
<Word>endmac</Word>
<Word>brnull</Word>
<Word>brnull.s</Word>
<Word>brzero</Word>
<Word>brzero.s</Word>
<Word>brinst</Word>
<Word>brinst.s</Word>
<Word>ldind.u8</Word>
<Word>ldelem.u8</Word>
<Word>ldc.i4.M1</Word>
<Word>endfault</Word>
</Keywords>
<Keywords color="Keywords">
<Word>void</Word>
<Word>bool</Word>
<Word>char</Word>
<Word>wchar</Word>
<Word>int</Word>
<Word>int8</Word>
<Word>int16</Word>
<Word>int32</Word>
<Word>int64</Word>
<Word>uint8</Word>
<Word>uint16</Word>
<Word>uint32</Word>
<Word>uint64</Word>
<Word>float</Word>
<Word>float32</Word>
<Word>float64</Word>
<Word>refany</Word>
<Word>typedref</Word>
<Word>object</Word>
<Word>string</Word>
<Word>native</Word>
<Word>unsigned</Word>
<Word>value</Word>
<Word>valuetype</Word>
<Word>class</Word>
<Word>const</Word>
<Word>vararg</Word>
<Word>default</Word>
<Word>stdcall</Word>
<Word>thiscall</Word>
<Word>fastcall</Word>
<Word>unmanaged</Word>
<Word>not_in_gc_heap</Word>
<Word>beforefieldinit</Word>
<Word>instance</Word>
<Word>filter</Word>
<Word>catch</Word>
<Word>static</Word>
<Word>public</Word>
<Word>private</Word>
<Word>synchronized</Word>
<Word>interface</Word>
<Word>extends</Word>
<Word>implements</Word>
<Word>handler</Word>
<Word>finally</Word>
<Word>fault</Word>
<Word>to</Word>
<Word>abstract</Word>
<Word>auto</Word>
<Word>sequential</Word>
<Word>explicit</Word>
<Word>wrapper</Word>
<Word>ansi</Word>
<Word>unicode</Word>
<Word>autochar</Word>
<Word>import</Word>
<Word>enum</Word>
<Word>virtual</Word>
<Word>notremotable</Word>
<Word>special</Word>
<Word>il</Word>
<Word>cil</Word>
<Word>optil</Word>
<Word>managed</Word>
<Word>preservesig</Word>
<Word>runtime</Word>
<Word>method</Word>
<Word>field</Word>
<Word>bytearray</Word>
<Word>final</Word>
<Word>sealed</Word>
<Word>specialname</Word>
<Word>family</Word>
<Word>assembly</Word>
<Word>famandassem</Word>
<Word>famorassem</Word>
<Word>privatescope</Word>
<Word>nested</Word>
<Word>hidebysig</Word>
<Word>newslot</Word>
<Word>rtspecialname</Word>
<Word>pinvokeimpl</Word>
<Word>unmanagedexp</Word>
<Word>reqsecobj</Word>
<Word>.ctor</Word>
<Word>.cctor</Word>
<Word>initonly</Word>
<Word>literal</Word>
<Word>notserialized</Word>
<Word>forwardref</Word>
<Word>internalcall</Word>
<Word>noinlining</Word>
<Word>aggressiveinlining</Word>
<Word>nomangle</Word>
<Word>lasterr</Word>
<Word>winapi</Word>
<Word>cdecl</Word>
<Word>stdcall</Word>
<Word>thiscall</Word>
<Word>fastcall</Word>
<Word>as</Word>
<Word>pinned</Word>
<Word>modreq</Word>
<Word>modopt</Word>
<Word>serializable</Word>
<Word>at</Word>
<Word>tls</Word>
<Word>true</Word>
<Word>false</Word>
<Word>strict</Word>
</Keywords>
<Keywords color="Directives">
<Word>.class</Word>
<Word>.namespace</Word>
<Word>.method</Word>
<Word>.field</Word>
<Word>.emitbyte</Word>
<Word>.try</Word>
<Word>.maxstack</Word>
<Word>.locals</Word>
<Word>.entrypoint</Word>
<Word>.zeroinit</Word>
<Word>.pdirect</Word>
<Word>.data</Word>
<Word>.event</Word>
<Word>.addon</Word>
<Word>.removeon</Word>
<Word>.fire</Word>
<Word>.other</Word>
<Word>protected</Word>
<Word>.property</Word>
<Word>.set</Word>
<Word>.get</Word>
<Word>default</Word>
<Word>.import</Word>
<Word>.permission</Word>
<Word>.permissionset</Word>
<Word>.line</Word>
<Word>.language</Word>
<Word>#line</Word>
</Keywords>
<Keywords color="Security">
<Word>request</Word>
<Word>demand</Word>
<Word>assert</Word>
<Word>deny</Word>
<Word>permitonly</Word>
<Word>linkcheck</Word>
<Word>inheritcheck</Word>
<Word>reqmin</Word>
<Word>reqopt</Word>
<Word>reqrefuse</Word>
<Word>prejitgrant</Word>
<Word>prejitdeny</Word>
<Word>noncasdemand</Word>
<Word>noncaslinkdemand</Word>
<Word>noncasinheritance</Word>
</Keywords>
<Keywords color="Directives">
<!-- custom value specifier -->
<Word>.custom</Word>
<!-- IL method attribute -->
<Word>init</Word>
<!-- Class layout directives -->
<Word>.size</Word>
<Word>.pack</Word>
<!-- Manifest-related keywords -->
<Word>.file</Word>
<Word>nometadata</Word>
<Word>.hash</Word>
<Word>.assembly</Word>
<Word>implicitcom</Word>
<Word>noappdomain</Word>
<Word>noprocess</Word>
<Word>nomachine</Word>
<Word>.publickey</Word>
<Word>.publickeytoken</Word>
<Word>algorithm</Word>
<Word>.ver</Word>
<Word>.locale</Word>
<Word>extern</Word>
<Word>.export</Word>
<Word>.manifestres</Word>
<Word>.mresource</Word>
<Word>.localized</Word>
<!-- Field marshaling keywords -->
<Word>.module</Word>
<Word>marshal</Word>
<Word>custom</Word>
<Word>sysstring</Word>
<Word>fixed</Word>
<Word>variant</Word>
<Word>currency</Word>
<Word>syschar</Word>
<Word>decimal</Word>
<Word>date</Word>
<Word>bstr</Word>
<Word>tbstr</Word>
<Word>lpstr</Word>
<Word>lpwstr</Word>
<Word>lptstr</Word>
<Word>objectref</Word>
<Word>iunknown</Word>
<Word>idispatch</Word>
<Word>struct</Word>
<Word>safearray</Word>
<Word>byvalstr</Word>
<Word>lpvoid</Word>
<Word>any</Word>
<Word>array</Word>
<Word>lpstruct</Word>
<!-- VTable fixup keywords -->
<Word>.vtfixup</Word>
<Word>fromunmanaged</Word>
<Word>callmostderived</Word>
<Word>.vtentry</Word>
<!-- Parameter attributes -->
<Word>in</Word>
<Word>out</Word>
<Word>opt</Word>
<Word>lcid</Word>
<Word>retval</Word>
<Word>.param</Word>
<!-- Method implementations -->
<Word>.override</Word>
<Word>with</Word>
<!-- VariantType keywords -->
<Word>null</Word>
<Word>error</Word>
<Word>hresult</Word>
<Word>carray</Word>
<Word>userdefined</Word>
<Word>record</Word>
<Word>filetime</Word>
<Word>blob</Word>
<Word>stream</Word>
<Word>storage</Word>
<Word>streamed_object</Word>
<Word>stored_object</Word>
<Word>blob_object</Word>
<Word>cf</Word>
<Word>clsid</Word>
<Word>vector</Word>
<!-- Null reference keyword for InitOpt -->
<Word>nullref</Word>
<!-- Header flags keywords -->
<Word>.subsystem</Word>
<Word>.corflags</Word>
<Word>.stackreserve</Word>
<Word>alignment</Word>
<Word>.imagebase</Word>
</Keywords>
<Span color="Comment" ruleSet="CommentMarkerSet">
<Begin>//</Begin>
</Span>
<Span color="Comment" ruleSet="CommentMarkerSet">
<Begin>/\*</Begin>
<End>\*/</End>
</Span>
<Span color="String">
<Begin>"</Begin>
<End>"</End>
</Span>
</RuleSet>
<RuleSet name="CommentMarkerSet" ignoreCase="false">
<Keywords foreground="#FFFF0000" fontWeight="bold">
<Word>TODO</Word>
<Word>FIXME</Word>
</Keywords>
<Keywords foreground="#EEE0E000" fontWeight="bold">
<Word>HACK</Word>
<Word>UNDONE</Word>
</Keywords>
</RuleSet>
</SyntaxDefinition>

63
ILSpy/TextView/XML-Mode-Dark.xshd

@ -0,0 +1,63 @@ @@ -0,0 +1,63 @@
<SyntaxDefinition name="XML" extensions=".xml;.xsl;.xslt;.xsd;.manifest;.config;.addin;.xshd;.wxs;.wxi;.wxl;.proj;.csproj;.vbproj;.ilproj;.booproj;.build;.xfrm;.targets;.xaml;.xpt;.xft;.map;.wsdl;.disco;.ps1xml;.nuspec" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008">
<Color foreground="Green" name="Comment" exampleText="&lt;!-- comment --&gt;" />
<Color foreground="#FFD69D85" name="CData" exampleText="&lt;![CDATA[data]]&gt;" />
<Color foreground="#FFD69D85" name="DocType" exampleText="&lt;!DOCTYPE rootElement&gt;" />
<Color foreground="#FFD69D85" name="XmlDeclaration" exampleText='&lt;?xml version="1.0"?&gt;' />
<Color foreground="#FFD69D85" name="XmlTag" exampleText='&lt;tag attribute="value" /&gt;' />
<Color foreground="#FF00A0FF" name="AttributeName" exampleText='&lt;tag attribute="value" /&gt;' />
<Color foreground="#FFD69D85" name="AttributeValue" exampleText='&lt;tag attribute="value" /&gt;' />
<Color foreground="#FFd8a0df" name="Entity" exampleText="index.aspx?a=1&amp;amp;b=2" />
<Color foreground="#FF559CD6" name="BrokenEntity" exampleText="index.aspx?a=1&amp;b=2" />
<RuleSet>
<Span color="Comment" multiline="true">
<Begin>&lt;!--</Begin>
<End>--&gt;</End>
</Span>
<Span color="CData" multiline="true">
<Begin>&lt;!\[CDATA\[</Begin>
<End>]]&gt;</End>
</Span>
<Span color="DocType" multiline="true">
<Begin>&lt;!DOCTYPE</Begin>
<End>&gt;</End>
</Span>
<Span color="XmlDeclaration" multiline="true">
<Begin>&lt;\?</Begin>
<End>\?&gt;</End>
</Span>
<Span color="XmlTag" multiline="true">
<Begin>&lt;</Begin>
<End>&gt;</End>
<RuleSet>
<!-- Treat the position before '<' as end, as that's not a valid character
in attribute names and indicates the user forgot a closing quote. -->
<Span color="AttributeValue" multiline="true" ruleSet="EntitySet">
<Begin>"</Begin>
<End>"|(?=&lt;)</End>
</Span>
<Span color="AttributeValue" multiline="true" ruleSet="EntitySet">
<Begin>'</Begin>
<End>'|(?=&lt;)</End>
</Span>
<Rule color="AttributeName">[\d\w_\-\.]+(?=(\s*=))</Rule>
<Rule color="AttributeValue">=</Rule>
</RuleSet>
</Span>
<Import ruleSet="EntitySet"/>
</RuleSet>
<RuleSet name="EntitySet">
<Rule color="Entity">
&amp;
[\w\d\#]+
;
</Rule>
<Rule color="BrokenEntity">
&amp;
[\w\d\#]*
#missing ;
</Rule>
</RuleSet>
</SyntaxDefinition>

63
ILSpy/TextView/XML-Mode.xshd

@ -0,0 +1,63 @@ @@ -0,0 +1,63 @@
<SyntaxDefinition name="XML" extensions=".xml;.xsl;.xslt;.xsd;.manifest;.config;.addin;.xshd;.wxs;.wxi;.wxl;.proj;.csproj;.vbproj;.ilproj;.booproj;.build;.xfrm;.targets;.xaml;.xpt;.xft;.map;.wsdl;.disco;.ps1xml;.nuspec" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008">
<Color foreground="Green" name="Comment" exampleText="&lt;!-- comment --&gt;" />
<Color foreground="Blue" name="CData" exampleText="&lt;![CDATA[data]]&gt;" />
<Color foreground="Blue" name="DocType" exampleText="&lt;!DOCTYPE rootElement&gt;" />
<Color foreground="Blue" name="XmlDeclaration" exampleText='&lt;?xml version="1.0"?&gt;' />
<Color foreground="DarkMagenta" name="XmlTag" exampleText='&lt;tag attribute="value" /&gt;' />
<Color foreground="Red" name="AttributeName" exampleText='&lt;tag attribute="value" /&gt;' />
<Color foreground="Blue" name="AttributeValue" exampleText='&lt;tag attribute="value" /&gt;' />
<Color foreground="Teal" name="Entity" exampleText="index.aspx?a=1&amp;amp;b=2" />
<Color foreground="Olive" name="BrokenEntity" exampleText="index.aspx?a=1&amp;b=2" />
<RuleSet>
<Span color="Comment" multiline="true">
<Begin>&lt;!--</Begin>
<End>--&gt;</End>
</Span>
<Span color="CData" multiline="true">
<Begin>&lt;!\[CDATA\[</Begin>
<End>]]&gt;</End>
</Span>
<Span color="DocType" multiline="true">
<Begin>&lt;!DOCTYPE</Begin>
<End>&gt;</End>
</Span>
<Span color="XmlDeclaration" multiline="true">
<Begin>&lt;\?</Begin>
<End>\?&gt;</End>
</Span>
<Span color="XmlTag" multiline="true">
<Begin>&lt;</Begin>
<End>&gt;</End>
<RuleSet>
<!-- Treat the position before '<' as end, as that's not a valid character
in attribute names and indicates the user forgot a closing quote. -->
<Span color="AttributeValue" multiline="true" ruleSet="EntitySet">
<Begin>"</Begin>
<End>"|(?=&lt;)</End>
</Span>
<Span color="AttributeValue" multiline="true" ruleSet="EntitySet">
<Begin>'</Begin>
<End>'|(?=&lt;)</End>
</Span>
<Rule color="AttributeName">[\d\w_\-\.]+(?=(\s*=))</Rule>
<Rule color="AttributeValue">=</Rule>
</RuleSet>
</Span>
<Import ruleSet="EntitySet"/>
</RuleSet>
<RuleSet name="EntitySet">
<Rule color="Entity">
&amp;
[\w\d\#]+
;
</Rule>
<Rule color="BrokenEntity">
&amp;
[\w\d\#]*
#missing ;
</Rule>
</RuleSet>
</SyntaxDefinition>

50
ILSpy/ThemeManager.cs

@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
using System;
using System.Windows;
using System.Windows.Controls;
namespace ICSharpCode.ILSpy
{
internal class ThemeManager
{
private bool _isDarkMode;
private readonly ResourceDictionary _themeDictionaryContainer = new ResourceDictionary();
public static readonly ThemeManager Current = new ThemeManager();
private ThemeManager()
{
Application.Current.Resources.MergedDictionaries.Add(_themeDictionaryContainer);
}
public bool IsDarkMode {
get => _isDarkMode;
set {
_isDarkMode = value;
_themeDictionaryContainer.MergedDictionaries.Clear();
string theme = value ? "Dark" : "Light";
_themeDictionaryContainer.MergedDictionaries.Add(new ResourceDictionary { Source = new Uri($"themes/{theme}Theme.xaml", UriKind.Relative) });
}
}
public Button CreateButton()
{
return new Button {
Style = CreateButtonStyle()
};
}
public Style CreateButtonStyle()
{
return new Style(typeof(Button), (Style)Application.Current.FindResource(typeof(Button)));
}
public Style CreateToolBarButtonStyle()
{
return new Style(typeof(Button), (Style)Application.Current.FindResource(ToolBar.ButtonStyleKey));
}
}
}

24
ILSpy/TreeNodes/AssemblyTreeNode.cs

@ -181,14 +181,21 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -181,14 +181,21 @@ namespace ICSharpCode.ILSpy.TreeNodes
// if we crashed on loading, then we don't have any children
return;
}
if (loadResult.PEFile != null)
try
{
LoadChildrenForPEFile(loadResult.PEFile);
if (loadResult.PEFile != null)
{
LoadChildrenForPEFile(loadResult.PEFile);
}
else if (loadResult.Package != null)
{
var package = loadResult.Package;
this.Children.AddRange(PackageFolderTreeNode.LoadChildrenForFolder(package.RootFolder));
}
}
else if (loadResult.Package != null)
catch (Exception ex)
{
var package = loadResult.Package;
this.Children.AddRange(PackageFolderTreeNode.LoadChildrenForFolder(package.RootFolder));
App.UnhandledException(ex);
}
}
@ -198,9 +205,10 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -198,9 +205,10 @@ namespace ICSharpCode.ILSpy.TreeNodes
var assembly = (MetadataModule)typeSystem.MainModule;
this.Children.Add(new Metadata.MetadataTreeNode(module, this));
Decompiler.DebugInfo.IDebugInfoProvider debugInfo = LoadedAssembly.GetDebugInfoOrNull();
if (debugInfo is Decompiler.PdbProvider.PortableDebugInfoProvider ppdb)
if (debugInfo is Decompiler.PdbProvider.PortableDebugInfoProvider ppdb
&& ppdb.GetMetadataReader() is System.Reflection.Metadata.MetadataReader reader)
{
this.Children.Add(new Metadata.DebugMetadataTreeNode(module, ppdb.IsEmbedded, ppdb.Provider.GetMetadataReader(), this));
this.Children.Add(new Metadata.DebugMetadataTreeNode(module, ppdb.IsEmbedded, reader, this));
}
this.Children.Add(new ReferenceFolderTreeNode(module, this));
if (module.Resources.Any())
@ -539,7 +547,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -539,7 +547,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
if (!loadedAssm.HasLoadError)
{
loadedAssm.IsAutoLoaded = false;
node.RaisePropertyChanged(nameof(node.Foreground));
node.RaisePropertyChanged(nameof(ILSpyTreeNode.IsAutoLoaded));
}
}
MainWindow.Instance.CurrentAssemblyList.RefreshSave();

3
ILSpy/TreeNodes/DerivedTypesEntryNode.cs

@ -85,8 +85,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -85,8 +85,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
IEnumerable<ILSpyTreeNode> FetchChildren(CancellationToken ct)
{
// FetchChildren() runs on the main thread; but the enumerator will be consumed on a background thread
var assemblies = list.GetAssemblies().Select(node => node.GetPEFileOrNull()).Where(asm => asm != null).ToArray();
return DerivedTypesTreeNode.FindDerivedTypes(list, type, assemblies, ct);
return DerivedTypesTreeNode.FindDerivedTypes(list, type, ct);
}
public override void ActivateItem(System.Windows.RoutedEventArgs e)

7
ILSpy/TreeNodes/DerivedTypesTreeNode.cs

@ -58,15 +58,16 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -58,15 +58,16 @@ 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.GetPEFileOrNull()).Where(asm => asm != null).ToArray();
return FindDerivedTypes(list, type, assemblies, cancellationToken);
return FindDerivedTypes(list, type, cancellationToken);
}
internal static IEnumerable<DerivedTypesEntryNode> FindDerivedTypes(AssemblyList list, ITypeDefinition type,
PEFile[] assemblies, CancellationToken cancellationToken)
CancellationToken cancellationToken)
{
var definitionMetadata = type.ParentModule.PEFile.Metadata;
var metadataToken = (SRM.TypeDefinitionHandle)type.MetadataToken;
var assemblies = list.GetAllAssemblies().GetAwaiter().GetResult()
.Select(node => node.GetPEFileOrNull()).Where(asm => asm != null).ToArray();
foreach (var module in assemblies)
{
var metadata = module.Metadata;

17
ILSpy/TreeNodes/ILSpyTreeNode.cs

@ -185,22 +185,5 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -185,22 +185,5 @@ namespace ICSharpCode.ILSpy.TreeNodes
public virtual bool IsAutoLoaded {
get { return false; }
}
public override System.Windows.Media.Brush Foreground {
get {
if (IsPublicAPI)
if (IsAutoLoaded)
{
// HACK: should not be hard coded?
return System.Windows.Media.Brushes.SteelBlue;
}
else
{
return base.Foreground;
}
else
return System.Windows.SystemColors.GrayTextBrush;
}
}
}
}

4
ILSpy/TreeNodes/ReferenceFolderTreeNode.cs

@ -56,7 +56,9 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -56,7 +56,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
{
language.WriteCommentLine(output, $"Detected Target-Framework-Id: {parentAssembly.LoadedAssembly.GetTargetFrameworkIdAsync().Result}");
language.WriteCommentLine(output, $"Detected TargetFramework-Id: {parentAssembly.LoadedAssembly.GetTargetFrameworkIdAsync().Result}");
language.WriteCommentLine(output, $"Detected RuntimePack: {parentAssembly.LoadedAssembly.GetRuntimePackAsync().Result}");
App.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(EnsureLazyChildren));
output.WriteLine();
language.WriteCommentLine(output, "Referenced assemblies (in metadata order):");

60
ILSpy/themes/DarkTheme.xaml

@ -0,0 +1,60 @@ @@ -0,0 +1,60 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:styles="urn:TomsToolbox.Wpf.Styles"
xmlns:themes="clr-namespace:ICSharpCode.ILSpy.themes">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/AvalonDock.Themes.VS2013;component/darktheme.xaml" />
</ResourceDictionary.MergedDictionaries>
<Color x:Key="{x:Static SystemColors.ControlLightLightColorKey}">#333337</Color>
<Color x:Key="{x:Static SystemColors.ControlLightColorKey}">#464646</Color>
<Color x:Key="{x:Static SystemColors.ControlColorKey}">#252526</Color>
<Color x:Key="{x:Static SystemColors.ControlDarkColorKey}">#686868</Color>
<Color x:Key="{x:Static SystemColors.ControlDarkDarkColorKey}">#9E9E9E</Color>
<Color x:Key="{x:Static SystemColors.ControlTextColorKey}">#F1F1F1</Color>
<Color x:Key="{x:Static SystemColors.GrayTextColorKey}">#999999</Color>
<Color x:Key="{x:Static SystemColors.HighlightColorKey}">#3399FF</Color>
<Color x:Key="{x:Static SystemColors.HighlightTextColorKey}">#FFFFFF</Color>
<Color x:Key="{x:Static SystemColors.InfoTextColorKey}">#F1F1F1</Color>
<Color x:Key="{x:Static SystemColors.InfoColorKey}">#333337</Color>
<Color x:Key="{x:Static SystemColors.MenuColorKey}">#1B1B1C</Color>
<Color x:Key="{x:Static SystemColors.MenuBarColorKey}">#1B1B1C</Color>
<Color x:Key="{x:Static SystemColors.MenuTextColorKey}">#F1F1F1</Color>
<Color x:Key="{x:Static SystemColors.WindowColorKey}">#333337</Color>
<Color x:Key="{x:Static SystemColors.WindowTextColorKey}">#F1F1F1</Color>
<Color x:Key="{x:Static SystemColors.ActiveCaptionColorKey}">#2D2D30</Color>
<Color x:Key="{x:Static SystemColors.ActiveBorderColorKey}">#007ACC</Color>
<Color x:Key="{x:Static SystemColors.ActiveCaptionTextColorKey}">#F1F1F1</Color>
<Color x:Key="{x:Static SystemColors.InactiveCaptionColorKey}">#2D2D30</Color>
<Color x:Key="{x:Static SystemColors.InactiveBorderColorKey}">#434346</Color>
<Color x:Key="{x:Static SystemColors.InactiveCaptionTextColorKey}">#F1F1F1</Color>
<SolidColorBrush x:Key="{x:Static SystemColors.ControlLightLightBrushKey}" Color="#333337" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlLightBrushKey}" Color="#464646" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="#252526" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlDarkBrushKey}" Color="#686868" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlDarkDarkBrushKey}" Color="#9E9E9E" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="#F1F1F1" />
<SolidColorBrush x:Key="{x:Static SystemColors.GrayTextBrushKey}" Color="#999999" />
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="#3399FF" />
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="#FFFFFF" />
<SolidColorBrush x:Key="{x:Static SystemColors.InfoTextBrushKey}" Color="#F1F1F1" />
<SolidColorBrush x:Key="{x:Static SystemColors.InfoBrushKey}" Color="#333337" />
<SolidColorBrush x:Key="{x:Static SystemColors.MenuBrushKey}" Color="#1B1B1C" />
<SolidColorBrush x:Key="{x:Static SystemColors.MenuBarBrushKey}" Color="#1B1B1C" />
<SolidColorBrush x:Key="{x:Static SystemColors.MenuTextBrushKey}" Color="#F1F1F1" />
<SolidColorBrush x:Key="{x:Static SystemColors.WindowBrushKey}" Color="#333337" />
<SolidColorBrush x:Key="{x:Static SystemColors.WindowTextBrushKey}" Color="#F1F1F1" />
<SolidColorBrush x:Key="{x:Static SystemColors.ActiveCaptionBrushKey}" Color="#2D2D30" />
<SolidColorBrush x:Key="{x:Static SystemColors.ActiveBorderBrushKey}" Color="#007ACC" />
<SolidColorBrush x:Key="{x:Static SystemColors.ActiveCaptionTextBrushKey}" Color="#F1F1F1" />
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveCaptionBrushKey}" Color="#2D2D30" />
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveBorderBrushKey}" Color="#434346" />
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveCaptionTextBrushKey}" Color="#F1F1F1" />
<SolidColorBrush x:Key="{x:Static styles:ResourceKeys.BorderBrush}" Color="#9E9E9E" />
<SolidColorBrush x:Key="{x:Static styles:ResourceKeys.DisabledBrush}" Color="#2D2D30" />
<Color x:Key="{x:Static themes:ResourceKeys.TextMarkerBackgroundColor}">MediumVioletRed</Color>
<SolidColorBrush x:Key="{x:Static themes:ResourceKeys.LinkTextForegroundBrush}">CornflowerBlue</SolidColorBrush>
</ResourceDictionary>

52
ILSpy/themes/LightTheme.xaml

@ -0,0 +1,52 @@ @@ -0,0 +1,52 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:styles="urn:TomsToolbox.Wpf.Styles">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/AvalonDock.Themes.VS2013;component/lighttheme.xaml" />
</ResourceDictionary.MergedDictionaries>
<Color x:Key="{x:Static SystemColors.ControlLightLightColorKey}">#FCFCFC</Color>
<Color x:Key="{x:Static SystemColors.ControlLightColorKey}">#D8D8E0</Color>
<Color x:Key="{x:Static SystemColors.ControlColorKey}">#F5F5F5</Color>
<Color x:Key="{x:Static SystemColors.ControlDarkColorKey}">#C2C3C9</Color>
<Color x:Key="{x:Static SystemColors.ControlDarkDarkColorKey}">#686868</Color>
<Color x:Key="{x:Static SystemColors.ControlTextColorKey}">#1E1E1E</Color>
<Color x:Key="{x:Static SystemColors.GrayTextColorKey}">#717171</Color>
<Color x:Key="{x:Static SystemColors.HighlightColorKey}">#3399FF</Color>
<Color x:Key="{x:Static SystemColors.HighlightTextColorKey}">#FFFFFF</Color>
<Color x:Key="{x:Static SystemColors.MenuColorKey}">#F6F6F6</Color>
<Color x:Key="{x:Static SystemColors.MenuBarColorKey}">#F6F6F6</Color>
<Color x:Key="{x:Static SystemColors.MenuTextColorKey}">#1E1E1E</Color>
<Color x:Key="{x:Static SystemColors.WindowColorKey}">#FFFFFF</Color>
<Color x:Key="{x:Static SystemColors.WindowTextColorKey}">#1E1E1E</Color>
<Color x:Key="{x:Static SystemColors.ActiveCaptionColorKey}">#EEEEF2</Color>
<Color x:Key="{x:Static SystemColors.ActiveBorderColorKey}">#007ACC</Color>
<Color x:Key="{x:Static SystemColors.ActiveCaptionTextColorKey}">#1E1E1E</Color>
<Color x:Key="{x:Static SystemColors.InactiveCaptionColorKey}">#EEEEF2</Color>
<Color x:Key="{x:Static SystemColors.InactiveBorderColorKey}">#CCCEDB</Color>
<Color x:Key="{x:Static SystemColors.InactiveCaptionTextColorKey}">#1E1E1E</Color>
<SolidColorBrush x:Key="{x:Static SystemColors.ControlLightLightBrushKey}" Color="#FCFCFC" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlLightBrushKey}" Color="#D8D8E0" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="#F5F5F5" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlDarkBrushKey}" Color="#C2C3C9" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlDarkDarkBrushKey}" Color="#686868" />
<SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}" Color="#1E1E1E" />
<SolidColorBrush x:Key="{x:Static SystemColors.GrayTextBrushKey}" Color="#717171" />
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="#3399FF" />
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="#FFFFFF" />
<SolidColorBrush x:Key="{x:Static SystemColors.MenuBrushKey}" Color="#F6F6F6" />
<SolidColorBrush x:Key="{x:Static SystemColors.MenuBarBrushKey}" Color="#F6F6F6" />
<SolidColorBrush x:Key="{x:Static SystemColors.MenuTextBrushKey}" Color="#1E1E1E" />
<SolidColorBrush x:Key="{x:Static SystemColors.WindowBrushKey}" Color="#FFFFFF" />
<SolidColorBrush x:Key="{x:Static SystemColors.WindowTextBrushKey}" Color="#1E1E1E" />
<SolidColorBrush x:Key="{x:Static SystemColors.ActiveCaptionBrushKey}" Color="#EEEEF2" />
<SolidColorBrush x:Key="{x:Static SystemColors.ActiveBorderBrushKey}" Color="#007ACC" />
<SolidColorBrush x:Key="{x:Static SystemColors.ActiveCaptionTextBrushKey}" Color="#1E1E1E" />
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveCaptionBrushKey}" Color="#EEEEF2" />
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveBorderBrushKey}" Color="#CCCEDB" />
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveCaptionTextBrushKey}" Color="#1E1E1E" />
<SolidColorBrush x:Key="{x:Static styles:ResourceKeys.BorderBrush}" Color="#686868" />
<SolidColorBrush x:Key="{x:Static styles:ResourceKeys.DisabledBrush}" Color="#EEEEF2" />
</ResourceDictionary>

11
ILSpy/themes/ResourceKeys.cs

@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
using System.Windows;
namespace ICSharpCode.ILSpy.themes
{
public static class ResourceKeys
{
public static ResourceKey TextMarkerBackgroundColor = new ComponentResourceKey(typeof(ResourceKeys), "TextMarkerBackgroundColor");
public static ResourceKey TextMarkerDefinitionBackgroundColor = new ComponentResourceKey(typeof(ResourceKeys), "TextMarkerDefinitionBackgroundColor");
public static ResourceKey LinkTextForegroundBrush = new ComponentResourceKey(typeof(ResourceKeys), "LinkTextForegroundBrush");
}
}

6
ILSpy/themes/generic.xaml

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:ICSharpCode.ILSpy.Controls"
>
xmlns:themes="clr-namespace:ICSharpCode.ILSpy.themes">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../Controls/SearchBoxStyle.xaml" />
</ResourceDictionary.MergedDictionaries>
@ -26,4 +26,8 @@ @@ -26,4 +26,8 @@
Data = "M 5,5 L 10,10 L 15,5 L 5,5"/>
</StackPanel>
</DataTemplate>
<Color x:Key="{x:Static themes:ResourceKeys.TextMarkerBackgroundColor}">GreenYellow</Color>
<Color x:Key="{x:Static themes:ResourceKeys.TextMarkerDefinitionBackgroundColor}">LightSeaGreen</Color>
<SolidColorBrush x:Key="{x:Static themes:ResourceKeys.LinkTextForegroundBrush}">Blue</SolidColorBrush>
</ResourceDictionary>

4
SharpTreeView/ICSharpCode.TreeView.csproj

@ -19,4 +19,8 @@ @@ -19,4 +19,8 @@
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="TomsToolbox.Wpf.Styles" Version="2.4.2" />
</ItemGroup>
</Project>

4
SharpTreeView/SharpTreeNode.cs

@ -122,10 +122,6 @@ namespace ICSharpCode.TreeView @@ -122,10 +122,6 @@ namespace ICSharpCode.TreeView
get { return null; }
}
public virtual Brush Foreground {
get { return SystemColors.WindowTextBrush; }
}
public virtual object Icon {
get { return null; }
}

4
SharpTreeView/SharpTreeView.cs

@ -669,8 +669,8 @@ namespace ICSharpCode.TreeView @@ -669,8 +669,8 @@ namespace ICSharpCode.TreeView
if (place == DropPlace.Inside)
{
previewNodeView.TextBackground = SystemColors.HighlightBrush;
previewNodeView.Foreground = SystemColors.HighlightTextBrush;
previewNodeView.SetResourceReference(SharpTreeNodeView.TextBackgroundProperty, SystemColors.HighlightBrushKey);
previewNodeView.SetResourceReference(SharpTreeNodeView.ForegroundProperty, SystemColors.HighlightTextBrushKey);
}
else
{

35
SharpTreeView/Themes/Generic.xaml

@ -1,12 +1,10 @@ @@ -1,12 +1,10 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Default="clr-namespace:ICSharpCode.TreeView">
<SolidColorBrush x:Key="ListBorder"
Color="#FF7F9DB9" />
xmlns:Default="clr-namespace:ICSharpCode.TreeView"
xmlns:styles="urn:TomsToolbox.Wpf.Styles">
<Style x:Key="ExpandCollapseToggleStyle"
TargetType="{x:Type ToggleButton}">
TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource {x:Type ToggleButton}}">
<Setter Property="Focusable"
Value="False" />
<Setter Property="Template">
@ -15,7 +13,7 @@ @@ -15,7 +13,7 @@
<Border Width="9"
Height="9"
BorderThickness="1"
BorderBrush="#FF7898B5"
BorderBrush="{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}"
CornerRadius="1"
SnapsToDevicePixels="True">
<Border.Background>
@ -85,7 +83,7 @@ @@ -85,7 +83,7 @@
<ControlTemplate TargetType="{x:Type Default:EditTextBox}">
<Border Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"
BorderThickness="1"
BorderBrush="{StaticResource ListBorder}"
BorderBrush="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}"
Padding="0 1 2 0">
<ScrollViewer Name="PART_ContentHost" />
</Border>
@ -95,7 +93,7 @@ @@ -95,7 +93,7 @@
</Style>
<Style TargetType="{x:Type Default:SharpTreeView}"
BasedOn="{StaticResource {x:Type ListBox}}">
BasedOn="{StaticResource {x:Static styles:ResourceKeys.ListBoxStyle}}">
<Style.Triggers>
<Trigger Property="ShowRoot"
Value="False">
@ -116,13 +114,13 @@ @@ -116,13 +114,13 @@
Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Background"
Value="WhiteSmoke" />
Value="{DynamicResource {x:Static SystemColors.ControlLightLightBrushKey}}" />
</MultiTrigger>
</Style.Triggers>
</Style>
<Style x:Key="{x:Static Default:SharpGridView.ItemContainerStyleKey}"
TargetType="{x:Type ListViewItem}">
TargetType="{x:Type ListViewItem}" BasedOn="{StaticResource {x:Type ListViewItem}}">
<Setter Property="Background"
Value="Transparent" />
<Setter Property="VerticalContentAlignment"
@ -180,14 +178,21 @@ @@ -180,14 +178,21 @@
<ControlTemplate TargetType="{x:Type Default:SharpTreeViewItem}">
<Border Background="Transparent">
<Border Background="{TemplateBinding Background}">
<Default:SharpTreeNodeView Name="nodeView"
Foreground="{Binding Foreground}"
<Default:SharpTreeNodeView x:Name="nodeView"
HorizontalAlignment="Left" />
</Border>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected"
Value="True">
<DataTrigger Binding="{Binding IsAutoLoaded}"
Value="True">
<Setter Property="Foreground" Value="SteelBlue" />
</DataTrigger>
<DataTrigger Binding="{Binding IsPublicAPI}"
Value="False">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</DataTrigger>
<Trigger Property="IsSelected"
Value="True">
<Setter TargetName="nodeView"
Property="TextBackground"
Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
@ -228,7 +233,7 @@ @@ -228,7 +233,7 @@
<Setter.Value>
<ControlTemplate TargetType="{x:Type Default:SharpTreeNodeView}">
<Grid>
<Default:LinesRenderer Name="linesRenderer"
<Default:LinesRenderer x:Name="linesRenderer"
ClipToBounds="True"
Visibility="{Binding ShowLines, RelativeSource={RelativeSource AncestorType={x:Type Default:SharpTreeView}}, Converter={Default:CollapsedWhenFalse}}" />
<StackPanel Orientation="Horizontal">

331
decompiler-nuget-demos.ipynb

@ -0,0 +1,331 @@ @@ -0,0 +1,331 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Load the NuGet package and print out the version to make sure we are using the latest and greatest"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
}
},
"source": [
"#r \"nuget: ICSharpCode.Decompiler, 7.0.0.6372-preview3\"\n",
"\n",
"using System.Reflection.Metadata;\n",
"using ICSharpCode.Decompiler;\n",
"using ICSharpCode.Decompiler.CSharp;\n",
"using ICSharpCode.Decompiler.Metadata;\n",
"using ICSharpCode.Decompiler.TypeSystem;\n",
"\n",
"Console.WriteLine(typeof(FullTypeName).Assembly.GetName());"
],
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "ICSharpCode.Decompiler, Version=7.0.0.6372, Culture=neutral, PublicKeyToken=d4bfe873e7598c49\r\n"
},
"execution_count": 1,
"metadata": {}
}
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You must have compiled **frontends.sln** first (run “dotnet build” in ICSharpCode.Decompiler.PowerShell folder). Make sure to modify **basePath** to your repository path."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
}
},
"source": [
"const string basePath = @\"D:\\GitWorkspace\\ILSpy\\\";\n",
"string testAssemblyPath = basePath + @\"ICSharpCode.Decompiler.PowerShell\\bin\\Release\\netstandard2.0\\ICSharpCode.Decompiler.dll\";\n",
"\n",
"var decompiler = new CSharpDecompiler(testAssemblyPath, new DecompilerSettings());"
],
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Get the count of types in this module"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
}
},
"source": [
"var types = decompiler.TypeSystem.MainModule.TypeDefinitions;\n",
"Console.WriteLine(types.Count());"
],
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "1459\r\n"
},
"execution_count": 1,
"metadata": {}
}
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Decompile a known type (as a whole)"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
}
},
"source": [
"// ICSharpCode.Decompiler.Util.Empty<T> -> translates to `n, where n is the # of generic parameters\n",
"var nameOfGenericType = new FullTypeName(\"ICSharpCode.Decompiler.Util.Empty`1\");\n",
"Console.WriteLine(decompiler.DecompileTypeAsString(nameOfGenericType));"
],
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "using System;\r\n\r\nnamespace ICSharpCode.Decompiler.Util\r\n{\r\n\tpublic static class Empty<T>\r\n\t{\r\n\t\tpublic static readonly T[] Array = System.Array.Empty<T>();\r\n\t}\r\n}\r\n\r\n"
},
"execution_count": 1,
"metadata": {}
}
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If you want to decompile one single member (sample: first method)"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
}
},
"source": [
"var nameOfUniResolver = new FullTypeName(\"ICSharpCode.Decompiler.Metadata.UniversalAssemblyResolver\");\n",
"ITypeDefinition typeInfo = decompiler.TypeSystem.FindType(nameOfUniResolver).GetDefinition();\n",
"var tokenOfFirstMethod = typeInfo.Methods.First().MetadataToken;\n",
"Console.WriteLine(decompiler.DecompileAsString(tokenOfFirstMethod));"
],
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "using System;\r\n\r\nstatic UniversalAssemblyResolver()\r\n{\r\n\tgac_paths = GetGacPaths();\r\n\tZeroVersion = new Version(0, 0, 0, 0);\r\n\tif (Type.GetType(\"Mono.Runtime\") != null)\r\n\t{\r\n\t\tdecompilerRuntime = DecompilerRuntime.Mono;\r\n\t}\r\n\telse if (typeof(object).Assembly.GetName().Name == \"System.Private.CoreLib\")\r\n\t{\r\n\t\tdecompilerRuntime = DecompilerRuntime.NETCoreApp;\r\n\t}\r\n\telse if (Environment.OSVersion.Platform == PlatformID.Unix)\r\n\t{\r\n\t\tdecompilerRuntime = DecompilerRuntime.Mono;\r\n\t}\r\n}\r\n\r\n"
},
"execution_count": 1,
"metadata": {}
}
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If you need access to low-level metadata tables"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
}
},
"source": [
"ITypeDefinition type = decompiler.TypeSystem.FindType(nameOfUniResolver).GetDefinition();\n",
"var module = type.ParentModule.PEFile;"
],
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Get the child namespaces"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
}
},
"source": [
"var icsdns = decompiler.TypeSystem.RootNamespace;\n",
"foreach (var cn in icsdns.ChildNamespaces) Console.WriteLine(cn.FullName);"
],
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "Microsoft\r\n"
},
"execution_count": 1,
"metadata": {}
},
{
"output_type": "execute_result",
"data": {
"text/plain": "System\r\n"
},
"execution_count": 1,
"metadata": {}
},
{
"output_type": "execute_result",
"data": {
"text/plain": "LightJson\r\n"
},
"execution_count": 1,
"metadata": {}
},
{
"output_type": "execute_result",
"data": {
"text/plain": "Humanizer\r\n"
},
"execution_count": 1,
"metadata": {}
},
{
"output_type": "execute_result",
"data": {
"text/plain": "ICSharpCode\r\n"
},
"execution_count": 1,
"metadata": {}
},
{
"output_type": "execute_result",
"data": {
"text/plain": "FxResources\r\n"
},
"execution_count": 1,
"metadata": {}
},
{
"output_type": "execute_result",
"data": {
"text/plain": "Internal\r\n"
},
"execution_count": 1,
"metadata": {}
},
{
"output_type": "execute_result",
"data": {
"text/plain": "Windows\r\n"
},
"execution_count": 1,
"metadata": {}
},
{
"output_type": "execute_result",
"data": {
"text/plain": "MS\r\n"
},
"execution_count": 1,
"metadata": {}
}
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Get types in a single namespace"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
}
},
"source": [
"var typesInNamespace = icsdns.ChildNamespaces.First(cn => cn.FullName == \"LightJson\").Types;\n",
"Console.WriteLine(typesInNamespace.First().FullTypeName);"
],
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": "LightJson.JsonArray\r\n"
},
"execution_count": 1,
"metadata": {}
}
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
}
},
"source": [
""
],
"outputs": []
}
],
"metadata": {
"kernelspec": {
"display_name": ".NET (C#)",
"language": "C#",
"name": ".net-csharp"
},
"language_info": {
"file_extension": ".cs",
"mimetype": "text/x-csharp",
"name": "C#",
"pygments_lexer": "csharp",
"version": "8.0"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

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

Loading…
Cancel
Save