Browse Source

Merge branch 'christophwille/sbomtargets' of https://github.com/icsharpcode/ILSpy into christophwille/sbomtargets

pull/3346/head
Christoph Wille 1 year ago
parent
commit
6abd9524b9
  1. 3
      .github/workflows/build-frontends.yml
  2. 27
      .github/workflows/build-ilspy.yml
  3. 7
      .github/workflows/codeql-analysis.yml
  4. 3
      .github/workflows/generate-bom.yml
  5. 5
      .github/workflows/lock.yml
  6. 47
      .github/workflows/scorecard.yml
  7. 2
      BuildTools/pre-commit
  8. 49
      Directory.Packages.props
  9. 6
      ICSharpCode.BamlDecompiler/ICSharpCode.BamlDecompiler.csproj
  10. 44
      ICSharpCode.BamlDecompiler/packages.lock.json
  11. 6
      ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs
  12. 10
      ICSharpCode.Decompiler.Tests/ProjectDecompiler/TargetFrameworkTests.cs
  13. 186
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.cs
  14. 2
      ICSharpCode.Decompiler.Tests/UglyTestRunner.cs
  15. 2
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  16. 85
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  17. 25
      ICSharpCode.Decompiler/CSharp/StatementBuilder.cs
  18. 6
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  19. 89
      ICSharpCode.Decompiler/IL/Transforms/SwitchOnStringTransform.cs
  20. 15
      ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs
  21. 2
      ICSharpCode.Decompiler/Properties/DecompilerVersionInfo.template.cs
  22. 91
      ICSharpCode.Decompiler/packages.lock.json
  23. 6
      ICSharpCode.ILSpyCmd/ICSharpCode.ILSpyCmd.csproj
  24. 453
      ICSharpCode.ILSpyCmd/packages.lock.json
  25. 6
      ICSharpCode.ILSpyX/ICSharpCode.ILSpyX.csproj
  26. 79
      ICSharpCode.ILSpyX/packages.lock.json
  27. 2
      ILSpy.AddIn.VS2022/ILSpy.AddIn.VS2022.csproj
  28. 2
      ILSpy.AddIn.VS2022/source.extension.vsixmanifest.template
  29. 2
      ILSpy.AddIn/ILSpy.AddIn.csproj
  30. 2
      ILSpy.AddIn/source.extension.vsixmanifest.template
  31. 2
      ILSpy.Installer/ILSpy.Installer.csproj
  32. 5
      ILSpy.ReadyToRun/ReadyToRunLanguage.cs
  33. 124
      ILSpy/Commands/CreateDiagramContextMenuEntry.cs
  34. 11
      ILSpy/Controls/CustomDialog.cs
  35. 12
      ILSpy/Docking/DockWorkspace.cs
  36. 7
      ILSpy/ILSpy.csproj
  37. 2
      ILSpy/MainWindow.xaml
  38. 18
      ILSpy/Properties/Resources.Designer.cs
  39. 6
      ILSpy/Properties/Resources.resx
  40. 4
      ILSpy/TextView/DecompilerTextView.cs
  41. 2
      LICENSE
  42. 4
      NuGet.config
  43. 15
      SECURITY.md
  44. 2
      doc/ILSpyAboutPage.txt
  45. 2
      doc/ILSpyAboutPage_zh_Hans.txt
  46. 2
      doc/copyright.txt

3
.github/workflows/build-frontends.yml

