Browse Source

Support params keyword on non-array collections

net10upgrade-future
ds5678 3 months ago committed by Siegfried Pammer
parent
commit
b05b9231ec
  1. 3
      ICSharpCode.Decompiler.Tests/Helpers/Tester.cs
  2. 4
      ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
  3. 6
      ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs
  4. 21
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/ParamsCollections.cs
  5. 3
      ICSharpCode.Decompiler/CSharp/CSharpLanguageVersion.cs
  6. 1
      ICSharpCode.Decompiler/CSharp/Transforms/EscapeInvalidIdentifiers.cs
  7. 24
      ICSharpCode.Decompiler/DecompilerSettings.cs
  8. 11
      ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs
  9. 3
      ICSharpCode.Decompiler/TypeSystem/Implementation/AttributeListBuilder.cs
  10. 2
      ICSharpCode.Decompiler/TypeSystem/Implementation/KnownAttributes.cs
  11. 18
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataParameter.cs
  12. 1
      ILSpy/Languages/CSharpLanguage.cs
  13. 9
      ILSpy/Properties/Resources.Designer.cs
  14. 3
      ILSpy/Properties/Resources.resx
  15. 3
      ILSpy/Properties/Resources.zh-Hans.resx

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

@ -459,6 +459,7 @@ namespace System.Runtime.CompilerServices @@ -459,6 +459,7 @@ namespace System.Runtime.CompilerServices
preprocessorSymbols.Add("CS100");
preprocessorSymbols.Add("CS110");
preprocessorSymbols.Add("CS120");
preprocessorSymbols.Add("CS130");
}
}
else if ((flags & CompilerOptions.UseMcsMask) != 0)
@ -705,7 +706,7 @@ namespace System.Runtime.CompilerServices @@ -705,7 +706,7 @@ namespace System.Runtime.CompilerServices
CompilerOptions.UseRoslyn1_3_2 => CSharp.LanguageVersion.CSharp6,
CompilerOptions.UseRoslyn2_10_0 => CSharp.LanguageVersion.CSharp7_3,
CompilerOptions.UseRoslyn3_11_0 => CSharp.LanguageVersion.CSharp9_0,
_ => cscOptions.HasFlag(CompilerOptions.Preview) ? CSharp.LanguageVersion.Latest : CSharp.LanguageVersion.CSharp12_0,
_ => cscOptions.HasFlag(CompilerOptions.Preview) ? CSharp.LanguageVersion.Latest : CSharp.LanguageVersion.CSharp13_0,
};
DecompilerSettings settings = new(langVersion) {
// Never use file-scoped namespaces

4
ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj

@ -8,6 +8,7 @@ @@ -8,6 +8,7 @@
<PropertyGroup>
<TargetFramework>net10.0-windows</TargetFramework>
<LangVersion>13</LangVersion>
<RuntimeIdentifier Condition="$(IsWindowsX64) == true">win-x64</RuntimeIdentifier>
<RuntimeIdentifier Condition="$(IsWindowsARM64) == true">win-arm64</RuntimeIdentifier>
@ -17,7 +18,7 @@ @@ -17,7 +18,7 @@
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<NoWarn>1701;1702;1705,67,169,1058,728,1720,649,168,251,660,661,675;1998;162;8632;626;8618;8714;8602;8981</NoWarn>
<DefineConstants>ROSLYN;ROSLYN2;ROSLYN3;ROSLYN4;NET60;CS60;CS70;CS71;CS72;CS73;CS80;CS90;CS100;CS110;CS120</DefineConstants>
<DefineConstants>ROSLYN;ROSLYN2;ROSLYN3;ROSLYN4;NET60;CS60;CS70;CS71;CS72;CS73;CS80;CS90;CS100;CS110;CS120;CS130</DefineConstants>
<GenerateAssemblyVersionAttribute>False</GenerateAssemblyVersionAttribute>
<GenerateAssemblyFileVersionAttribute>False</GenerateAssemblyFileVersionAttribute>
@ -146,6 +147,7 @@ @@ -146,6 +147,7 @@
<Compile Include="TestCases\Pretty\Issue3442.cs" />
<Compile Include="TestCases\Pretty\Issue3483.cs" />
<Compile Include="TestCases\Pretty\PointerArithmetic.cs" />
<Compile Include="TestCases\Pretty\ParamsCollections.cs" />
<None Include="TestCases\VBPretty\VBAutomaticEvents.vb" />
<Compile Include="TestCases\VBPretty\VBAutomaticEvents.cs" />
<Compile Include="TestCases\VBPretty\VBNonGenericForEach.cs" />

6
ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs

@ -605,6 +605,12 @@ namespace ICSharpCode.Decompiler.Tests @@ -605,6 +605,12 @@ namespace ICSharpCode.Decompiler.Tests
await RunForLibrary(cscOptions: cscOptions);
}
[Test]
public async Task ParamsCollections([ValueSource(nameof(roslyn4OrNewerOptions))] CompilerOptions cscOptions)
{
await RunForLibrary(cscOptions: cscOptions);
}
[Test]
public async Task Issue1080([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
{

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

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
public static class ParamsCollections
{
public static void ParamsEnumerable(params IEnumerable<int> values)
{
}
public static void ParamsList(params List<int> values)
{
}
public static void ParamsReadOnlySpan(params ReadOnlySpan<int> values)
{
}
public static void ParamsSpan(params Span<int> values)
{
}
}
}

3
ICSharpCode.Decompiler/CSharp/CSharpLanguageVersion.cs

@ -35,7 +35,8 @@ namespace ICSharpCode.Decompiler.CSharp @@ -35,7 +35,8 @@ namespace ICSharpCode.Decompiler.CSharp
CSharp10_0 = 1000,
CSharp11_0 = 1100,
CSharp12_0 = 1200,
Preview = 1100,
CSharp13_0 = 1300,
Preview = 1300,
Latest = 0x7FFFFFFF
}
}

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

