Browse Source

Merge branch 'master' into patch-1

pull/3553/head
Youssef Victor 3 months ago committed by GitHub
parent
commit
014f69e2fc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      .github/workflows/build-frontends.yml
  2. 10
      .github/workflows/build-ilspy.yml
  3. 6
      .github/workflows/codeql-analysis.yml
  4. 4
      .github/workflows/scorecard.yml
  5. 2
      BuildTools/pre-commit
  6. 34
      Directory.Packages.props
  7. 8
      ICSharpCode.BamlDecompiler/Rewrite/ConnectionIdRewritePass.cs
  8. 16
      ICSharpCode.BamlDecompiler/packages.lock.json
  9. 8
      ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
  10. 6
      ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs
  11. 38
      ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs
  12. 11
      ICSharpCode.Decompiler.Tests/Semantics/ConversionTests.cs
  13. 66
      ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3552.cs
  14. 198
      ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3552.il
  15. 6
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Discards.cs
  16. 15
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3541.cs
  17. 33
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3571_A.cs
  18. 33
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3571_B.cs
  19. 37
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3571_C.cs
  20. 39
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3576.cs
  21. 9
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/OutVariables.cs
  22. 6
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/ParamsCollections.cs
  23. 17
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/PropertiesAndEvents.cs
  24. 8
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/QualifierTests.cs
  25. 10
      ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoLocalFunctions.Expected.cs
  26. 13
      ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemTestCase.cs
  27. 6
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  28. 6
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  29. 19
      ICSharpCode.Decompiler/CSharp/Resolver/CSharpConversions.cs
  30. 10
      ICSharpCode.Decompiler/CSharp/StatementBuilder.cs
  31. 32
      ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs
  32. 148
      ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs
  33. 34
      ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs
  34. 7
      ICSharpCode.Decompiler/IL/Transforms/LocalFunctionDecompiler.cs
  35. 8
      ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs
  36. 23
      ICSharpCode.Decompiler/IL/Transforms/TransformDisplayClassUsage.cs
  37. 18
      ICSharpCode.Decompiler/Metadata/DotNetCorePathFinderExtensions.cs
  38. 19
      ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs
  39. 23
      ICSharpCode.Decompiler/Metadata/PropertyAndEventBackingFieldLookup.cs
  40. 6
      ICSharpCode.Decompiler/Output/TextTokenWriter.cs
  41. 61
      ICSharpCode.Decompiler/TypeSystem/ExtensionInfo.cs
  42. 9
      ICSharpCode.Decompiler/TypeSystem/Implementation/KnownAttributes.cs
  43. 4
      ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs
  44. 344
      ICSharpCode.ILSpyCmd/packages.lock.json
  45. 38
      ICSharpCode.ILSpyX/TreeView/SharpTreeNode.cs
  46. 26
      ICSharpCode.ILSpyX/packages.lock.json
  47. 8
      ILSpy.BamlDecompiler.Tests/BamlTestRunner.cs
  48. 3
      ILSpy.BamlDecompiler.Tests/Cases/Issue3318.xaml
  49. 26
      ILSpy.BamlDecompiler.Tests/Cases/Issue3318.xaml.cs
  50. 4
      ILSpy.BamlDecompiler.Tests/ILSpy.BamlDecompiler.Tests.csproj
  51. 20
      ILSpy/Analyzers/AnalyzerEntityTreeNode.cs
  52. 22
      ILSpy/Analyzers/AnalyzerSearchTreeNode.cs
  53. 10
      ILSpy/Analyzers/AnalyzerTreeViewModel.cs
  54. 4
      ILSpy/Analyzers/TreeNodes/AnalyzedAccessorTreeNode.cs
  55. 18
      ILSpy/Analyzers/TreeNodes/AnalyzedEventTreeNode.cs
  56. 7
      ILSpy/Analyzers/TreeNodes/AnalyzedFieldTreeNode.cs
  57. 9
      ILSpy/Analyzers/TreeNodes/AnalyzedMethodTreeNode.cs
  58. 16
      ILSpy/Analyzers/TreeNodes/AnalyzedModuleTreeNode.cs
  59. 13
      ILSpy/Analyzers/TreeNodes/AnalyzedPropertyTreeNode.cs
  60. 9
      ILSpy/Analyzers/TreeNodes/AnalyzedTypeTreeNode.cs
  61. 20
      ILSpy/AssemblyTree/AssemblyTreeModel.cs
  62. 3
      ILSpy/Languages/CSharpILMixedLanguage.cs
  63. 3
      ILSpy/Languages/ILLanguage.cs
  64. 6
      ILSpy/Metadata/CorTables/TypeDefTableTreeNode.cs
  65. 8
      ILSpy/Options/DisplaySettings.cs
  66. 1
      ILSpy/Options/DisplaySettingsPanel.xaml
  67. 11
      ILSpy/Properties/Resources.Designer.cs
  68. 3
      ILSpy/Properties/Resources.resx
  69. 14
      ILSpy/Search/SearchPane.xaml
  70. 29
      ILSpy/Search/SearchPane.xaml.cs
  71. 7
      ILSpy/TextView/AvalonEditTextOutput.cs
  72. 49
      ILSpy/TextView/DecompilerTextView.cs
  73. 4
      ILSpy/Util/MessageBus.cs
  74. 2
      ILSpy/Views/DebugSteps.xaml.cs

2
.github/workflows/build-frontends.yml

@ -19,7 +19,7 @@ jobs: @@ -19,7 +19,7 @@ jobs:
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-dotnet@v4
- uses: actions/setup-dotnet@v5
with:
dotnet-version: '10.0.x'
dotnet-quality: 'preview'

10
.github/workflows/build-ilspy.yml

@ -32,7 +32,7 @@ jobs: @@ -32,7 +32,7 @@ jobs:
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-dotnet@v4
- uses: actions/setup-dotnet@v5
with:
dotnet-version: '10.0.x'
dotnet-quality: 'preview'
@ -45,7 +45,7 @@ jobs: @@ -45,7 +45,7 @@ jobs:
- name: Install dotnet-format
env:
DOTNET_FORMAT_VERSION: 10.0.100-preview.7.25380.108
DOTNET_FORMAT_VERSION: 10.0.100-rc.1.25451.107
DOTNET_FORMAT_SOURCE: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet10-transport/nuget/v3/index.json
run: dotnet tool install -g dotnet-format --version "${{env.DOTNET_FORMAT_VERSION}}" --add-source "${{env.DOTNET_FORMAT_SOURCE}}"
@ -65,6 +65,9 @@ jobs: @@ -65,6 +65,9 @@ jobs:
- name: Build
run: msbuild ILSpy.sln /p:Configuration=${{ matrix.configuration }} /p:Platform=$env:BuildPlatform /m
- name: Format check
run: dotnet-format whitespace --verify-no-changes --verbosity detailed ILSpy.sln
- name: Execute unit tests
run: dotnet test --solution ilspy.sln --configuration ${{ matrix.configuration }} --no-build --report-trx --results-directory test-results/${{ matrix.configuration }}
@ -81,9 +84,6 @@ jobs: @@ -81,9 +84,6 @@ jobs:
with:
paths: "test-results/${{ matrix.configuration }}/*.trx"
folded: true
- name: Format check
run: dotnet-format whitespace --verify-no-changes --verbosity detailed ILSpy.sln
- name: Verify package contents
if: matrix.configuration == 'debug'

6
.github/workflows/codeql-analysis.yml

@ -31,11 +31,11 @@ jobs: @@ -31,11 +31,11 @@ jobs:
persist-credentials: false
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
- uses: actions/setup-dotnet@v4
- uses: actions/setup-dotnet@v5
with:
dotnet-version: '10.0.x'
dotnet-quality: 'preview'
@ -44,4 +44,4 @@ jobs: @@ -44,4 +44,4 @@ jobs:
run: dotnet build ILSpy.XPlat.slnf --configuration Release -p:RestoreEnablePackagePruning=false
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@v4

4
.github/workflows/scorecard.yml

@ -29,7 +29,7 @@ jobs: @@ -29,7 +29,7 @@ jobs:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@v2.4.2 # https://github.com/marketplace/actions/ossf-scorecard-action
uses: ossf/scorecard-action@v2.4.3 # https://github.com/marketplace/actions/ossf-scorecard-action
with:
results_file: results.sarif
results_format: sarif
@ -43,6 +43,6 @@ jobs: @@ -43,6 +43,6 @@ jobs:
retention-days: 5
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@v3
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: results.sarif

2
BuildTools/pre-commit

@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
set -eu
DOTNET_FORMAT_VERSION=10.0.100-preview.7.25380.108
DOTNET_FORMAT_VERSION=10.0.100-rc.1.25451.107
DOTNET_FORMAT_SOURCE="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet10-transport/nuget/v3/index.json"
DOTNET_PATH="$LOCALAPPDATA/ICSharpCode/ILSpy/dotnet-format-$DOTNET_FORMAT_VERSION"
if [ ! -d "$DOTNET_PATH" ]; then

34
Directory.Packages.props

@ -6,10 +6,10 @@ @@ -6,10 +6,10 @@
<ItemGroup>
<PackageVersion Include="AvalonEdit" Version="6.3.1.120" />
<PackageVersion Include="CliWrap" Version="3.9.0" />
<PackageVersion Include="DataGridExtensions" Version="2.6.0" />
<PackageVersion Include="DataGridExtensions" Version="2.7.0" />
<PackageVersion Include="DiffLib" Version="2025.0.0" />
<PackageVersion Include="Dirkster.AvalonDock.Themes.VS2013" Version="4.72.1" />
<PackageVersion Include="ILCompiler.Reflection.ReadyToRun.Experimental" Version="10.0.0-preview.7.25380.108" />
<PackageVersion Include="ILCompiler.Reflection.ReadyToRun.Experimental" Version="10.0.0-rc.1.25451.107" />
<PackageVersion Include="Iced" Version="1.21.0" />
<PackageVersion Include="K4os.Compression.LZ4" Version="1.3.8" />
<PackageVersion Include="McMaster.Extensions.CommandLineUtils" Version="4.1.1" />
@ -19,17 +19,17 @@ @@ -19,17 +19,17 @@
<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.Native" Version="17.0.0-beta1.21524.1" />
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="10.0.0-preview.7.25380.108" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="10.0.0-preview.7.25380.108" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.0-preview.7.25380.108" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="10.0.0-preview.7.25380.108" />
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="10.0.0-rc.1.25451.107" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="10.0.0-rc.1.25451.107" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.0-rc.1.25451.107" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="10.0.0-rc.1.25451.107" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageVersion Include="Microsoft.NETCore.ILAsm" Version="10.0.0-preview.7.25380.108" />
<PackageVersion Include="Microsoft.NETCore.ILDAsm" Version="10.0.0-preview.7.25380.108" />
<PackageVersion Include="Microsoft.Sbom.Targets" Version="4.1.0" />
<PackageVersion Include="Microsoft.NETCore.ILAsm" Version="10.0.0-rc.1.25451.107" />
<PackageVersion Include="Microsoft.NETCore.ILDAsm" Version="10.0.0-rc.1.25451.107" />
<PackageVersion Include="Microsoft.Sbom.Targets" Version="4.1.2" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<PackageVersion Include="Microsoft.Testing.Extensions.TrxReport" Version="1.8.2" />
<PackageVersion Include="Microsoft.Testing.Extensions.VSTestBridge" Version="1.8.2" />
<PackageVersion Include="Microsoft.Testing.Extensions.TrxReport" Version="1.8.4" />
<PackageVersion Include="Microsoft.Testing.Extensions.VSTestBridge" Version="1.8.4" />
<PackageVersion Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" />
<PackageVersion Include="Mono.Cecil" Version="0.11.6" />
<PackageVersion Include="NSubstitute" Version="5.3.0" />
@ -39,13 +39,13 @@ @@ -39,13 +39,13 @@
<PackageVersion Include="NuGet.Protocol" Version="6.14.0" />
<PackageVersion Include="PowerShellStandard.Library" Version="5.1.1" />
<PackageVersion Include="Shouldly" Version="4.3.0" />
<PackageVersion Include="System.Composition.AttributedModel" Version="10.0.0-preview.7.25380.108" />
<PackageVersion Include="System.Collections.Immutable" Version="10.0.0-preview.7.25380.108" />
<PackageVersion Include="System.Composition.AttributedModel" Version="10.0.0-rc.1.25451.107" />
<PackageVersion Include="System.Collections.Immutable" Version="10.0.0-rc.1.25451.107" />
<PackageVersion Include="System.Memory" Version="4.6.3" />
<PackageVersion Include="System.Reflection.Metadata" Version="10.0.0-preview.7.25380.108" />
<PackageVersion Include="System.Resources.Extensions" Version="10.0.0-preview.7.25380.108" />
<PackageVersion Include="System.Reflection.Metadata" Version="10.0.0-rc.1.25451.107" />
<PackageVersion Include="System.Resources.Extensions" Version="10.0.0-rc.1.25451.107" />
<PackageVersion Include="System.Runtime.CompilerServices.Unsafe" Version="6.1.2" />
<PackageVersion Include="System.Security.Cryptography.Pkcs" Version="9.0.8" />
<PackageVersion Include="System.Security.Cryptography.Pkcs" Version="9.0.9" />
<PackageVersion Include="TomsToolbox.Composition.MicrosoftExtensions" Version="2.22.2" />
<PackageVersion Include="TomsToolbox.Wpf.Composition" Version="2.22.2" />
<PackageVersion Include="TomsToolbox.Wpf.Composition.AttributedModel" Version="2.22.2" />
@ -56,6 +56,6 @@ @@ -56,6 +56,6 @@
<PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1" />
</ItemGroup>
<ItemGroup>
<GlobalPackageReference Include="TomsToolbox.Composition.Analyzer" Version="2.22.1" />
<GlobalPackageReference Include="TomsToolbox.Composition.Analyzer" Version="2.22.2" />
</ItemGroup>
</Project>

8
ICSharpCode.BamlDecompiler/Rewrite/ConnectionIdRewritePass.cs

@ -22,13 +22,12 @@ using System.Linq; @@ -22,13 +22,12 @@ using System.Linq;
using System.Reflection.Metadata;
using System.Xml.Linq;
using ICSharpCode.BamlDecompiler.Xaml;
using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.IL.Transforms;
using ICSharpCode.Decompiler.Util;
using ICSharpCode.BamlDecompiler.Xaml;
namespace ICSharpCode.BamlDecompiler.Rewrite
{
using ICSharpCode.Decompiler.TypeSystem;
@ -67,6 +66,11 @@ namespace ICSharpCode.BamlDecompiler.Rewrite @@ -67,6 +66,11 @@ namespace ICSharpCode.BamlDecompiler.Rewrite
{
element.Add(new XAttribute(xName, fieldAssignment.Field.Name));
}
// x:FieldModifier can only be "public" or "internal" (in C#), where "internal" is the default and thus omitted
if (fieldAssignment.Field.Accessibility is Accessibility.Public)
{
element.Add(new XAttribute(ctx.GetKnownNamespace("FieldModifier", XamlContext.KnownNamespace_Xaml, element), "public"));
}
ctx.GeneratedMembers.Add(fieldAssignment.Field.MetadataToken);
found = true;
}

16
ICSharpCode.BamlDecompiler/packages.lock.json

