mirror of
https://github.com/icsharpcode/ILSpy.git
synced 2026-10-12 02:15:58 +00:00
ilspycmd: add --member for single-member decompilation
Decompiling one method or property previously required decompiling its whole type and searching the output, which is wasteful for scripted and agent-driven use against large assemblies. The new -m|--member option accepts an XML documentation id string (the syntax of compiler-generated documentation files and of the UI's --navigateto option) or a metadata token in 0x06000005 form, resolves it against the main module (with a bounds check for tokens and distinct error messages for malformed ids, unknown members, and members of other modules), and prints just that member through the engine's single-member decompilation path. The tests seed a new ICSharpCode.ILSpyCmd.Tests project (part of the XPlat and Desktop solution filters and of the per-project CI test steps), driving the real Main in-process via InternalsVisibleTo, so future ilspycmd features have a dedicated home for CLI tests. Assisted-by: Claude:claude-fable-5:Claude Code
This commit is contained in:
committed by
Siegfried Pammer
parent
89800af156
commit
74bc61b70f
@@ -350,6 +350,13 @@ jobs:
|
||||
--no-build --report-trx
|
||||
--results-directory test-results
|
||||
|
||||
- name: Execute ilspycmd tests
|
||||
run: >
|
||||
dotnet test --project ICSharpCode.ILSpyCmd.Tests/ICSharpCode.ILSpyCmd.Tests.csproj
|
||||
--configuration Release
|
||||
--no-build --report-trx
|
||||
--results-directory test-results
|
||||
|
||||
- name: Execute BAML decompiler tests
|
||||
run: >
|
||||
dotnet test --project ILSpy.BamlDecompiler.Tests/ILSpy.BamlDecompiler.Tests.csproj
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net11.0</TargetFramework>
|
||||
<LangVersion>preview</LangVersion>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
|
||||
<GenerateTestingPlatformEntryPoint>true</GenerateTestingPlatformEntryPoint>
|
||||
<StartupObject>ICSharpCode.ILSpyCmd.Tests.MicrosoftTestingPlatformEntryPoint</StartupObject>
|
||||
<OutputType>Exe</OutputType>
|
||||
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NUnit" />
|
||||
<PackageReference Include="NUnit3TestAdapter" />
|
||||
<PackageReference Include="Microsoft.Testing.Extensions.TrxReport" />
|
||||
<PackageReference Include="Microsoft.Testing.Extensions.VSTestBridge" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ICSharpCode.ILSpyCmd\ICSharpCode.ILSpyCmd.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,156 @@
|
||||
// Copyright (c) 2026 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.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace ICSharpCode.ILSpyCmd.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class ILSpyCmdMemberOptionTests
|
||||
{
|
||||
static readonly string testAssemblyPath = typeof(ILSpyCmdMemberOptionTests).Assembly.Location;
|
||||
|
||||
static async Task<(int ExitCode, string Output, string Error)> RunAsync(params string[] args)
|
||||
{
|
||||
var originalOut = Console.Out;
|
||||
var originalError = Console.Error;
|
||||
var stdout = new StringWriter();
|
||||
var stderr = new StringWriter();
|
||||
try
|
||||
{
|
||||
Console.SetOut(stdout);
|
||||
Console.SetError(stderr);
|
||||
int exitCode = await ILSpyCmdProgram.Main(args);
|
||||
return (exitCode, stdout.ToString(), stderr.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(originalOut);
|
||||
Console.SetError(originalError);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task MethodByDocumentationIdString()
|
||||
{
|
||||
var result = await RunAsync(testAssemblyPath, "--disable-updatecheck",
|
||||
"-m", "M:ICSharpCode.ILSpyCmd.Tests.MemberOptionSample.Add(System.Int32,System.Int32)");
|
||||
|
||||
Assert.That(result.ExitCode, Is.EqualTo(0), result.Error);
|
||||
Assert.That(result.Output, Does.Contain("int Add(int a, int b)"));
|
||||
Assert.That(result.Output, Does.Not.Contain("Unrelated"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task PropertyByDocumentationIdString()
|
||||
{
|
||||
var result = await RunAsync(testAssemblyPath, "--disable-updatecheck",
|
||||
"-m", "P:ICSharpCode.ILSpyCmd.Tests.MemberOptionSample.Answer");
|
||||
|
||||
Assert.That(result.ExitCode, Is.EqualTo(0), result.Error);
|
||||
Assert.That(result.Output, Does.Contain("Answer"));
|
||||
Assert.That(result.Output, Does.Not.Contain("Add(int a, int b)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task MethodByMetadataToken()
|
||||
{
|
||||
int token = typeof(MemberOptionSample).GetMethod(nameof(MemberOptionSample.Add))!.MetadataToken;
|
||||
var result = await RunAsync(testAssemblyPath, "--disable-updatecheck", "-m", $"0x{token:x8}");
|
||||
|
||||
Assert.That(result.ExitCode, Is.EqualTo(0), result.Error);
|
||||
Assert.That(result.Output, Does.Contain("int Add(int a, int b)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task UnknownMemberReportsError()
|
||||
{
|
||||
var result = await RunAsync(testAssemblyPath, "--disable-updatecheck",
|
||||
"-m", "M:ICSharpCode.ILSpyCmd.Tests.MemberOptionSample.DoesNotExist");
|
||||
|
||||
Assert.That(result.ExitCode, Is.EqualTo(ProgramExitCodes.EX_DATAERR));
|
||||
Assert.That(result.Error, Does.Contain("DoesNotExist"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task MalformedTokenReportsTokenSpecificError()
|
||||
{
|
||||
var result = await RunAsync(testAssemblyPath, "--disable-updatecheck", "-m", "0xZZ000001");
|
||||
|
||||
Assert.That(result.ExitCode, Is.EqualTo(ProgramExitCodes.EX_DATAERR));
|
||||
Assert.That(result.Error, Does.Contain("metadata token"));
|
||||
Assert.That(result.Error, Does.Not.Contain("documentation id"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task MemberOfAnotherModuleReportsDistinctError()
|
||||
{
|
||||
var result = await RunAsync(testAssemblyPath, "--disable-updatecheck", "-m", "M:System.Object.ToString");
|
||||
|
||||
Assert.That(result.ExitCode, Is.EqualTo(ProgramExitCodes.EX_DATAERR));
|
||||
Assert.That(result.Error, Does.Contain("defined in"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task SurroundingWhitespaceIsIgnored()
|
||||
{
|
||||
var result = await RunAsync(testAssemblyPath, "--disable-updatecheck",
|
||||
"-m", " M:ICSharpCode.ILSpyCmd.Tests.MemberOptionSample.Add(System.Int32,System.Int32) ");
|
||||
|
||||
Assert.That(result.ExitCode, Is.EqualTo(0), result.Error);
|
||||
Assert.That(result.Output, Does.Contain("int Add(int a, int b)"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task OutOfRangeTokenReportsError()
|
||||
{
|
||||
var result = await RunAsync(testAssemblyPath, "--disable-updatecheck", "-m", "0x06ffffff");
|
||||
|
||||
Assert.That(result.ExitCode, Is.EqualTo(ProgramExitCodes.EX_DATAERR));
|
||||
Assert.That(result.Error, Does.Contain("0x06ffffff"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TypeAndMemberOptionsAreMutuallyExclusive()
|
||||
{
|
||||
var result = await RunAsync(testAssemblyPath, "--disable-updatecheck",
|
||||
"-t", "ICSharpCode.ILSpyCmd.Tests.MemberOptionSample",
|
||||
"-m", "P:ICSharpCode.ILSpyCmd.Tests.MemberOptionSample.Answer");
|
||||
|
||||
Assert.That(result.ExitCode, Is.EqualTo(ProgramExitCodes.EX_USAGE));
|
||||
}
|
||||
}
|
||||
|
||||
public class MemberOptionSample
|
||||
{
|
||||
public int Add(int a, int b)
|
||||
{
|
||||
return a + b;
|
||||
}
|
||||
|
||||
public string Answer => "42";
|
||||
|
||||
public void Unrelated()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,549 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dependencies": {
|
||||
"net11.0": {
|
||||
"Microsoft.Testing.Extensions.TrxReport": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.1.0, )",
|
||||
"resolved": "2.1.0",
|
||||
"contentHash": "cXmP225WcMLLOSrW8xekaNhfzdBwXX3cbXbE5qSzmLbK0KZe3z8rAObKj70FWiPPPzm2W22x0ZW93gsmAfK6Mg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Testing.Extensions.TrxReport.Abstractions": "2.1.0",
|
||||
"Microsoft.Testing.Platform": "2.1.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Testing.Extensions.VSTestBridge": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.1.0, )",
|
||||
"resolved": "2.1.0",
|
||||
"contentHash": "bNRIEA2YoGr+Y+7LHdA7i1U80+7BAdf4K4Qh4Kx6eKkoBK/NV7QpoMg+GWPP0/eqAFzuUmUOIPVZ87Oo0Vyxmw==",
|
||||
"dependencies": {
|
||||
"Microsoft.TestPlatform.ObjectModel": "18.0.1",
|
||||
"Microsoft.Testing.Extensions.Telemetry": "2.1.0",
|
||||
"Microsoft.Testing.Extensions.TrxReport.Abstractions": "2.1.0",
|
||||
"Microsoft.Testing.Platform": "2.1.0"
|
||||
}
|
||||
},
|
||||
"NUnit": {
|
||||
"type": "Direct",
|
||||
"requested": "[4.6.1, )",
|
||||
"resolved": "4.6.1",
|
||||
"contentHash": "xS4+YaBFUv1r8bcAbjitSfYaRZGfMwUiMdiaRziBXZpKgVxKDSHhjUn0mV5mObHGZRZq6eNa+WFWr3g8grj66A=="
|
||||
},
|
||||
"NUnit3TestAdapter": {
|
||||
"type": "Direct",
|
||||
"requested": "[6.2.0, )",
|
||||
"resolved": "6.2.0",
|
||||
"contentHash": "8PMJB8za2u8S0ey/nEtvh9BHjLhv5yzUEMCmA0+VIPLKSeOAZ3TEHWDyAp0+iPQb3jnBH1o8k0PoU2FgzXLRnQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyModel": "8.0.2",
|
||||
"Microsoft.Testing.Extensions.VSTestBridge": "2.1.0",
|
||||
"Microsoft.Testing.Platform.MSBuild": "2.1.0"
|
||||
}
|
||||
},
|
||||
"TomsToolbox.Composition.Analyzer": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.24.0, )",
|
||||
"resolved": "2.24.0",
|
||||
"contentHash": "dKHqW1MeAMnDIbtx8qDTsGwy/7LUiQ3ccdzHX0PzCh1r98Lgl/1deIky9+ojZO0K5HjeA7uE+eW9/h+v7EOIBA=="
|
||||
},
|
||||
"Microsoft.ApplicationInsights": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.23.0",
|
||||
"contentHash": "nWArUZTdU7iqZLycLKWe0TDms48KKGE6pONH2terYNa8REXiqixrMOkf1sk5DHGMaUTqONU2YkS4SAXBhLStgw==",
|
||||
"dependencies": {
|
||||
"System.Diagnostics.DiagnosticSource": "5.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "5Vnd2I75DmZCVEjSynIdJ/0EGafgnLQwgR3t2C2/fkjx/nRG+cLwxLLdInoHeCEpkD5K4Ov/g9ZCRYrl4TRsaA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "10.0.10"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Binder": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "GqmN2o1CkJvk7uWp+p4CwBYW0w/zfoEbvsiFDbO2G8l1Uz+mrDAbAcZiXhU2lufKPby1cjAUdd5GTWpebYOkOA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "10.0.10",
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "10.0.10"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.CommandLine": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "33cBeR2HRbzHUTtmcmLdNOApneNGcymwwL4arHuotgVK9Frba8kcDTrvVTj7cSCmF1R9OiSbZH0KxNOwab3HUg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "10.0.10",
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "10.0.10"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.EnvironmentVariables": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "KRfFSSCV58vEdU7mPED/YMzeovIWF5P0g8s9K8n9HEfy0/WzMq37SrPdXdFN5/dFT/rPMHpF7AvpoXHckbcBFg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "10.0.10",
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "10.0.10"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.FileExtensions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "ZOhZYwvbXGTgGVRwswIirofEMVHuWdxjdh0JeUZXwaF9cgcjXdz/t0ELtgaevw7ezTyv47yPNCgGreWtLkn3IQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "10.0.10",
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.FileProviders.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.FileProviders.Physical": "10.0.10",
|
||||
"Microsoft.Extensions.Primitives": "10.0.10"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.UserSecrets": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "1s1sKFTk/Foam64JY6+m/diH8drL3Wx6V3gtSd5v1IEZtszZYyc1pW8uRnMblzpNiR0l0t8gGk7tXj3xHzFgdg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.Configuration.Json": "10.0.10",
|
||||
"Microsoft.Extensions.FileProviders.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.FileProviders.Physical": "10.0.10"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "ANyvsgkNBRvcJh2XLgn8veGmajf+8m0AbKK+HPWdRL1yraSNVVSmQhFntLtdz/C795jxqqup+k05cs/3jZQPOA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyModel": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.2",
|
||||
"contentHash": "mUBDZZRgZrSyFOsJ2qJJ9fXfqd/kXJwf3AiDoqLD9m6TjY5OO/vLNOb9fb4juC0487eq4hcGN/M2Rh/CKS7QYw=="
|
||||
},
|
||||
"Microsoft.Extensions.Diagnostics": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "Kr/e7lUf4+N8tacbqJ2Ctwe/HarKdAc9ZkgKVVqvtJDBKbez+T/KnUwu82KSlnBp/SrpBcxc7u7xkE2oUZT/5Q==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "10.0.10",
|
||||
"Microsoft.Extensions.Diagnostics.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.Options.ConfigurationExtensions": "10.0.10"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Diagnostics.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "9uWiKpeOVac355STyChWR/pliFX/5CeLqChW9kKsaxyDH4EUTZxMkT4Jwp/J/peLm0GBFmSX5c0WCse3yCnq1Q==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.Options": "10.0.10"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.FileProviders.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "c5zqFCY9DiIpMovLd7/d/CTiEtrMOuQ639dhv3PABtKQIKNQikSHwQt8+N679uii9q+B55lgK28Uv64FOwEu8w==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "10.0.10"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.FileProviders.Physical": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "jhJAyo38kSrH3ARvWUk0h8itogVnQu2DCZuPo+s0Z+tXes0ugTxMPaHYzap85785eHQmPFqD9TYERqBbtGxn/w==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.FileProviders.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.FileSystemGlobbing": "10.0.10",
|
||||
"Microsoft.Extensions.Primitives": "10.0.10"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.FileSystemGlobbing": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "jSOCVxEwCd4Aq925kJVz1kSO1EpX2OHYKL04qVREXkDU7Ce3pVDdHPYm+fEy8y/th2kJf/DAstRHpJAqoNWP8w=="
|
||||
},
|
||||
"Microsoft.Extensions.Hosting.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "5LugpYGHk+mkn0a8IZgcyfBca8PCTAU9RQFoMrTdtOOidq88M2SI5f3px6ugnzgxC+eTkvYYJi8pzlUnG5xdAQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.Diagnostics.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.FileProviders.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "10.0.10"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "Tf6z5HsL0VDYRTfvsoNrTGHGheCwkTsZBA2FFh5ATJUbkAwug+FFNISJK2gjpUNemlAOoWllAK52HOWCjto3EQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "10.0.10",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.Options": "10.0.10"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "zkFxGYUvdxAvIKTyXHrmW+Sux53D4SezD9dMyZ6hrwwzPQJNuwCRy1f5W7AvYTqacEGhWF2XderRQG1OvbV8og==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Configuration": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "cLrqxkuEfcilZ8SjK+9KAnpLk9lOoMPaOokF+wRUYie+iUEcdX4/p/+gJkt0BYgWLthjpBUCkVTBI6Kxg0nsOw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "10.0.10",
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.Configuration.Binder": "10.0.10",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.Logging": "10.0.10",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.Options": "10.0.10",
|
||||
"Microsoft.Extensions.Options.ConfigurationExtensions": "10.0.10"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Console": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "VIlNzPwPS0GeQVSmCqqo36ugryX3LpE9ul6gEkks5VLET3weH/XMLeWmclwfoGn4Nxi2mwVibB+OZBVJ9tDqvg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.Logging": "10.0.10",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.Logging.Configuration": "10.0.10",
|
||||
"Microsoft.Extensions.Options": "10.0.10"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Debug": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "8+TZBnV5fgBXoVNJ5ROSErUwYogk4hOgV7c2HWK1u5cqKGmiUTUn7+KqZ35iQu8e/B7Ykccyz5OTjdXcidNZ9g==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.Logging": "10.0.10",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "10.0.10"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.EventLog": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "0RE4951AzQ+YD4gVrvbq0BhdsiBgSDo44yM7+QBZ2mrmMJeNjY+teCIYfUjqDPVYnKs0HR6SkkhgrX1YgXZq3Q==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.Logging": "10.0.10",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.Options": "10.0.10",
|
||||
"System.Diagnostics.EventLog": "10.0.10"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.EventSource": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "85SAPwXhJtdBInzN2k7SChiFiBGh3KOWay5AfoY+GREF6P7oZA98+ST2p7Z9384iLKYjkZSKIZ/FqIO5aojtNw==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.Logging": "10.0.10",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.Options": "10.0.10",
|
||||
"Microsoft.Extensions.Primitives": "10.0.10"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Options": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "srnhnk7nE8krBiIXp71LvBmKBtraBONWSRzdjJgRv1Ko9Mp8IVNqv4vIS9hGeVteBig8aQkva9ZG+sC+o5sVcA==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.Primitives": "10.0.10"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Options.ConfigurationExtensions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "tnBmu/LwF25ZQK+HBNCu2xrwnkKoB/XEbJyooGGoYxHrhvxbSKi7eOFiJ4AXBy/QU4vtCvCJfoi8k9Ej72qzOQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.Configuration.Binder": "10.0.10",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.Options": "10.0.10",
|
||||
"Microsoft.Extensions.Primitives": "10.0.10"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Primitives": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "5wu/GrYVd8mG2DVUw3vFJzF+O336TyTGg/Kmcgw9bfwYhCoFiV5lR5QeEmKecJyrW4W54nMfD3p3589E8a7czQ=="
|
||||
},
|
||||
"Microsoft.Testing.Extensions.Telemetry": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.0",
|
||||
"contentHash": "5TwgTx2u7k9Al/xbZ18QXq4Hdy2xewkVTI6K3sk+jY2ykqUkIKNuj7rFu3GOV5KnEUkevhw6eZcyZs77STHJIA==",
|
||||
"dependencies": {
|
||||
"Microsoft.ApplicationInsights": "2.23.0",
|
||||
"Microsoft.Testing.Platform": "2.1.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Testing.Extensions.TrxReport.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.0",
|
||||
"contentHash": "D8xmIJYQFJ6D49Rx5/vPrkZZxb338Jkew+eSqZLBfBiWKw4QZKy3i1BOXiLfz0lOmaNErwDz/YWRojCdNl+B9Q==",
|
||||
"dependencies": {
|
||||
"Microsoft.Testing.Platform": "2.1.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Testing.Platform": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.0",
|
||||
"contentHash": "aHkjNTGIA+Zbdw6RJgSFrbDrCjO0CgqpElqYcvkRSeUhBv2bKarnvU3ep786U7UqrPlArT/B7VmImRibJD0Zrg=="
|
||||
},
|
||||
"Microsoft.Testing.Platform.MSBuild": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.0",
|
||||
"contentHash": "UpfPebXQtHGrWz21+YLHmJSm+5zsuPE9U9pfdCtoB+67g75fDmWlNgpkH2ZmdVhSwkjNIed9Icg8Iu63z2ei5Q==",
|
||||
"dependencies": {
|
||||
"Microsoft.Testing.Platform": "2.1.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.TestPlatform.ObjectModel": {
|
||||
"type": "Transitive",
|
||||
"resolved": "18.0.1",
|
||||
"contentHash": "qT/mwMcLF9BieRkzOBPL2qCopl8hQu6A1P7JWAoj/FMu5i9vds/7cjbJ/LLtaiwWevWLAeD5v5wjQJ/l6jvhWQ==",
|
||||
"dependencies": {
|
||||
"System.Reflection.Metadata": "8.0.0"
|
||||
}
|
||||
},
|
||||
"Newtonsoft.Json": {
|
||||
"type": "Transitive",
|
||||
"resolved": "13.0.3",
|
||||
"contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ=="
|
||||
},
|
||||
"NuGet.Common": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.6.0",
|
||||
"contentHash": "uyXLqkbbZmkMvdHOR23l1EHW2hRmULtzoG3Ocj84VpGptnNfkODVboHGJfDfcn9Gi9oUNDs8/VjL4FZcST6zVg==",
|
||||
"dependencies": {
|
||||
"NuGet.Frameworks": "7.6.0"
|
||||
}
|
||||
},
|
||||
"NuGet.Configuration": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.6.0",
|
||||
"contentHash": "+bNj+YneC5CNg1vR+WZjLAakscJlsi0KhADZUgIJPn4pwh8/jeCUMC5ik5cpET/i+QOplDy7aJVTGkpdfrlPww==",
|
||||
"dependencies": {
|
||||
"NuGet.Common": "7.6.0",
|
||||
"System.Security.Cryptography.ProtectedData": "8.0.0"
|
||||
}
|
||||
},
|
||||
"NuGet.Packaging": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.6.0",
|
||||
"contentHash": "TDp+qHzRBy1zjwiJGCbfpdO0jMG5hH/bk7p1EABLKv9p5SIykDPGnbuYXm2iZO0QJ/H+hOI/vo5LfqM17Q+G0w==",
|
||||
"dependencies": {
|
||||
"Newtonsoft.Json": "13.0.3",
|
||||
"NuGet.Configuration": "7.6.0",
|
||||
"NuGet.Versioning": "7.6.0",
|
||||
"System.Security.Cryptography.Pkcs": "8.0.1"
|
||||
}
|
||||
},
|
||||
"NuGet.Versioning": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.6.0",
|
||||
"contentHash": "TpZxfOoQBQk/0r/2uc1A1qNYIKHkJGgOrWP+ax3nsNAUN/1BOQMDrgmGADogSA4hOXH1ZJiyeYg4Ca+vUW0sEg=="
|
||||
},
|
||||
"System.Diagnostics.DiagnosticSource": {
|
||||
"type": "Transitive",
|
||||
"resolved": "5.0.0",
|
||||
"contentHash": "tCQTzPsGZh/A9LhhA6zrqCRV4hOHsK90/G7q3Khxmn6tnB1PuNU0cRaKANP2AWcF9bn0zsuOoZOSrHuJk6oNBA=="
|
||||
},
|
||||
"System.Diagnostics.EventLog": {
|
||||
"type": "Transitive",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "OvGz3PrzuAI/Sj7LTcXcCe3FClRI1IyRMZjNONcZtFh+Ww7nAtSh4kh08r8KVe/xxkXJPjR0Y1jF7H+N42d4xQ=="
|
||||
},
|
||||
"System.Security.Cryptography.ProtectedData": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "+TUFINV2q2ifyXauQXRwy4CiBhqvDEDZeVJU7qfxya4aRYOKzVBpN+4acx25VcPB9ywUN6C0n8drWl110PhZEg=="
|
||||
},
|
||||
"icsharpcode.bamldecompiler": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"ICSharpCode.Decompiler": "[8.0.0-noversion, )"
|
||||
}
|
||||
},
|
||||
"icsharpcode.decompiler": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"System.Collections.Immutable": "[9.0.0, )",
|
||||
"System.Reflection.Metadata": "[9.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": "[10.0.10, )",
|
||||
"System.Reflection.Metadata": "[10.0.10, )",
|
||||
"System.Runtime.CompilerServices.Unsafe": "[6.1.2, )"
|
||||
}
|
||||
},
|
||||
"ilspycmd": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"ICSharpCode.BamlDecompiler": "[10.0.0-noversion, )",
|
||||
"ICSharpCode.Decompiler": "[8.0.0-noversion, )",
|
||||
"ICSharpCode.ILSpyX": "[8.0.0-noversion, )",
|
||||
"McMaster.Extensions.Hosting.CommandLine": "[5.1.0, )",
|
||||
"Microsoft.Extensions.Hosting": "[10.0.10, )",
|
||||
"NuGet.Protocol": "[7.6.0, )",
|
||||
"System.Security.Cryptography.Pkcs": "[10.0.10, )"
|
||||
}
|
||||
},
|
||||
"K4os.Compression.LZ4": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[1.3.8, )",
|
||||
"resolved": "1.3.8",
|
||||
"contentHash": "LhwlPa7c1zs1OV2XadMtAWdImjLIsqFJPoRcIWAadSRn0Ri1DepK65UbWLPmt4riLqx2d40xjXRk0ogpqNtK7g=="
|
||||
},
|
||||
"McMaster.Extensions.CommandLineUtils": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[5.1.0, )",
|
||||
"resolved": "5.1.0",
|
||||
"contentHash": "YceiKmxdsBrlkAJpmJ2N8XkLyAH01xLsm4VLfjNp5MvtAom2wflZtEBz3CLMQret6Z7jSh3oBO1ULF1Is0tNxA=="
|
||||
},
|
||||
"McMaster.Extensions.Hosting.CommandLine": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[5.1.0, )",
|
||||
"resolved": "5.1.0",
|
||||
"contentHash": "XN6s/86/bP0PSsP5p2eX49ZKmWrURSNg7nvrG5vws3abm7Py1A4bv3x3Pdvg7FqR8mLgEE0gNTI1qDtlYQIQnw==",
|
||||
"dependencies": {
|
||||
"McMaster.Extensions.CommandLineUtils": "5.1.0",
|
||||
"Microsoft.Extensions.Hosting.Abstractions": "10.0.5",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "10.0.5"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[10.0.10, )",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "plJWK2zpWuuyxI8F8s2scx6Je7N1Ajjs6HvYUGKwRnDMWIVIz9FHwAkiT7ASgrvAOd10T0FPVlh9BzAJJME+jg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.Primitives": "10.0.10"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Json": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[10.0.10, )",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "uvJ6sHwjgrkMEJOgiC76G0mcZGXerwyyWkwX34EOjCbxKG6TCtfAoqDKAMsCvEBf9HxjlGQEgqsSMOGCmGBf+A==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "10.0.10",
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.Configuration.FileExtensions": "10.0.10",
|
||||
"Microsoft.Extensions.FileProviders.Abstractions": "10.0.10"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[10.0.10, )",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "z/2xXlFw2aLGjHyEm6E0tQ+In6VfzQzTrtArbQ2c0TQE16ZbyDCMGPvaUT9I0s8rgy9sRWlU2P9waW37qV04qA=="
|
||||
},
|
||||
"Microsoft.Extensions.Hosting": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[10.0.10, )",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "tL9FkfV64GPUDSPvwrgyw42LVzsnVAnyrqJEuZVJbODgrQ3eL63zmzEcVWoCHzfgqUhWggzbgAyUCnz/zfI3Pg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "10.0.10",
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.Configuration.Binder": "10.0.10",
|
||||
"Microsoft.Extensions.Configuration.CommandLine": "10.0.10",
|
||||
"Microsoft.Extensions.Configuration.EnvironmentVariables": "10.0.10",
|
||||
"Microsoft.Extensions.Configuration.FileExtensions": "10.0.10",
|
||||
"Microsoft.Extensions.Configuration.Json": "10.0.10",
|
||||
"Microsoft.Extensions.Configuration.UserSecrets": "10.0.10",
|
||||
"Microsoft.Extensions.DependencyInjection": "10.0.10",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.Diagnostics": "10.0.10",
|
||||
"Microsoft.Extensions.FileProviders.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.FileProviders.Physical": "10.0.10",
|
||||
"Microsoft.Extensions.Hosting.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.Logging": "10.0.10",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "10.0.10",
|
||||
"Microsoft.Extensions.Logging.Configuration": "10.0.10",
|
||||
"Microsoft.Extensions.Logging.Console": "10.0.10",
|
||||
"Microsoft.Extensions.Logging.Debug": "10.0.10",
|
||||
"Microsoft.Extensions.Logging.EventLog": "10.0.10",
|
||||
"Microsoft.Extensions.Logging.EventSource": "10.0.10",
|
||||
"Microsoft.Extensions.Options": "10.0.10"
|
||||
}
|
||||
},
|
||||
"Mono.Cecil": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[0.11.6, )",
|
||||
"resolved": "0.11.6",
|
||||
"contentHash": "f33RkDtZO8VlGXCtmQIviOtxgnUdym9xx/b1p9h91CRGOsJFxCFOFK1FDbVt1OCf1aWwYejUFa2MOQyFWTFjbA=="
|
||||
},
|
||||
"NuGet.Frameworks": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[7.6.0, )",
|
||||
"resolved": "7.6.0",
|
||||
"contentHash": "rJ7QtKN45XzLXCrMATve6eFLiUyUGEkA1rFSb6U6Fw6laM4hEAcKOrcdbgWlcFUlCK2158qP1LF00hg/ivF3nw=="
|
||||
},
|
||||
"NuGet.Protocol": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[7.6.0, )",
|
||||
"resolved": "7.6.0",
|
||||
"contentHash": "Ccb9dJG9hW0FdHFjXoHmhJBBJRYSCeSJArLdZjyZj6/FEAIKezLn75KFQNrTPE5UiAp4HVrjBizufZ/0IXhfKQ==",
|
||||
"dependencies": {
|
||||
"NuGet.Packaging": "7.6.0"
|
||||
}
|
||||
},
|
||||
"System.Collections.Immutable": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[10.0.10, )",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "Ih5zrydoDc1H5I0eNP6f4Lzw3cjsPMN4Nikd86kbyi66y0flkM9GfjVo62aUbcxeTbypzBCFAFQ+/6RF2jRORg=="
|
||||
},
|
||||
"System.Composition.AttributedModel": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[10.0.10, )",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "alK+Ew7XBsxHgwmSmiZzg7x4sLpNIaQ3QVJUkJ/issHZY0L+RHceqO27pDp0J0sDnSf8g6yJNpDnWSKL5sAa/g=="
|
||||
},
|
||||
"System.Reflection.Metadata": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[10.0.10, )",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "NZIS6/IUBh70nJfVvE577oDc81y5GfYRgjWssC8AGpSlVzSu5YfbHXEtHXyLeEY7gqqbAaASwJEP0Oy3Q54Jfw=="
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[6.1.2, )",
|
||||
"resolved": "6.1.2",
|
||||
"contentHash": "2hBr6zdbIBTDE3EhK7NSVNdX58uTK6iHW/P/Axmm9sl1xoGSLqDvMtpecn226TNwHByFokYwJmt/aQQNlO5CRw=="
|
||||
},
|
||||
"System.Security.Cryptography.Pkcs": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[10.0.10, )",
|
||||
"resolved": "10.0.10",
|
||||
"contentHash": "KG8t5RHczdgB3IWvRndpI0nE1DSo7ikDYSDbITxfgRFyIvnYiKzuPjaZOsPnwFQ1aOGUl9sEulJul9wlHLEUoA=="
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,4 +71,8 @@
|
||||
</ReadLinesFromFile>
|
||||
</Target>
|
||||
|
||||
<ItemGroup>
|
||||
<InternalsVisibleTo Include="ICSharpCode.ILSpyCmd.Tests" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -23,7 +23,9 @@ using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.IO.MemoryMappedFiles;
|
||||
using System.Linq;
|
||||
using System.Globalization;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@@ -33,6 +35,7 @@ using ICSharpCode.Decompiler;
|
||||
using ICSharpCode.Decompiler.CSharp;
|
||||
using ICSharpCode.Decompiler.CSharp.ProjectDecompiler;
|
||||
using ICSharpCode.Decompiler.DebugInfo;
|
||||
using ICSharpCode.Decompiler.Documentation;
|
||||
using ICSharpCode.Decompiler.Disassembler;
|
||||
using ICSharpCode.Decompiler.Metadata;
|
||||
using ICSharpCode.Decompiler.Solution;
|
||||
@@ -105,6 +108,9 @@ Examples:
|
||||
[Option("-t|--type <type-name>", "The fully qualified name of the type to decompile.", CommandOptionType.SingleValue)]
|
||||
public string TypeName { get; }
|
||||
|
||||
[Option("-m|--member <doc-id-or-token>", "The single member to decompile: an XML documentation id string (e.g. \"M:System.String.Concat(System.String,System.String)\", as also accepted by the UI's --navigateto option) or a metadata token (e.g. 0x06000005).", CommandOptionType.SingleValue)]
|
||||
public string MemberIdString { get; }
|
||||
|
||||
[Option("-il|--ilcode", "Show IL code.", CommandOptionType.NoValue)]
|
||||
public bool ShowILCodeFlag { get; }
|
||||
|
||||
@@ -359,6 +365,12 @@ Examples:
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MemberIdString != null && TypeName != null)
|
||||
{
|
||||
app.Error.WriteLine("The --type and --member options are mutually exclusive.");
|
||||
return ProgramExitCodes.EX_USAGE;
|
||||
}
|
||||
|
||||
if (outputDirectory != null)
|
||||
{
|
||||
string outputName = Path.GetFileNameWithoutExtension(fileName);
|
||||
@@ -366,6 +378,11 @@ Examples:
|
||||
(string.IsNullOrEmpty(TypeName) ? outputName : TypeName) + ".decompiled.cs"));
|
||||
}
|
||||
|
||||
if (MemberIdString != null)
|
||||
{
|
||||
return DecompileMember(fileName, output, MemberIdString);
|
||||
}
|
||||
|
||||
return Decompile(fileName, output, TypeName);
|
||||
}
|
||||
}
|
||||
@@ -619,6 +636,84 @@ Examples:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DecompileMember(string assemblyFileName, TextWriter output, string idOrToken)
|
||||
{
|
||||
CSharpDecompiler decompiler = GetDecompiler(assemblyFileName);
|
||||
|
||||
if (!TryResolveMember(decompiler.TypeSystem, idOrToken, out EntityHandle handle, out string error))
|
||||
{
|
||||
Console.Error.WriteLine(error);
|
||||
return ProgramExitCodes.EX_DATAERR;
|
||||
}
|
||||
|
||||
output.Write(decompiler.DecompileAsString(handle));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resolves a member reference supplied on the command line: either an XML
|
||||
/// documentation id string ("M:...", "P:...", "F:...", "E:..." or "T:...") or a
|
||||
/// metadata token in hexadecimal "0x06000005" form. Documentation id strings use
|
||||
/// the same syntax as the compiler-generated documentation files and the UI's
|
||||
/// --navigateto option.
|
||||
/// </summary>
|
||||
static bool TryResolveMember(IDecompilerTypeSystem typeSystem, string idOrToken, out EntityHandle handle, out string error)
|
||||
{
|
||||
handle = default;
|
||||
error = null;
|
||||
string trimmed = idOrToken.Trim();
|
||||
|
||||
if (trimmed.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (!int.TryParse(trimmed.AsSpan(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int tokenValue))
|
||||
{
|
||||
error = $"'{trimmed}' is not a valid metadata token; expected a hexadecimal value like 0x06000005.";
|
||||
return false;
|
||||
}
|
||||
var metadata = typeSystem.MainModule.MetadataFile.Metadata;
|
||||
var candidate = MetadataTokens.EntityHandle(tokenValue);
|
||||
int rowNumber = tokenValue & 0x00ffffff;
|
||||
int rowCount = candidate.Kind switch {
|
||||
HandleKind.TypeDefinition => metadata.TypeDefinitions.Count,
|
||||
HandleKind.FieldDefinition => metadata.FieldDefinitions.Count,
|
||||
HandleKind.MethodDefinition => metadata.MethodDefinitions.Count,
|
||||
HandleKind.PropertyDefinition => metadata.PropertyDefinitions.Count,
|
||||
HandleKind.EventDefinition => metadata.EventDefinitions.Count,
|
||||
_ => 0,
|
||||
};
|
||||
if (rowNumber < 1 || rowNumber > rowCount)
|
||||
{
|
||||
error = $"Metadata token {trimmed} does not reference a type or member of this module.";
|
||||
return false;
|
||||
}
|
||||
handle = candidate;
|
||||
return true;
|
||||
}
|
||||
|
||||
IEntity entity;
|
||||
try
|
||||
{
|
||||
entity = IdStringProvider.FindEntity(trimmed, new SimpleTypeResolveContext(typeSystem.MainModule));
|
||||
}
|
||||
catch (ReflectionNameParseException ex)
|
||||
{
|
||||
error = $"'{trimmed}' is not a valid documentation id string: {ex.Message}";
|
||||
return false;
|
||||
}
|
||||
if (entity == null || entity.MetadataToken.IsNil)
|
||||
{
|
||||
error = $"Member '{trimmed}' was not found in this module. Expected an XML documentation id string (e.g. \"M:System.String.Concat(System.String,System.String)\") or a metadata token (e.g. 0x06000005).";
|
||||
return false;
|
||||
}
|
||||
if (entity.ParentModule != typeSystem.MainModule)
|
||||
{
|
||||
error = $"Member '{trimmed}' is defined in '{entity.ParentModule?.AssemblyName}', not in this module.";
|
||||
return false;
|
||||
}
|
||||
handle = entity.MetadataToken;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resolves a type name supplied on the command line to a single type definition.
|
||||
/// <para>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"ICSharpCode.BamlDecompiler\\ICSharpCode.BamlDecompiler.csproj",
|
||||
"ICSharpCode.Decompiler.TestRunner\\ICSharpCode.Decompiler.TestRunner.csproj",
|
||||
"ICSharpCode.Decompiler.Tests\\ICSharpCode.Decompiler.Tests.csproj",
|
||||
"ICSharpCode.ILSpyCmd.Tests\\ICSharpCode.ILSpyCmd.Tests.csproj",
|
||||
"ICSharpCode.Decompiler\\ICSharpCode.Decompiler.csproj",
|
||||
"ICSharpCode.ILSpyX\\ICSharpCode.ILSpyX.csproj",
|
||||
"ILSpy.BamlDecompiler.Tests\\ILSpy.BamlDecompiler.Tests.csproj",
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"path": "ILSpy.sln",
|
||||
"projects": [
|
||||
"ICSharpCode.ILSpyCmd\\ICSharpCode.ILSpyCmd.csproj",
|
||||
"ICSharpCode.ILSpyCmd.Tests\\ICSharpCode.ILSpyCmd.Tests.csproj",
|
||||
"ICSharpCode.Decompiler.PowerShell\\ICSharpCode.Decompiler.PowerShell.csproj",
|
||||
"ICSharpCode.Decompiler.TestRunner\\ICSharpCode.Decompiler.TestRunner.csproj",
|
||||
"ICSharpCode.Decompiler.Tests\\ICSharpCode.Decompiler.Tests.csproj",
|
||||
|
||||
@@ -49,6 +49,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILSpy.BamlDecompiler.Tests"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILSpy.BamlDecompiler.Tests.Windows", "ILSpy.BamlDecompiler.Tests.Windows\ILSpy.BamlDecompiler.Tests.Windows.csproj", "{7A5C3CEF-0744-4643-BA1E-7AE6610FF269}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.ILSpyCmd.Tests", "ICSharpCode.ILSpyCmd.Tests\ICSharpCode.ILSpyCmd.Tests.csproj", "{042FE5F2-3C0A-4B99-A268-D1917CC67B47}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -239,6 +241,18 @@ Global
|
||||
{7A5C3CEF-0744-4643-BA1E-7AE6610FF269}.Release|x64.Build.0 = Release|Any CPU
|
||||
{7A5C3CEF-0744-4643-BA1E-7AE6610FF269}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{7A5C3CEF-0744-4643-BA1E-7AE6610FF269}.Release|x86.Build.0 = Release|Any CPU
|
||||
{042FE5F2-3C0A-4B99-A268-D1917CC67B47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{042FE5F2-3C0A-4B99-A268-D1917CC67B47}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{042FE5F2-3C0A-4B99-A268-D1917CC67B47}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{042FE5F2-3C0A-4B99-A268-D1917CC67B47}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{042FE5F2-3C0A-4B99-A268-D1917CC67B47}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{042FE5F2-3C0A-4B99-A268-D1917CC67B47}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{042FE5F2-3C0A-4B99-A268-D1917CC67B47}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{042FE5F2-3C0A-4B99-A268-D1917CC67B47}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{042FE5F2-3C0A-4B99-A268-D1917CC67B47}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{042FE5F2-3C0A-4B99-A268-D1917CC67B47}.Release|x64.Build.0 = Release|Any CPU
|
||||
{042FE5F2-3C0A-4B99-A268-D1917CC67B47}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{042FE5F2-3C0A-4B99-A268-D1917CC67B47}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
Reference in New Issue
Block a user