@ -6,6 +6,9 @@ on:
pull_request: pull_request:
branches: [ master, release/** ] branches: [ master, release/** ]
permissions:
contents: read
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest

27
.github/workflows/build-ilspy.yml

@ -6,8 +6,13 @@ on:
pull_request: pull_request:
branches: [ master, release/** ] branches: [ master, release/** ]
permissions:
contents: read
jobs: jobs:
Build: Build:
permissions:
packages: write # for dotnet nuget push
runs-on: windows-2022 runs-on: windows-2022
strategy: strategy:
fail-fast: false fail-fast: false
@ -30,12 +35,15 @@ jobs:
with: with:
dotnet-version: '8.0.x' dotnet-version: '8.0.x'
dotnet-quality: 'ga' dotnet-quality: 'ga'
env:
DOTNET_INSTALL_DIR: ${{ runner.temp }}/.dotnet
DOTNET_ROOT: ${{ runner.temp }}/.dotnet
- name: Add msbuild to PATH - name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v2 uses: microsoft/setup-msbuild@v2
- name: Install dotnet-format - name: Install dotnet-format
run: dotnet tool install -g dotnet-format --version "8.0.453106" --add-source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8/nuget/v3/index.json run: dotnet tool install -g dotnet-format --version "8.3.546805" --add-source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8/nuget/v3/index.json
- name: Get Version - name: Get Version
id: version id: version
@ -150,7 +158,20 @@ jobs:
if: github.ref == 'refs/heads/master' && matrix.configuration == 'release' if: github.ref == 'refs/heads/master' && matrix.configuration == 'release'
run: | run: |
dotnet nuget push "ICSharpCode.ILSpyX\bin\Release\ICSharpCode.ILSpyX*.nupkg" --api-key ${{ secrets.GITHUB_TOKEN }} --source https://nuget.pkg.github.com/${{ github.repository_owner }} dotnet nuget push "ICSharpCode.ILSpyX\bin\Release\ICSharpCode.ILSpyX*.nupkg" --api-key ${{ secrets.GITHUB_TOKEN }} --source https://nuget.pkg.github.com/${{ github.repository_owner }}
- name: Upload BamlDecompiler NuGet release build artifacts
if: matrix.configuration == 'release'
uses: actions/upload-artifact@v4
with:
name: ICSharpCode.BamlDecompiler NuGet Package (${{ matrix.configuration }})
path: ICSharpCode.BamlDecompiler\bin\Release\ICSharpCode.BamlDecompiler*.nupkg
if-no-files-found: error
- name: Publish DecomBamlDecompilerpiler NuGet
if: github.ref == 'refs/heads/master' && matrix.configuration == 'release'
run: |
dotnet nuget push "ICSharpCode.BamlDecompiler\bin\Release\ICSharpCode.BamlDecompiler*.nupkg" --api-key ${{ secrets.GITHUB_TOKEN }} --source https://nuget.pkg.github.com/${{ github.repository_owner }}
- name: Upload zip binaries build artifacts - name: Upload zip binaries build artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:

7
.github/workflows/codeql-analysis.yml

@ -6,8 +6,15 @@ on:
pull_request: pull_request:
branches: [ master, release/** ] branches: [ master, release/** ]
permissions:
contents: read
jobs: jobs:
analyze: analyze:
permissions:
actions: read # for github/codeql-action/init to get workflow details
security-events: write # for github/codeql-action/analyze to upload SARIF results
name: Analyze name: Analyze
runs-on: ubuntu-latest runs-on: ubuntu-latest

3
.github/workflows/generate-bom.yml

@ -3,6 +3,9 @@ name: Generate BOM
on: on:
workflow_dispatch: workflow_dispatch:
permissions:
contents: read
jobs: jobs:
build: build:

5
.github/workflows/lock.yml

@ -4,8 +4,13 @@ on:
schedule: schedule:
- cron: '0 0 * * *' - cron: '0 0 * * *'
permissions:
contents: read
jobs: jobs:
lock: lock:
permissions:
issues: write # for dessant/lock-threads to lock issues
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: dessant/lock-threads@v5.0.1 - uses: dessant/lock-threads@v5.0.1

47
.github/workflows/scorecard.yml

@ -0,0 +1,47 @@
name: Scorecard supply-chain security
on:
# For Branch-Protection check. Only the default branch is supported. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection (disabled)
# branch_protection_rule:
workflow_dispatch:
# schedule ("Maintained") and push are disabled atm
# schedule:
# - cron: '25 1 * * 2'
# push:
# branches: [ "master" ]
permissions: read-all
jobs:
analysis:
name: Scorecard analysis
runs-on: ubuntu-latest
permissions:
security-events: write # Needed to upload the results to code-scanning dashboard.
id-token: write # Needed to publish results and get a badge (see publish_results below).
steps:
- name: "Checkout code"
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
with:
results_file: results.sarif
results_format: sarif
publish_results: true
- name: "Upload artifact"
uses: actions/upload-artifact@97a0fba1372883ab732affbe8f94b823f91727db # v3.pre.node20
with:
name: SARIF file
path: results.sarif
retention-days: 5
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif

2
BuildTools/pre-commit

@ -5,7 +5,7 @@
set -eu set -eu
DOTNET_FORMAT_VERSION=8.0.453106 DOTNET_FORMAT_VERSION=8.3.546805
DOTNET_PATH="$LOCALAPPDATA/ICSharpCode/ILSpy/dotnet-format-$DOTNET_FORMAT_VERSION" DOTNET_PATH="$LOCALAPPDATA/ICSharpCode/ILSpy/dotnet-format-$DOTNET_FORMAT_VERSION"
if [ ! -d "$DOTNET_PATH" ]; then if [ ! -d "$DOTNET_PATH" ]; then
echo "Downloading dotnet-format $DOTNET_FORMAT_VERSION..." echo "Downloading dotnet-format $DOTNET_FORMAT_VERSION..."

49
Directory.Packages.props

@ -5,19 +5,19 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageVersion Include="AvalonEdit" Version="6.3.0.90" /> <PackageVersion Include="AvalonEdit" Version="6.3.0.90" />
<PackageVersion Include="CliWrap" Version="3.6.6" /> <PackageVersion Include="CliWrap" Version="3.7.0" />
<PackageVersion Include="DataGridExtensions" Version="2.6.0" /> <PackageVersion Include="DataGridExtensions" Version="2.6.0" />
<PackageVersion Include="DiffLib" Version="2017.7.26.1241" /> <PackageVersion Include="DiffLib" Version="2017.7.26.1241" />
<PackageVersion Include="Dirkster.AvalonDock.Themes.VS2013" Version="4.72.1" /> <PackageVersion Include="Dirkster.AvalonDock.Themes.VS2013" Version="4.72.1" />
<PackageVersion Include="FluentAssertions" Version="6.12.1" /> <PackageVersion Include="FluentAssertions" Version="7.0.0" />
<PackageVersion Include="ILCompiler.Reflection.ReadyToRun.Experimental" Version="8.0.0-rc.2.23471.30" /> <PackageVersion Include="ILCompiler.Reflection.ReadyToRun.Experimental" Version="9.0.1-rtm.24557.9" />
<PackageVersion Include="Iced" Version="1.21.0" /> <PackageVersion Include="Iced" Version="1.21.0" />
<PackageVersion Include="JunitXml.TestLogger" Version="4.1.0" /> <PackageVersion Include="JunitXml.TestLogger" Version="5.0.0" />
<PackageVersion Include="K4os.Compression.LZ4" Version="1.3.8" /> <PackageVersion Include="K4os.Compression.LZ4" Version="1.3.8" />
<PackageVersion Include="McMaster.Extensions.CommandLineUtils" Version="4.1.1" /> <PackageVersion Include="McMaster.Extensions.CommandLineUtils" Version="4.1.1" />
<PackageVersion Include="McMaster.Extensions.Hosting.CommandLine" Version="4.1.1" /> <PackageVersion Include="McMaster.Extensions.Hosting.CommandLine" Version="4.1.1" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.11.0" /> <PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.12.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.VisualBasic" Version="4.11.0" /> <PackageVersion Include="Microsoft.CodeAnalysis.VisualBasic" Version="4.12.0" />
<PackageVersion Include="Microsoft.DiaSymReader.Converter.Xml" Version="1.1.0-beta2-22171-02" /> <PackageVersion Include="Microsoft.DiaSymReader.Converter.Xml" Version="1.1.0-beta2-22171-02" />
<PackageVersion Include="Microsoft.DiaSymReader" Version="1.4.0" /> <PackageVersion Include="Microsoft.DiaSymReader" Version="1.4.0" />
<PackageVersion Include="Microsoft.DiaSymReader.Native" Version="17.0.0-beta1.21524.1" /> <PackageVersion Include="Microsoft.DiaSymReader.Native" Version="17.0.0-beta1.21524.1" />
@ -25,32 +25,35 @@
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="8.0.1" /> <PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2" /> <PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.2" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.1" /> <PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.11.1" /> <PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageVersion Include="Microsoft.NETCore.ILAsm" Version="8.0.0" /> <PackageVersion Include="Microsoft.NETCore.ILAsm" Version="9.0.0" />
<PackageVersion Include="Microsoft.NETCore.ILDAsm" Version="8.0.0" /> <PackageVersion Include="Microsoft.NETCore.ILDAsm" Version="9.0.0" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" /> <PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<PackageVersion Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" /> <PackageVersion Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" />
<PackageVersion Include="Mono.Cecil" Version="0.11.6" /> <PackageVersion Include="Mono.Cecil" Version="0.11.6" />
<PackageVersion Include="NaturalSort.Extension" Version="4.3.0" /> <PackageVersion Include="NaturalSort.Extension" Version="4.3.0" />
<PackageVersion Include="NSubstitute" Version="5.1.0" /> <PackageVersion Include="NSubstitute" Version="5.3.0" />
<PackageVersion Include="NSubstitute.Analyzers.CSharp" Version="1.0.17" /> <PackageVersion Include="NSubstitute.Analyzers.CSharp" Version="1.0.17" />
<PackageVersion Include="NUnit" Version="4.2.2" /> <PackageVersion Include="NUnit" Version="4.3.2" />
<PackageVersion Include="NUnit3TestAdapter" Version="4.6.0" /> <PackageVersion Include="NUnit3TestAdapter" Version="4.6.0" />
<PackageVersion Include="NuGet.Protocol" Version="6.11.1" /> <PackageVersion Include="NuGet.Protocol" Version="6.12.1" />
<PackageVersion Include="PowerShellStandard.Library" Version="5.1.1" /> <PackageVersion Include="PowerShellStandard.Library" Version="5.1.1" />
<PackageVersion Include="System.Composition.AttributedModel" Version="8.0.0" /> <PackageVersion Include="System.Composition.AttributedModel" Version="9.0.0" />
<PackageVersion Include="System.Collections.Immutable" Version="8.0.0" /> <PackageVersion Include="System.Collections.Immutable" Version="9.0.0" />
<PackageVersion Include="System.Memory" Version="4.5.5" /> <PackageVersion Include="System.Memory" Version="4.6.0" />
<PackageVersion Include="System.Reflection.Metadata" Version="8.0.1" /> <PackageVersion Include="System.Reflection.Metadata" Version="9.0.0" />
<PackageVersion Include="System.Resources.Extensions" Version="8.0.0" /> <PackageVersion Include="System.Resources.Extensions" Version="9.0.0" />
<PackageVersion Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" /> <PackageVersion Include="System.Runtime.CompilerServices.Unsafe" Version="6.1.0" />
<PackageVersion Include="TomsToolbox.Composition.MicrosoftExtensions" Version="2.20.0" /> <PackageVersion Include="TomsToolbox.Composition.MicrosoftExtensions" Version="2.21.0" />
<PackageVersion Include="TomsToolbox.Wpf.Composition" Version="2.20.0" /> <PackageVersion Include="TomsToolbox.Wpf.Composition" Version="2.20.0" />
<PackageVersion Include="TomsToolbox.Wpf.Composition.AttributedModel" Version="2.20.0" /> <PackageVersion Include="TomsToolbox.Wpf.Composition.AttributedModel" Version="2.21.0" />
<PackageVersion Include="TomsToolbox.Wpf.Styles" Version="2.20.0" /> <PackageVersion Include="TomsToolbox.Wpf.Styles" Version="2.21.0" />
<PackageVersion Include="coverlet.collector" Version="6.0.2" /> <PackageVersion Include="coverlet.collector" Version="6.0.3" />
<PackageVersion Include="System.Net.Http" Version="4.3.4" />
<PackageVersion Include="System.Private.Uri" Version="4.3.2" />
<PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<GlobalPackageReference Include="TomsToolbox.Composition.Analyzer" Version="2.20.0" /> <GlobalPackageReference Include="TomsToolbox.Composition.Analyzer" Version="2.21.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

6
ICSharpCode.BamlDecompiler/ICSharpCode.BamlDecompiler.csproj

@ -41,6 +41,12 @@
<None Include="PackageReadme.md" Pack="true" PackagePath="\" /> <None Include="PackageReadme.md" Pack="true" PackagePath="\" />
</ItemGroup> </ItemGroup>
<!-- https://devblogs.microsoft.com/nuget/enable-repeatable-package-restores-using-a-lock-file/ -->
<PropertyGroup>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
<RestoreLockedMode Condition="'$(GITHUB_ACTIONS)' == 'true'">true</RestoreLockedMode>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Remove="Properties\AssemblyInfo.template.cs" /> <Compile Remove="Properties\AssemblyInfo.template.cs" />
</ItemGroup> </ItemGroup>

44
ICSharpCode.BamlDecompiler/packages.lock.json

@ -0,0 +1,44 @@
{
"version": 2,
"dependencies": {
"net8.0": {
"TomsToolbox.Composition.Analyzer": {
"type": "Direct",
"requested": "[2.21.0, )",
"resolved": "2.21.0",
"contentHash": "vJx9hxAzjni34slGz78ewqYP9Ylk8dJszfEUK1TF5cflVKMBO3ORSFd0FtICTwJtE8munvZrMrcLWwXt5bIcEA=="
},
"icsharpcode.decompiler": {
"type": "Project",
"dependencies": {
"System.Collections.Immutable": "[6.0.0, )",
"System.Reflection.Metadata": "[6.0.0, )"
}
},
"System.Collections.Immutable": {
"type": "CentralTransitive",
"requested": "[9.0.0, )",
"resolved": "6.0.0",
"contentHash": "l4zZJ1WU2hqpQQHXz1rvC3etVZN+2DLmQMO79FhOTZHMn8tDRr+WU287sbomD0BETlmKDn0ygUgVy9k5xkkJdA==",
"dependencies": {
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
}
},
"System.Reflection.Metadata": {
"type": "CentralTransitive",
"requested": "[9.0.0, )",
"resolved": "6.0.0",
"contentHash": "sffDOcex1C3HO5kDolOYcWXTwRpZY/LvJujM6SMjn63fWMJWchYAAmkoAJXlbpZ5yf4d+KMgxd+LeETa4gD9sQ==",
"dependencies": {
"System.Collections.Immutable": "6.0.0"
}
},
"System.Runtime.CompilerServices.Unsafe": {
"type": "CentralTransitive",
"requested": "[6.1.0, )",
"resolved": "6.0.0",
"contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg=="
}
}
}
}

6
ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs

@ -409,7 +409,7 @@ namespace ICSharpCode.Decompiler.Tests
options |= CompilerOptions.UseTestRunner; options |= CompilerOptions.UseTestRunner;
string testFileName = testName + ".cs"; string testFileName = testName + ".cs";
string testOutputFileName = TestsAssemblyOutput.GetFilePath(TestCasePath, testName, Tester.GetSuffix(options) + ".exe"); string testOutputFileName = TestsAssemblyOutput.GetFilePath(TestCasePath, testName, Tester.GetSuffix(options) + ".exe");
CompilerResults outputFile = null, decompiledOutputFile = null; Helpers.CompilerResults outputFile = null, decompiledOutputFile = null;
try try
{ {
@ -453,7 +453,7 @@ namespace ICSharpCode.Decompiler.Tests
options |= CompilerOptions.UseTestRunner; options |= CompilerOptions.UseTestRunner;
string testFileName = testName + ".vb"; string testFileName = testName + ".vb";
string testOutputFileName = TestsAssemblyOutput.GetFilePath(TestCasePath, testName, Tester.GetSuffix(options) + ".exe"); string testOutputFileName = TestsAssemblyOutput.GetFilePath(TestCasePath, testName, Tester.GetSuffix(options) + ".exe");
CompilerResults outputFile = null, decompiledOutputFile = null; Helpers.CompilerResults outputFile = null, decompiledOutputFile = null;
try try
{ {
@ -477,7 +477,7 @@ namespace ICSharpCode.Decompiler.Tests
async Task RunIL(string testFileName, CompilerOptions options = CompilerOptions.UseDebug, AssemblerOptions asmOptions = AssemblerOptions.None) async Task RunIL(string testFileName, CompilerOptions options = CompilerOptions.UseDebug, AssemblerOptions asmOptions = AssemblerOptions.None)
{ {
string outputFile = null; string outputFile = null;
CompilerResults decompiledOutputFile = null; Helpers.CompilerResults decompiledOutputFile = null;
bool optionsForce32Bit = options.HasFlag(CompilerOptions.Force32Bit); bool optionsForce32Bit = options.HasFlag(CompilerOptions.Force32Bit);
bool asmOptionsForce32Bit = asmOptions.HasFlag(AssemblerOptions.Force32Bit); bool asmOptionsForce32Bit = asmOptions.HasFlag(AssemblerOptions.Force32Bit);

10
ICSharpCode.Decompiler.Tests/ProjectDecompiler/TargetFrameworkTests.cs

@ -19,6 +19,7 @@
using System; using System;
using ICSharpCode.Decompiler.CSharp.ProjectDecompiler; using ICSharpCode.Decompiler.CSharp.ProjectDecompiler;
using ICSharpCode.Decompiler.Metadata;
using NUnit.Framework; using NUnit.Framework;
@ -119,5 +120,14 @@ namespace ICSharpCode.Decompiler.Tests
// Assert // Assert
Assert.That(targetFramework.Moniker, Is.EqualTo(expectedMoniker)); Assert.That(targetFramework.Moniker, Is.EqualTo(expectedMoniker));
} }
[TestCase(".NETCoreApp, Version=v5.0", TargetFrameworkIdentifier.NET, "5.0.0")]
[TestCase(".NETCoreApp, Version=v10.0", TargetFrameworkIdentifier.NET, "10.0.0")]
public void VerifyUniversalAssemblyResolverParseTargetFramework(string targetFramework, TargetFrameworkIdentifier identifier, string version)
{
var (id, v) = UniversalAssemblyResolver.ParseTargetFramework(targetFramework);
Assert.That(id, Is.EqualTo(identifier));
Assert.That(v.ToString(3), Is.EqualTo(version));
}
} }
} }

186
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.cs

@ -67,6 +67,76 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
} }
} }
public class ImplicitInt
{
private readonly int s;
public ImplicitInt(int s)
{
this.s = s;
}
public static implicit operator int(ImplicitInt v)
{
return v.s;
}
}
public class ImplicitConversionConflictWithLong
{
private readonly int s;
public ImplicitConversionConflictWithLong(int s)
{
this.s = s;
}
public static implicit operator int(ImplicitConversionConflictWithLong v)
{
return v.s;
}
public static implicit operator long(ImplicitConversionConflictWithLong v)
{
return v.s;
}
}
public class ImplicitConversionConflictWithString
{
private readonly int s;
public ImplicitConversionConflictWithString(int s)
{
this.s = s;
}
public static implicit operator int(ImplicitConversionConflictWithString v)
{
return v.s;
}
public static implicit operator string(ImplicitConversionConflictWithString v)
{
return string.Empty;
}
}
public class ExplicitInt
{
private readonly int s;
public ExplicitInt(int s)
{
this.s = s;
}
public static explicit operator int(ExplicitInt v)
{
return v.s;
}
}
public enum State public enum State
{ {
False, False,
@ -310,6 +380,118 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
} }
} }
public static void SwitchOverExplicitInt(ExplicitInt i)
{
switch ((int)i)
{
case 0:
Console.WriteLine("zero");
break;
case 5:
Console.WriteLine("five");
break;
case 10:
Console.WriteLine("ten");
break;
case 15:
Console.WriteLine("fifteen");
break;
case 20:
Console.WriteLine("twenty");
break;
case 25:
Console.WriteLine("twenty-five");
break;
case 30:
Console.WriteLine("thirty");
break;
}
}
public static void SwitchOverImplicitInt(ImplicitInt i)
{
switch (i)
{
case 0:
Console.WriteLine("zero");
break;
case 5:
Console.WriteLine("five");
break;
case 10:
Console.WriteLine("ten");
break;
case 15:
Console.WriteLine("fifteen");
break;
case 20:
Console.WriteLine("twenty");
break;
case 25:
Console.WriteLine("twenty-five");
break;
case 30:
Console.WriteLine("thirty");
break;
}
}
public static void SwitchOverImplicitIntConflictLong(ImplicitConversionConflictWithLong i)
{
switch ((int)i)
{
case 0:
Console.WriteLine("zero");
break;
case 5:
Console.WriteLine("five");
break;
case 10:
Console.WriteLine("ten");
break;
case 15:
Console.WriteLine("fifteen");
break;
case 20:
Console.WriteLine("twenty");
break;
case 25:
Console.WriteLine("twenty-five");
break;
case 30:
Console.WriteLine("thirty");
break;
}
}
public static void SwitchOverImplicitIntConflictString(ImplicitConversionConflictWithString i)
{
switch ((string)i)
{
case "0":
Console.WriteLine("zero");
break;
case "5":
Console.WriteLine("five");
break;
case "10":
Console.WriteLine("ten");
break;
case "15":
Console.WriteLine("fifteen");
break;
case "20":
Console.WriteLine("twenty");
break;
case "25":
Console.WriteLine("twenty-five");
break;
case "30":
Console.WriteLine("thirty");
break;
}
}
// SwitchDetection.UseCSharpSwitch requires more complex heuristic to identify this when compiled with Roslyn // SwitchDetection.UseCSharpSwitch requires more complex heuristic to identify this when compiled with Roslyn
public static void CompactSwitchOverInt(int i) public static void CompactSwitchOverInt(int i)
{ {
@ -421,9 +603,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
public static string SwitchOverImplicitString(ImplicitString s) public static string SwitchOverImplicitString(ImplicitString s)
{ {
// we emit an explicit cast, because the rules used by the C# compiler are counter-intuitive: switch (s)
// The C# compiler does *not* take the type of the switch labels into account at all.
switch ((string)s)
{ {
case "First case": case "First case":
return "Text1"; return "Text1";

2
ICSharpCode.Decompiler.Tests/UglyTestRunner.cs

@ -146,7 +146,7 @@ namespace ICSharpCode.Decompiler.Tests
if (!File.Exists(ilFile)) if (!File.Exists(ilFile))
{ {
// re-create .il file if necessary // re-create .il file if necessary
CompilerResults output = null; Helpers.CompilerResults output = null;
try try
{ {
output = await Tester.CompileCSharp(csFile, cscOptions).ConfigureAwait(false); output = await Tester.CompileCSharp(csFile, cscOptions).ConfigureAwait(false);

2
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -521,7 +521,7 @@ namespace ICSharpCode.Decompiler.CSharp
file.DetectTargetFrameworkId(), file.DetectRuntimePack(), file.DetectTargetFrameworkId(), file.DetectRuntimePack(),
settings.LoadInMemory ? PEStreamOptions.PrefetchMetadata : PEStreamOptions.Default, settings.LoadInMemory ? PEStreamOptions.PrefetchMetadata : PEStreamOptions.Default,
settings.ApplyWindowsRuntimeProjections ? MetadataReaderOptions.ApplyWindowsRuntimeProjections : MetadataReaderOptions.None); settings.ApplyWindowsRuntimeProjections ? MetadataReaderOptions.ApplyWindowsRuntimeProjections : MetadataReaderOptions.None);
return new DecompilerTypeSystem(file, resolver); return new DecompilerTypeSystem(file, resolver, settings);
} }
static TypeSystemAstBuilder CreateAstBuilder(DecompilerSettings settings) static TypeSystemAstBuilder CreateAstBuilder(DecompilerSettings settings)

85
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -3900,31 +3900,94 @@ namespace ICSharpCode.Decompiler.CSharp
} }
} }
protected internal override TranslatedExpression VisitSwitchInstruction(SwitchInstruction inst, TranslationContext context) internal (TranslatedExpression, IType, StringToInt) TranslateSwitchValue(SwitchInstruction inst, bool isExpressionContext)
{ {
TranslatedExpression value; TranslatedExpression value;
IType type; IType type;
// prepare expression and expected type
if (inst.Value is StringToInt strToInt) if (inst.Value is StringToInt strToInt)
{ {
value = Translate(strToInt.Argument) value = Translate(strToInt.Argument);
.ConvertTo( type = strToInt.ExpectedType ?? compilation.FindType(KnownTypeCode.String);
strToInt.ExpectedType,
this,
allowImplicitConversion: false // switch-expression does not support implicit conversions
);
type = compilation.FindType(KnownTypeCode.String);
} }
else else
{ {
strToInt = null; strToInt = null;
value = Translate(inst.Value); value = Translate(inst.Value);
if (inst.Type != null) type = inst.Type ?? value.Type;
}
// find and unwrap the input type
IType inputType = value.Type;
if (value.Expression is CastExpression && value.ResolveResult is ConversionResolveResult crr)
{
inputType = crr.Input.Type;
}
inputType = NullableType.GetUnderlyingType(inputType).GetEnumUnderlyingType();
// check input/underlying type for compatibility
bool allowImplicitConversion;
if (IsCompatibleWithSwitch(inputType) || (strToInt != null && inputType.Equals(type)))
{
allowImplicitConversion = !isExpressionContext;
}
else
{
var applicableImplicitConversionOperators = inputType.GetMethods(IsCompatibleImplicitConversionOperator).ToArray();
switch (applicableImplicitConversionOperators.Length)
{ {
value = value.ConvertTo(inst.Type, this, allowImplicitConversion: true); case 0:
allowImplicitConversion = !isExpressionContext;
break;
case 1:
allowImplicitConversion = !isExpressionContext;
// TODO validate
break;
default:
allowImplicitConversion = false;
break;
} }
type = value.Type;
} }
value = value.ConvertTo(type, this, allowImplicitConversion: allowImplicitConversion);
var caseType = strToInt != null
? compilation.FindType(KnownTypeCode.String)
: type;
return (value, caseType, strToInt);
static bool IsCompatibleWithSwitch(IType type)
{
return type.IsKnownType(KnownTypeCode.SByte)
|| type.IsKnownType(KnownTypeCode.Byte)
|| type.IsKnownType(KnownTypeCode.Int16)
|| type.IsKnownType(KnownTypeCode.UInt16)
|| type.IsKnownType(KnownTypeCode.Int32)
|| type.IsKnownType(KnownTypeCode.UInt32)
|| type.IsKnownType(KnownTypeCode.Int64)
|| type.IsKnownType(KnownTypeCode.UInt64)
|| type.IsKnownType(KnownTypeCode.Char)
|| type.IsKnownType(KnownTypeCode.String);
}
bool IsCompatibleImplicitConversionOperator(IMethod operatorMethod)
{
if (!operatorMethod.IsOperator)
return false;
if (operatorMethod.Name != "op_Implicit")
return false;
if (operatorMethod.Parameters.Count != 1)
return false;
return IsCompatibleWithSwitch(operatorMethod.ReturnType);
}
}
protected internal override TranslatedExpression VisitSwitchInstruction(SwitchInstruction inst, TranslationContext context)
{
// switch-expression does not support implicit conversions
var (value, type, strToInt) = TranslateSwitchValue(inst, true);
IL.SwitchSection defaultSection = inst.GetDefaultSection(); IL.SwitchSection defaultSection = inst.GetDefaultSection();
SwitchExpression switchExpr = new SwitchExpression(); SwitchExpression switchExpr = new SwitchExpression();
switchExpr.Expression = value; switchExpr.Expression = value;

25
ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

@ -210,30 +210,7 @@ namespace ICSharpCode.Decompiler.CSharp
var oldCaseLabelMapping = caseLabelMapping; var oldCaseLabelMapping = caseLabelMapping;
caseLabelMapping = new Dictionary<Block, ConstantResolveResult>(); caseLabelMapping = new Dictionary<Block, ConstantResolveResult>();
TranslatedExpression value; var (value, type, strToInt) = exprBuilder.TranslateSwitchValue(inst, false);
IType type;
if (inst.Value is StringToInt strToInt)
{
value = exprBuilder.Translate(strToInt.Argument)
.ConvertTo(
strToInt.ExpectedType,
exprBuilder,
// switch statement does support implicit conversions in general, however, the rules are
// not very intuitive and in order to prevent bugs, we emit an explicit cast.
allowImplicitConversion: false
);
type = exprBuilder.compilation.FindType(KnownTypeCode.String);
}
else
{
strToInt = null;
value = exprBuilder.Translate(inst.Value);
if (inst.Type != null)
{
value = value.ConvertTo(inst.Type, exprBuilder, allowImplicitConversion: true);
}
type = value.Type;
}
IL.SwitchSection defaultSection = inst.GetDefaultSection(); IL.SwitchSection defaultSection = inst.GetDefaultSection();

6
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -48,6 +48,12 @@
<None Include="PackageReadme.md" Pack="true" PackagePath="\" /> <None Include="PackageReadme.md" Pack="true" PackagePath="\" />
<None Include="DecompilerNuGetPackageIcon.png" Pack="true" PackagePath="\" /> <None Include="DecompilerNuGetPackageIcon.png" Pack="true" PackagePath="\" />
</ItemGroup> </ItemGroup>
<!-- https://devblogs.microsoft.com/nuget/enable-repeatable-package-restores-using-a-lock-file/ -->
<PropertyGroup>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
<RestoreLockedMode Condition="'$(GITHUB_ACTIONS)' == 'true'">true</RestoreLockedMode>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Debug'"> <PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow> <CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>

89
ICSharpCode.Decompiler/IL/Transforms/SwitchOnStringTransform.cs

@ -1070,10 +1070,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms
stringValues.Add((null, nullValueCaseBlock)); stringValues.Add((null, nullValueCaseBlock));
} }
// In newer Roslyn versions (>=3.7) the null check appears in the default case, not prior to the switch. // In newer Roslyn versions (>=3.7) the null check appears in the default case, not prior to the switch.
if (!stringValues.Any(pair => pair.Value == null) && IsNullCheckInDefaultBlock(ref exitOrDefaultBlock, switchValueLoad.Variable, out nullValueCaseBlock)) ILInstruction exitOrDefault = exitOrDefaultBlock;
if (!stringValues.Any(pair => pair.Value == null) && IsNullCheckInDefaultBlock(ref exitOrDefault, switchValueLoad.Variable, out nullValueCaseBlock))
{ {
stringValues.Add((null, nullValueCaseBlock)); stringValues.Add((null, nullValueCaseBlock));
} }
exitOrDefaultBlock = (Block)exitOrDefault;
context.Step(nameof(MatchRoslynSwitchOnString), switchValueLoad); context.Step(nameof(MatchRoslynSwitchOnString), switchValueLoad);
if (exitOrDefaultBlock != null) if (exitOrDefaultBlock != null)
@ -1176,7 +1178,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{ {
if (!instructions[i + 1].MatchBranch(out var nextBlock)) if (!instructions[i + 1].MatchBranch(out var nextBlock))
return false; return false;
if (!exitBlockJump.MatchBranch(out nullCase)) if (!exitBlockJump.MatchBranch(out nullCase) && !exitBlockJump.MatchLeave(out _))
return false; return false;
// if (comp(ldloc switchValueVar == ldnull)) br ... // if (comp(ldloc switchValueVar == ldnull)) br ...
// br switchOnLengthBlock // br switchOnLengthBlock
@ -1202,7 +1204,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
switchValueVar = null; // will be extracted in MatchSwitchOnLengthBlock switchValueVar = null; // will be extracted in MatchSwitchOnLengthBlock
switchOnLengthBlockStartOffset = i; switchOnLengthBlockStartOffset = i;
} }
Block defaultCase = null; ILInstruction defaultCase = null;
if (!MatchSwitchOnLengthBlock(ref switchValueVar, switchOnLengthBlock, switchOnLengthBlockStartOffset, out var blocksByLength)) if (!MatchSwitchOnLengthBlock(ref switchValueVar, switchOnLengthBlock, switchOnLengthBlockStartOffset, out var blocksByLength))
return false; return false;
List<(string, ILInstruction)> stringValues = new(); List<(string, ILInstruction)> stringValues = new();
@ -1216,41 +1218,51 @@ namespace ICSharpCode.Decompiler.IL.Transforms
else else
{ {
int length = (int)b.Length.Intervals[0].Start; int length = (int)b.Length.Intervals[0].Start;
if (MatchSwitchOnCharBlock(b.TargetBlock, length, switchValueVar, out var mapping)) switch (b.TargetBlock)
{ {
foreach (var item in mapping) case Leave leave:
{ break;
if (!stringValues.Any(x => x.Item1 == item.StringValue)) case Block targetBlock:
if (MatchSwitchOnCharBlock(targetBlock, length, switchValueVar, out var mapping))
{
foreach (var item in mapping)
{
if (!stringValues.Any(x => x.Item1 == item.StringValue))
{
stringValues.Add(item);
}
else
{
return false;
}
}
}
else if (MatchRoslynCaseBlockHead(targetBlock, switchValueVar, out var bodyOrLeave, out var exit, out string stringValue, out _))
{
if (exit != defaultCase)
return false;
if (!stringValues.Any(x => x.Item1 == stringValue))
{
stringValues.Add((stringValue, bodyOrLeave));
}
else
{
return false;
}
}
else if (length == 0)
{ {
stringValues.Add(item); stringValues.Add(("", b.TargetBlock));
} }
else else
{ {
return false; return false;
} }
} break;
} default:
else if (MatchRoslynCaseBlockHead(b.TargetBlock, switchValueVar, out var bodyOrLeave, out var exit, out string stringValue, out _))
{
if (exit != defaultCase)
return false; return false;
if (!stringValues.Any(x => x.Item1 == stringValue))
{
stringValues.Add((stringValue, bodyOrLeave));
}
else
{
return false;
}
}
else if (length == 0)
{
stringValues.Add(("", b.TargetBlock));
}
else
{
return false;
} }
} }
} }
@ -1278,7 +1290,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
} }
var newSwitch = new SwitchInstruction(new StringToInt(new LdLoc(switchValueVar), values, switchValueVar.Type)); var newSwitch = new SwitchInstruction(new StringToInt(new LdLoc(switchValueVar), values, switchValueVar.Type));
newSwitch.Sections.AddRange(sections); newSwitch.Sections.AddRange(sections);
newSwitch.Sections.Add(new SwitchSection { Labels = defaultLabel, Body = new Branch(defaultCase) }); newSwitch.Sections.Add(new SwitchSection { Labels = defaultLabel, Body = defaultCase is Block b2 ? new Branch(b2) : defaultCase });
newSwitch.AddILRange(instructions[i]); newSwitch.AddILRange(instructions[i]);
if (nullCase != null) if (nullCase != null)
{ {
@ -1399,7 +1411,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return results?.Count > 0; return results?.Count > 0;
} }
bool MatchSwitchOnLengthBlock(ref ILVariable switchValueVar, Block switchOnLengthBlock, int startOffset, out List<(LongSet Length, Block TargetBlock)> blocks) bool MatchSwitchOnLengthBlock(ref ILVariable switchValueVar, Block switchOnLengthBlock, int startOffset, out List<(LongSet Length, ILInstruction TargetBlock)> blocks)
{ {
blocks = null; blocks = null;
SwitchInstruction @switch; SwitchInstruction @switch;
@ -1482,17 +1494,18 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{ {
if (section.HasNullLabel) if (section.HasNullLabel)
return false; return false;
if (!section.Body.MatchBranch(out var target)) if (!section.Body.MatchBranch(out var target) && !section.Body.MatchLeave(out _))
return false; return false;
ILInstruction targetInst = target ?? section.Body;
if (section.Labels.Count() != 1) if (section.Labels.Count() != 1)
{ {
defaultCase ??= target; defaultCase ??= targetInst;
if (defaultCase != target) if (defaultCase != targetInst)
return false; return false;
} }
else else
{ {
blocks.Add((section.Labels, target)); blocks.Add((section.Labels, targetInst));
} }
} }
return true; return true;
@ -1506,10 +1519,10 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// br newDefaultBlock /// br newDefaultBlock
/// } /// }
/// </summary> /// </summary>
private bool IsNullCheckInDefaultBlock(ref Block exitOrDefaultBlock, ILVariable switchVar, out Block nullValueCaseBlock) private bool IsNullCheckInDefaultBlock(ref ILInstruction exitOrDefault, ILVariable switchVar, out Block nullValueCaseBlock)
{ {
nullValueCaseBlock = null; nullValueCaseBlock = null;
if (exitOrDefaultBlock == null) if (exitOrDefault is not Block exitOrDefaultBlock)
return false; return false;
if (!exitOrDefaultBlock.Instructions[0].MatchIfInstruction(out var condition, out var thenBranch)) if (!exitOrDefaultBlock.Instructions[0].MatchIfInstruction(out var condition, out var thenBranch))
return false; return false;
@ -1523,7 +1536,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return false; return false;
if (elseBlock.Parent != exitOrDefaultBlock.Parent) if (elseBlock.Parent != exitOrDefaultBlock.Parent)
return false; return false;
exitOrDefaultBlock = elseBlock; exitOrDefault = elseBlock;
return true; return true;
} }

15
ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs

@ -189,15 +189,16 @@ namespace ICSharpCode.Decompiler.Metadata
switch (pair[0].Trim().ToUpperInvariant()) switch (pair[0].Trim().ToUpperInvariant())
{ {
case "VERSION": case "VERSION":
var versionString = pair[1].TrimStart('v', ' ', '\t'); var versionString = pair[1].TrimStart('v', 'V', ' ', '\t');
if (identifier == TargetFrameworkIdentifier.NETCoreApp ||
identifier == TargetFrameworkIdentifier.NETStandard)
{
if (versionString.Length == 3)
versionString += ".0";
}
if (!Version.TryParse(versionString, out version)) if (!Version.TryParse(versionString, out version))
{
version = null; version = null;
}
else
{
version = new Version(version.Major, version.Minor, version.Build < 0 ? 0 : version.Build);
}
// .NET 5 or greater still use ".NETCOREAPP" as TargetFrameworkAttribute value... // .NET 5 or greater still use ".NETCOREAPP" as TargetFrameworkAttribute value...
if (version?.Major >= 5 && identifier == TargetFrameworkIdentifier.NETCoreApp) if (version?.Major >= 5 && identifier == TargetFrameworkIdentifier.NETCoreApp)
identifier = TargetFrameworkIdentifier.NET; identifier = TargetFrameworkIdentifier.NET;

2
ICSharpCode.Decompiler/Properties/DecompilerVersionInfo.template.cs

@ -4,7 +4,7 @@
public const string Minor = "0"; public const string Minor = "0";
public const string Build = "0"; public const string Build = "0";
public const string Revision = "$INSERTREVISION$"; public const string Revision = "$INSERTREVISION$";
public const string VersionName = "preview3"; public const string VersionName = "RC";
public const string FullVersion = Major + "." + Minor + "." + Build + ".$INSERTREVISION$$INSERTBRANCHPOSTFIX$$INSERTVERSIONNAMEPOSTFIX$"; public const string FullVersion = Major + "." + Minor + "." + Build + ".$INSERTREVISION$$INSERTBRANCHPOSTFIX$$INSERTVERSIONNAMEPOSTFIX$";
public const string FullVersionWithShortCommitHash = FullVersion + "+$INSERTSHORTCOMMITHASH$"; public const string FullVersionWithShortCommitHash = FullVersion + "+$INSERTSHORTCOMMITHASH$";

91
ICSharpCode.Decompiler/packages.lock.json

@ -0,0 +1,91 @@
{
"version": 1,
"dependencies": {
".NETStandard,Version=v2.0": {
"Microsoft.SourceLink.GitHub": {
"type": "Direct",
"requested": "[8.0.0, )",
"resolved": "8.0.0",
"contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "8.0.0",
"Microsoft.SourceLink.Common": "8.0.0"
}
},
"NETStandard.Library": {
"type": "Direct",
"requested": "[2.0.3, )",
"resolved": "2.0.3",
"contentHash": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0"
}
},
"System.Collections.Immutable": {
"type": "Direct",
"requested": "[6.0.0, )",
"resolved": "6.0.0",
"contentHash": "l4zZJ1WU2hqpQQHXz1rvC3etVZN+2DLmQMO79FhOTZHMn8tDRr+WU287sbomD0BETlmKDn0ygUgVy9k5xkkJdA==",
"dependencies": {
"System.Memory": "4.5.4",
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
}
},
"System.Reflection.Metadata": {
"type": "Direct",
"requested": "[6.0.0, )",
"resolved": "6.0.0",
"contentHash": "sffDOcex1C3HO5kDolOYcWXTwRpZY/LvJujM6SMjn63fWMJWchYAAmkoAJXlbpZ5yf4d+KMgxd+LeETa4gD9sQ==",
"dependencies": {
"System.Collections.Immutable": "6.0.0"
}
},
"TunnelVisionLabs.ReferenceAssemblyAnnotator": {
"type": "Direct",
"requested": "[1.0.0-alpha.160, )",
"resolved": "1.0.0-alpha.160",
"contentHash": "ktxB8PGoPpIaYKjLk/+P94Fi2Qw2E1Dw7atBQRrKnHA57sk8WwmkI4RJmg6s5ph4k1RIaaAZMus05ah/AikEkA=="
},
"Microsoft.Build.Tasks.Git": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
},
"Microsoft.NETCore.Platforms": {
"type": "Transitive",
"resolved": "1.1.0",
"contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A=="
},
"Microsoft.SourceLink.Common": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"System.Buffers": {
"type": "Transitive",
"resolved": "4.5.1",
"contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg=="
},
"System.Memory": {
"type": "Transitive",
"resolved": "4.5.4",
"contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==",
"dependencies": {
"System.Buffers": "4.5.1",
"System.Numerics.Vectors": "4.4.0",
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
}
},
"System.Numerics.Vectors": {
"type": "Transitive",
"resolved": "4.4.0",
"contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ=="
},
"System.Runtime.CompilerServices.Unsafe": {
"type": "Transitive",
"resolved": "6.0.0",
"contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg=="
}
}
}
}

6
ICSharpCode.ILSpyCmd/ICSharpCode.ILSpyCmd.csproj

@ -31,6 +31,12 @@
<ItemGroup> <ItemGroup>
<None Include="README.md" Pack="true" PackagePath="\" /> <None Include="README.md" Pack="true" PackagePath="\" />
</ItemGroup> </ItemGroup>
<!-- https://devblogs.microsoft.com/nuget/enable-repeatable-package-restores-using-a-lock-file/ -->
<PropertyGroup>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
<RestoreLockedMode Condition="'$(GITHUB_ACTIONS)' == 'true'">true</RestoreLockedMode>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<TreatWarningsAsErrors>false</TreatWarningsAsErrors> <TreatWarningsAsErrors>false</TreatWarningsAsErrors>

453
ICSharpCode.ILSpyCmd/packages.lock.json

@ -0,0 +1,453 @@
{
"version": 2,
"dependencies": {
"net8.0": {
"McMaster.Extensions.Hosting.CommandLine": {
"type": "Direct",
"requested": "[4.1.1, )",
"resolved": "4.1.1",
"contentHash": "+a37L3hHZC2KG1sbwdzTGlUWIJWYQv/9I4dLnrC0OVusR/665hkewjlz1jiAKa8jYbve4GTSZsRCoVXcSFFrdA==",
"dependencies": {
"McMaster.Extensions.CommandLineUtils": "4.1.1",
"Microsoft.Extensions.Hosting.Abstractions": "6.0.0",
"Microsoft.Extensions.Logging.Abstractions": "6.0.0"
}
},
"Microsoft.Extensions.Hosting": {
"type": "Direct",
"requested": "[8.0.1, )",
"resolved": "8.0.1",
"contentHash": "bP9EEkHBEfjgYiG8nUaXqMk/ujwJrffOkNPP7onpRMO8R+OUSESSP4xHkCAXgYZ1COP2Q9lXlU5gkMFh20gRuw==",
"dependencies": {
"Microsoft.Extensions.Configuration": "8.0.0",
"Microsoft.Extensions.Configuration.Abstractions": "8.0.0",
"Microsoft.Extensions.Configuration.Binder": "8.0.2",
"Microsoft.Extensions.Configuration.CommandLine": "8.0.0",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "8.0.0",
"Microsoft.Extensions.Configuration.FileExtensions": "8.0.1",
"Microsoft.Extensions.Configuration.Json": "8.0.1",
"Microsoft.Extensions.Configuration.UserSecrets": "8.0.1",
"Microsoft.Extensions.DependencyInjection": "8.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.2",
"Microsoft.Extensions.Diagnostics": "8.0.1",
"Microsoft.Extensions.FileProviders.Abstractions": "8.0.0",
"Microsoft.Extensions.FileProviders.Physical": "8.0.0",
"Microsoft.Extensions.Hosting.Abstractions": "8.0.1",
"Microsoft.Extensions.Logging": "8.0.1",
"Microsoft.Extensions.Logging.Abstractions": "8.0.2",
"Microsoft.Extensions.Logging.Configuration": "8.0.1",
"Microsoft.Extensions.Logging.Console": "8.0.1",
"Microsoft.Extensions.Logging.Debug": "8.0.1",
"Microsoft.Extensions.Logging.EventLog": "8.0.1",
"Microsoft.Extensions.Logging.EventSource": "8.0.1",
"Microsoft.Extensions.Options": "8.0.2"
}
},
"NuGet.Protocol": {
"type": "Direct",
"requested": "[6.12.1, )",
"resolved": "6.12.1",
"contentHash": "VBN7OtG/Y9Rnj1WT3G8X88ZHu5Pq+yzca5Z6OI/FWXcENVAQkUl0ml6Cv8ghOqYyiuvnObGDV9oWLD/bIuVtDw==",
"dependencies": {
"NuGet.Packaging": "6.12.1"
}
},
"TomsToolbox.Composition.Analyzer": {
"type": "Direct",
"requested": "[2.21.0, )",
"resolved": "2.21.0",
"contentHash": "vJx9hxAzjni34slGz78ewqYP9Ylk8dJszfEUK1TF5cflVKMBO3ORSFd0FtICTwJtE8munvZrMrcLWwXt5bIcEA=="
},
"Microsoft.Extensions.Configuration.Abstractions": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "3lE/iLSutpgX1CC0NOW70FJoGARRHbyKmG7dc0klnUZ9Dd9hS6N/POPWhKhMLCEuNN5nXEY5agmlFtH562vqhQ==",
"dependencies": {
"Microsoft.Extensions.Primitives": "8.0.0"
}
},
"Microsoft.Extensions.Configuration.Binder": {
"type": "Transitive",
"resolved": "8.0.2",
"contentHash": "7IQhGK+wjyGrNsPBjJcZwWAr+Wf6D4+TwOptUt77bWtgNkiV8tDEbhFS+dDamtQFZ2X7kWG9m71iZQRj2x3zgQ==",
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "8.0.0"
}
},
"Microsoft.Extensions.Configuration.CommandLine": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "NZuZMz3Q8Z780nKX3ifV1fE7lS+6pynDHK71OfU4OZ1ItgvDOhyOC7E6z+JMZrAj63zRpwbdldYFk499t3+1dQ==",
"dependencies": {
"Microsoft.Extensions.Configuration": "8.0.0",
"Microsoft.Extensions.Configuration.Abstractions": "8.0.0"
}
},
"Microsoft.Extensions.Configuration.EnvironmentVariables": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "plvZ0ZIpq+97gdPNNvhwvrEZ92kNml9hd1pe3idMA7svR0PztdzVLkoWLcRFgySYXUJc3kSM3Xw3mNFMo/bxRA==",
"dependencies": {
"Microsoft.Extensions.Configuration": "8.0.0",
"Microsoft.Extensions.Configuration.Abstractions": "8.0.0"
}
},
"Microsoft.Extensions.Configuration.FileExtensions": {
"type": "Transitive",
"resolved": "8.0.1",
"contentHash": "EJzSNO9oaAXnTdtdNO6npPRsIIeZCBSNmdQ091VDO7fBiOtJAAeEq6dtrVXIi3ZyjC5XRSAtVvF8SzcneRHqKQ==",
"dependencies": {
"Microsoft.Extensions.Configuration": "8.0.0",
"Microsoft.Extensions.Configuration.Abstractions": "8.0.0",
"Microsoft.Extensions.FileProviders.Abstractions": "8.0.0",
"Microsoft.Extensions.FileProviders.Physical": "8.0.0",
"Microsoft.Extensions.Primitives": "8.0.0"
}
},
"Microsoft.Extensions.Configuration.UserSecrets": {
"type": "Transitive",
"resolved": "8.0.1",
"contentHash": "7tYqdPPpAK+3jO9d5LTuCK2VxrEdf85Ol4trUr6ds4jclBecadWZ/RyPCbNjfbN5iGTfUnD/h65TOQuqQv2c+A==",
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "8.0.0",
"Microsoft.Extensions.Configuration.Json": "8.0.1",
"Microsoft.Extensions.FileProviders.Abstractions": "8.0.0",
"Microsoft.Extensions.FileProviders.Physical": "8.0.0"
}
},
"Microsoft.Extensions.DependencyInjection": {
"type": "Transitive",
"resolved": "8.0.1",
"contentHash": "BmANAnR5Xd4Oqw7yQ75xOAYODybZQRzdeNucg7kS5wWKd2PNnMdYtJ2Vciy0QLylRmv42DGl5+AFL9izA6F1Rw==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.2"
}
},
"Microsoft.Extensions.Diagnostics": {
"type": "Transitive",
"resolved": "8.0.1",
"contentHash": "doVPCUUCY7c6LhBsEfiy3W1bvS7Mi6LkfQMS8nlC22jZWNxBv8VO8bdfeyvpYFst6Kxqk7HBC6lytmEoBssvSQ==",
"dependencies": {
"Microsoft.Extensions.Configuration": "8.0.0",
"Microsoft.Extensions.Diagnostics.Abstractions": "8.0.1",
"Microsoft.Extensions.Options.ConfigurationExtensions": "8.0.0"
}
},
"Microsoft.Extensions.Diagnostics.Abstractions": {
"type": "Transitive",
"resolved": "8.0.1",
"contentHash": "elH2vmwNmsXuKmUeMQ4YW9ldXiF+gSGDgg1vORksob5POnpaI6caj1Hu8zaYbEuibhqCoWg0YRWDazBY3zjBfg==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.2",
"Microsoft.Extensions.Options": "8.0.2"
}
},
"Microsoft.Extensions.FileProviders.Abstractions": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "ZbaMlhJlpisjuWbvXr4LdAst/1XxH3vZ6A0BsgTphZ2L4PGuxRLz7Jr/S7mkAAnOn78Vu0fKhEgNF5JO3zfjqQ==",
"dependencies": {
"Microsoft.Extensions.Primitives": "8.0.0"
}
},
"Microsoft.Extensions.FileProviders.Physical": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "UboiXxpPUpwulHvIAVE36Knq0VSHaAmfrFkegLyBZeaADuKezJ/AIXYAW8F5GBlGk/VaibN2k/Zn1ca8YAfVdA==",
"dependencies": {
"Microsoft.Extensions.FileProviders.Abstractions": "8.0.0",
"Microsoft.Extensions.FileSystemGlobbing": "8.0.0",
"Microsoft.Extensions.Primitives": "8.0.0"
}
},
"Microsoft.Extensions.FileSystemGlobbing": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "OK+670i7esqlQrPjdIKRbsyMCe9g5kSLpRRQGSr4Q58AOYEe/hCnfLZprh7viNisSUUQZmMrbbuDaIrP+V1ebQ=="
},
"Microsoft.Extensions.Hosting.Abstractions": {
"type": "Transitive",
"resolved": "8.0.1",
"contentHash": "nHwq9aPBdBPYXPti6wYEEfgXddfBrYC+CQLn+qISiwQq5tpfaqDZSKOJNxoe9rfQxGf1c+2wC/qWFe1QYJPYqw==",
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "8.0.0",
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.2",
"Microsoft.Extensions.Diagnostics.Abstractions": "8.0.1",
"Microsoft.Extensions.FileProviders.Abstractions": "8.0.0",
"Microsoft.Extensions.Logging.Abstractions": "8.0.2"
}
},
"Microsoft.Extensions.Logging": {
"type": "Transitive",
"resolved": "8.0.1",
"contentHash": "4x+pzsQEbqxhNf1QYRr5TDkLP9UsLT3A6MdRKDDEgrW7h1ljiEPgTNhKYUhNCCAaVpQECVQ+onA91PTPnIp6Lw==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "8.0.1",
"Microsoft.Extensions.Logging.Abstractions": "8.0.2",
"Microsoft.Extensions.Options": "8.0.2"
}
},
"Microsoft.Extensions.Logging.Abstractions": {
"type": "Transitive",
"resolved": "8.0.2",
"contentHash": "nroMDjS7hNBPtkZqVBbSiQaQjWRDxITI8Y7XnDs97rqG3EbzVTNLZQf7bIeUJcaHOV8bca47s1Uxq94+2oGdxA==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.2"
}
},
"Microsoft.Extensions.Logging.Configuration": {
"type": "Transitive",
"resolved": "8.0.1",
"contentHash": "QWwTrsgOnJMmn+XUslm8D2H1n3PkP/u/v52FODtyBc/k4W9r3i2vcXXeeX/upnzllJYRRbrzVzT0OclfNJtBJA==",
"dependencies": {
"Microsoft.Extensions.Configuration": "8.0.0",
"Microsoft.Extensions.Configuration.Abstractions": "8.0.0",
"Microsoft.Extensions.Configuration.Binder": "8.0.2",
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.2",
"Microsoft.Extensions.Logging": "8.0.1",
"Microsoft.Extensions.Logging.Abstractions": "8.0.2",
"Microsoft.Extensions.Options": "8.0.2",
"Microsoft.Extensions.Options.ConfigurationExtensions": "8.0.0"
}
},
"Microsoft.Extensions.Logging.Console": {
"type": "Transitive",
"resolved": "8.0.1",
"contentHash": "uzcg/5U2eLyn5LIKlERkdSxw6VPC1yydnOSQiRRWGBGN3kphq3iL4emORzrojScDmxRhv49gp5BI8U3Dz7y4iA==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.2",
"Microsoft.Extensions.Logging": "8.0.1",
"Microsoft.Extensions.Logging.Abstractions": "8.0.2",
"Microsoft.Extensions.Logging.Configuration": "8.0.1",
"Microsoft.Extensions.Options": "8.0.2"
}
},
"Microsoft.Extensions.Logging.Debug": {
"type": "Transitive",
"resolved": "8.0.1",
"contentHash": "B8hqNuYudC2RB+L/DI33uO4rf5by41fZVdcVL2oZj0UyoAZqnwTwYHp1KafoH4nkl1/23piNeybFFASaV2HkFg==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.2",
"Microsoft.Extensions.Logging": "8.0.1",
"Microsoft.Extensions.Logging.Abstractions": "8.0.2"
}
},
"Microsoft.Extensions.Logging.EventLog": {
"type": "Transitive",
"resolved": "8.0.1",
"contentHash": "ZD1m4GXoxcZeDJIq8qePKj+QAWeQNO/OG8skvrOG8RQfxLp9MAKRoliTc27xanoNUzeqvX5HhS/I7c0BvwAYUg==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.2",
"Microsoft.Extensions.Logging": "8.0.1",
"Microsoft.Extensions.Logging.Abstractions": "8.0.2",
"Microsoft.Extensions.Options": "8.0.2",
"System.Diagnostics.EventLog": "8.0.1"
}
},
"Microsoft.Extensions.Logging.EventSource": {
"type": "Transitive",
"resolved": "8.0.1",
"contentHash": "YMXMAla6B6sEf/SnfZYTty633Ool3AH7KOw2LOaaEqwSo2piK4f7HMtzyc3CNiipDnq1fsUSuG5Oc7ZzpVy8WQ==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.2",
"Microsoft.Extensions.Logging": "8.0.1",
"Microsoft.Extensions.Logging.Abstractions": "8.0.2",
"Microsoft.Extensions.Options": "8.0.2",
"Microsoft.Extensions.Primitives": "8.0.0"
}
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "8.0.2",
"contentHash": "dWGKvhFybsaZpGmzkGCbNNwBD1rVlWzrZKANLW/CcbFJpCEceMCGzT7zZwHOGBCbwM0SzBuceMj5HN1LKV1QqA==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0",
"Microsoft.Extensions.Primitives": "8.0.0"
}
},
"Microsoft.Extensions.Options.ConfigurationExtensions": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "0f4DMRqEd50zQh+UyJc+/HiBsZ3vhAQALgdkcQEalSH1L2isdC7Yj54M3cyo5e+BeO5fcBQ7Dxly8XiBBcvRgw==",
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "8.0.0",
"Microsoft.Extensions.Configuration.Binder": "8.0.0",
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0",
"Microsoft.Extensions.Options": "8.0.0",
"Microsoft.Extensions.Primitives": "8.0.0"
}
},
"Microsoft.Extensions.Primitives": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "bXJEZrW9ny8vjMF1JV253WeLhpEVzFo1lyaZu1vQ4ZxWUlVvknZ/+ftFgVheLubb4eZPSwwxBeqS1JkCOjxd8g=="
},
"Newtonsoft.Json": {
"type": "Transitive",
"resolved": "13.0.3",
"contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ=="
},
"NuGet.Common": {
"type": "Transitive",
"resolved": "6.12.1",
"contentHash": "nk8nTdhQl4x2VaAQUvefI7DDYAuBDlE+OZZRffm50Qx5dUAEq8wkc5JIqrN2lTEohObHPI/SXyG2UFdMQkrdyg==",
"dependencies": {
"NuGet.Frameworks": "6.12.1"
}
},
"NuGet.Configuration": {
"type": "Transitive",
"resolved": "6.12.1",
"contentHash": "IRwlY1379ZgJ0oEJvjD+lDuOhJ5S1fsU5n/bEC5/i0+N9bo2WIMDAdaQ/qIdyK/gMJ/YWS+++GSX6rN7luqEvg==",
"dependencies": {
"NuGet.Common": "6.12.1",
"System.Security.Cryptography.ProtectedData": "4.4.0"
}
},
"NuGet.Frameworks": {
"type": "Transitive",
"resolved": "6.12.1",
"contentHash": "kPaRD5RJC0ByUg+yGX6bDz5XHMI7OYmQwP8kbtef+vZ+csj/VDb5Bwas4ChxwhoAbI8lEvwP5/3aViQPpgNBow=="
},
"NuGet.Packaging": {
"type": "Transitive",
"resolved": "6.12.1",
"contentHash": "6s5NO3VNX6fIx6GwuWZtIsal9W1xkelYd3Vg2KUAg1zGqnKC3wB5IZlombvVGVGcwyl/A+iDvpUwSvgeDoB3wA==",
"dependencies": {
"Newtonsoft.Json": "13.0.3",
"NuGet.Configuration": "6.12.1",
"NuGet.Versioning": "6.12.1",
"System.Formats.Asn1": "8.0.1",
"System.Security.Cryptography.Pkcs": "6.0.4"
}
},
"NuGet.Versioning": {
"type": "Transitive",
"resolved": "6.12.1",
"contentHash": "fJ6rFYANDnohFsdpaY79FvrJxI6murmoOxXz6nZlf819F48+IBKMnAIg3oIBRtZq5y498ObMtKnro5IitvizUg=="
},
"System.ComponentModel.Annotations": {
"type": "Transitive",
"resolved": "5.0.0",
"contentHash": "dMkqfy2el8A8/I76n2Hi1oBFEbG1SfxD2l5nhwXV3XjlnOmwxJlQbYpJH4W51odnU9sARCSAgv7S3CyAFMkpYg=="
},
"System.Diagnostics.EventLog": {
"type": "Transitive",
"resolved": "8.0.1",
"contentHash": "n1ZP7NM2Gkn/MgD8+eOT5MulMj6wfeQMNS2Pizvq5GHCZfjlFMXV2irQlQmJhwA2VABC57M0auudO89Iu2uRLg=="
},
"System.Formats.Asn1": {
"type": "Transitive",
"resolved": "8.0.1",
"contentHash": "XqKba7Mm/koKSjKMfW82olQdmfbI5yqeoLV/tidRp7fbh5rmHAQ5raDI/7SU0swTzv+jgqtUGkzmFxuUg0it1A=="
},
"System.Security.Cryptography.Pkcs": {
"type": "Transitive",
"resolved": "6.0.4",
"contentHash": "LGbXi1oUJ9QgCNGXRO9ndzBL/GZgANcsURpMhNR8uO+rca47SZmciS3RSQUvlQRwK3QHZSHNOXzoMUASKA+Anw==",
"dependencies": {
"System.Formats.Asn1": "6.0.0"
}
},
"System.Security.Cryptography.ProtectedData": {
"type": "Transitive",
"resolved": "4.4.0",
"contentHash": "cJV7ScGW7EhatRsjehfvvYVBvtiSMKgN8bOVI0bQhnF5bU7vnHVIsH49Kva7i7GWaWYvmEzkYVk1TC+gZYBEog=="
},
"icsharpcode.decompiler": {
"type": "Project",
"dependencies": {
"System.Collections.Immutable": "[6.0.0, )",
"System.Reflection.Metadata": "[6.0.0, )"
}
},
"icsharpcode.ilspyx": {
"type": "Project",
"dependencies": {
"ICSharpCode.Decompiler": "[8.0.0-noversion, )",
"K4os.Compression.LZ4": "[1.3.8, )",
"Mono.Cecil": "[0.11.6, )",
"System.Composition.AttributedModel": "[9.0.0, )",
"System.Reflection.Metadata": "[9.0.0, )",
"System.Runtime.CompilerServices.Unsafe": "[6.1.0, )"
}
},
"K4os.Compression.LZ4": {
"type": "CentralTransitive",
"requested": "[1.3.8, )",
"resolved": "1.3.8",
"contentHash": "LhwlPa7c1zs1OV2XadMtAWdImjLIsqFJPoRcIWAadSRn0Ri1DepK65UbWLPmt4riLqx2d40xjXRk0ogpqNtK7g=="
},
"McMaster.Extensions.CommandLineUtils": {
"type": "CentralTransitive",
"requested": "[4.1.1, )",
"resolved": "4.1.1",
"contentHash": "zxgDY+G5yVq2q8sVB3Z275Qkxed1jC95nwAfnlSyoG4l5Nicvd4+ke1jXusEZEfyuErlAgXCKS937c13FmZWBg==",
"dependencies": {
"System.ComponentModel.Annotations": "5.0.0"
}
},
"Microsoft.Extensions.Configuration": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
"resolved": "8.0.0",
"contentHash": "0J/9YNXTMWSZP2p2+nvl8p71zpSwokZXZuJW+VjdErkegAnFdO1XlqtA62SJtgVYHdKu3uPxJHcMR/r35HwFBA==",
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "8.0.0",
"Microsoft.Extensions.Primitives": "8.0.0"
}
},
"Microsoft.Extensions.Configuration.Json": {
"type": "CentralTransitive",
"requested": "[8.0.1, )",
"resolved": "8.0.1",
"contentHash": "L89DLNuimOghjV3tLx0ArFDwVEJD6+uGB3BMCMX01kaLzXkaXHb2021xOMl2QOxUxbdePKUZsUY7n2UUkycjRg==",
"dependencies": {
"Microsoft.Extensions.Configuration": "8.0.0",
"Microsoft.Extensions.Configuration.Abstractions": "8.0.0",
"Microsoft.Extensions.Configuration.FileExtensions": "8.0.1",
"Microsoft.Extensions.FileProviders.Abstractions": "8.0.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[8.0.2, )",
"resolved": "8.0.2",
"contentHash": "3iE7UF7MQkCv1cxzCahz+Y/guQbTqieyxyaWKhrRO91itI9cOKO76OHeQDahqG4MmW5umr3CcCvGmK92lWNlbg=="
},
"Mono.Cecil": {
"type": "CentralTransitive",
"requested": "[0.11.6, )",
"resolved": "0.11.6",
"contentHash": "f33RkDtZO8VlGXCtmQIviOtxgnUdym9xx/b1p9h91CRGOsJFxCFOFK1FDbVt1OCf1aWwYejUFa2MOQyFWTFjbA=="
},
"System.Collections.Immutable": {
"type": "CentralTransitive",
"requested": "[9.0.0, )",
"resolved": "9.0.0",
"contentHash": "QhkXUl2gNrQtvPmtBTQHb0YsUrDiDQ2QS09YbtTTiSjGcf7NBqtYbrG/BE06zcBPCKEwQGzIv13IVdXNOSub2w=="
},
"System.Composition.AttributedModel": {
"type": "CentralTransitive",
"requested": "[9.0.0, )",
"resolved": "9.0.0",
"contentHash": "iri00l/zIX9g4lHMY+Nz0qV1n40+jFYAmgsaiNn16xvt2RDwlqByNG4wgblagnDYxm3YSQQ0jLlC/7Xlk9CzyA=="
},
"System.Reflection.Metadata": {
"type": "CentralTransitive",
"requested": "[9.0.0, )",
"resolved": "9.0.0",
"contentHash": "ANiqLu3DxW9kol/hMmTWbt3414t9ftdIuiIU7j80okq2YzAueo120M442xk1kDJWtmZTqWQn7wHDvMRipVOEOQ==",
"dependencies": {
"System.Collections.Immutable": "9.0.0"
}
},
"System.Runtime.CompilerServices.Unsafe": {
"type": "CentralTransitive",
"requested": "[6.1.0, )",
"resolved": "6.1.0",
"contentHash": "5o/HZxx6RVqYlhKSq8/zronDkALJZUT2Vz0hx43f0gwe8mwlM0y2nYlqdBwLMzr262Bwvpikeb/yEwkAa5PADg=="
}
}
}
}

6
ICSharpCode.ILSpyX/ICSharpCode.ILSpyX.csproj

@ -48,6 +48,12 @@
<None Include="PackageReadme.md" Pack="true" PackagePath="\" /> <None Include="PackageReadme.md" Pack="true" PackagePath="\" />
</ItemGroup> </ItemGroup>
<!-- https://devblogs.microsoft.com/nuget/enable-repeatable-package-restores-using-a-lock-file/ -->
<PropertyGroup>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
<RestoreLockedMode Condition="'$(GITHUB_ACTIONS)' == 'true'">true</RestoreLockedMode>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Remove="Properties\AssemblyInfo.template.cs" /> <Compile Remove="Properties\AssemblyInfo.template.cs" />
</ItemGroup> </ItemGroup>

79
ICSharpCode.ILSpyX/packages.lock.json

@ -0,0 +1,79 @@
{
"version": 2,
"dependencies": {
"net8.0": {
"K4os.Compression.LZ4": {
"type": "Direct",
"requested": "[1.3.8, )",
"resolved": "1.3.8",
"contentHash": "LhwlPa7c1zs1OV2XadMtAWdImjLIsqFJPoRcIWAadSRn0Ri1DepK65UbWLPmt4riLqx2d40xjXRk0ogpqNtK7g=="
},
"Microsoft.SourceLink.GitHub": {
"type": "Direct",
"requested": "[8.0.0, )",
"resolved": "8.0.0",
"contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "8.0.0",
"Microsoft.SourceLink.Common": "8.0.0"
}
},
"Mono.Cecil": {
"type": "Direct",
"requested": "[0.11.6, )",
"resolved": "0.11.6",
"contentHash": "f33RkDtZO8VlGXCtmQIviOtxgnUdym9xx/b1p9h91CRGOsJFxCFOFK1FDbVt1OCf1aWwYejUFa2MOQyFWTFjbA=="
},
"System.Composition.AttributedModel": {
"type": "Direct",
"requested": "[9.0.0, )",
"resolved": "9.0.0",
"contentHash": "iri00l/zIX9g4lHMY+Nz0qV1n40+jFYAmgsaiNn16xvt2RDwlqByNG4wgblagnDYxm3YSQQ0jLlC/7Xlk9CzyA=="
},
"System.Reflection.Metadata": {
"type": "Direct",
"requested": "[9.0.0, )",
"resolved": "9.0.0",
"contentHash": "ANiqLu3DxW9kol/hMmTWbt3414t9ftdIuiIU7j80okq2YzAueo120M442xk1kDJWtmZTqWQn7wHDvMRipVOEOQ==",
"dependencies": {
"System.Collections.Immutable": "9.0.0"
}
},
"System.Runtime.CompilerServices.Unsafe": {
"type": "Direct",
"requested": "[6.1.0, )",
"resolved": "6.1.0",
"contentHash": "5o/HZxx6RVqYlhKSq8/zronDkALJZUT2Vz0hx43f0gwe8mwlM0y2nYlqdBwLMzr262Bwvpikeb/yEwkAa5PADg=="
},
"TomsToolbox.Composition.Analyzer": {
"type": "Direct",
"requested": "[2.21.0, )",
"resolved": "2.21.0",
"contentHash": "vJx9hxAzjni34slGz78ewqYP9Ylk8dJszfEUK1TF5cflVKMBO3ORSFd0FtICTwJtE8munvZrMrcLWwXt5bIcEA=="
},
"Microsoft.Build.Tasks.Git": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
},
"Microsoft.SourceLink.Common": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
"icsharpcode.decompiler": {
"type": "Project",
"dependencies": {
"System.Collections.Immutable": "[6.0.0, )",
"System.Reflection.Metadata": "[6.0.0, )"
}
},
"System.Collections.Immutable": {
"type": "CentralTransitive",
"requested": "[9.0.0, )",
"resolved": "9.0.0",
"contentHash": "QhkXUl2gNrQtvPmtBTQHb0YsUrDiDQ2QS09YbtTTiSjGcf7NBqtYbrG/BE06zcBPCKEwQGzIv13IVdXNOSub2w=="
}
}
}
}

2
ILSpy.AddIn.VS2022/ILSpy.AddIn.VS2022.csproj

@ -149,7 +149,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="..\doc\license.txt" Link="license.txt"> <Content Include="..\LICENSE" Link="license.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
<IncludeInVSIX>true</IncludeInVSIX> <IncludeInVSIX>true</IncludeInVSIX>
</Content> </Content>

2
ILSpy.AddIn.VS2022/source.extension.vsixmanifest.template

@ -5,7 +5,7 @@
<DisplayName>ILSpy 2022</DisplayName> <DisplayName>ILSpy 2022</DisplayName>
<Description xml:space="preserve">Integrates the ILSpy decompiler into Visual Studio.</Description> <Description xml:space="preserve">Integrates the ILSpy decompiler into Visual Studio.</Description>
<MoreInfo>https://ilspy.net</MoreInfo> <MoreInfo>https://ilspy.net</MoreInfo>
<License>license.txt</License> <License>LICENSE</License>
<Icon>ILSpy-Large.ico</Icon> <Icon>ILSpy-Large.ico</Icon>
<Tags>ILSpy;IL;decompile;decompiler;decompilation;C#;CSharp;.NET;Productivity;Open Source;Free</Tags> <Tags>ILSpy;IL;decompile;decompiler;decompilation;C#;CSharp;.NET;Productivity;Open Source;Free</Tags>
</Metadata> </Metadata>

2
ILSpy.AddIn/ILSpy.AddIn.csproj

@ -148,7 +148,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="..\doc\license.txt" Link="license.txt"> <Content Include="..\LICENSE" Link="license.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
<IncludeInVSIX>true</IncludeInVSIX> <IncludeInVSIX>true</IncludeInVSIX>
</Content> </Content>

2
ILSpy.AddIn/source.extension.vsixmanifest.template

@ -5,7 +5,7 @@
<DisplayName>ILSpy</DisplayName> <DisplayName>ILSpy</DisplayName>
<Description xml:space="preserve">Integrates the ILSpy decompiler into Visual Studio.</Description> <Description xml:space="preserve">Integrates the ILSpy decompiler into Visual Studio.</Description>
<MoreInfo>https://ilspy.net</MoreInfo> <MoreInfo>https://ilspy.net</MoreInfo>
<License>license.txt</License> <License>LICENSE</License>
<Icon>ILSpy-Large.ico</Icon> <Icon>ILSpy-Large.ico</Icon>
</Metadata> </Metadata>
<Installation> <Installation>

2
ILSpy.Installer/ILSpy.Installer.csproj

@ -15,7 +15,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="WixSharp" Version="1.25.3" /> <PackageReference Include="WixSharp" Version="1.26.0" />
<PackageReference Include="WixSharp.wix.bin" Version="3.14.1" /> <PackageReference Include="WixSharp.wix.bin" Version="3.14.1" />
</ItemGroup> </ItemGroup>

5
ILSpy.ReadyToRun/ReadyToRunLanguage.cs

@ -30,6 +30,7 @@ using System.Runtime.CompilerServices;
using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.Solution; using ICSharpCode.Decompiler.Solution;
using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem;
@ -96,6 +97,10 @@ namespace ICSharpCode.ILSpy.ReadyToRun
public void WriteReference(IMember member, string text, bool isDefinition = false) public void WriteReference(IMember member, string text, bool isDefinition = false)
{ {
} }
public void WriteReference(MetadataFile metadata, Handle handle, string text, string protocol = "decompile", bool isDefinition = false)
{
}
} }
#endif #endif

124
ILSpy/Commands/CreateDiagramContextMenuEntry.cs

@ -0,0 +1,124 @@
// Copyright (c) 2024 Christoph Wille 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.Composition;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using ICSharpCode.Decompiler;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpyX.MermaidDiagrammer;
using Microsoft.Win32;
namespace ICSharpCode.ILSpy.TextView
{
[ExportContextMenuEntry(Header = nameof(Resources._CreateDiagram), Category = nameof(Resources.Save), Icon = "Images/Save")]
[Shared]
sealed class CreateDiagramContextMenuEntry(DockWorkspace dockWorkspace) : IContextMenuEntry
{
public void Execute(TextViewContext context)
{
var assembly = (context.SelectedTreeNodes?.FirstOrDefault() as AssemblyTreeNode)?.LoadedAssembly;
if (assembly == null)
return;
var selectedPath = SelectDestinationFolder();
if (string.IsNullOrEmpty(selectedPath))
return;
dockWorkspace.RunWithCancellation(ct => Task<AvalonEditTextOutput>.Factory.StartNew(() => {
AvalonEditTextOutput output = new() {
EnableHyperlinks = true
};
Stopwatch stopwatch = Stopwatch.StartNew();
try
{
var command = new GenerateHtmlDiagrammer {
Assembly = assembly.FileName,
OutputFolder = selectedPath
};
command.Run();
}
catch (OperationCanceledException)
{
output.WriteLine();
output.WriteLine(Resources.GenerationWasCancelled);
throw;
}
stopwatch.Stop();
output.WriteLine(Resources.GenerationCompleteInSeconds, stopwatch.Elapsed.TotalSeconds.ToString("F1"));
output.WriteLine();
output.WriteLine("Learn more: " + "https://github.com/icsharpcode/ILSpy/wiki/Diagramming#tips-for-using-the-html-diagrammer");
output.WriteLine();
var diagramHtml = Path.Combine(selectedPath, "index.html");
output.AddButton(null, Resources.OpenExplorer, delegate { Process.Start("explorer", "/select,\"" + diagramHtml + "\""); });
output.WriteLine();
return output;
}, ct), Properties.Resources.CreatingDiagram).Then(dockWorkspace.ShowText).HandleExceptions();
return;
}
public bool IsEnabled(TextViewContext context) => true;
public bool IsVisible(TextViewContext context)
{
return context.SelectedTreeNodes?.Length == 1
&& context.SelectedTreeNodes?.FirstOrDefault() is AssemblyTreeNode tn
&& tn.LoadedAssembly.IsLoadedAsValidAssembly;
}
static string SelectDestinationFolder()
{
OpenFolderDialog dialog = new();
dialog.Multiselect = false;
dialog.Title = "Select target folder";
if (dialog.ShowDialog() != true)
{
return null;
}
string selectedPath = Path.GetDirectoryName(dialog.FolderName);
bool directoryNotEmpty;
try
{
directoryNotEmpty = Directory.EnumerateFileSystemEntries(selectedPath).Any();
}
catch (Exception e) when (e is IOException || e is UnauthorizedAccessException || e is System.Security.SecurityException)
{
MessageBox.Show(
"The directory cannot be accessed. Please ensure it exists and you have sufficient rights to access it.",
"Target directory not accessible",
MessageBoxButton.OK, MessageBoxImage.Error);
return null;
}
return dialog.FolderName;
}
}
}

11
ILSpy/Controls/CustomDialog.cs

@ -51,9 +51,8 @@ namespace ICSharpCode.ILSpy.Controls
using (Graphics g = this.CreateGraphics()) using (Graphics g = this.CreateGraphics())
{ {
Rectangle screen = Screen.PrimaryScreen.WorkingArea; SizeF size = TextRenderer.MeasureText(message, label.Font, default, TextFormatFlags.NoPrefix);
SizeF size = g.MeasureString(message, label.Font, screen.Width - 20); Size clientSize = new Size((int)Math.Ceiling(size.Width * 96 / g.DpiX) + DockPadding.Left + DockPadding.Right, (int)Math.Ceiling(size.Height * 96 / g.DpiY) + DockPadding.Top + DockPadding.Bottom);
Size clientSize = size.ToSize();
Button[] buttons = new Button[buttonLabels.Length]; Button[] buttons = new Button[buttonLabels.Length];
int[] positions = new int[buttonLabels.Length]; int[] positions = new int[buttonLabels.Length];
int pos = 0; int pos = 0;
@ -65,8 +64,8 @@ namespace ICSharpCode.ILSpy.Controls
string buttonLabel = buttonLabels[i]; string buttonLabel = buttonLabels[i];
newButton.Text = buttonLabel; newButton.Text = buttonLabel;
newButton.Click += new EventHandler(ButtonClick); newButton.Click += new EventHandler(ButtonClick);
SizeF buttonSize = g.MeasureString(buttonLabel, newButton.Font); SizeF buttonSize = TextRenderer.MeasureText(buttonLabel, newButton.Font);
newButton.Width = Math.Max(newButton.Width, ((int)Math.Ceiling(buttonSize.Width / 8.0) + 1) * 8); newButton.Width = Math.Max(newButton.Width, ((int)Math.Ceiling(buttonSize.Width * 96 / g.DpiX / 8.0) + 1) * 8);
positions[i] = pos; positions[i] = pos;
buttons[i] = newButton; buttons[i] = newButton;
pos += newButton.Width + 4; pos += newButton.Width + 4;
@ -87,7 +86,7 @@ namespace ICSharpCode.ILSpy.Controls
{ {
clientSize.Width = pos; clientSize.Width = pos;
} }
clientSize.Height += panel.Height + 6; clientSize.Height += panel.Height;
this.ClientSize = clientSize; this.ClientSize = clientSize;
int start = (clientSize.Width - pos) / 2; int start = (clientSize.Width - pos) / 2;
for (int i = 0; i < buttons.Length; i++) for (int i = 0; i < buttons.Length; i++)

12
ILSpy/Docking/DockWorkspace.cs

@ -25,6 +25,7 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Data;
using System.Windows.Threading; using System.Windows.Threading;
using AvalonDock; using AvalonDock;
@ -50,6 +51,7 @@ namespace ICSharpCode.ILSpy.Docking
private readonly IExportProvider exportProvider; private readonly IExportProvider exportProvider;
private readonly ObservableCollection<TabPageModel> tabPages = []; private readonly ObservableCollection<TabPageModel> tabPages = [];
private ReadOnlyCollection<ToolPaneModel> toolPanes;
readonly SessionSettings sessionSettings; readonly SessionSettings sessionSettings;
@ -123,7 +125,7 @@ namespace ICSharpCode.ILSpy.Docking
public ReadOnlyObservableCollection<TabPageModel> TabPages { get; } public ReadOnlyObservableCollection<TabPageModel> TabPages { get; }
public ReadOnlyCollection<ToolPaneModel> ToolPanes => exportProvider public ReadOnlyCollection<ToolPaneModel> ToolPanes => toolPanes ??= exportProvider
.GetExportedValues<ToolPaneModel>("ToolPane") .GetExportedValues<ToolPaneModel>("ToolPane")
.OrderBy(item => item.Title) .OrderBy(item => item.Title)
.ToArray() .ToArray()
@ -194,6 +196,9 @@ namespace ICSharpCode.ILSpy.Docking
{ {
serializer.LayoutSerializationCallback -= LayoutSerializationCallback; serializer.LayoutSerializationCallback -= LayoutSerializationCallback;
} }
DockingManager.SetBinding(DockingManager.AnchorablesSourceProperty, new Binding(nameof(ToolPanes)));
DockingManager.SetBinding(DockingManager.DocumentsSourceProperty, new Binding(nameof(TabPages)));
} }
void LayoutSerializationCallback(object sender, LayoutSerializationCallbackEventArgs e) void LayoutSerializationCallback(object sender, LayoutSerializationCallbackEventArgs e)
@ -226,6 +231,11 @@ namespace ICSharpCode.ILSpy.Docking
return ActiveTabPage.ShowTextViewAsync(textView => textView.RunWithCancellation(taskCreation)); return ActiveTabPage.ShowTextViewAsync(textView => textView.RunWithCancellation(taskCreation));
} }
public Task<T> RunWithCancellation<T>(Func<CancellationToken, Task<T>> taskCreation, string progressTitle)
{
return ActiveTabPage.ShowTextViewAsync(textView => textView.RunWithCancellation(taskCreation, progressTitle));
}
internal void ShowNodes(AvalonEditTextOutput output, TreeNodes.ILSpyTreeNode[] nodes, IHighlightingDefinition highlighting) internal void ShowNodes(AvalonEditTextOutput output, TreeNodes.ILSpyTreeNode[] nodes, IHighlightingDefinition highlighting)
{ {
ActiveTabPage.ShowTextView(textView => textView.ShowNodes(output, nodes, highlighting)); ActiveTabPage.ShowTextView(textView => textView.ShowNodes(output, nodes, highlighting));

7
ILSpy/ILSpy.csproj

@ -58,7 +58,7 @@
<EmbeddedResource Include="..\doc\ILSpyAboutPage.txt" /> <EmbeddedResource Include="..\doc\ILSpyAboutPage.txt" />
<EmbeddedResource Include="..\doc\ILSpyAboutPage_zh_Hans.txt" /> <EmbeddedResource Include="..\doc\ILSpyAboutPage_zh_Hans.txt" />
<EmbeddedResource Include="..\doc\third-party-notices.txt" /> <EmbeddedResource Include="..\doc\third-party-notices.txt" />
<EmbeddedResource Include="..\doc\license.txt"> <EmbeddedResource Include="..\LICENSE">
<Link>license.txt</Link> <Link>license.txt</Link>
</EmbeddedResource> </EmbeddedResource>
<Resource Include="Images\NuGet.png" /> <Resource Include="Images\NuGet.png" />
@ -93,6 +93,11 @@
<PackageReference Include="Microsoft.DiaSymReader.Converter.Xml" /> <PackageReference Include="Microsoft.DiaSymReader.Converter.Xml" />
<PackageReference Include="Microsoft.DiaSymReader" /> <PackageReference Include="Microsoft.DiaSymReader" />
<PackageReference Include="Microsoft.DiaSymReader.Native" /> <PackageReference Include="Microsoft.DiaSymReader.Native" />
<!-- 4.3.0 of all those have security vulnerabilities, and although only a debug build, we'll override the versions for good measure -->
<PackageReference Include="System.Net.Http" />
<PackageReference Include="System.Private.Uri" />
<PackageReference Include="System.Text.RegularExpressions" />
</ItemGroup> </ItemGroup>
<PropertyGroup> <PropertyGroup>

2
ILSpy/MainWindow.xaml

@ -67,8 +67,6 @@
<avalondock:DockingManager x:Name="DockManager" <avalondock:DockingManager x:Name="DockManager"
DataContext="{Binding Workspace}" DataContext="{Binding Workspace}"
AnchorablesSource="{Binding ToolPanes}"
DocumentsSource="{Binding TabPages}"
ActiveContent="{Binding ActiveTabPage, Mode=TwoWay, Converter={docking:TabPageGuardConverter}}" ActiveContent="{Binding ActiveTabPage, Mode=TwoWay, Converter={docking:TabPageGuardConverter}}"
AllowMixedOrientation="True"> AllowMixedOrientation="True">

18
ILSpy/Properties/Resources.Designer.cs generated

@ -114,6 +114,15 @@ namespace ICSharpCode.ILSpy.Properties {
} }
} }
/// <summary>
/// Looks up a localized string similar to Create _Diagram....
/// </summary>
public static string _CreateDiagram {
get {
return ResourceManager.GetString("_CreateDiagram", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to _File. /// Looks up a localized string similar to _File.
/// </summary> /// </summary>
@ -567,6 +576,15 @@ namespace ICSharpCode.ILSpy.Properties {
} }
} }
/// <summary>
/// Looks up a localized string similar to Creating diagram....
/// </summary>
public static string CreatingDiagram {
get {
return ResourceManager.GetString("CreatingDiagram", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Culture. /// Looks up a localized string similar to Culture.
/// </summary> /// </summary>

6
ILSpy/Properties/Resources.resx

@ -210,6 +210,9 @@ Are you sure you want to continue?</value>
<data name="Create" xml:space="preserve"> <data name="Create" xml:space="preserve">
<value>Create</value> <value>Create</value>
</data> </data>
<data name="CreatingDiagram" xml:space="preserve">
<value>Creating diagram...</value>
</data>
<data name="CultureLabel" xml:space="preserve"> <data name="CultureLabel" xml:space="preserve">
<value>Culture</value> <value>Culture</value>
</data> </data>
@ -1036,6 +1039,9 @@ Do you want to continue?</value>
<data name="_CollapseTreeNodes" xml:space="preserve"> <data name="_CollapseTreeNodes" xml:space="preserve">
<value>_Collapse all tree nodes</value> <value>_Collapse all tree nodes</value>
</data> </data>
<data name="_CreateDiagram" xml:space="preserve">
<value>Create _Diagram...</value>
</data>
<data name="_File" xml:space="preserve"> <data name="_File" xml:space="preserve">
<value>_File</value> <value>_File</value>
</data> </data>

4
ILSpy/TextView/DecompilerTextView.cs

@ -595,14 +595,14 @@ namespace ICSharpCode.ILSpy.TextView
/// the task. /// the task.
/// If another task is started before the previous task finishes running, the previous task is cancelled. /// If another task is started before the previous task finishes running, the previous task is cancelled.
/// </summary> /// </summary>
public Task<T> RunWithCancellation<T>(Func<CancellationToken, Task<T>> taskCreation) public Task<T> RunWithCancellation<T>(Func<CancellationToken, Task<T>> taskCreation, string? progressTitle = null)
{ {
if (waitAdorner.Visibility != Visibility.Visible) if (waitAdorner.Visibility != Visibility.Visible)
{ {
waitAdorner.Visibility = Visibility.Visible; waitAdorner.Visibility = Visibility.Visible;
// Work around a WPF bug by setting IsIndeterminate only while the progress bar is visible. // Work around a WPF bug by setting IsIndeterminate only while the progress bar is visible.
// https://github.com/icsharpcode/ILSpy/issues/593 // https://github.com/icsharpcode/ILSpy/issues/593
progressTitle.Text = Properties.Resources.Decompiling; this.progressTitle.Text = progressTitle == null ? Properties.Resources.Decompiling : progressTitle;
progressBar.IsIndeterminate = true; progressBar.IsIndeterminate = true;
progressText.Text = null; progressText.Text = null;
progressText.Visibility = Visibility.Collapsed; progressText.Visibility = Visibility.Collapsed;

2
doc/license.txt → LICENSE

@ -1,6 +1,6 @@
MIT license MIT license
Copyright (c) 2011-2023 AlphaSierraPapa for the ILSpy team Copyright (c) 2011-2025 AlphaSierraPapa for the ILSpy team
Permission is hereby granted, free of charge, to any person obtaining a copy of this 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 software and associated documentation files (the "Software"), to deal in the Software

4
NuGet.config

@ -4,7 +4,7 @@
<clear /> <clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" /> <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="dotnet-tools" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json" /> <add key="dotnet-tools" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json" />
<add key="dotnet8-transport" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8-transport/nuget/v3/index.json" /> <add key="dotnet9-transport" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet9-transport/nuget/v3/index.json" />
</packageSources> </packageSources>
<packageSourceMapping> <packageSourceMapping>
<packageSource key="nuget.org"> <packageSource key="nuget.org">
@ -12,7 +12,7 @@
<package pattern="Microsoft.DiaSymReader.Native" /> <package pattern="Microsoft.DiaSymReader.Native" />
<package pattern="Microsoft.DiaSymReader" /> <package pattern="Microsoft.DiaSymReader" />
</packageSource> </packageSource>
<packageSource key="dotnet8-transport"> <packageSource key="dotnet9-transport">
<package pattern="ILCompiler.Reflection.ReadyToRun.Experimental" /> <package pattern="ILCompiler.Reflection.ReadyToRun.Experimental" />
</packageSource> </packageSource>
<packageSource key="dotnet-tools"> <packageSource key="dotnet-tools">

15
SECURITY.md

@ -0,0 +1,15 @@
# Security Policy
## Supported Versions
Supported are the latest released version as well as the latest preview/rc version.
## Reporting a Vulnerability
Security issues and bugs should be reported privately to christoph.wille AT gmail.com. Please note that
we cannot guarantee a response time (*) although we will strive to get back to you within one business day. If you
do not hear back from Chris within a week, alternatively try to contact siegfriedpammer AT gmail.com.
Please do not open issues for anything you think might have a security implication.
(*) We are an OSS project entirely run by volunteers and sometimes life<sup>tm</sup> will mean longer response times.

2
doc/ILSpyAboutPage.txt

@ -3,7 +3,7 @@ ILSpy is the open-source .NET assembly browser and decompiler.
Website: https://ilspy.net/ Website: https://ilspy.net/
Found a bug? https://github.com/icsharpcode/ILSpy/issues/new/choose Found a bug? https://github.com/icsharpcode/ILSpy/issues/new/choose
Copyright 2011-2023 AlphaSierraPapa for the ILSpy team Copyright 2011-2025 AlphaSierraPapa for the ILSpy team
Current and past contributors: https://github.com/icsharpcode/ILSpy/graphs/contributors Current and past contributors: https://github.com/icsharpcode/ILSpy/graphs/contributors
ILSpy is distributed under the MIT License. ILSpy is distributed under the MIT License.

2
doc/ILSpyAboutPage_zh_Hans.txt

@ -4,7 +4,7 @@ ILSpy 是开源的 .NET 程序集浏览器和反编译器。
反馈BUG: https://github.com/icsharpcode/ILSpy/issues/new/choose 反馈BUG: https://github.com/icsharpcode/ILSpy/issues/new/choose
中文翻译反馈:https://github.com/maikebing/ILSpy/issues 中文翻译反馈:https://github.com/maikebing/ILSpy/issues
Copyright 2011-2023 AlphaSierraPapa for the ILSpy team Copyright 2011-2025 AlphaSierraPapa for the ILSpy team
当前和过去的贡献者: https://github.com/icsharpcode/ILSpy/graphs/contributors 当前和过去的贡献者: https://github.com/icsharpcode/ILSpy/graphs/contributors
ILSpy 基于 MIT 许可证发行。 ILSpy 基于 MIT 许可证发行。

2
doc/copyright.txt

@ -1,4 +1,4 @@
Copyright 2011-2023 for the ILSpy team Copyright 2011-2025 for the ILSpy team
by by
AlphaSierraPapa, Christoph Wille AlphaSierraPapa, Christoph Wille

Loading…
Cancel
Save