@ -4,15 +4,15 @@ @@ -4,15 +4,15 @@
"net10.0": {
"Microsoft.Sbom.Targets": {
"type": "Direct",
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "GidfeSVHFtNwZSbD2wmwWiUiGkVdND8QR1z21WpFa+/47Mi3YiDkAzsWF02wXrMx2Xd8j3QSfKOUY1JtnF+7uw=="
"requested": "[4.1.2, )",
"resolved": "4.1.2",
"contentHash": "AmGCBhWtWu1d1PCit6WTdmpq48nPmmnJz9zZFBsxoCjYZjjZ0Gjm+wuAzHzVMF8VmTo/NeDGi2C73969QXiryw=="
},
"TomsToolbox.Composition.Analyzer": {
"type": "Direct",
"requested": "[2.22.1, )",
"resolved": "2.22.1",
"contentHash": "bKcte9zaz+xH1k6C1YIYpheQ9mPNRSmd0dHQIEIq31KxAKMTLfiAo80aROKDJMYJ7ZomlUjjSMo/QCIikMMWTg=="
"requested": "[2.22.2, )",
"resolved": "2.22.2",
"contentHash": "7gYo8ZR2eq3XkrilvUpLbTypeZy6IlD5FB8jah0YPhMOmDGhya4jJ3kfDMTTRt5m258Ou78P69mHMkG6DKZXsg=="
},
"icsharpcode.decompiler": {
"type": "Project",
@ -23,13 +23,13 @@ @@ -23,13 +23,13 @@
},
"System.Collections.Immutable": {
"type": "CentralTransitive",
"requested": "[10.0.0-preview.7.25380.108, )",
"requested": "[10.0.0-rc.1.25451.107, )",
"resolved": "9.0.0",
"contentHash": "QhkXUl2gNrQtvPmtBTQHb0YsUrDiDQ2QS09YbtTTiSjGcf7NBqtYbrG/BE06zcBPCKEwQGzIv13IVdXNOSub2w=="
},
"System.Reflection.Metadata": {
"type": "CentralTransitive",
"requested": "[10.0.0-preview.7.25380.108, )",
"requested": "[10.0.0-rc.1.25451.107, )",
"resolved": "9.0.0",
"contentHash": "ANiqLu3DxW9kol/hMmTWbt3414t9ftdIuiIU7j80okq2YzAueo120M442xk1kDJWtmZTqWQn7wHDvMRipVOEOQ=="
}

8
ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj

@ -105,6 +105,7 @@ @@ -105,6 +105,7 @@
<None Include="TestCases\ILPretty\Issue3466.il" />
<None Include="testcases\ilpretty\Issue3504.il" />
<None Include="testcases\ilpretty\Issue3524.il" />
<None Include="testcases\ilpretty\Issue3552.il" />
<None Include="TestCases\ILPretty\MonoFixed.il" />
<None Include="TestCases\Correctness\NonGenericConstrainedCallVirt.il" />
<None Include="TestCases\ILPretty\UnknownTypes.cs" />
@ -150,8 +151,15 @@ @@ -150,8 +151,15 @@
<Compile Include="TestCases\ILPretty\Issue3442.cs" />
<Compile Include="TestCases\ILPretty\Issue3466.cs" />
<Compile Include="TestCases\ILPretty\Issue3524.cs" />
<Compile Include="TestCases\ILPretty\Issue3552.cs" />
<Compile Include="TestCases\Pretty\ExpandParamsArgumentsDisabled.cs" />
<Compile Include="TestCases\Pretty\ExtensionProperties.cs" />
<Compile Include="TestCases\Pretty\Issue3541.cs" />
<Compile Include="TestCases\Pretty\Issue3571_C.cs" />
<Compile Include="TestCases\Pretty\Issue3571_B.cs" />
<Compile Include="TestCases\Pretty\Issue3571_A.cs" />
<Compile Include="TestCases\Pretty\Issue3576.cs" />
<None Include="TestCases\Ugly\NoLocalFunctions.Expected.cs" />
<None Include="TestCases\ILPretty\Issue3504.cs" />
<Compile Include="TestCases\ILPretty\MonoFixed.cs" />
<Compile Include="TestCases\Pretty\Comparisons.cs" />

6
ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs

@ -249,6 +249,12 @@ namespace ICSharpCode.Decompiler.Tests @@ -249,6 +249,12 @@ namespace ICSharpCode.Decompiler.Tests
await Run();
}
[Test]
public async Task Issue3552()
{
await Run();
}
[Test]
public async Task Issue2260SwitchString()
{

38
ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs

@ -133,6 +133,14 @@ namespace ICSharpCode.Decompiler.Tests @@ -133,6 +133,14 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
};
static readonly CompilerOptions[] roslyn4OrNewerWithNet40Options =
{
CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
};
static readonly CompilerOptions[] roslyn4OrNewerOptions =
{
CompilerOptions.UseRoslynLatest,
@ -664,6 +672,36 @@ namespace ICSharpCode.Decompiler.Tests @@ -664,6 +672,36 @@ namespace ICSharpCode.Decompiler.Tests
await RunForLibrary(cscOptions: cscOptions | CompilerOptions.CheckForOverflowUnderflow, configureDecompiler: settings => settings.CheckForOverflowUnderflow = true);
}
[Test]
public async Task Issue3541([ValueSource(nameof(roslyn4OrNewerWithNet40Options))] CompilerOptions cscOptions)
{
await RunForLibrary(cscOptions: cscOptions);
}
[Test]
public async Task Issue3571_A([ValueSource(nameof(roslyn2OrNewerWithNet40Options))] CompilerOptions cscOptions)
{
await RunForLibrary(cscOptions: cscOptions);
}
[Test]
public async Task Issue3571_B([ValueSource(nameof(roslyn2OrNewerWithNet40Options))] CompilerOptions cscOptions)
{
await RunForLibrary(cscOptions: cscOptions);
}
[Test]
public async Task Issue3571_C([ValueSource(nameof(roslyn2OrNewerWithNet40Options))] CompilerOptions cscOptions)
{
await RunForLibrary(cscOptions: cscOptions);
}
[Test]
public async Task Issue3576([ValueSource(nameof(roslyn2OrNewerWithNet40Options))] CompilerOptions cscOptions)
{
await RunForLibrary(cscOptions: cscOptions);
}
[Test]
public async Task AssemblyCustomAttributes([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{

11
ICSharpCode.Decompiler.Tests/Semantics/ConversionTests.cs

@ -529,6 +529,17 @@ namespace ICSharpCode.Decompiler.Tests.Semantics @@ -529,6 +529,17 @@ namespace ICSharpCode.Decompiler.Tests.Semantics
Assert.That(c.Method.FullName, Is.EqualTo("System.DateTimeOffset.op_Implicit"));
Assert.That(ImplicitConversion(typeof(DateTimeOffset), typeof(DateTime)), Is.EqualTo(C.None));
ITypeDefinition classImplementingIDisposable = compilation.FindType(typeof(ClassImplementingIDisposable)).GetDefinition();
ITypeDefinition genericStructWithIDisposableConstraintAndImplicitConversion = compilation.FindType(typeof(GenericStructWithIDisposableConstraintAndImplicitConversion<>)).GetDefinition();
IType genericStructIDisposableInstance = new ParameterizedType(genericStructWithIDisposableConstraintAndImplicitConversion, ImmutableArray.Create(compilation.FindType(typeof(IDisposable))));
// C => S<I>
Conversion c2 = conversions.ImplicitConversion(classImplementingIDisposable, genericStructIDisposableInstance);
Assert.That(c2.IsImplicit && c2.IsUserDefined);
Assert.That(c2.Method.FullName, Is.EqualTo("ICSharpCode.Decompiler.Tests.TypeSystem.GenericStructWithIDisposableConstraintAndImplicitConversion.op_Implicit"));
Assert.That(conversions.ImplicitConversion(genericStructIDisposableInstance, classImplementingIDisposable), Is.EqualTo(C.None));
}
[Test]

66
ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3552.cs

@ -0,0 +1,66 @@ @@ -0,0 +1,66 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty
{
public static class Issue3552
{
public static Issue3552_IntegerPair MakePair1(int x, int y)
{
Issue3552_IntegerPairBuilder issue3552_IntegerPairBuilder = new Issue3552_IntegerPairBuilder { x, y };
return issue3552_IntegerPairBuilder.ToPair();
}
public static Issue3552_IntegerPair MakePair2(int x, int y)
{
Issue3552_IntegerPairBuilder issue3552_IntegerPairBuilder = new Issue3552_IntegerPairBuilder { x, y };
return issue3552_IntegerPairBuilder.ToPair();
}
public static Issue3552_IntegerPair MakePair3(int x, int y)
{
Issue3552_IntegerPairBuilder issue3552_IntegerPairBuilder = new Issue3552_IntegerPairBuilder { x, y };
return issue3552_IntegerPairBuilder.ToPair();
}
}
public struct Issue3552_IntegerPair
{
public int X;
public int Y;
}
public struct Issue3552_IntegerPairBuilder : IEnumerable<int>, IEnumerable
{
private int index;
private Issue3552_IntegerPair pair;
public readonly Issue3552_IntegerPair ToPair()
{
return pair;
}
public void Add(int value)
{
switch (index)
{
case 0:
pair.X = value;
break;
case 1:
pair.Y = value;
break;
default:
throw new IndexOutOfRangeException();
}
index++;
}
public IEnumerator<int> GetEnumerator()
{
return null;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}

198
ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3552.il

@ -0,0 +1,198 @@ @@ -0,0 +1,198 @@
.class public auto ansi abstract sealed beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552
extends [System.Runtime]System.Object
{
// Methods
.method public hidebysig static
valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair MakePair1 (
int32 x,
int32 y
) cil managed
{
// Method begins at RVA 0x2050
// Header size: 12
// Code size: 34 (0x22)
.maxstack 2
.locals init (
[0] valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder
)
IL_0000: ldloca.s 0
IL_0002: initobj ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder
IL_0008: ldloca.s 0
IL_000a: ldarg.0
IL_000b: call instance void ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::Add(int32)
IL_0010: ldloca.s 0
IL_0012: ldarg.1
IL_0013: call instance void ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::Add(int32)
IL_0015: ldloca.s 0
IL_001c: call instance valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::ToPair()
IL_0021: ret
} // end of method Issue3552::MakePair1
.method public hidebysig static
valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair MakePair2 (
int32 x,
int32 y
) cil managed
{
// Method begins at RVA 0x2050
// Header size: 12
// Code size: 34 (0x22)
.maxstack 2
.locals init (
[0] valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder
)
IL_0000: ldloca.s 0
IL_0001: dup
IL_0002: initobj ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder
IL_0008: dup
IL_000a: ldarg.0
IL_000b: call instance void ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::Add(int32)
IL_0012: ldarg.1
IL_0013: call instance void ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::Add(int32)
IL_0015: ldloca.s 0
IL_001c: call instance valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::ToPair()
IL_0021: ret
} // end of method Issue3552::MakePair2
.method public hidebysig static
valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair MakePair3 (
int32 x,
int32 y
) cil managed
{
// Method begins at RVA 0x2050
// Header size: 12
// Code size: 34 (0x22)
.maxstack 2
.locals init (
[0] valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder
)
IL_0000: ldloca.s 0
IL_0001: dup
IL_0002: initobj ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder
IL_0008: dup
IL_000a: ldarg.0
IL_000b: call instance void ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::Add(int32)
IL_0010: dup
IL_0012: ldarg.1
IL_0013: call instance void ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::Add(int32)
IL_001c: call instance valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::ToPair()
IL_0021: ret
} // end of method Issue3552::MakePair3
} // end of class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552
.class public sequential ansi sealed beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair
extends [System.Runtime]System.ValueType
{
// Fields
.field public int32 X
.field public int32 Y
} // end of class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair
.class public sequential ansi sealed beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder
extends [System.Runtime]System.ValueType
implements class [System.Runtime]System.Collections.Generic.IEnumerable`1<int32>,
[System.Runtime]System.Collections.IEnumerable
{
// Fields
.field private int32 index
.field private valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair pair
// Methods
.method public hidebysig
instance valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair ToPair () cil managed
{
.custom instance void [System.Runtime]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x207e
// Header size: 1
// Code size: 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::pair
IL_0006: ret
} // end of method Issue3552_IntegerPairBuilder::ToPair
.method public hidebysig
instance void Add (
int32 'value'
) cil managed
{
// Method begins at RVA 0x2088
// Header size: 12
// Code size: 65 (0x41)
.maxstack 3
.locals init (
[0] int32
)
IL_0000: ldarg.0
IL_0001: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::index
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: brfalse.s IL_0010
IL_000a: ldloc.0
IL_000b: ldc.i4.1
IL_000c: beq.s IL_001e
IL_000e: br.s IL_002c
IL_0010: ldarg.0
IL_0011: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::pair
IL_0016: ldarg.1
IL_0017: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair::X
IL_001c: br.s IL_0032
IL_001e: ldarg.0
IL_001f: ldflda valuetype ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::pair
IL_0024: ldarg.1
IL_0025: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPair::Y
IL_002a: br.s IL_0032
IL_002c: newobj instance void [System.Runtime]System.IndexOutOfRangeException::.ctor()
IL_0031: throw
IL_0032: ldarg.0
IL_0033: ldarg.0
IL_0034: ldfld int32 ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::index
IL_0039: ldc.i4.1
IL_003a: add
IL_003b: stfld int32 ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::index
IL_0040: ret
} // end of method Issue3552_IntegerPairBuilder::Add
.method public final hidebysig newslot virtual
instance class [System.Runtime]System.Collections.Generic.IEnumerator`1<int32> GetEnumerator () cil managed
{
// Method begins at RVA 0x20d5
// Header size: 1
// Code size: 2 (0x2)
.maxstack 8
IL_0000: ldnull
IL_0001: ret
} // end of method Issue3552_IntegerPairBuilder::GetEnumerator
.method private final hidebysig newslot virtual
instance class [System.Runtime]System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator () cil managed
{
.override method instance class [System.Runtime]System.Collections.IEnumerator [System.Runtime]System.Collections.IEnumerable::GetEnumerator()
// Method begins at RVA 0x20d8
// Header size: 1
// Code size: 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance class [System.Runtime]System.Collections.Generic.IEnumerator`1<int32> ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder::GetEnumerator()
IL_0006: ret
} // end of method Issue3552_IntegerPairBuilder::System.Collections.IEnumerable.GetEnumerator
} // end of class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue3552_IntegerPairBuilder

6
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Discards.cs

@ -43,12 +43,6 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -43,12 +43,6 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
GetOut(out var _);
}
public void DiscardedOutVsLambdaParameter()
{
GetOut(out var _);
MakeValue((@_ _) => 5);
}
public void ExplicitlyTypedDiscard()
{
GetOutOverloaded(out string _);

15
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3541.cs

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
internal class Issue3541
{
private void Test(string format)
{
TestLocal();
void TestLocal(int a = 0)
{
a.ToString(format);
}
}
}
}

33
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3571_A.cs

@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
using System;
using System.Runtime.InteropServices;
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
internal static class Issue3571_A
{
[StructLayout(LayoutKind.Sequential, Size = 1)]
public readonly struct fsResult
{
public static fsResult Success => default(fsResult);
public static fsResult Failure => default(fsResult);
public bool Succeeded => true;
public bool Failed => false;
public static fsResult operator +(fsResult a, fsResult b)
{
return default(fsResult);
}
}
public static fsResult M()
{
fsResult success = fsResult.Success;
fsResult fsResult2 = success + fsResult.Success;
if (fsResult2.Succeeded)
{
return success;
}
Console.WriteLine("Failed");
return fsResult2 + fsResult.Failure;
}
}
}

33
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3571_B.cs

@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
using System;
using System.Runtime.InteropServices;
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.Issue3571_B
{
[StructLayout(LayoutKind.Sequential, Size = 1)]
public readonly struct fsResult
{
public static fsResult Success => default(fsResult);
public static fsResult Failure => default(fsResult);
public bool Succeeded => true;
public bool Failed => false;
public static fsResult operator +(fsResult a, fsResult b)
{
return default(fsResult);
}
}
internal static class Issue3571_B
{
public static fsResult M()
{
fsResult success = fsResult.Success;
fsResult fsResult2 = success + fsResult.Success;
if (fsResult2.Succeeded)
{
return success;
}
Console.WriteLine("Failed");
return fsResult2 + fsResult.Failure;
}
}
}

37
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3571_C.cs

@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
using System;
using System.Runtime.InteropServices;
using ICSharpCode.Decompiler.Tests.TestCases.Pretty.Issue3571_Helper;
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
internal static class Issue3571_C
{
public static fsResult M()
{
fsResult success = fsResult.Success;
fsResult fsResult2 = success + fsResult.Success;
if (fsResult2.Succeeded)
{
return success;
}
Console.WriteLine("Failed");
return fsResult2 + fsResult.Failure;
}
}
}
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.Issue3571_Helper
{
[StructLayout(LayoutKind.Sequential, Size = 1)]
public readonly struct fsResult
{
public static fsResult Success => default(fsResult);
public static fsResult Failure => default(fsResult);
public bool Succeeded => true;
public bool Failed => false;
public static fsResult operator +(fsResult a, fsResult b)
{
return default(fsResult);
}
}
}

39
ICSharpCode.Decompiler.Tests/TestCases/Pretty/Issue3576.cs

@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
using System.Collections.Generic;
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
internal static class Issue3576
{
public static Issue3576_Camera GetOrCreate(long key, int frameCount, Dictionary<long, (Issue3576_Camera, int)> cache)
{
if (!cache.TryGetValue(key, out var value))
{
Issue3576_GameObject issue3576_GameObject = new Issue3576_GameObject();
value = (issue3576_GameObject.AddComponent<Issue3576_Camera>(), frameCount);
value.Item1.Property = 1;
issue3576_GameObject.SetActive(value: false);
cache[key] = value;
}
else
{
value.Item2 = frameCount;
cache[key] = value;
}
return value.Item1;
}
}
internal sealed class Issue3576_Camera
{
public int Property { get; set; }
}
internal sealed class Issue3576_GameObject
{
public T AddComponent<T>()
{
throw null;
}
public void SetActive(bool value)
{
}
}
}

9
ICSharpCode.Decompiler.Tests/TestCases/Pretty/OutVariables.cs

@ -72,5 +72,14 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -72,5 +72,14 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
GetObject(out dynamic obj);
obj.Method();
}
public void M5()
{
Func<bool> func = () => TryGet<object>(out var result) && result != null;
Func<bool> func2 = () => TryGet<object>(out var result) && result != null;
func();
func2();
}
}
}

6
ICSharpCode.Decompiler.Tests/TestCases/Pretty/ParamsCollections.cs

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
@ -15,6 +16,11 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -15,6 +16,11 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
}
public static void ParamsSpan(params Span<int> values)
{
// note: implicitly "scoped", "params scoped Span<int> values" is allowed
// but "scoped" is always redundant for params.
}
public static void ParamUnscopedSpan([UnscopedRef] params Span<int> values)
{
}
}

17
ICSharpCode.Decompiler.Tests/TestCases/Pretty/PropertiesAndEvents.cs

@ -192,6 +192,23 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -192,6 +192,23 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
}
}
public event EventHandler Issue3575_AutoEvent;
public event EventHandler Issue3575_NonAuto;
public event EventHandler Issue3575_Auto {
add {
}
remove {
}
}
public event EventHandler Issue3575_NonAutoEvent {
add {
}
remove {
}
}
public int Getter(StringBuilder b)
{
return b.Length;

8
ICSharpCode.Decompiler.Tests/TestCases/Pretty/QualifierTests.cs

@ -305,14 +305,6 @@ namespace ICSharpCode.Decompiler.Tests.Pretty @@ -305,14 +305,6 @@ namespace ICSharpCode.Decompiler.Tests.Pretty
{
System.Array.Sort(Array);
}
private void LocalConflictsWithTypeName()
{
for (int i = 0; i < 10; i++)
{
QualifierTests.i.Test();
}
}
#if CS70
private void LocalConflictsWithLocalFunction()
{

10
ICSharpCode.Decompiler.Tests/TestCases/Ugly/NoLocalFunctions.Expected.cs

@ -51,12 +51,14 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Ugly @@ -51,12 +51,14 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Ugly
private static void SimpleCaptureWithRef()
{
_003C_003Ec__DisplayClass2_0 _003C_003Ec__DisplayClass2_ = new _003C_003Ec__DisplayClass2_0();
_003C_003Ec__DisplayClass2_.x = 1;
#if OPT
new Handle(new Func<int>(_003C_003Ec__DisplayClass2_._003CSimpleCaptureWithRef_003Eg__F_007C0));
_003C_003Ec__DisplayClass2_0 obj = new _003C_003Ec__DisplayClass2_0();
obj.x = 1;
new Handle(new Func<int>(obj._003CSimpleCaptureWithRef_003Eg__F_007C0));
#else
Handle handle = new Handle(new Func<int>(_003C_003Ec__DisplayClass2_._003CSimpleCaptureWithRef_003Eg__F_007C0));
_003C_003Ec__DisplayClass2_0 _003C_003Ec__DisplayClass2_1 = new _003C_003Ec__DisplayClass2_0();
_003C_003Ec__DisplayClass2_1.x = 1;
Handle handle = new Handle(new Func<int>(_003C_003Ec__DisplayClass2_1._003CSimpleCaptureWithRef_003Eg__F_007C0));
#endif
}

13
ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemTestCase.cs

@ -559,6 +559,19 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem @@ -559,6 +559,19 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
}
}
public struct GenericStructWithIDisposableConstraintAndImplicitConversion<T> where T : IDisposable
{
public static implicit operator GenericStructWithIDisposableConstraintAndImplicitConversion<T>(T s)
{
return default(GenericStructWithIDisposableConstraintAndImplicitConversion<T>);
}
}
public class ClassImplementingIDisposable : IDisposable
{
public void Dispose() { }
}
public class ClassWithAttributeOnTypeParameter<[Double(2)] T> { }
[Guid("790C6E0B-9194-4cc9-9426-A48A63185696"), InterfaceType(ComInterfaceType.InterfaceIsDual)]