@ -166,6 +166,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -166,6 +166,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
"System.Runtime.CompilerServices.NullableAttribute",
"System.Runtime.CompilerServices.NullableContextAttribute",
"System.Runtime.CompilerServices.NativeIntegerAttribute",
"System.Runtime.CompilerServices.ParamCollectionAttribute",
"System.Runtime.CompilerServices.RefSafetyRulesAttribute",
"System.Runtime.CompilerServices.ScopedRefAttribute",
"System.Runtime.CompilerServices.RequiresLocationAttribute",

24
ICSharpCode.Decompiler/DecompilerSettings.cs

@ -166,10 +166,16 @@ namespace ICSharpCode.Decompiler @@ -166,10 +166,16 @@ namespace ICSharpCode.Decompiler
usePrimaryConstructorSyntaxForNonRecordTypes = false;
inlineArrays = false;
}
if (languageVersion < CSharp.LanguageVersion.CSharp13_0)
{
paramsCollections = false;
}
}
public CSharp.LanguageVersion GetMinimumRequiredVersion()
{
if (paramsCollections)
return CSharp.LanguageVersion.CSharp13_0;
if (refReadOnlyParameters || usePrimaryConstructorSyntaxForNonRecordTypes || inlineArrays)
return CSharp.LanguageVersion.CSharp12_0;
if (scopedRef || requiredMembers || numericIntPtr || utf8StringLiterals || unsignedRightShift || checkedOperators)
@ -849,6 +855,24 @@ namespace ICSharpCode.Decompiler @@ -849,6 +855,24 @@ namespace ICSharpCode.Decompiler
}
}
bool paramsCollections = true;
/// <summary>
/// Support params collections.
/// </summary>
[Category("C# 13.0 / VS 2022.12")]
[Description("DecompilerSettings.DecompileParamsCollections")]
public bool ParamsCollections {
get { return paramsCollections; }
set {
if (paramsCollections != value)
{
paramsCollections = value;
OnPropertyChanged();
}
}
}
bool lockStatement = true;
/// <summary>

11
ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs

@ -138,12 +138,19 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -138,12 +138,19 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// </summary>
RefReadOnlyParameters = 0x10000,
/// <summary>
/// If this option is active, [ParamCollectionAttribute] on parameters is removed
/// and parameters are marked as params.
/// Otherwise, the attribute is preserved but the parameters are not marked
/// as if it was a normal parameter without any attributes.
/// </summary>
ParamsCollections = 0x20000,
/// <summary>
/// Default settings: typical options for the decompiler, with all C# languages features enabled.
/// </summary>
Default = Dynamic | Tuple | ExtensionMethods | DecimalConstants | ReadOnlyStructsAndParameters
| RefStructs | UnmanagedConstraints | NullabilityAnnotations | ReadOnlyMethods
| NativeIntegers | FunctionPointers | ScopedRef | NativeIntegersWithoutAttribute
| RefReadOnlyParameters
| RefReadOnlyParameters | ParamsCollections
}
/// <summary>
@ -185,6 +192,8 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -185,6 +192,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
typeSystemOptions |= TypeSystemOptions.NativeIntegersWithoutAttribute;
if (settings.RefReadOnlyParameters)
typeSystemOptions |= TypeSystemOptions.RefReadOnlyParameters;
if (settings.ParamsCollections)
typeSystemOptions |= TypeSystemOptions.ParamsCollections;
return typeSystemOptions;
}

3
ICSharpCode.Decompiler/TypeSystem/Implementation/AttributeListBuilder.cs