6
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -1436,7 +1436,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1436,7 +1436,7 @@ namespace ICSharpCode.Decompiler.CSharp
}
if (settings.RequiredMembers)
{
RemoveAttribute(typeDecl, KnownAttribute.RequiredAttribute);
RemoveAttribute(typeDecl, KnownAttribute.Required);
}
if (typeDecl.ClassType == ClassType.Enum)
{
@ -2016,7 +2016,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -2016,7 +2016,7 @@ namespace ICSharpCode.Decompiler.CSharp
typeSystemAstBuilder.UseSpecialConstants = !(field.DeclaringType.Equals(field.ReturnType) || isMathPIOrE);
var fieldDecl = typeSystemAstBuilder.ConvertEntity(field);
SetNewModifier(fieldDecl);
if (settings.RequiredMembers && RemoveAttribute(fieldDecl, KnownAttribute.RequiredAttribute))
if (settings.RequiredMembers && RemoveAttribute(fieldDecl, KnownAttribute.Required))
{
fieldDecl.Modifiers |= Modifiers.Required;
}
@ -2132,7 +2132,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -2132,7 +2132,7 @@ namespace ICSharpCode.Decompiler.CSharp
propertyDecl.Modifiers &= ~(Modifiers.New | Modifiers.Virtual);
propertyDecl.Modifiers |= Modifiers.Override;
}
if (settings.RequiredMembers && RemoveAttribute(propertyDecl, KnownAttribute.RequiredAttribute))
if (settings.RequiredMembers && RemoveAttribute(propertyDecl, KnownAttribute.Required))
{
propertyDecl.Modifiers |= Modifiers.Required;
}

6
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -3513,11 +3513,11 @@ namespace ICSharpCode.Decompiler.CSharp @@ -3513,11 +3513,11 @@ namespace ICSharpCode.Decompiler.CSharp
);
break;
case IL.Transforms.AccessPathKind.Setter:
Debug.Assert(lastElement.Member is IProperty || lastElement.Member is IField);
if (lastElement.Indices?.Length > 0)
Debug.Assert(lastElement.Member is IProperty or IField);
if (lastElement.Indices?.Length is var indices and > 0)
{
var property = (IProperty)lastElement.Member;
Debug.Assert(property.IsIndexer);
Debug.Assert(property.Parameters.Count == indices);
Debug.Assert(property.Setter != null, $"Indexer property {property} has no setter");
elementsStack.Peek().Add(
new CallBuilder(this, typeSystem, settings)

19
ICSharpCode.Decompiler/CSharp/Resolver/CSharpConversions.cs

@ -955,13 +955,12 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver @@ -955,13 +955,12 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
/// </summary>
bool IsEncompassedBy(IType a, IType b)
{
return a.Kind != TypeKind.Interface && b.Kind != TypeKind.Interface && StandardImplicitConversion(a, b).IsValid;
return StandardImplicitConversion(a, b).IsValid;
}
bool IsEncompassingOrEncompassedBy(IType a, IType b)
{
return a.Kind != TypeKind.Interface && b.Kind != TypeKind.Interface
&& (StandardImplicitConversion(a, b).IsValid || StandardImplicitConversion(b, a).IsValid);
return (StandardImplicitConversion(a, b).IsValid || StandardImplicitConversion(b, a).IsValid);
}
IType FindMostEncompassedType(IEnumerable<IType> candidates)
@ -1027,6 +1026,13 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver @@ -1027,6 +1026,13 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
Conversion UserDefinedImplicitConversion(ResolveResult fromResult, IType fromType, IType toType)
{
// C# 4.0 spec §6.4.4 User-defined implicit conversions
// user-defined conversions are not supported with interfaces
if (fromType.Kind == TypeKind.Interface || toType.Kind == TypeKind.Interface)
{
return Conversion.None;
}
var operators = GetApplicableConversionOperators(fromResult, fromType, toType, false);
if (operators.Count > 0)
@ -1069,6 +1075,13 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver @@ -1069,6 +1075,13 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
Conversion UserDefinedExplicitConversion(ResolveResult fromResult, IType fromType, IType toType)
{
// C# 4.0 spec §6.4.5 User-defined explicit conversions
// user-defined conversions are not supported with interfaces
if (fromType.Kind == TypeKind.Interface || toType.Kind == TypeKind.Interface)
{
return Conversion.None;
}
var operators = GetApplicableConversionOperators(fromResult, fromType, toType, true);
if (operators.Count > 0)
{

10
ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

@ -551,7 +551,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -551,7 +551,7 @@ namespace ICSharpCode.Decompiler.CSharp
var.Kind = VariableKind.Local;
var disposeVariable = currentFunction.RegisterVariable(
VariableKind.Local, disposeType,
AssignVariableNames.GenerateVariableName(currentFunction, disposeType)
AssignVariableNames.GenerateVariableName(currentFunction, disposeType, decompileRun.UsingScope)
);
Expression disposeInvocation = new InvocationExpression(new MemberReferenceExpression(exprBuilder.ConvertVariable(disposeVariable).Expression, disposeTypeMethodName));
if (inst.IsAsync)
@ -712,12 +712,12 @@ namespace ICSharpCode.Decompiler.CSharp @@ -712,12 +712,12 @@ namespace ICSharpCode.Decompiler.CSharp
if (foreachVariable.Type.Kind != TypeKind.Dynamic)
foreachVariable.Type = type;
foreachVariable.Kind = VariableKind.ForeachLocal;
foreachVariable.Name = AssignVariableNames.GenerateForeachVariableName(currentFunction, collectionExpr.Annotation<ILInstruction>(), foreachVariable);
foreachVariable.Name = AssignVariableNames.GenerateForeachVariableName(currentFunction, collectionExpr.Annotation<ILInstruction>(), decompileRun.UsingScope, foreachVariable);
break;
case RequiredGetCurrentTransformation.IntroduceNewVariable:
foreachVariable = currentFunction.RegisterVariable(
VariableKind.ForeachLocal, type,
AssignVariableNames.GenerateForeachVariableName(currentFunction, collectionExpr.Annotation<ILInstruction>())
AssignVariableNames.GenerateForeachVariableName(currentFunction, collectionExpr.Annotation<ILInstruction>(), decompileRun.UsingScope)
);
instToReplace.ReplaceWith(new LdLoc(foreachVariable));
body.Instructions.Insert(0, new StLoc(foreachVariable, instToReplace));
@ -725,11 +725,11 @@ namespace ICSharpCode.Decompiler.CSharp @@ -725,11 +725,11 @@ namespace ICSharpCode.Decompiler.CSharp
case RequiredGetCurrentTransformation.IntroduceNewVariableAndLocalCopy:
foreachVariable = currentFunction.RegisterVariable(
VariableKind.ForeachLocal, type,
AssignVariableNames.GenerateForeachVariableName(currentFunction, collectionExpr.Annotation<ILInstruction>())
AssignVariableNames.GenerateForeachVariableName(currentFunction, collectionExpr.Annotation<ILInstruction>(), decompileRun.UsingScope)
);
var localCopyVariable = currentFunction.RegisterVariable(
VariableKind.Local, type,
AssignVariableNames.GenerateVariableName(currentFunction, type)
AssignVariableNames.GenerateVariableName(currentFunction, type, decompileRun.UsingScope)
);
instToReplace.Parent.ReplaceWith(new LdLoca(localCopyVariable));
body.Instructions.Insert(0, new StLoc(localCopyVariable, new LdLoc(foreachVariable)));

32
ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs

@ -227,7 +227,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -227,7 +227,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
var v = function.RegisterVariable(
VariableKind.StackSlot,
type,
AssignVariableNames.GenerateVariableName(function, type,
AssignVariableNames.GenerateVariableName(function, type, context.DecompileRun.UsingScope,
stmt.Expression.Annotations.OfType<ILInstruction>()
.Where(AssignVariableNames.IsSupportedInstruction).FirstOrDefault(),
mustResolveConflicts: true)
@ -290,6 +290,15 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -290,6 +290,15 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
// track loops and function bodies as scopes, for comparison with CaptureScope.
scopeTracking.Add((new InsertionPoint { level = nodeLevel, nextNode = node }, scope));
}
else if (node is LambdaExpression { Body: Expression expr })
{
// expression-bodied lambdas don't have a BlockStatement linking to the BlockContainer
scope = node.Annotation<ILFunction>()?.Body as BlockContainer;
if (scope != null)
{
scopeTracking.Add((new InsertionPoint { level = nodeLevel + 1, nextNode = expr }, scope));
}
}
else
{
scope = null; // don't remove a scope if we didn't add one
@ -455,7 +464,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -455,7 +464,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
// We can only insert variable declarations in blocks, but FindInsertionPoints() didn't
// guarantee that it finds only blocks.
// Fix that up now.
while (!(v.InsertionPoint.nextNode.Parent is BlockStatement))
while (!(v.InsertionPoint.nextNode.Parent is BlockStatement or LambdaExpression))
{
if (v.InsertionPoint.nextNode.Parent is ForStatement f && v.InsertionPoint.nextNode == f.Initializers.FirstOrDefault() && IsMatchingAssignment(v, out _))
{
@ -673,6 +682,17 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -673,6 +682,17 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
}
var vds = new VariableDeclarationStatement(type, v.Name, initializer);
vds.Variables.Single().AddAnnotation(new ILVariableResolveResult(ilVariable));
if (v.InsertionPoint.nextNode.Parent is LambdaExpression lambda)
{
Debug.Assert(lambda.Body is not BlockStatement);
lambda.Body = new BlockStatement() {
new ReturnStatement((Expression)lambda.Body.Detach())
};
}
if (v.InsertionPoint.nextNode.Parent is ReturnStatement)
{
v.InsertionPoint = v.InsertionPoint.Up();
}
Debug.Assert(v.InsertionPoint.nextNode.Role == BlockStatement.StatementRole);
if (v.DefaultInitialization == VariableInitKind.NeedsSkipInit)
{
@ -756,11 +776,13 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -756,11 +776,13 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
}
switch (node)
{
case IfElseStatement _: // variable declared in if condition appears in parent scope
case ExpressionStatement _:
case IfElseStatement: // variable declared in if condition appears in parent scope
case ExpressionStatement:
return node == v.InsertionPoint.nextNode;
case Statement _:
case Statement:
return false; // other statements (e.g. while) don't allow variables to be promoted to parent scope
case LambdaExpression lambda:
return lambda.Body == v.InsertionPoint.nextNode;
}
}
return false;

148
ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs

@ -74,6 +74,12 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -74,6 +74,12 @@ namespace ICSharpCode.Decompiler.Disassembler
public bool ExpandMemberDefinitions { get; set; }
/// <summary>
/// Gets or sets whether custom attribute blobs should be decoded or dumped as raw bytes. Default is <see langword="false"/>.
/// Setting this value to <see langword="true"/> (roughly) corresponds to the <c>/CAVERBAL</c> switch of <c>ildasm</c>.
/// </summary>
public bool DecodeCustomAttributeBlobs { get; set; }
public IAssemblyResolver AssemblyResolver { get; set; }
public IEntityProcessor EntityProcessor { get; set; }
@ -476,7 +482,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -476,7 +482,7 @@ namespace ICSharpCode.Decompiler.Disassembler
}
}
class SecurityDeclarationDecoder : ICustomAttributeTypeProvider<(PrimitiveTypeCode, string)>
class SecurityDeclarationDecoder : ICustomAttributeTypeProvider<(PrimitiveTypeCode Code, string Name)>
{
readonly ITextOutput output;
readonly IAssemblyResolver resolver;
@ -506,12 +512,54 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -506,12 +512,54 @@ namespace ICSharpCode.Decompiler.Disassembler
public (PrimitiveTypeCode, string) GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)
{
throw new NotImplementedException();
string fullTypeName = handle.GetFullTypeName(reader).FullName;
if (handle.IsEnum(reader, out var typeCode))
return (typeCode, "enum " + fullTypeName);
return (0, fullTypeName);
}
public (PrimitiveTypeCode, string) GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)
{
throw new NotImplementedException();
string fullTypeName = handle.GetFullTypeName(reader).FullName;
var containingModule = GetDeclaringModule(handle);
string assemblyQualifiedTypeName = containingModule != null
? fullTypeName + ", " + containingModule
: fullTypeName;
PrimitiveTypeCode typeCode = 0;
var (targetModule, resolvedType) = ResolveType(assemblyQualifiedTypeName, module);
if (targetModule != null)
{
if (!resolvedType.IsEnum(targetModule.Metadata, out typeCode))
{
typeCode = 0;
}
else
{
assemblyQualifiedTypeName = "enum " + assemblyQualifiedTypeName;
}
}
return (typeCode, assemblyQualifiedTypeName);
string GetDeclaringModule(TypeReferenceHandle handle)
{
var tr = reader.GetTypeReference(handle);
switch (tr.ResolutionScope.Kind)
{
case HandleKind.TypeReference:
return GetDeclaringModule((TypeReferenceHandle)tr.ResolutionScope);
case HandleKind.AssemblyReference:
var asmRef = reader.GetAssemblyReference((AssemblyReferenceHandle)tr.ResolutionScope);
return asmRef.TryGetFullAssemblyName(reader, out var assemblyName) ? assemblyName : null;
case HandleKind.ModuleReference:
var modRef = reader.GetModuleReference((ModuleReferenceHandle)tr.ResolutionScope);
return reader.GetString(modRef.Name);
default:
return null;
}
}
}
public (PrimitiveTypeCode, string) GetTypeFromSerializedName(string name)
@ -608,17 +656,6 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -608,17 +656,6 @@ namespace ICSharpCode.Decompiler.Disassembler
}
}
PrimitiveTypeCode ResolveEnumUnderlyingType(string typeName, PEFile module)
{
if (typeName.StartsWith("enum ", StringComparison.Ordinal))
typeName = typeName.Substring(5);
var (containingModule, typeDefHandle) = ResolveType(typeName, module);
if (typeDefHandle.IsNil || !typeDefHandle.IsEnum(containingModule.Metadata, out var typeCode))
throw new EnumUnderlyingTypeResolveException();
return typeCode;
}
MetadataFile mscorlib;
bool TryResolveMscorlib(out MetadataFile mscorlib)
@ -704,7 +741,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -704,7 +741,7 @@ namespace ICSharpCode.Decompiler.Disassembler
}
output.Write(argument.Type.Name ?? PrimitiveTypeCodeToString(argument.Type.Code));
output.Write(" " + argument.Name + " = ");
output.Write(" " + DisassemblerHelpers.Escape(argument.Name) + " = ");
WriteValue(output, argument.Type, argument.Value);
output.WriteLine();
@ -1824,12 +1861,62 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1824,12 +1861,62 @@ namespace ICSharpCode.Decompiler.Disassembler
if (!attr.Value.IsNil)
{
output.Write(" = ");
WriteBlob(attr.Value, metadata);
if (DecodeCustomAttributeBlobs)
WriteDecodedCustomAttributeBlob(attr, module);
else
WriteBlob(attr.Value, metadata);
}
output.WriteLine();
}
}
void WriteDecodedCustomAttributeBlob(CustomAttribute attr, MetadataFile module)
{
CustomAttributeValue<(PrimitiveTypeCode Code, string Name)> value;
try
{
var provider = new SecurityDeclarationDecoder(output, AssemblyResolver, module);
value = attr.DecodeValue(provider);
}
catch (BadImageFormatException)
{
output.Write("/* Could not decode attribute value */ ");
WriteBlob(attr.Value, module.Metadata);
return;
}
output.Write("{");
output.Indent();
foreach (var arg in value.FixedArguments)
{
output.WriteLine();
WriteValue(output, arg.Type, arg.Value);
}
foreach (var arg in value.NamedArguments)
{
output.WriteLine();
switch (arg.Kind)
{
case CustomAttributeNamedArgumentKind.Field:
output.Write("field ");
break;
case CustomAttributeNamedArgumentKind.Property:
output.Write("property ");
break;
}
output.Write(arg.Type.Name ?? PrimitiveTypeCodeToString(arg.Type.Code));
output.Write(" " + DisassemblerHelpers.Escape(arg.Name) + " = ");
WriteValue(output, arg.Type, arg.Value);
}
output.WriteLine();
output.Unindent();
output.Write("}");
}
void WriteBlob(BlobHandle blob, MetadataReader metadata)
{
var reader = metadata.GetBlobReader(blob);
@ -1839,23 +1926,26 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1839,23 +1926,26 @@ namespace ICSharpCode.Decompiler.Disassembler
void WriteBlob(BlobReader reader)
{
output.Write("(");
output.Indent();
for (int i = 0; i < reader.Length; i++)
if (reader.Length > 0)
{
if (i % 16 == 0 && i < reader.Length - 1)
{
output.WriteLine();
}
else
output.Indent();
for (int i = 0; i < reader.Length; i++)
{
output.Write(' ');
if (i % 16 == 0 && i < reader.Length - 1)
{
output.WriteLine();
}
else
{
output.Write(' ');
}
output.Write(reader.ReadByte().ToString("x2"));
}
output.Write(reader.ReadByte().ToString("x2"));
}
output.WriteLine();
output.Unindent();
output.WriteLine();
output.Unindent();
}
output.Write(")");
}

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