@ -258,6 +258,9 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -258,6 +258,9 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
case "RequiresLocationAttribute":
return (options & TypeSystemOptions.RefReadOnlyParameters) != 0
&& (target == SymbolKind.Parameter);
case "ParamCollectionAttribute":
return (options & TypeSystemOptions.ParamsCollections) != 0
&& (target == SymbolKind.Parameter);
default:
return false;
}

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

@ -87,6 +87,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -87,6 +87,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
// Parameter attributes:
ParamArray,
ParamCollection,
In,
Out,
Optional,
@ -169,6 +170,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -169,6 +170,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
new TopLevelTypeName("System.Runtime.CompilerServices", nameof(IndexerNameAttribute)),
// Parameter attributes:
new TopLevelTypeName("System", nameof(ParamArrayAttribute)),
new TopLevelTypeName("System.Runtime.CompilerServices", "ParamCollectionAttribute"),
new TopLevelTypeName("System.Runtime.InteropServices", nameof(InAttribute)),
new TopLevelTypeName("System.Runtime.InteropServices", nameof(OutAttribute)),
new TopLevelTypeName("System.Runtime.InteropServices", nameof(OptionalAttribute)),

18
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataParameter.cs

@ -125,6 +125,12 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -125,6 +125,12 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
var metadata = module.metadata;
var parameterDef = metadata.GetParameter(handle);
if ((module.TypeSystemOptions & TypeSystemOptions.ParamsCollections) != 0
&& parameterDef.GetCustomAttributes().HasKnownAttribute(metadata, KnownAttribute.ParamCollection))
{
// params collections are implicitly scoped
return default;
}
if (parameterDef.GetCustomAttributes().HasKnownAttribute(metadata, KnownAttribute.ScopedRef))
{
return new LifetimeAnnotation { ScopedRef = true };
@ -135,11 +141,17 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -135,11 +141,17 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public bool IsParams {
get {
if (Type.Kind != TypeKind.Array)
return false;
var metadata = module.metadata;
var parameterDef = metadata.GetParameter(handle);
return parameterDef.GetCustomAttributes().HasKnownAttribute(metadata, KnownAttribute.ParamArray);
if (Type.Kind == TypeKind.Array)
{
return parameterDef.GetCustomAttributes().HasKnownAttribute(metadata, KnownAttribute.ParamArray);
}
if (module.TypeSystemOptions.HasFlag(TypeSystemOptions.ParamsCollections))
{
return parameterDef.GetCustomAttributes().HasKnownAttribute(metadata, KnownAttribute.ParamCollection);
}
return false;
}
}

1
ILSpy/Languages/CSharpLanguage.cs

@ -116,6 +116,7 @@ namespace ICSharpCode.ILSpy @@ -116,6 +116,7 @@ namespace ICSharpCode.ILSpy
new LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp10_0.ToString(), "C# 10.0 / VS 2022"),
new LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp11_0.ToString(), "C# 11.0 / VS 2022.4"),
new LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp12_0.ToString(), "C# 12.0 / VS 2022.8"),
new LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp13_0.ToString(), "C# 13.0 / VS 2022.12"),
};
}
return versions;

9
ILSpy/Properties/Resources.Designer.cs generated

@ -918,6 +918,15 @@ namespace ICSharpCode.ILSpy.Properties { @@ -918,6 +918,15 @@ namespace ICSharpCode.ILSpy.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Decompile params collections.
/// </summary>
public static string DecompilerSettings_DecompileParamsCollections {
get {
return ResourceManager.GetString("DecompilerSettings.DecompileParamsCollections", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Decompile use of the &apos;dynamic&apos; type.
/// </summary>

3
ILSpy/Properties/Resources.resx

@ -327,6 +327,9 @@ Are you sure you want to continue?</value> @@ -327,6 +327,9 @@ Are you sure you want to continue?</value>
<data name="DecompilerSettings.DecompileForEachWithGetEnumeratorExtension" xml:space="preserve">
<value>Decompile foreach statements with GetEnumerator extension methods</value>
</data>
<data name="DecompilerSettings.DecompileParamsCollections" xml:space="preserve">
<value>Decompile params collections</value>
</data>
<data name="DecompilerSettings.DecompileUseOfTheDynamicType" xml:space="preserve">
<value>Decompile use of the 'dynamic' type</value>
</data>

3
ILSpy/Properties/Resources.zh-Hans.resx

@ -315,6 +315,9 @@ @@ -315,6 +315,9 @@
<data name="DecompilerSettings.DecompileForEachWithGetEnumeratorExtension" xml:space="preserve">
<value>反编译使用 GetEnumerator 扩展方法的 foreach 语句</value>
</data>
<data name="DecompilerSettings.DecompileParamsCollections" xml:space="preserve">
<value />
</data>
<data name="DecompilerSettings.DecompileUseOfTheDynamicType" xml:space="preserve">
<value>反编译 dynamic 类型</value>
</data>

Loading…
Cancel
Save