@ -28,6 +28,7 @@ using Humanizer.Inflections; @@ -28,6 +28,7 @@ using Humanizer.Inflections;
using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.CSharp.OutputVisitor;
using ICSharpCode.Decompiler.CSharp.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.Decompiler.Util;
@ -110,6 +111,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -110,6 +111,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms
currentLowerCaseTypeOrMemberNames.Add(name);
AddExistingName(reservedVariableNames, name);
}
foreach (var name in CollectAllLowerCaseTypeNames(context.UsingScope))
{
currentLowerCaseTypeOrMemberNames.Add(name);
AddExistingName(reservedVariableNames, name);
}
this.currentLowerCaseTypeOrMemberNames = currentLowerCaseTypeOrMemberNames.ToImmutableHashSet();
// handle implicit parameters of set or event accessors
@ -618,6 +624,21 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -618,6 +624,21 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (IsLowerCase(item.Name))
yield return item.Name;
}
var current = type;
while (current != null)
{
foreach (var nested in current.NestedTypes)
{
if (IsLowerCase(nested.Name))
yield return nested.Name;
}
current = current.DeclaringTypeDefinition;
}
}
static IEnumerable<string> CollectAllLowerCaseTypeNames(UsingScope usingScope)
{
return usingScope?.Usings.SelectMany(n => n.Types).Select(t => t.Name).Where(IsLowerCase) ?? [];
}
static bool IsLowerCase(string name)
@ -870,7 +891,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -870,7 +891,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
static Dictionary<string, int> CollectReservedVariableNames(ILFunction function,
ILVariable existingVariable, bool mustResolveConflicts)
ILVariable existingVariable, bool mustResolveConflicts, UsingScope usingScope)
{
var reservedVariableNames = new Dictionary<string, int>();
var rootFunction = function.Ancestors.OfType<ILFunction>().Single(f => f.Parent == null);
@ -889,14 +910,15 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -889,14 +910,15 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (mustResolveConflicts)
{
var memberNames = CollectAllLowerCaseMemberNames(function.Method.DeclaringTypeDefinition)
.Concat(CollectAllLowerCaseTypeNames(function.Method.DeclaringTypeDefinition));
.Concat(CollectAllLowerCaseTypeNames(function.Method.DeclaringTypeDefinition))
.Concat(CollectAllLowerCaseTypeNames(usingScope));
foreach (var name in memberNames)
AddExistingName(reservedVariableNames, name);
}
return reservedVariableNames;
}
internal static string GenerateForeachVariableName(ILFunction function, ILInstruction valueContext,
internal static string GenerateForeachVariableName(ILFunction function, ILInstruction valueContext, UsingScope usingScope,
ILVariable existingVariable = null, bool mustResolveConflicts = false)
{
if (function == null)
@ -905,7 +927,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -905,7 +927,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{
return existingVariable.Name;
}
var reservedVariableNames = CollectReservedVariableNames(function, existingVariable, mustResolveConflicts);
var reservedVariableNames = CollectReservedVariableNames(function, existingVariable, mustResolveConflicts, usingScope);
string baseName = GetNameFromInstruction(valueContext);
if (string.IsNullOrEmpty(baseName))
@ -955,13 +977,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -955,13 +977,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
}
internal static string GenerateVariableName(ILFunction function, IType type,
internal static string GenerateVariableName(ILFunction function, IType type, UsingScope usingScope,
ILInstruction valueContext = null, ILVariable existingVariable = null,
bool mustResolveConflicts = false)
{
if (function == null)
throw new ArgumentNullException(nameof(function));
var reservedVariableNames = CollectReservedVariableNames(function, existingVariable, mustResolveConflicts);
var reservedVariableNames = CollectReservedVariableNames(function, existingVariable, mustResolveConflicts, usingScope);
string baseName = valueContext != null ? GetNameFromInstruction(valueContext) ?? GetNameByType(type) : GetNameByType(type);
string proposedName = "obj";

7
ICSharpCode.Decompiler/IL/Transforms/LocalFunctionDecompiler.cs

@ -566,13 +566,18 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -566,13 +566,18 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
internal static bool IsClosureParameter(IParameter parameter, ITypeResolveContext context)
{
return IsClosureParameter(parameter, context.CurrentTypeDefinition);
}
internal static bool IsClosureParameter(IParameter parameter, ITypeDefinition currentTypeDefinition)
{
if (parameter.Type is not ByReferenceType brt)
return false;
var type = brt.ElementType.GetDefinition();
return type != null
&& type.Kind == TypeKind.Struct
&& TransformDisplayClassUsage.IsPotentialClosure(context.CurrentTypeDefinition, type);
&& TransformDisplayClassUsage.IsPotentialClosure(currentTypeDefinition, type);
}
LocalFunctionMethod ReduceToLocalFunction(IMethod method, int typeParametersToRemove)

8
ICSharpCode.Decompiler/IL/Transforms/TransformCollectionAndObjectInitializers.cs

@ -69,6 +69,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -69,6 +69,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms
// anon = new { A = 5 } { 3,4,5 } is invalid syntax.
if (newObjInst.Method.DeclaringType.ContainsAnonymousType())
return;
// Tuples cannot have initializers
if (TupleTransform.MatchTupleConstruction(newObjInst, out _))
return;
instType = newObjInst.Method.DeclaringType;
break;
case DefaultValue defaultVal:
@ -97,6 +100,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -97,6 +100,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
return;
}
// Copy-propagate stack slot holding an 'ldloca' of the variable
if (pos < block.Instructions.Count && block.Instructions[pos + 1] is StLoc { Variable: { Kind: VariableKind.StackSlot, IsSingleDefinition: true }, Value: LdLoca ldLoca } stLocStack && ldLoca.Variable == v)
{
CopyPropagation.Propagate(stLocStack, context);
}
int initializerItemsCount = 0;
bool initializerContainsInitOnlyItems = false;
possibleIndexVariables.Clear();

23
ICSharpCode.Decompiler/IL/Transforms/TransformDisplayClassUsage.cs

@ -716,13 +716,26 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -716,13 +716,26 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return false;
}
while (potentialDisplayClass != decompiledTypeDefinition)
// Make sure that potentialDisplayCLass and decompiledTypeDefinition are part of the same type tree
// Either decompiledTypeDefinition is an ancestor type of potentialDisplayClass or both have
// at least one common ancestor.
var potentialDisplayClassAncestors = new HashSet<ITypeDefinition>();
var potentialDisplayClassParent = potentialDisplayClass.DeclaringTypeDefinition;
while (potentialDisplayClassParent != null)
{
potentialDisplayClass = potentialDisplayClass.DeclaringTypeDefinition;
if (potentialDisplayClass == null)
return false;
potentialDisplayClassAncestors.Add(potentialDisplayClassParent);
potentialDisplayClassParent = potentialDisplayClassParent.DeclaringTypeDefinition;
}
return true;
var decompiledTypeDefinitionOrAncestor = decompiledTypeDefinition;
while (decompiledTypeDefinitionOrAncestor != null)
{
if (potentialDisplayClassAncestors.Contains(decompiledTypeDefinitionOrAncestor))
return true;
decompiledTypeDefinitionOrAncestor = decompiledTypeDefinitionOrAncestor.DeclaringTypeDefinition;
}
return false;
}
readonly Stack<ILFunction> currentFunctions = new Stack<ILFunction>();

18
ICSharpCode.Decompiler/Metadata/DotNetCorePathFinderExtensions.cs

@ -100,16 +100,24 @@ namespace ICSharpCode.Decompiler.Metadata @@ -100,16 +100,24 @@ namespace ICSharpCode.Decompiler.Metadata
// 4.2.0 => .NET Core 2.0
// 4.2.1 => .NET Core 2.1 / 3.0
// 4.2.2 => .NET Core 3.1
// 5.0.0+ => .NET 5+
if (r.Version >= new Version(4, 2, 0))
{
version = "2.0";
if (r.Version >= new Version(4, 2, 1))
if (r.Version.Major >= 5)
{
version = "3.0";
version = r.Version.ToString(2);
}
if (r.Version >= new Version(4, 2, 2))
else if (r.Version.Major == 4 && r.Version.Minor == 2)
{
version = "3.1";
version = r.Version.Build switch {
<= 0 => "2.0",
1 => "3.0",
_ => "3.1"
};
}
else
{
version = "2.0";
}
return $".NETCoreApp,Version=v{version}";
}

19
ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs

@ -210,25 +210,6 @@ namespace ICSharpCode.Decompiler.Metadata @@ -210,25 +210,6 @@ namespace ICSharpCode.Decompiler.Metadata
return Disassembler.DisassemblerHelpers.Escape(name);
}
[Obsolete("Use MetadataModule.GetDeclaringModule() instead")]
public static IModuleReference GetDeclaringModule(this TypeReferenceHandle handle, MetadataReader reader)
{
var tr = reader.GetTypeReference(handle);
switch (tr.ResolutionScope.Kind)
{
case HandleKind.TypeReference:
return ((TypeReferenceHandle)tr.ResolutionScope).GetDeclaringModule(reader);
case HandleKind.AssemblyReference:
var asmRef = reader.GetAssemblyReference((AssemblyReferenceHandle)tr.ResolutionScope);
return new DefaultAssemblyReference(reader.GetString(asmRef.Name));
case HandleKind.ModuleReference:
var modRef = reader.GetModuleReference((ModuleReferenceHandle)tr.ResolutionScope);
return new DefaultAssemblyReference(reader.GetString(modRef.Name));
default:
return DefaultAssemblyReference.CurrentAssembly;
}
}
internal static readonly TypeProvider minimalCorlibTypeProvider =
new TypeProvider(new SimpleCompilation(MinimalCorlib.Instance));

23
ICSharpCode.Decompiler/Metadata/PropertyAndEventBackingFieldLookup.cs

@ -37,6 +37,8 @@ namespace ICSharpCode.Decompiler.Metadata @@ -37,6 +37,8 @@ namespace ICSharpCode.Decompiler.Metadata
var nameToFieldMap = new MultiDictionary<string, FieldDefinitionHandle>();
HashSet<string> eventNames = new();
foreach (var tdh in metadata.TypeDefinitions)
{
var type = metadata.GetTypeDefinition(tdh);
@ -72,6 +74,16 @@ namespace ICSharpCode.Decompiler.Metadata @@ -72,6 +74,16 @@ namespace ICSharpCode.Decompiler.Metadata
}
}
// first get all names of events defined, so that we can make sure we don't accidentally
// associate the wrong backing field with the event, in case there is an event called "Something"
// without a backing field (i.e., custom event) as well as an auto/field event called "SomethingEvent"
// declared in the same type.
foreach (var edh in type.GetEvents())
{
var ev = metadata.GetEventDefinition(edh);
eventNames.Add(metadata.GetString(ev.Name));
}
foreach (var edh in type.GetEvents())
{
var ev = metadata.GetEventDefinition(edh);
@ -83,15 +95,20 @@ namespace ICSharpCode.Decompiler.Metadata @@ -83,15 +95,20 @@ namespace ICSharpCode.Decompiler.Metadata
eventLookup[fieldHandle] = edh;
}
}
else if (nameToFieldMap.TryGetValues($"{name}Event", out fieldHandles))
else
{
foreach (var fieldHandle in fieldHandles)
var nameWithSuffix = $"{name}Event";
if (!eventNames.Contains(nameWithSuffix) && nameToFieldMap.TryGetValues(nameWithSuffix, out fieldHandles))
{
eventLookup[fieldHandle] = edh;
foreach (var fieldHandle in fieldHandles)
{
eventLookup[fieldHandle] = edh;
}
}
}
}
eventNames.Clear();
nameToFieldMap.Clear();
}
}

6
ICSharpCode.Decompiler/Output/TextTokenWriter.cs

@ -22,12 +22,12 @@ using System.Linq; @@ -22,12 +22,12 @@ using System.Linq;
using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.CSharp.OutputVisitor;
using ICSharpCode.Decompiler.CSharp.Resolver;
using ICSharpCode.Decompiler.CSharp.Syntax;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Semantics;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler
{
@ -255,7 +255,7 @@ namespace ICSharpCode.Decompiler @@ -255,7 +255,7 @@ namespace ICSharpCode.Decompiler
}
if (braceLevelWithinType >= 0 || nodeStack.Peek() is TypeDeclaration)
braceLevelWithinType++;
if (nodeStack.OfType<BlockStatement>().Count() <= 1 || settings.FoldBraces)
if (nodeStack.PeekOrDefault() is TypeDeclaration or BlockStatement { Parent: EntityDeclaration or LocalFunctionDeclarationStatement or AnonymousMethodExpression or LambdaExpression } || settings.FoldBraces)
{
output.MarkFoldStart(defaultCollapsed: !settings.ExpandMemberDefinitions && braceLevelWithinType == 1, isDefinition: braceLevelWithinType == 1);
}
@ -265,7 +265,7 @@ namespace ICSharpCode.Decompiler @@ -265,7 +265,7 @@ namespace ICSharpCode.Decompiler
output.Write('}');
if (role != Roles.RBrace)
break;
if (nodeStack.OfType<BlockStatement>().Count() <= 1 || settings.FoldBraces)
if (nodeStack.PeekOrDefault() is TypeDeclaration or BlockStatement { Parent: EntityDeclaration or LocalFunctionDeclarationStatement or AnonymousMethodExpression or LambdaExpression } || settings.FoldBraces)
output.MarkFoldEnd();
if (braceLevelWithinType >= 0)
braceLevelWithinType--;

61
ICSharpCode.Decompiler/TypeSystem/ExtensionInfo.cs

@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Metadata;
@ -37,11 +38,21 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -37,11 +38,21 @@ namespace ICSharpCode.Decompiler.TypeSystem
var metadata = module.MetadataFile.Metadata;
foreach (var extGroup in extensionContainer.NestedTypes)
{
if (TryEncodingV1(extGroup))
{
continue;
}
TryEncodingV2(extGroup);
}
bool TryEncodingV1(ITypeDefinition extGroup)
{
if (!(extGroup is { Kind: TypeKind.Class, IsSealed: true }
&& extGroup.Name.StartsWith("<>E__", System.StringComparison.Ordinal)))
{
continue;
return false;
}
TypeDefinition td = metadata.GetTypeDefinition((TypeDefinitionHandle)extGroup.MetadataToken);
@ -69,8 +80,53 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -69,8 +80,53 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
if (marker == null || hasMultipleMarkers)
continue;
return false;
CollectImplementationMethods(extGroup, marker, extensionMethods);
return true;
}
bool TryEncodingV2(ITypeDefinition extGroup)
{
if (!(extGroup is { Kind: TypeKind.Class, IsSealed: true }
&& extGroup.Name.StartsWith("<G>$", StringComparison.Ordinal)))
{
return false;
}
var markerType = extGroup.NestedTypes.SingleOrDefault(t => t.Name.StartsWith("<M>$", StringComparison.Ordinal) && t.IsStatic);
var marker = markerType?.Methods.SingleOrDefault(m => m.Name == "<Extension>$" && m.IsStatic && m.Parameters.Count == 1);
if (markerType == null || marker == null)
return false;
TypeDefinition td = metadata.GetTypeDefinition((TypeDefinitionHandle)extGroup.MetadataToken);
List<IMethod> extensionMethods = [];
// For easier access to accessors we use SRM
foreach (var h in td.GetMethods())
{
var method = module.GetDefinition(h);
if (method.SymbolKind is SymbolKind.Constructor)
continue;
var attribute = method.GetAttribute(KnownAttribute.ExtensionMarker);
if (attribute == null)
continue;
if (attribute.FixedArguments[0].Value?.ToString() != markerType.Name)
continue;
extensionMethods.Add(method);
}
CollectImplementationMethods(extGroup, marker, extensionMethods);
return true;
}
void CollectImplementationMethods(ITypeDefinition extGroup, IMethod marker, List<IMethod> extensionMethods)
{
foreach (var extension in extensionMethods)
{
int expectedTypeParameterCount = extension.TypeParameters.Count + extGroup.TypeParameterCount;
@ -119,7 +175,6 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -119,7 +175,6 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
}
}
}
public ExtensionMemberInfo? InfoOfExtensionMember(IMethod method)

9
ICSharpCode.Decompiler/TypeSystem/Implementation/KnownAttributes.cs

@ -112,15 +112,18 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -112,15 +112,18 @@ namespace ICSharpCode.Decompiler.TypeSystem
PreserveBaseOverrides,
// C# 11 attributes:
RequiredAttribute,
Required,
// C# 12 attributes:
InlineArray,
// C# 14 attributes:
ExtensionMarker,
}
public static class KnownAttributes
{
internal const int Count = (int)KnownAttribute.InlineArray + 1;
internal const int Count = (int)KnownAttribute.ExtensionMarker + 1;
static readonly TopLevelTypeName[] typeNames = new TopLevelTypeName[Count]{
default,
@ -193,6 +196,8 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -193,6 +196,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
new TopLevelTypeName("System.Runtime.CompilerServices", "RequiredMemberAttribute"),
// C# 12 attributes:
new TopLevelTypeName("System.Runtime.CompilerServices", "InlineArrayAttribute"),
// C# 14 attributes:
new TopLevelTypeName("System.Runtime.CompilerServices", "ExtensionMarkerAttribute"),
};
public static ref readonly TopLevelTypeName GetTypeName(this KnownAttribute attr)

4
ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs

@ -21,6 +21,7 @@ using System.Collections.Generic; @@ -21,6 +21,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection.Metadata;
using ICSharpCode.Decompiler.IL.Transforms;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.Semantics;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
@ -681,6 +682,9 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -681,6 +682,9 @@ namespace ICSharpCode.Decompiler.TypeSystem
if (otherParameter == parameter)
break;
if (LocalFunctionDecompiler.IsClosureParameter(otherParameter, otherParameter.Owner.DeclaringTypeDefinition))
continue;
if (DefaultValueAssignmentAllowedIndividual(otherParameter) || otherParameter.IsParams)
continue;

344
ICSharpCode.ILSpyCmd/packages.lock.json

@ -15,32 +15,32 @@ @@ -15,32 +15,32 @@
},
"Microsoft.Extensions.Hosting": {
"type": "Direct",
"requested": "[10.0.0-preview.7.25380.108, )",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "VcqnTGY8bMnFxZQb3cjcXnXy4x7dJgp85UlujErNh34xh4ZislQ2XhX7ak0gUnRh8c9ZTI3xj4groyqBl/DNHA==",
"dependencies": {
"Microsoft.Extensions.Configuration": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Configuration.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Configuration.Binder": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Configuration.CommandLine": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Configuration.FileExtensions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Configuration.Json": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Configuration.UserSecrets": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.DependencyInjection": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Diagnostics": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.FileProviders.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.FileProviders.Physical": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Hosting.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Logging": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Logging.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Logging.Configuration": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Logging.Console": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Logging.Debug": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Logging.EventLog": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Logging.EventSource": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Options": "10.0.0-preview.7.25380.108"
"requested": "[10.0.0-rc.1.25451.107, )",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "MSxUXg8ZrySaprKTWT/nPXHo1JW9TcLuTb0E3DtQ0DRK8KJKkYJhvvbLWKHUZ/vyvMcL4Msp0jbnZQ4ywTdWdQ==",
"dependencies": {
"Microsoft.Extensions.Configuration": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Configuration.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Configuration.Binder": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Configuration.CommandLine": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Configuration.FileExtensions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Configuration.Json": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Configuration.UserSecrets": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.DependencyInjection": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Diagnostics": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.FileProviders.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.FileProviders.Physical": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Hosting.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Logging": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Logging.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Logging.Configuration": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Logging.Console": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Logging.Debug": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Logging.EventLog": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Logging.EventSource": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Options": "10.0.0-rc.1.25451.107"
}
},
"NuGet.Protocol": {
@ -54,240 +54,240 @@ @@ -54,240 +54,240 @@
},
"System.Security.Cryptography.Pkcs": {
"type": "Direct",
"requested": "[9.0.8, )",
"resolved": "9.0.8",
"contentHash": "+mtc8dZnrP9N1HZICncBzLUrX4YBP+WvAWb817auAA5mKOJzHZShuGpCtQiekgV/7N0uS/x0LkdBAezBcSBwVA=="
"requested": "[9.0.9, )",
"resolved": "9.0.9",
"contentHash": "Y7/wY5lqrzJOu53yLFLPGaeKBcdWNw193udOFRB2joFDVpXLkmfPpfgks7dEIJYPIrW4k3onwR+4nQz6vIaaqA=="
},
"TomsToolbox.Composition.Analyzer": {
"type": "Direct",
"requested": "[2.22.1, )",
"resolved": "2.22.1",
"contentHash": "bKcte9zaz+xH1k6C1YIYpheQ9mPNRSmd0dHQIEIq31KxAKMTLfiAo80aROKDJMYJ7ZomlUjjSMo/QCIikMMWTg=="
"requested": "[2.22.2, )",
"resolved": "2.22.2",
"contentHash": "7gYo8ZR2eq3XkrilvUpLbTypeZy6IlD5FB8jah0YPhMOmDGhya4jJ3kfDMTTRt5m258Ou78P69mHMkG6DKZXsg=="
},
"Microsoft.Extensions.Configuration.Abstractions": {
"type": "Transitive",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "Tos2R09p02UbSg97w7QNr+dNTKuBtmsWKy4+awTnn2d34CXDpsKkAdDis6gLmhuCjz4c0HyB5S0l2ahaqu+u7A==",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "NOCQeNLsBMq0rdmZAWMWMEepO+/4iV6zBO2iyOBAzwtR1kZCVjrm/p4Z2Vda7IycOLEJKkcXfjN+oeqXH8mcFw==",
"dependencies": {
"Microsoft.Extensions.Primitives": "10.0.0-preview.7.25380.108"
"Microsoft.Extensions.Primitives": "10.0.0-rc.1.25451.107"
}
},
"Microsoft.Extensions.Configuration.Binder": {
"type": "Transitive",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "BAcZtIevY+MgiTX9t9iuz8CoYmGPoL1QeAlhNav8EVJmNlhKR/H7nESjxJifejcCRuwQ+dcXlFtHo1xrCMaZWA==",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "leKQmXsApCae6Mp65B29INCh3IFEALvpvKNAmcNV1GcwgAxZaDFVS6WbOQegkYLvTAX2G3DT5KE0skI8jy1kig==",
"dependencies": {
"Microsoft.Extensions.Configuration": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Configuration.Abstractions": "10.0.0-preview.7.25380.108"
"Microsoft.Extensions.Configuration": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Configuration.Abstractions": "10.0.0-rc.1.25451.107"
}
},
"Microsoft.Extensions.Configuration.CommandLine": {
"type": "Transitive",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "wrRFfwx7avg204vRHD1C7//zo9axtSLqNydbPXVN6r1tpQUsTz2Mbd6QsYMo+zoNUSvFD7fPFZPsG8pkmbX50A==",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "oIrzvbO70HUqC4rkzoc44Qt/sRr+RGECOHH1ju5iNDVfLLZS/GVNyKf9dqcrLhuqotmasIsqyjWktzVkJdYbWQ==",
"dependencies": {
"Microsoft.Extensions.Configuration": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Configuration.Abstractions": "10.0.0-preview.7.25380.108"
"Microsoft.Extensions.Configuration": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Configuration.Abstractions": "10.0.0-rc.1.25451.107"
}
},
"Microsoft.Extensions.Configuration.EnvironmentVariables": {
"type": "Transitive",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "bIh84M0Clp94aGE827+cw3Ld3E+LN68Goqk1oyHTAkOMftp3YbkGB/yEHGdydsNEi3kfiLw5lZdu3Nh1Agt9gg==",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "uWgOErLi+EWXVFPFklgJ3NO4wgG6K5XxahCP248jktCOR4pgDymW8bLIIPZAyQXEX7tJ0qUoh/+SXudml56ecw==",
"dependencies": {
"Microsoft.Extensions.Configuration": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Configuration.Abstractions": "10.0.0-preview.7.25380.108"
"Microsoft.Extensions.Configuration": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Configuration.Abstractions": "10.0.0-rc.1.25451.107"
}
},
"Microsoft.Extensions.Configuration.FileExtensions": {
"type": "Transitive",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "eGgKM6UgrXTTGNDkPsXE4gofRMK+LPv2PIzMRUOVFLB2iAjoVhSgTTDBiQgVSXZW279FCaoILD8wC7zz5+sZBA==",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "gZO0j5JQjHy+CoBO7XRz4m5DhB16FOJsZIMj328xA/xSHhU6qK0xC2iboeC11W4MDKTukfnaj+yCtAtfHTcHkA==",
"dependencies": {
"Microsoft.Extensions.Configuration": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Configuration.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.FileProviders.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.FileProviders.Physical": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Primitives": "10.0.0-preview.7.25380.108"
"Microsoft.Extensions.Configuration": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Configuration.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.FileProviders.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.FileProviders.Physical": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Primitives": "10.0.0-rc.1.25451.107"
}
},
"Microsoft.Extensions.Configuration.UserSecrets": {
"type": "Transitive",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "X6M5ARSre9pHhQcrdIoPGCrGe2Xh6iM4AYwJGXRrgG6+blFTc04Iau7tvnjOhCDaEFr2g2cxMJI1wiLlJFOECg==",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "wHLjtFft+I8raeZ+ZEVMlWNlh67IIfbNKd+mdQ5D38crV9b7m3QgK3DwK2YAgYOGLgP44qrYweuoi6zSvUEklw==",
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Configuration.Json": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.FileProviders.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.FileProviders.Physical": "10.0.0-preview.7.25380.108"
"Microsoft.Extensions.Configuration.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Configuration.Json": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.FileProviders.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.FileProviders.Physical": "10.0.0-rc.1.25451.107"
}
},
"Microsoft.Extensions.DependencyInjection": {
"type": "Transitive",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "UVMEx1ZOOugXCNxXARPsmtu7B3RzYShFoeGvmO4wA1OmcW8cOSXr7QNTiCTp3uXNrx14daefmDX/BlsExlZyVg==",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "LyE1mwZNT30J/6ygkZZm6QlDRaKpwQf5dHkREGAlJQr75kz1VGx0RI/cxa6kevnuYaLNE5UtgtGT2Amp+dFT1Q==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0-preview.7.25380.108"
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0-rc.1.25451.107"
}
},
"Microsoft.Extensions.Diagnostics": {
"type": "Transitive",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "hbUpAah1f1gSx7NT7GKnmnzdQiP6POB7Mo8HNGZQ5qdcsZm6c3e6toK92u4kMkgJ9Cp0mRgL2wIyDfT6ixS/qw==",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "tuZIsk+xd+/jdBOhfjtJMnjnl6qNitUrx6WO7qUUCyJ5vMZiEaDW0XXdVWtvefUs08inp6fdYoL0+PBlHCtrAQ==",
"dependencies": {
"Microsoft.Extensions.Configuration": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Diagnostics.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Options.ConfigurationExtensions": "10.0.0-preview.7.25380.108"
"Microsoft.Extensions.Configuration": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Diagnostics.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Options.ConfigurationExtensions": "10.0.0-rc.1.25451.107"
}
},
"Microsoft.Extensions.Diagnostics.Abstractions": {
"type": "Transitive",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "4KCRTDM1TUA1+zwUBefsM9vjCRzAjkhLOsITu5X/z8GxdwxvhVRQL3svELII4AwcWG2PUvAqWHIGnjmKlYJmIQ==",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "rskaFEs+RNVX8AXFeC3QqjS9O5cMjYsyHLGt/3SV5IYXIJdIA+iy3W8/fVsJED0ydkssEkftewhiTCOqh1DM3w==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Options": "10.0.0-preview.7.25380.108"
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Options": "10.0.0-rc.1.25451.107"
}
},
"Microsoft.Extensions.FileProviders.Abstractions": {
"type": "Transitive",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "lvXcu7o7ETZ0SRPTOMhMuzyABFSiTwQdye1ATqdQH4u0n46s0QtTMN8u8zrHdIDtU5zv8hv3PqnOmmQt6lMzEQ==",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "/Fi7B/NuEG5XMc80bHXb33ZO8SykBMcwOhZFygmNQ0SvmOUFD41M4XEtF27kmII73p1C4U84LWidkMZyvELmBw==",
"dependencies": {
"Microsoft.Extensions.Primitives": "10.0.0-preview.7.25380.108"
"Microsoft.Extensions.Primitives": "10.0.0-rc.1.25451.107"
}
},
"Microsoft.Extensions.FileProviders.Physical": {
"type": "Transitive",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "CCWJM/f0hEldsKdB+QXJpcyELI0VRHbIuWWejCk9pNQBTuPOJHX5Lxsn4Lt8d30DGosTfkAQWLpy/wh+TGT6xA==",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "EdAkxAb8BQO6GI6NijKj7SYj79j7OOQlRCVJfyjw+6YvVBepery5gAUieu05ig4o4CYlpvie4xzmYoHiCN/6dQ==",
"dependencies": {
"Microsoft.Extensions.FileProviders.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.FileSystemGlobbing": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Primitives": "10.0.0-preview.7.25380.108"
"Microsoft.Extensions.FileProviders.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.FileSystemGlobbing": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Primitives": "10.0.0-rc.1.25451.107"
}
},
"Microsoft.Extensions.FileSystemGlobbing": {
"type": "Transitive",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "HsDTy1yAhOyznpgtbaUpiHojeMDrmkwAI/iW6G9PksLfhJAFXT1PffKoWMG2+fS4rWo6yoaro2cmJH0RYBKJ0Q=="
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "EgPqaVLU+duTIlONHfipkTt0xtNZlHgta54QUj5nrXb7pY4rPMwgYExwxbjM9xGJ3lIMjp5H/zkKii55aZk9Sg=="
},
"Microsoft.Extensions.Hosting.Abstractions": {
"type": "Transitive",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "J6zRebs9tVxWat6q3Z8v1fknqYhUbyUVoZYiGqhu7g+ChVYeCdp/YL2qSvC/Ap/KThXu6+C+R40gdDPCjUq5EQ==",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "lfe8ZALjb5z95IUadn/NBPdqvPG1XX7UbBuRbtPu9al6RwrbQnVq5Sq+tQ7PTPxNh5WABtcnFbNnuc9MpAWypQ==",
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Diagnostics.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.FileProviders.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Logging.Abstractions": "10.0.0-preview.7.25380.108"
"Microsoft.Extensions.Configuration.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Diagnostics.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.FileProviders.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Logging.Abstractions": "10.0.0-rc.1.25451.107"
}
},
"Microsoft.Extensions.Logging": {
"type": "Transitive",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "vktcXpKfaF3TEC5OoAv2ySdImeBErcbFwUduuFIGvKOdYGw1B1N8ZpG5GLxApMXFgygdMcAFrkotDWzOF1npUA==",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "XKPlZZoN7eZjtpaincJm60Il2k5tBxuOfeT3w6gXcTNL5dM1tOR80hzDQaBIikyxI3uBApKtTU1Vge7In3W8Kg==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Logging.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Options": "10.0.0-preview.7.25380.108"
"Microsoft.Extensions.DependencyInjection": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Logging.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Options": "10.0.0-rc.1.25451.107"
}
},
"Microsoft.Extensions.Logging.Abstractions": {
"type": "Transitive",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "qfx62EG7wvjym/GusNX+kzqPByIVYiXyqBYaObQlIch5YukiVd4ovUJHALYt11jpcxpv9nmjgmqahIluf2j5xA==",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "RwlHkxMbkgvKs5m0jfguF+a6nZH1qaJVC63cSAODNLMVyX22VumSWwDBgnzFTB3oUHfOnQgLmtEK1U/eEQRLLQ==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0-preview.7.25380.108"
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0-rc.1.25451.107"
}
},
"Microsoft.Extensions.Logging.Configuration": {
"type": "Transitive",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "nfivpgjltKnYWCT62WtNgaRyyTv92nRYkqJabEQIvmtlQrjuYNb/kiECy74+jd4t4AQPx3hlPn9hWiLGvIEHhg==",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "Pv+5gS1QQJ3/RgfoQR9qFXbExFerQfcsWWYSkZSBmq0X6FmaM/HYHeb9epAfpWYagbBCM6QwSqltMG8uJZLMdg==",
"dependencies": {
"Microsoft.Extensions.Configuration": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Configuration.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Configuration.Binder": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Logging": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Logging.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Options": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Options.ConfigurationExtensions": "10.0.0-preview.7.25380.108"
"Microsoft.Extensions.Configuration": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Configuration.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Configuration.Binder": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Logging": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Logging.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Options": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Options.ConfigurationExtensions": "10.0.0-rc.1.25451.107"
}
},
"Microsoft.Extensions.Logging.Console": {
"type": "Transitive",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "VfOeXETfctJamiTwovg1SmyfEboi8klawzpE6hv45f8KPajn/PPTuYRCQjaQWiP0praYdAJWrV4TjvDF0+xxeg==",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "0o2U5BuYJFt6c2XwOpfSEb5knaSgKwpYi1Jm7+CU1IlTFvyA5ddjLBmUm/dJmzWiWnoFvUJvsvPvLQYWCxGiDg==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Logging": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Logging.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Logging.Configuration": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Options": "10.0.0-preview.7.25380.108"
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Logging": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Logging.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Logging.Configuration": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Options": "10.0.0-rc.1.25451.107"
}
},
"Microsoft.Extensions.Logging.Debug": {
"type": "Transitive",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "R1XFfHifpXKXtIGDt/QrvwnqPEOMEMdDppBMVjb5UpI3RSBKriTWdKeaJIcc1gx6e56aVO2xOT3EtfnK6Xb3Ig==",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "HMpGwPNYt7M5XVSFkc8Y76CzLXvrM7AnyFgyDGfynhYvmX4MH2eT3w7c6eOb390WQcsNGkTGgZnb6QlaEwm9QA==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Logging": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Logging.Abstractions": "10.0.0-preview.7.25380.108"
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Logging": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Logging.Abstractions": "10.0.0-rc.1.25451.107"
}
},
"Microsoft.Extensions.Logging.EventLog": {
"type": "Transitive",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "pa6ggb9nqfU+DPLI2NXRaUDmkrw3mvmXcnh4NQrgcvzNQPB1PW8HySNm+KvzX/nK/UmPtJEa3NbOhmpDBdrbMA==",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "s2k2ihzSGm2lCGvc4Az3zJoijNPZ9xrT6U+ORj9T4rocLCSxe/21MKqxcjInJvVZgTn7HWpJomFw5qcJz+HXYg==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Logging": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Logging.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Options": "10.0.0-preview.7.25380.108",
"System.Diagnostics.EventLog": "10.0.0-preview.7.25380.108"
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Logging": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Logging.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Options": "10.0.0-rc.1.25451.107",
"System.Diagnostics.EventLog": "10.0.0-rc.1.25451.107"
}
},
"Microsoft.Extensions.Logging.EventSource": {
"type": "Transitive",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "K0Qydvu3fnotw1kynMz6kDt8FX+VnKxOjX1lVFjKKkyHroHitpz8YUOuA+TlbXQFZQyv3bO7nDimKVkcvPFcVQ==",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "kQtRLj0UHV44+CVxPXwIhK2emuxjym1zqH3pAbtONYU6B8QuvFjThW0vU+SElEIfFGM8L11F84CIOJQeLGVvGQ==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Logging": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Logging.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Options": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Primitives": "10.0.0-preview.7.25380.108"
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Logging": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Logging.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Options": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Primitives": "10.0.0-rc.1.25451.107"
}
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "kG3XdCpBiMSxPsAeMCy8YhHpe3sUlSoBGuZQfTcC/VaWKrvpQ5OrbhBCfb/SOPLzWexijSsDwtgjYenRvqE91Q==",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "lM7V/A39nKSh7kdTqqh8yRCEvgw1P3X0odWd5o7A94j/Ln8xT+1kV60MTP/i78jaa4FNDhFfYE7yao5T84aQZg==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Primitives": "10.0.0-preview.7.25380.108"
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Primitives": "10.0.0-rc.1.25451.107"
}
},
"Microsoft.Extensions.Options.ConfigurationExtensions": {
"type": "Transitive",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "z05jUKh7+6FTFE+Obdg6wEQqvdxNf+ty5YUZ9VjNyzYcoN9hZMbX7RucTifl4CZCJXadlv79C7ZCSmHIK4x0pw==",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "6G5VB30lHscf+GUb/e0ZNdN8/yeLzNHWDPfdk1zDVODIlDL3Lm0zcr/h0v9gatilVlKKzLno49ftwLqyhw0sbw==",
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Configuration.Binder": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Options": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Primitives": "10.0.0-preview.7.25380.108"
"Microsoft.Extensions.Configuration.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Configuration.Binder": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Options": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Primitives": "10.0.0-rc.1.25451.107"
}
},
"Microsoft.Extensions.Primitives": {
"type": "Transitive",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "0oC37fX0irgi29vN8JQdvXn1jZI6upCIs8Q8J+loetDrWrB3fwYBqbUdz/mMS41G+kkjCSaGRfZM8dBiZqqMpw=="
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "BNCfqG7CvhUQp7Sj8Qcr+HVNXkwV/nQfD6uS1HXXY2oO//QNpi4Mqy6IGeaIPIZIoQxykhLgPoSOJqRPCJRh/Q=="
},
"Newtonsoft.Json": {
"type": "Transitive",
@ -340,8 +340,8 @@ @@ -340,8 +340,8 @@
},
"System.Diagnostics.EventLog": {
"type": "Transitive",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "kKFLata6tLJ/1+jJTbsE9YZu/zeOGO+9ZeukQ3uni5flEjcPpjqGxtmqOx/IFUecMQjNGheNEVyC1KaMl+aZMg=="
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "rwQ/QDgOb3qLSOs8UbLBFigL8ewMCETOmrQwVbksRXLt3c/kizzljOdBf+KdXKCS3XmrKqMeOLOkZZM8WQDcTw=="
},
"System.Security.Cryptography.ProtectedData": {
"type": "Transitive",
@ -361,8 +361,8 @@ @@ -361,8 +361,8 @@
"ICSharpCode.Decompiler": "[8.0.0-noversion, )",
"K4os.Compression.LZ4": "[1.3.8, )",
"Mono.Cecil": "[0.11.6, )",
"System.Composition.AttributedModel": "[10.0.0-preview.7.25380.108, )",
"System.Reflection.Metadata": "[10.0.0-preview.7.25380.108, )",
"System.Composition.AttributedModel": "[10.0.0-rc.1.25451.107, )",
"System.Reflection.Metadata": "[10.0.0-rc.1.25451.107, )",
"System.Runtime.CompilerServices.Unsafe": "[6.1.2, )"
}
},
@ -383,31 +383,31 @@ @@ -383,31 +383,31 @@
},
"Microsoft.Extensions.Configuration": {
"type": "CentralTransitive",
"requested": "[10.0.0-preview.7.25380.108, )",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "bqeb/og5BMVpJ0cAfVgHhyNPfQa/uF/t6MhoQ9Z0kAUuOvk+hCfnSKlx2CZUzrkrWN6zK/jRXZW8RsbIxtzexw==",
"requested": "[10.0.0-rc.1.25451.107, )",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "pyIiy0uo0i2pM1IPTHf9X/sy1lOxRjAPuj7TAHlt+prfEvurKOXVdTrK41Xmr4e6mScWdesoOVpIoAhgP/N5BQ==",
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Primitives": "10.0.0-preview.7.25380.108"
"Microsoft.Extensions.Configuration.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Primitives": "10.0.0-rc.1.25451.107"
}
},
"Microsoft.Extensions.Configuration.Json": {
"type": "CentralTransitive",
"requested": "[10.0.0-preview.7.25380.108, )",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "vMUtXxczM+wt2rZT3AtDHRG4m0Wzn4R+cTFSr4RDq3VPy1z+qeX+xa+a9Ft73R5ODy/T0N5F1fXxYN6h1fvh6w==",
"requested": "[10.0.0-rc.1.25451.107, )",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "vvKbTkuv/v4D/DQ65nKz4V55eN/JL23Mvm31GNvxvY9rpOsy4MtOu68+WE/fX62r0MVByGYULd1GLmQPAgJ3wQ==",
"dependencies": {
"Microsoft.Extensions.Configuration": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Configuration.Abstractions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.Configuration.FileExtensions": "10.0.0-preview.7.25380.108",
"Microsoft.Extensions.FileProviders.Abstractions": "10.0.0-preview.7.25380.108"
"Microsoft.Extensions.Configuration": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Configuration.Abstractions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.Configuration.FileExtensions": "10.0.0-rc.1.25451.107",
"Microsoft.Extensions.FileProviders.Abstractions": "10.0.0-rc.1.25451.107"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "CentralTransitive",
"requested": "[10.0.0-preview.7.25380.108, )",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "0oSQ8o2O8eMxaInqR1GykEzzlerBTN3xQMsEtaWA4zbf1LmrqV7H9ctTTjK4oMeWMCTb9mfYoN9fsVWbAhkTXA=="
"requested": "[10.0.0-rc.1.25451.107, )",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "Wm2HfC0GlWExQmJajq85FHM9iHEOm61Z1c2YLivbzI6R5eT+TTSyfk3RHUra4oBU+oj1XhOIQ5hLW6Kg2r85tg=="
},
"Mono.Cecil": {
"type": "CentralTransitive",
@ -417,21 +417,21 @@ @@ -417,21 +417,21 @@
},
"System.Collections.Immutable": {
"type": "CentralTransitive",
"requested": "[10.0.0-preview.7.25380.108, )",
"requested": "[10.0.0-rc.1.25451.107, )",
"resolved": "9.0.0",
"contentHash": "QhkXUl2gNrQtvPmtBTQHb0YsUrDiDQ2QS09YbtTTiSjGcf7NBqtYbrG/BE06zcBPCKEwQGzIv13IVdXNOSub2w=="
},
"System.Composition.AttributedModel": {
"type": "CentralTransitive",
"requested": "[10.0.0-preview.7.25380.108, )",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "BgKfmK5BAjJPj3DvCh7Qv2v/91FQfY2HwYchSurW1JajkVNhpSCCciZgk5tNOr815yUUpcAG8gY/CUUdYYdXcw=="
"requested": "[10.0.0-rc.1.25451.107, )",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "0zroRtuBzQdbwuCRklmRY9NXin4DYNVcZOkZ8zqgZFuKNb66GrxeWw3kfnymfyZ0Ib9J8J3kXlYfxKRXIzb+2g=="
},
"System.Reflection.Metadata": {
"type": "CentralTransitive",
"requested": "[10.0.0-preview.7.25380.108, )",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "8oQpCMmBOI24XT+xwG1dec/gOv+1uUqAasXYu2vq0NWpXsg/TYw563jD9wMSbQ/lIjnKJmPRvjLFyG8xaX9uww=="
"requested": "[10.0.0-rc.1.25451.107, )",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "ixP5rSQVGhwbYomPUL7XDRQpoh6YVXXomjfJGn0WasADk+ykq9C4pPN3as8F2KktDQ434vGz55NWU+vfZSt2EQ=="
},
"System.Runtime.CompilerServices.Unsafe": {
"type": "CentralTransitive",

38
ICSharpCode.ILSpyX/TreeView/SharpTreeNode.cs

@ -21,21 +21,21 @@ using System.Collections.Generic; @@ -21,21 +21,21 @@ using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
#nullable disable
using ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;
namespace ICSharpCode.ILSpyX.TreeView
{
public partial class SharpTreeNode : INotifyPropertyChanged
{
[AllowNull]
protected static ITreeNodeImagesProvider ImagesProvider { get; private set; }
public static void SetImagesProvider(ITreeNodeImagesProvider provider) => ImagesProvider = provider;
SharpTreeNodeCollection modelChildren;
internal SharpTreeNode modelParent;
SharpTreeNodeCollection? modelChildren;
internal SharpTreeNode? modelParent;
bool isVisible = true;
void UpdateIsVisible(bool parentIsVisible, bool updateFlattener)
@ -53,7 +53,7 @@ namespace ICSharpCode.ILSpyX.TreeView @@ -53,7 +53,7 @@ namespace ICSharpCode.ILSpyX.TreeView
node = node.listParent;
}
// Remember the removed nodes:
List<SharpTreeNode> removedNodes = null;
List<SharpTreeNode>? removedNodes = null;
if (updateFlattener && !newIsVisible)
{
removedNodes = VisibleDescendantsAndSelf().ToList();
@ -118,19 +118,19 @@ namespace ICSharpCode.ILSpyX.TreeView @@ -118,19 +118,19 @@ namespace ICSharpCode.ILSpyX.TreeView
}
}
public SharpTreeNode Parent {
public SharpTreeNode? Parent {
get { return modelParent; }
}
public virtual object Text {
public virtual object? Text {
get { return null; }
}
public virtual object Icon {
public virtual object? Icon {
get { return null; }
}
public virtual object ToolTip {
public virtual object? ToolTip {
get { return null; }
}
@ -199,7 +199,7 @@ namespace ICSharpCode.ILSpyX.TreeView @@ -199,7 +199,7 @@ namespace ICSharpCode.ILSpyX.TreeView
while (removeEnd.modelChildren != null && removeEnd.modelChildren.Count > 0)
removeEnd = removeEnd.modelChildren.Last();
List<SharpTreeNode> removedNodes = null;
List<SharpTreeNode>? removedNodes = null;
int visibleIndexOfRemoval = 0;
if (node.isVisible)
{
@ -221,11 +221,11 @@ namespace ICSharpCode.ILSpyX.TreeView @@ -221,11 +221,11 @@ namespace ICSharpCode.ILSpyX.TreeView
}
if (e.NewItems != null)
{
SharpTreeNode insertionPos;
SharpTreeNode? insertionPos;
if (e.NewStartingIndex == 0)
insertionPos = null;
else
insertionPos = modelChildren[e.NewStartingIndex - 1];
insertionPos = modelChildren?[e.NewStartingIndex - 1];
foreach (SharpTreeNode node in e.NewItems)
{
@ -260,7 +260,7 @@ namespace ICSharpCode.ILSpyX.TreeView @@ -260,7 +260,7 @@ namespace ICSharpCode.ILSpyX.TreeView
#region Expanding / LazyLoading
public virtual object ExpandedIcon {
public virtual object? ExpandedIcon {
get { return Icon; }
}
@ -371,13 +371,13 @@ namespace ICSharpCode.ILSpyX.TreeView @@ -371,13 +371,13 @@ namespace ICSharpCode.ILSpyX.TreeView
public IEnumerable<SharpTreeNode> Ancestors()
{
for (SharpTreeNode n = this.Parent; n != null; n = n.Parent)
for (SharpTreeNode? n = this.Parent; n != null; n = n.Parent)
yield return n;
}
public IEnumerable<SharpTreeNode> AncestorsAndSelf()
{
for (SharpTreeNode n = this; n != null; n = n.Parent)
for (SharpTreeNode? n = this; n != null; n = n.Parent)
yield return n;
}
@ -402,7 +402,7 @@ namespace ICSharpCode.ILSpyX.TreeView @@ -402,7 +402,7 @@ namespace ICSharpCode.ILSpyX.TreeView
}
}
public virtual string LoadEditText()
public virtual string? LoadEditText()
{
return null;
}
@ -699,7 +699,7 @@ namespace ICSharpCode.ILSpyX.TreeView @@ -699,7 +699,7 @@ namespace ICSharpCode.ILSpyX.TreeView
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
public event PropertyChangedEventHandler? PropertyChanged;
public void RaisePropertyChanged(string name)
{
@ -725,10 +725,10 @@ namespace ICSharpCode.ILSpyX.TreeView @@ -725,10 +725,10 @@ namespace ICSharpCode.ILSpyX.TreeView
{
}
public override string ToString()
public override string? ToString()
{
// used for keyboard navigation
object text = this.Text;
object? text = this.Text;
return text != null ? text.ToString() : string.Empty;
}
}

26
ICSharpCode.ILSpyX/packages.lock.json

@ -10,9 +10,9 @@ @@ -10,9 +10,9 @@
},
"Microsoft.Sbom.Targets": {
"type": "Direct",
"requested": "[4.1.0, )",
"resolved": "4.1.0",
"contentHash": "GidfeSVHFtNwZSbD2wmwWiUiGkVdND8QR1z21WpFa+/47Mi3YiDkAzsWF02wXrMx2Xd8j3QSfKOUY1JtnF+7uw=="
"requested": "[4.1.2, )",
"resolved": "4.1.2",
"contentHash": "AmGCBhWtWu1d1PCit6WTdmpq48nPmmnJz9zZFBsxoCjYZjjZ0Gjm+wuAzHzVMF8VmTo/NeDGi2C73969QXiryw=="
},
"Microsoft.SourceLink.GitHub": {
"type": "Direct",
@ -32,15 +32,15 @@ @@ -32,15 +32,15 @@
},
"System.Composition.AttributedModel": {
"type": "Direct",
"requested": "[10.0.0-preview.7.25380.108, )",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "BgKfmK5BAjJPj3DvCh7Qv2v/91FQfY2HwYchSurW1JajkVNhpSCCciZgk5tNOr815yUUpcAG8gY/CUUdYYdXcw=="
"requested": "[10.0.0-rc.1.25451.107, )",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "0zroRtuBzQdbwuCRklmRY9NXin4DYNVcZOkZ8zqgZFuKNb66GrxeWw3kfnymfyZ0Ib9J8J3kXlYfxKRXIzb+2g=="
},
"System.Reflection.Metadata": {
"type": "Direct",
"requested": "[10.0.0-preview.7.25380.108, )",
"resolved": "10.0.0-preview.7.25380.108",
"contentHash": "8oQpCMmBOI24XT+xwG1dec/gOv+1uUqAasXYu2vq0NWpXsg/TYw563jD9wMSbQ/lIjnKJmPRvjLFyG8xaX9uww=="
"requested": "[10.0.0-rc.1.25451.107, )",
"resolved": "10.0.0-rc.1.25451.107",
"contentHash": "ixP5rSQVGhwbYomPUL7XDRQpoh6YVXXomjfJGn0WasADk+ykq9C4pPN3as8F2KktDQ434vGz55NWU+vfZSt2EQ=="
},
"System.Runtime.CompilerServices.Unsafe": {
"type": "Direct",
@ -50,9 +50,9 @@ @@ -50,9 +50,9 @@
},
"TomsToolbox.Composition.Analyzer": {
"type": "Direct",
"requested": "[2.22.1, )",
"resolved": "2.22.1",
"contentHash": "bKcte9zaz+xH1k6C1YIYpheQ9mPNRSmd0dHQIEIq31KxAKMTLfiAo80aROKDJMYJ7ZomlUjjSMo/QCIikMMWTg=="
"requested": "[2.22.2, )",
"resolved": "2.22.2",
"contentHash": "7gYo8ZR2eq3XkrilvUpLbTypeZy6IlD5FB8jah0YPhMOmDGhya4jJ3kfDMTTRt5m258Ou78P69mHMkG6DKZXsg=="
},
"Microsoft.Build.Tasks.Git": {
"type": "Transitive",
@ -73,7 +73,7 @@ @@ -73,7 +73,7 @@
},
"System.Collections.Immutable": {
"type": "CentralTransitive",
"requested": "[10.0.0-preview.7.25380.108, )",
"requested": "[10.0.0-rc.1.25451.107, )",
"resolved": "9.0.0",
"contentHash": "QhkXUl2gNrQtvPmtBTQHb0YsUrDiDQ2QS09YbtTTiSjGcf7NBqtYbrG/BE06zcBPCKEwQGzIv13IVdXNOSub2w=="
}

8
ILSpy.BamlDecompiler.Tests/BamlTestRunner.cs

@ -17,10 +17,8 @@ @@ -17,10 +17,8 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections;
using System.IO;
using System.Linq;
using System.Threading;
using System.Xml.Linq;
using ICSharpCode.BamlDecompiler;
@ -155,6 +153,12 @@ namespace ILSpy.BamlDecompiler.Tests @@ -155,6 +153,12 @@ namespace ILSpy.BamlDecompiler.Tests
RunTest("cases/issue2116");
}
[Test]
public void Issue3318()
{
RunTest("cases/issue3318");
}
[Test]
public void ReadonlyProperty()
{

3
ILSpy.BamlDecompiler.Tests/Cases/Issue3318.xaml

@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
<UserControl x:Class="ILSpy.BamlDecompiler.Tests.Cases.Issue3318" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:cases="clr-namespace:ILSpy.BamlDecompiler.Tests.Cases;assembly=ILSpy.BamlDecompiler.Tests">
<Grid Name="Root" x:FieldModifier="public" />
</UserControl>

26
ILSpy.BamlDecompiler.Tests/Cases/Issue3318.xaml.cs

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace ILSpy.BamlDecompiler.Tests.Cases
{
/// <summary>
/// Interaction logic for Issue3318.xaml
/// </summary>
public partial class Issue3318 : UserControl
{
public Issue3318()
{
InitializeComponent();
}
}
}

4
ILSpy.BamlDecompiler.Tests/ILSpy.BamlDecompiler.Tests.csproj

@ -62,6 +62,7 @@ @@ -62,6 +62,7 @@
<Compile Include="Cases\Issue1547.xaml.cs" />
<Compile Include="Cases\Issue2097.xaml.cs" />
<Compile Include="Cases\Issue2116.xaml.cs" />
<Compile Include="Cases\Issue3318.xaml.cs" />
<Compile Include="Cases\MyControl.xaml.cs">
<DependentUpon>MyControl.xaml</DependentUpon>
</Compile>
@ -104,6 +105,9 @@ @@ -104,6 +105,9 @@
<Page Include="Cases\Issue2116.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Cases\Issue3318.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Cases\Issue775.xaml">
<SubType>Designer</SubType>
</Page>

20
ILSpy/Analyzers/AnalyzerEntityTreeNode.cs

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using ICSharpCode.Decompiler.TypeSystem;
@ -25,6 +26,8 @@ using ICSharpCode.ILSpyX; @@ -25,6 +26,8 @@ using ICSharpCode.ILSpyX;
using ICSharpCode.ILSpyX.TreeView;
using ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;
#nullable enable
namespace ICSharpCode.ILSpy.Analyzers
{
/// <summary>
@ -32,7 +35,9 @@ namespace ICSharpCode.ILSpy.Analyzers @@ -32,7 +35,9 @@ namespace ICSharpCode.ILSpy.Analyzers
/// </summary>
public abstract class AnalyzerEntityTreeNode : AnalyzerTreeNode, IMemberTreeNode
{
public abstract IEntity Member { get; }
public abstract IEntity? Member { get; }
public IEntity? SourceMember { get; protected set; }
public override void ActivateItem(IPlatformRoutedEventArgs e)
{
@ -43,10 +48,14 @@ namespace ICSharpCode.ILSpy.Analyzers @@ -43,10 +48,14 @@ namespace ICSharpCode.ILSpy.Analyzers
return;
}
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(this.Member.ParentModule?.MetadataFile, this.Member.MetadataToken)));
var module = this.Member.ParentModule?.MetadataFile;
Debug.Assert(module != null);
MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(module, this.Member.MetadataToken), this.SourceMember));
}
public override object ToolTip => Member?.ParentModule?.MetadataFile?.FileName;
public override object? ToolTip => Member?.ParentModule?.MetadataFile?.FileName;
public override bool HandleAssemblyListChanged(ICollection<LoadedAssembly> removedAssemblies, ICollection<LoadedAssembly> addedAssemblies)
{
@ -56,13 +65,12 @@ namespace ICSharpCode.ILSpy.Analyzers @@ -56,13 +65,12 @@ namespace ICSharpCode.ILSpy.Analyzers
}
foreach (LoadedAssembly asm in removedAssemblies)
{
if (this.Member.ParentModule.MetadataFile == asm.GetMetadataFileOrNull())
if (this.Member.ParentModule!.MetadataFile == asm.GetMetadataFileOrNull())
return false; // remove this node
}
this.Children.RemoveAll(
delegate (SharpTreeNode n) {
AnalyzerTreeNode an = n as AnalyzerTreeNode;
return an == null || !an.HandleAssemblyListChanged(removedAssemblies, addedAssemblies);
return n is not AnalyzerTreeNode an || !an.HandleAssemblyListChanged(removedAssemblies, addedAssemblies);
});
return true;
}

22
ILSpy/Analyzers/AnalyzerSearchTreeNode.cs

@ -76,29 +76,29 @@ namespace ICSharpCode.ILSpy.Analyzers @@ -76,29 +76,29 @@ namespace ICSharpCode.ILSpy.Analyzers
}
}
AnalyzerTreeNode SymbolTreeNodeFactory(ISymbol symbol)
AnalyzerTreeNode SymbolTreeNodeFactory(ISymbol resultSymbol)
{
if (symbol == null)
if (resultSymbol == null)
{
throw new ArgumentNullException(nameof(symbol));
throw new ArgumentNullException(nameof(resultSymbol));
}
switch (symbol)
switch (resultSymbol)
{
case IModule module:
return new AnalyzedModuleTreeNode(module) { };
return new AnalyzedModuleTreeNode(module, (IEntity)this.symbol);
case ITypeDefinition td:
return new AnalyzedTypeTreeNode(td) { };
return new AnalyzedTypeTreeNode(td, (IEntity)this.symbol);
case IField fd:
return new AnalyzedFieldTreeNode(fd) { };
return new AnalyzedFieldTreeNode(fd, (IEntity)this.symbol);
case IMethod md:
return new AnalyzedMethodTreeNode(md) { };
return new AnalyzedMethodTreeNode(md, (IEntity)this.symbol);
case IProperty pd:
return new AnalyzedPropertyTreeNode(pd) { };
return new AnalyzedPropertyTreeNode(pd, (IEntity)this.symbol);
case IEvent ed:
return new AnalyzedEventTreeNode(ed) { };
return new AnalyzedEventTreeNode(ed, (IEntity)this.symbol);
default:
throw new ArgumentOutOfRangeException(nameof(symbol), $"Symbol {symbol.GetType().FullName} is not supported.");
throw new ArgumentOutOfRangeException(nameof(resultSymbol), $"Symbol {resultSymbol.GetType().FullName} is not supported.");
}
}

10
ILSpy/Analyzers/AnalyzerTreeViewModel.cs

@ -109,20 +109,20 @@ namespace ICSharpCode.ILSpy.Analyzers @@ -109,20 +109,20 @@ namespace ICSharpCode.ILSpy.Analyzers
switch (entity)
{
case ITypeDefinition td:
AddOrSelect(new AnalyzedTypeTreeNode(td));
AddOrSelect(new AnalyzedTypeTreeNode(td, null));
break;
case IField fd:
if (!fd.IsConst)
AddOrSelect(new AnalyzedFieldTreeNode(fd));
AddOrSelect(new AnalyzedFieldTreeNode(fd, null));
break;
case IMethod md:
AddOrSelect(new AnalyzedMethodTreeNode(md));
AddOrSelect(new AnalyzedMethodTreeNode(md, null));
break;
case IProperty pd:
AddOrSelect(new AnalyzedPropertyTreeNode(pd));
AddOrSelect(new AnalyzedPropertyTreeNode(pd, null));
break;
case IEvent ed:
AddOrSelect(new AnalyzedEventTreeNode(ed));
AddOrSelect(new AnalyzedEventTreeNode(ed, null));
break;
default:
throw new ArgumentOutOfRangeException(nameof(entity), $@"Entity {entity.GetType().FullName} is not supported.");

4
ILSpy/Analyzers/TreeNodes/AnalyzedAccessorTreeNode.cs

@ -24,8 +24,8 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes @@ -24,8 +24,8 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
{
readonly string name;
public AnalyzedAccessorTreeNode(IMethod analyzedMethod, string name)
: base(analyzedMethod)
public AnalyzedAccessorTreeNode(IMethod analyzedMethod, IEntity source, string name)
: base(analyzedMethod, source)
{
if (string.IsNullOrWhiteSpace(name))
{

18
ILSpy/Analyzers/TreeNodes/AnalyzedEventTreeNode.cs

@ -17,10 +17,14 @@ @@ -17,10 +17,14 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.TreeNodes;
#nullable enable
namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
{
internal sealed class AnalyzedEventTreeNode : AnalyzerEntityTreeNode
@ -28,11 +32,12 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes @@ -28,11 +32,12 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
readonly IEvent analyzedEvent;
readonly string prefix;
public AnalyzedEventTreeNode(IEvent analyzedEvent, string prefix = "")
public AnalyzedEventTreeNode(IEvent analyzedEvent, IEntity? source, string prefix = "")
{
this.analyzedEvent = analyzedEvent ?? throw new ArgumentNullException(nameof(analyzedEvent));
this.prefix = prefix;
this.LazyLoading = true;
this.SourceMember = source;
}
public override IEntity Member => analyzedEvent;
@ -45,15 +50,16 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes @@ -45,15 +50,16 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
protected override void LoadChildren()
{
if (analyzedEvent.CanAdd)
this.Children.Add(new AnalyzedAccessorTreeNode(analyzedEvent.AddAccessor, "add"));
this.Children.Add(new AnalyzedAccessorTreeNode(analyzedEvent.AddAccessor, this.SourceMember, "add"));
if (analyzedEvent.CanRemove)
this.Children.Add(new AnalyzedAccessorTreeNode(analyzedEvent.RemoveAccessor, "remove"));
this.Children.Add(new AnalyzedAccessorTreeNode(analyzedEvent.RemoveAccessor, this.SourceMember, "remove"));
if (TryFindBackingField(analyzedEvent, out var backingField))
this.Children.Add(new AnalyzedFieldTreeNode(backingField));
this.Children.Add(new AnalyzedFieldTreeNode(backingField, this.SourceMember));
foreach (var lazy in Analyzers)
{
var analyzer = lazy.Value;
Debug.Assert(analyzer != null);
if (analyzer.Show(analyzedEvent))
{
this.Children.Add(new AnalyzerSearchTreeNode(analyzedEvent, analyzer, lazy.Metadata?.Header));
@ -61,10 +67,10 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes @@ -61,10 +67,10 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
}
}
bool TryFindBackingField(IEvent analyzedEvent, out IField backingField)
bool TryFindBackingField(IEvent analyzedEvent, [NotNullWhen(true)] out IField? backingField)
{
backingField = null;
foreach (var field in analyzedEvent.DeclaringTypeDefinition.GetFields(options: GetMemberOptions.IgnoreInheritedMembers))
foreach (var field in analyzedEvent.DeclaringTypeDefinition?.GetFields(options: GetMemberOptions.IgnoreInheritedMembers) ?? [])
{
if (field.Name == analyzedEvent.Name && field.Accessibility == Decompiler.TypeSystem.Accessibility.Private)
{

7
ILSpy/Analyzers/TreeNodes/AnalyzedFieldTreeNode.cs

@ -17,19 +17,23 @@ @@ -17,19 +17,23 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Diagnostics;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.TreeNodes;
#nullable enable
namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
{
class AnalyzedFieldTreeNode : AnalyzerEntityTreeNode
{
readonly IField analyzedField;
public AnalyzedFieldTreeNode(IField analyzedField)
public AnalyzedFieldTreeNode(IField analyzedField, IEntity? source)
{
this.analyzedField = analyzedField ?? throw new ArgumentNullException(nameof(analyzedField));
this.SourceMember = source;
this.LazyLoading = true;
}
@ -42,6 +46,7 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes @@ -42,6 +46,7 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
foreach (var lazy in Analyzers)
{
var analyzer = lazy.Value;
Debug.Assert(analyzer != null);
if (analyzer.Show(analyzedField))
{
this.Children.Add(new AnalyzerSearchTreeNode(analyzedField, analyzer, lazy.Metadata?.Header));

9
ILSpy/Analyzers/TreeNodes/AnalyzedMethodTreeNode.cs

@ -17,10 +17,13 @@ @@ -17,10 +17,13 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Diagnostics;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.TreeNodes;
#nullable enable
namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
{
internal class AnalyzedMethodTreeNode : AnalyzerEntityTreeNode
@ -28,9 +31,10 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes @@ -28,9 +31,10 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
readonly IMethod analyzedMethod;
readonly string prefix;
public AnalyzedMethodTreeNode(IMethod analyzedMethod, string prefix = "")
public AnalyzedMethodTreeNode(IMethod analyzedMethod, IEntity? source, string prefix = "")
{
this.analyzedMethod = analyzedMethod ?? throw new ArgumentNullException(nameof(analyzedMethod));
this.SourceMember = source;
this.prefix = prefix;
this.LazyLoading = true;
}
@ -44,9 +48,10 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes @@ -44,9 +48,10 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
foreach (var lazy in Analyzers)
{
var analyzer = lazy.Value;
Debug.Assert(analyzer != null);
if (analyzer.Show(analyzedMethod))
{
this.Children.Add(new AnalyzerSearchTreeNode(analyzedMethod, analyzer, lazy.Metadata.Header));
this.Children.Add(new AnalyzerSearchTreeNode(analyzedMethod, analyzer, lazy.Metadata!.Header));
}
}
}

16
ILSpy/Analyzers/TreeNodes/AnalyzedModuleTreeNode.cs

@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using ICSharpCode.Decompiler.TypeSystem;
@ -25,15 +26,18 @@ using ICSharpCode.ILSpyX; @@ -25,15 +26,18 @@ using ICSharpCode.ILSpyX;
using ICSharpCode.ILSpyX.TreeView;
using ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;
#nullable enable
namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
{
internal class AnalyzedModuleTreeNode : AnalyzerEntityTreeNode
{
readonly IModule analyzedModule;
public AnalyzedModuleTreeNode(IModule analyzedModule)
public AnalyzedModuleTreeNode(IModule analyzedModule, IEntity? source)
{
this.analyzedModule = analyzedModule ?? throw new ArgumentNullException(nameof(analyzedModule));
this.SourceMember = source;
this.LazyLoading = true;
}
@ -41,16 +45,17 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes @@ -41,16 +45,17 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
public override object Text => analyzedModule.AssemblyName;
public override object ToolTip => analyzedModule.MetadataFile?.FileName;
public override object? ToolTip => analyzedModule.MetadataFile?.FileName;
protected override void LoadChildren()
{
foreach (var lazy in Analyzers)
{
var analyzer = lazy.Value;
Debug.Assert(analyzer != null);
if (analyzer.Show(analyzedModule))
{
this.Children.Add(new AnalyzerSearchTreeNode(analyzedModule, analyzer, lazy.Metadata.Header));
this.Children.Add(new AnalyzerSearchTreeNode(analyzedModule, analyzer, lazy.Metadata!.Header));
}
}
}
@ -66,7 +71,7 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes @@ -66,7 +71,7 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
MessageBus.Send(this, new NavigateToReferenceEventArgs(analyzedModule.MetadataFile));
}
public override IEntity Member => null;
public override IEntity? Member => null;
public override bool HandleAssemblyListChanged(ICollection<LoadedAssembly> removedAssemblies, ICollection<LoadedAssembly> addedAssemblies)
{
@ -81,8 +86,7 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes @@ -81,8 +86,7 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
}
this.Children.RemoveAll(
delegate (SharpTreeNode n) {
AnalyzerTreeNode an = n as AnalyzerTreeNode;
return an == null || !an.HandleAssemblyListChanged(removedAssemblies, addedAssemblies);
return n is not AnalyzerTreeNode an || !an.HandleAssemblyListChanged(removedAssemblies, addedAssemblies);
});
return true;
}

13
ILSpy/Analyzers/TreeNodes/AnalyzedPropertyTreeNode.cs

@ -17,10 +17,13 @@ @@ -17,10 +17,13 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Diagnostics;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.TreeNodes;
#nullable enable
namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
{
sealed class AnalyzedPropertyTreeNode : AnalyzerEntityTreeNode
@ -28,11 +31,12 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes @@ -28,11 +31,12 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
readonly IProperty analyzedProperty;
readonly string prefix;
public AnalyzedPropertyTreeNode(IProperty analyzedProperty, string prefix = "")
public AnalyzedPropertyTreeNode(IProperty analyzedProperty, IEntity? source, string prefix = "")
{
this.analyzedProperty = analyzedProperty ?? throw new ArgumentNullException(nameof(analyzedProperty));
this.prefix = prefix;
this.LazyLoading = true;
this.SourceMember = source;
}
public override object Icon => PropertyTreeNode.GetIcon(analyzedProperty);
@ -43,16 +47,17 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes @@ -43,16 +47,17 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
protected override void LoadChildren()
{
if (analyzedProperty.CanGet)
this.Children.Add(new AnalyzedAccessorTreeNode(analyzedProperty.Getter, "get"));
this.Children.Add(new AnalyzedAccessorTreeNode(analyzedProperty.Getter, this.SourceMember, "get"));
if (analyzedProperty.CanSet)
this.Children.Add(new AnalyzedAccessorTreeNode(analyzedProperty.Setter, "set"));
this.Children.Add(new AnalyzedAccessorTreeNode(analyzedProperty.Setter, this.SourceMember, "set"));
foreach (var lazy in Analyzers)
{
var analyzer = lazy.Value;
Debug.Assert(analyzer != null);
if (analyzer.Show(analyzedProperty))
{
this.Children.Add(new AnalyzerSearchTreeNode(analyzedProperty, analyzer, lazy.Metadata.Header));
this.Children.Add(new AnalyzerSearchTreeNode(analyzedProperty, analyzer, lazy.Metadata!.Header));
}
}
}

9
ILSpy/Analyzers/TreeNodes/AnalyzedTypeTreeNode.cs

@ -17,19 +17,23 @@ @@ -17,19 +17,23 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Diagnostics;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.TreeNodes;
#nullable enable
namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
{
internal class AnalyzedTypeTreeNode : AnalyzerEntityTreeNode
{
readonly ITypeDefinition analyzedType;
public AnalyzedTypeTreeNode(ITypeDefinition analyzedType)
public AnalyzedTypeTreeNode(ITypeDefinition analyzedType, IEntity? source)
{
this.analyzedType = analyzedType ?? throw new ArgumentNullException(nameof(analyzedType));
this.SourceMember = source;
this.LazyLoading = true;
}
@ -42,9 +46,10 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes @@ -42,9 +46,10 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
foreach (var lazy in Analyzers)
{
var analyzer = lazy.Value;
Debug.Assert(analyzer != null);
if (analyzer.Show(analyzedType))
{
this.Children.Add(new AnalyzerSearchTreeNode(analyzedType, analyzer, lazy.Metadata.Header));
this.Children.Add(new AnalyzerSearchTreeNode(analyzedType, analyzer, lazy.Metadata!.Header));
}
}
}

20
ILSpy/AssemblyTree/AssemblyTreeModel.cs

@ -67,6 +67,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -67,6 +67,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree
private readonly NavigationHistory<NavigationState> history = new();
private NavigationState? navigatingToState;
private object? sourceOfReference;
private readonly SettingsService settingsService;
private readonly LanguageService languageService;
private readonly IExportProvider exportProvider;
@ -262,7 +263,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -262,7 +263,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree
found = true;
if (SelectedItem == initialSelection)
{
await JumpToReferenceAsync(mr);
await JumpToReferenceAsync(mr, null);
}
}
}
@ -468,9 +469,9 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -468,9 +469,9 @@ namespace ICSharpCode.ILSpy.AssemblyTree
#endif
else
#if DEBUG
mainWindow.Title = $"ILSpy {DecompilerVersionInfo.FullVersion} - " + assemblyList.ListName;
mainWindow.Title = string.Format(settingsService.MiscSettings.AllowMultipleInstances ? "{1} - {0}" : "{0} - {1}", $"ILSpy {DecompilerVersionInfo.FullVersion}", assemblyList.ListName);
#else
mainWindow.Title = "ILSpy - " + assemblyList.ListName;
mainWindow.Title = string.Format(settingsService.MiscSettings.AllowMultipleInstances ? "{1} - {0}" : "{0} - {1}", "ILSpy", assemblyList.ListName);
#endif
}
@ -601,7 +602,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -601,7 +602,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree
List<string> path = new List<string>();
while (node.Parent != null)
{
path.Add(node.ToString());
path.Add(node.ToString()!);
node = node.Parent;
}
path.Reverse();
@ -642,7 +643,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -642,7 +643,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree
private void JumpToReference(object? sender, NavigateToReferenceEventArgs e)
{
JumpToReferenceAsync(e.Reference, e.InNewTabPage).HandleExceptions();
JumpToReferenceAsync(e.Reference, e.Source, e.InNewTabPage).HandleExceptions();
IsActive = true;
}
@ -653,8 +654,9 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -653,8 +654,9 @@ namespace ICSharpCode.ILSpy.AssemblyTree
/// Returns a task that will signal completion when the decompilation of the jump target has finished.
/// The task will be marked as canceled if the decompilation is canceled.
/// </returns>
private Task JumpToReferenceAsync(object? reference, bool inNewTabPage = false)
private Task JumpToReferenceAsync(object? reference, object? source, bool inNewTabPage = false)
{
this.sourceOfReference = source;
var decompilationTask = Task.CompletedTask;
switch (reference)
@ -804,6 +806,8 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -804,6 +806,8 @@ namespace ICSharpCode.ILSpy.AssemblyTree
public void DecompileSelectedNodes(ViewState? newState = null)
{
object? source = this.sourceOfReference;
this.sourceOfReference = null;
var activeTabPage = DockWorkspace.ActiveTabPage;
if (activeTabPage.FrozenContent)
@ -831,7 +835,9 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -831,7 +835,9 @@ namespace ICSharpCode.ILSpy.AssemblyTree
var options = activeTabPage.CreateDecompilationOptions();
options.TextViewState = newState as DecompilerTextViewState;
activeTabPage.ShowTextViewAsync(textView => textView.DecompileAsync(this.CurrentLanguage, this.SelectedNodes, options));
activeTabPage.ShowTextViewAsync(textView => {
return textView.DecompileAsync(this.CurrentLanguage, this.SelectedNodes, source, options);
});
}
public void RefreshDecompiledView()

3
ILSpy/Languages/CSharpILMixedLanguage.cs

@ -60,7 +60,8 @@ namespace ICSharpCode.ILSpy @@ -60,7 +60,8 @@ namespace ICSharpCode.ILSpy
ShowMetadataTokens = displaySettings.ShowMetadataTokens,
ShowMetadataTokensInBase10 = displaySettings.ShowMetadataTokensInBase10,
ShowRawRVAOffsetAndBytes = displaySettings.ShowRawOffsetsAndBytesBeforeInstruction,
ExpandMemberDefinitions = options.DecompilerSettings.ExpandMemberDefinitions
ExpandMemberDefinitions = options.DecompilerSettings.ExpandMemberDefinitions,
DecodeCustomAttributeBlobs = displaySettings.DecodeCustomAttributeBlobs
};
}

3
ILSpy/Languages/ILLanguage.cs

@ -67,7 +67,8 @@ namespace ICSharpCode.ILSpy @@ -67,7 +67,8 @@ namespace ICSharpCode.ILSpy
ShowMetadataTokens = displaySettings.ShowMetadataTokens,
ShowMetadataTokensInBase10 = displaySettings.ShowMetadataTokensInBase10,
ShowRawRVAOffsetAndBytes = displaySettings.ShowRawOffsetsAndBytesBeforeInstruction,
ExpandMemberDefinitions = options.DecompilerSettings.ExpandMemberDefinitions
ExpandMemberDefinitions = options.DecompilerSettings.ExpandMemberDefinitions,
DecodeCustomAttributeBlobs = displaySettings.DecodeCustomAttributeBlobs
};
}

6
ILSpy/Metadata/CorTables/TypeDefTableTreeNode.cs

@ -125,10 +125,10 @@ namespace ICSharpCode.ILSpy.Metadata @@ -125,10 +125,10 @@ namespace ICSharpCode.ILSpy.Metadata
string fieldListTooltip;
public string FieldListTooltip {
get {
var field = typeDef.GetFields().FirstOrDefault();
if (field.IsNil)
var @field = typeDef.GetFields().FirstOrDefault();
if (@field.IsNil)
return null;
return GenerateTooltip(ref fieldListTooltip, metadataFile, field);
return GenerateTooltip(ref fieldListTooltip, metadataFile, @field);
}
}

8
ILSpy/Options/DisplaySettings.cs

@ -156,6 +156,12 @@ namespace ICSharpCode.ILSpy.Options @@ -156,6 +156,12 @@ namespace ICSharpCode.ILSpy.Options
set => SetProperty(ref enableSmoothScrolling, value);
}
private bool decodeCustomAttributeBlobs;
public bool DecodeCustomAttributeBlobs {
get => decodeCustomAttributeBlobs;
set => SetProperty(ref decodeCustomAttributeBlobs, value);
}
public XName SectionName => "DisplaySettings";
public void LoadFromXml(XElement section)
@ -181,6 +187,7 @@ namespace ICSharpCode.ILSpy.Options @@ -181,6 +187,7 @@ namespace ICSharpCode.ILSpy.Options
ShowRawOffsetsAndBytesBeforeInstruction = (bool?)section.Attribute("ShowRawOffsetsAndBytesBeforeInstruction") ?? false;
StyleWindowTitleBar = (bool?)section.Attribute("StyleWindowTitleBar") ?? false;
EnableSmoothScrolling = (bool?)section.Attribute("EnableSmoothScrolling") ?? true;
DecodeCustomAttributeBlobs = (bool?)section.Attribute("DecodeCustomAttributeBlobs") ?? false;
}
public XElement SaveToXml()
@ -208,6 +215,7 @@ namespace ICSharpCode.ILSpy.Options @@ -208,6 +215,7 @@ namespace ICSharpCode.ILSpy.Options
section.SetAttributeValue("ShowRawOffsetsAndBytesBeforeInstruction", ShowRawOffsetsAndBytesBeforeInstruction);
section.SetAttributeValue("StyleWindowTitleBar", StyleWindowTitleBar);
section.SetAttributeValue("EnableSmoothScrolling", EnableSmoothScrolling);
section.SetAttributeValue("DecodeCustomAttributeBlobs", DecodeCustomAttributeBlobs);
return section;
}

1
ILSpy/Options/DisplaySettingsPanel.xaml

@ -64,6 +64,7 @@ @@ -64,6 +64,7 @@
<CheckBox IsChecked="{Binding Settings.ExpandUsingDeclarations}" Content="{x:Static properties:Resources.ExpandUsingDeclarationsAfterDecompilation}"></CheckBox>
<CheckBox IsChecked="{Binding Settings.ShowDebugInfo}" Content="{x:Static properties:Resources.ShowInfoFromDebugSymbolsAvailable}"></CheckBox>
<CheckBox IsChecked="{Binding Settings.ShowRawOffsetsAndBytesBeforeInstruction}" Content="{x:Static properties:Resources.ShowRawOffsetsAndBytesBeforeInstruction}"></CheckBox>
<CheckBox IsChecked="{Binding Settings.DecodeCustomAttributeBlobs}" Content="{x:Static properties:Resources.DecodeCustomAttributeBlobs}"></CheckBox>
</StackPanel>
</GroupBox>
<GroupBox Header="{x:Static properties:Resources.TreeViewOptions}">

11
ILSpy/Properties/Resources.Designer.cs generated

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
@ -648,6 +648,15 @@ namespace ICSharpCode.ILSpy.Properties { @@ -648,6 +648,15 @@ namespace ICSharpCode.ILSpy.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Decode custom attribute blobs.
/// </summary>
public static string DecodeCustomAttributeBlobs {
get {
return ResourceManager.GetString("DecodeCustomAttributeBlobs", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Decompilation complete in {0:F1} seconds..
/// </summary>

3
ILSpy/Properties/Resources.resx

@ -234,6 +234,9 @@ Are you sure you want to continue?</value> @@ -234,6 +234,9 @@ Are you sure you want to continue?</value>
<data name="DebugThisStep" xml:space="preserve">
<value>Debug this step</value>
</data>
<data name="DecodeCustomAttributeBlobs" xml:space="preserve">
<value>Decode custom attribute blobs</value>
</data>
<data name="DecompilationCompleteInF1Seconds" xml:space="preserve">
<value>Decompilation complete in {0:F1} seconds.</value>
</data>

14
ILSpy/Search/SearchPane.xaml

@ -48,7 +48,7 @@ @@ -48,7 +48,7 @@
</Grid>
</Border>
<ProgressBar x:Name="searchProgressBar" Grid.Row="1" BorderThickness="0" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<ListView Grid.Row="2" BorderThickness="0,1,0,0" HorizontalContentAlignment="Stretch" KeyDown="ListBox_KeyDown"
<ListView Grid.Row="2" BorderThickness="0,1,0,0" HorizontalContentAlignment="Stretch" KeyDown="ListBox_KeyDown" MouseDown="ListBox_MouseDown" MouseUp="ListBox_MouseUp"
MouseDoubleClick="ListBox_MouseDoubleClick" Name="listBox" SelectionMode="Single" controls:SortableGridViewColumn.SortMode="Automatic"
controls:GridViewColumnAutoSize.AutoWidth="40%;40%;20%" BorderBrush="{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}"
ItemsSource="{Binding Results, ElementName=self}"
@ -58,30 +58,30 @@ @@ -58,30 +58,30 @@
<controls:SortableGridViewColumn Header="{x:Static properties:Resources.Name}" SortBy="Name">
<controls:SortableGridViewColumn.CellTemplate>
<DataTemplate DataType="{x:Type spyX:SearchResult}">
<StackPanel Orientation="Horizontal">
<DockPanel>
<Image Height="16" Margin="0,0,4,0" Width="16" Source="{Binding Image}" />
<TextBlock Text="{Binding Name}" ToolTip="{Binding ToolTip}" TextTrimming="CharacterEllipsis" />
</StackPanel>
</DockPanel>
</DataTemplate>
</controls:SortableGridViewColumn.CellTemplate>
</controls:SortableGridViewColumn>
<controls:SortableGridViewColumn Header="{x:Static properties:Resources.Location}" SortBy="Location">
<controls:SortableGridViewColumn.CellTemplate>
<DataTemplate DataType="{x:Type spyX:SearchResult}">
<StackPanel Orientation="Horizontal">
<DockPanel>
<Image Height="16" Margin="4,0,4,0" Width="16" Source="{Binding LocationImage}" />
<TextBlock Text="{Binding Location}" ToolTip="{Binding Location}" TextTrimming="CharacterEllipsis" />
</StackPanel>
</DockPanel>
</DataTemplate>
</controls:SortableGridViewColumn.CellTemplate>
</controls:SortableGridViewColumn>
<controls:SortableGridViewColumn Header="{x:Static properties:Resources.Assembly}" SortBy="Assembly">
<controls:SortableGridViewColumn.CellTemplate>
<DataTemplate DataType="{x:Type spyX:SearchResult}">
<StackPanel Orientation="Horizontal">
<DockPanel>
<Image Height="16" Margin="4,0,4,0" Width="16" Source="{Binding AssemblyImage}" />
<TextBlock Text="{Binding Assembly}" ToolTip="{Binding Assembly}" TextTrimming="CharacterEllipsis" />
</StackPanel>
</DockPanel>
</DataTemplate>
</controls:SortableGridViewColumn.CellTemplate>
</controls:SortableGridViewColumn>

29
ILSpy/Search/SearchPane.xaml.cs

@ -167,12 +167,35 @@ namespace ICSharpCode.ILSpy.Search @@ -167,12 +167,35 @@ namespace ICSharpCode.ILSpy.Search
e.Handled = true;
}
private void ListBox_MouseDown(object sender, MouseButtonEventArgs e)
{
var item = listBox.InputHitTest(e.GetPosition(listBox)) as DependencyObject;
while (item != null && item != listBox)
{
if (item is ListBoxItem)
{
listBox.SelectedItem = ((ListBoxItem)item).DataContext;
break;
}
item = VisualTreeHelper.GetParent(item);
}
}
private void ListBox_MouseUp(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Middle)
{
JumpToSelectedItem(inNewTabPage: true);
e.Handled = true;
}
}
void ListBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Return)
{
e.Handled = true;
JumpToSelectedItem();
JumpToSelectedItem(e.KeyboardDevice.Modifiers.HasFlag(ModifierKeys.Control));
}
else if (e.Key == Key.Up && listBox.SelectedIndex == 0)
{
@ -281,11 +304,11 @@ namespace ICSharpCode.ILSpy.Search @@ -281,11 +304,11 @@ namespace ICSharpCode.ILSpy.Search
}
}
void JumpToSelectedItem()
void JumpToSelectedItem(bool inNewTabPage = false)
{
if (listBox.SelectedItem is SearchResult result)
{
MessageBus.Send(this, new NavigateToReferenceEventArgs(result.Reference));
MessageBus.Send(this, new NavigateToReferenceEventArgs(result.Reference, inNewTabPage));
}
}

7
ILSpy/TextView/AvalonEditTextOutput.cs

@ -312,6 +312,13 @@ namespace ICSharpCode.ILSpy.TextView @@ -312,6 +312,13 @@ namespace ICSharpCode.ILSpy.TextView
references.Add(new ReferenceSegment { StartOffset = start, EndOffset = end, Reference = reference, IsLocal = true, IsDefinition = isDefinition });
}
internal object InitialHighlightReference = null;
public void SetInitialHighlight(object reference)
{
this.InitialHighlightReference = reference;
}
public void MarkFoldStart(string collapsedText = "...", bool defaultCollapsed = false, bool isDefinition = false)
{
WriteIndent();

49
ILSpy/TextView/DecompilerTextView.cs

@ -802,6 +802,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -802,6 +802,7 @@ namespace ICSharpCode.ILSpy.TextView
currentAddress = textOutput.Address;
currentTitle = textOutput.Title;
expandMemberDefinitions = settingsService.DisplaySettings.ExpandMemberDefinitions;
SetLocalReferenceMarks(textOutput.InitialHighlightReference);
}
#endregion
@ -817,7 +818,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -817,7 +818,7 @@ namespace ICSharpCode.ILSpy.TextView
[Obsolete("Use DecompileAsync() instead")]
public void Decompile(ILSpy.Language language, IEnumerable<ILSpyTreeNode> treeNodes, DecompilationOptions options)
{
DecompileAsync(language, treeNodes, options).HandleExceptions();
DecompileAsync(language, treeNodes, null, options).HandleExceptions();
}
/// <summary>
@ -826,7 +827,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -826,7 +827,7 @@ namespace ICSharpCode.ILSpy.TextView
/// If any errors occur, the error message is displayed in the text view, and the task returned by this method completes successfully.
/// If the operation is cancelled (by starting another decompilation action); the returned task is marked as cancelled.
/// </summary>
public Task DecompileAsync(ILSpy.Language language, IEnumerable<ILSpyTreeNode> treeNodes, DecompilationOptions options)
public Task DecompileAsync(ILSpy.Language language, IEnumerable<ILSpyTreeNode> treeNodes, object? source, DecompilationOptions options)
{
// Some actions like loading an assembly list cause several selection changes in the tree view,
// and each of those will start a decompilation action.
@ -834,7 +835,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -834,7 +835,7 @@ namespace ICSharpCode.ILSpy.TextView
bool isDecompilationScheduled = this.nextDecompilationRun != null;
if (this.nextDecompilationRun != null)
this.nextDecompilationRun.TaskCompletionSource.TrySetCanceled();
this.nextDecompilationRun = new DecompilationContext(language, treeNodes.ToArray(), options);
this.nextDecompilationRun = new DecompilationContext(language, treeNodes.ToArray(), options, source);
var task = this.nextDecompilationRun.TaskCompletionSource.Task;
if (!isDecompilationScheduled)
{
@ -857,12 +858,14 @@ namespace ICSharpCode.ILSpy.TextView @@ -857,12 +858,14 @@ namespace ICSharpCode.ILSpy.TextView
public readonly ILSpyTreeNode[] TreeNodes;
public readonly DecompilationOptions Options;
public readonly TaskCompletionSource<object?> TaskCompletionSource = new TaskCompletionSource<object?>();
public readonly object? Source;
public DecompilationContext(ILSpy.Language language, ILSpyTreeNode[] treeNodes, DecompilationOptions options)
public DecompilationContext(ILSpy.Language language, ILSpyTreeNode[] treeNodes, DecompilationOptions options, object? source = null)
{
this.Language = language;
this.TreeNodes = treeNodes;
this.Options = options;
this.Source = source;
}
}
@ -914,6 +917,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -914,6 +917,7 @@ namespace ICSharpCode.ILSpy.TextView
{
AvalonEditTextOutput textOutput = new AvalonEditTextOutput();
textOutput.LengthLimit = outputLengthLimit;
textOutput.SetInitialHighlight(context.Source);
DecompileNodes(context, textOutput);
textOutput.PrepareDocument();
tcs.SetResult(textOutput);
@ -994,19 +998,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -994,19 +998,7 @@ namespace ICSharpCode.ILSpy.TextView
if (referenceSegment.IsLocal)
{
ClearLocalReferenceMarks();
if (references != null)
{
foreach (var r in references)
{
if (reference.Equals(r.Reference))
{
var mark = textMarkerService.Create(r.StartOffset, r.Length);
mark.BackgroundColor = (Color)(r.IsDefinition ? FindResource(ResourceKeys.TextMarkerDefinitionBackgroundColor) : FindResource(ResourceKeys.TextMarkerBackgroundColor));
localReferenceMarks.Add(mark);
}
}
}
SetLocalReferenceMarks(reference);
return;
}
if (definitionLookup != null)
@ -1027,6 +1019,23 @@ namespace ICSharpCode.ILSpy.TextView @@ -1027,6 +1019,23 @@ namespace ICSharpCode.ILSpy.TextView
MessageBus.Send(this, new NavigateToReferenceEventArgs(reference, openInNewTab));
}
private void SetLocalReferenceMarks(object reference)
{
if (references == null || reference == null)
{
return;
}
foreach (var r in references)
{
if (reference.Equals(r.Reference))
{
var mark = textMarkerService.Create(r.StartOffset, r.Length);
mark.BackgroundColor = (Color)(r.IsDefinition ? FindResource(ResourceKeys.TextMarkerDefinitionBackgroundColor) : FindResource(ResourceKeys.TextMarkerBackgroundColor));
localReferenceMarks.Add(mark);
}
}
}
Point? mouseDownPos;
void TextAreaMouseDown(object sender, MouseButtonEventArgs e)
@ -1091,7 +1100,11 @@ namespace ICSharpCode.ILSpy.TextView @@ -1091,7 +1100,11 @@ namespace ICSharpCode.ILSpy.TextView
SaveFileDialog dlg = new SaveFileDialog();
dlg.DefaultExt = language.FileExtension;
dlg.Filter = language.Name + "|*" + language.FileExtension + Properties.Resources.AllFiles;
dlg.FileName = WholeProjectDecompiler.CleanUpFileName(treeNodes.First().ToString(), language.FileExtension);
string? nodeText = treeNodes.First().Text?.ToString();
if (!string.IsNullOrWhiteSpace(nodeText))
{
dlg.FileName = WholeProjectDecompiler.CleanUpFileName(nodeText, language.FileExtension);
}
if (dlg.ShowDialog() == true)
{
SaveToDisk(new DecompilationContext(language, treeNodes.ToArray(), options), dlg.FileName);

4
ILSpy/Util/MessageBus.cs

@ -79,10 +79,10 @@ namespace ICSharpCode.ILSpy.Util @@ -79,10 +79,10 @@ namespace ICSharpCode.ILSpy.Util
public class SettingsChangedEventArgs(PropertyChangedEventArgs e) : WrappedEventArgs<PropertyChangedEventArgs>(e);
public class NavigateToReferenceEventArgs(object reference, bool inNewTabPage = false) : EventArgs
public class NavigateToReferenceEventArgs(object reference, object? source = null, bool inNewTabPage = false) : EventArgs
{
public object Reference { get; } = reference;
public object? Source { get; } = source;
public bool InNewTabPage { get; } = inNewTabPage;
}

2
ILSpy/Views/DebugSteps.xaml.cs

@ -140,7 +140,7 @@ namespace ICSharpCode.ILSpy @@ -140,7 +140,7 @@ namespace ICSharpCode.ILSpy
}
var state = dockWorkspace.ActiveTabPage.GetState();
dockWorkspace.ActiveTabPage.ShowTextViewAsync(textView => textView.DecompileAsync(assemblyTreeModel.CurrentLanguage, assemblyTreeModel.SelectedNodes,
dockWorkspace.ActiveTabPage.ShowTextViewAsync(textView => textView.DecompileAsync(assemblyTreeModel.CurrentLanguage, assemblyTreeModel.SelectedNodes, null,
new DecompilationOptions(assemblyTreeModel.CurrentLanguageVersion, settingsService.DecompilerSettings, settingsService.DisplaySettings) {
StepLimit = step,
IsDebug = isDebug,

Loading…
Cancel
Save