Skip to content

Commit 382ee0f

Browse files
Merge latest master with firstClassSpanTypes feature
Co-authored-by: christophwille <[email protected]>
1 parent 98d27e8 commit 382ee0f

File tree

17 files changed

+368
-77
lines changed

17 files changed

+368
-77
lines changed

Directory.Packages.props

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
<PackageVersion Include="K4os.Compression.LZ4" Version="1.3.8" />
1515
<PackageVersion Include="McMaster.Extensions.CommandLineUtils" Version="4.1.1" />
1616
<PackageVersion Include="McMaster.Extensions.Hosting.CommandLine" Version="4.1.1" />
17-
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0" />
18-
<PackageVersion Include="Microsoft.CodeAnalysis.VisualBasic" Version="4.14.0" />
17+
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="5.0.0" />
18+
<PackageVersion Include="Microsoft.CodeAnalysis.VisualBasic" Version="5.0.0" />
1919
<PackageVersion Include="Microsoft.DiaSymReader.Converter.Xml" Version="1.1.0-beta2-22171-02" />
2020
<PackageVersion Include="Microsoft.DiaSymReader" Version="1.4.0" />
2121
<PackageVersion Include="Microsoft.DiaSymReader.Native" Version="17.0.0-beta1.21524.1" />

ICSharpCode.Decompiler.Tests/Helpers/Tester.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,7 @@ internal static DecompilerSettings GetSettings(CompilerOptions cscOptions)
721721
CompilerOptions.UseRoslyn1_3_2 => CSharp.LanguageVersion.CSharp6,
722722
CompilerOptions.UseRoslyn2_10_0 => CSharp.LanguageVersion.CSharp7_3,
723723
CompilerOptions.UseRoslyn3_11_0 => CSharp.LanguageVersion.CSharp9_0,
724-
_ => cscOptions.HasFlag(CompilerOptions.Preview) ? CSharp.LanguageVersion.Latest : CSharp.LanguageVersion.CSharp13_0,
724+
_ => cscOptions.HasFlag(CompilerOptions.Preview) ? CSharp.LanguageVersion.Latest : CSharp.LanguageVersion.CSharp14_0,
725725
};
726726
DecompilerSettings settings = new(langVersion) {
727727
// Never use file-scoped namespaces

ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,7 @@ public async Task Issue3598([ValueSource(nameof(roslyn4OrNewerOptions))] Compile
562562
[Test]
563563
public async Task ExtensionProperties([ValueSource(nameof(roslyn4OrNewerOptions))] CompilerOptions cscOptions)
564564
{
565-
await RunForLibrary(cscOptions: cscOptions | CompilerOptions.Preview);
565+
await RunForLibrary(cscOptions: cscOptions | CompilerOptions.Preview | CompilerOptions.NullableEnable);
566566
}
567567

568568
[Test]

ICSharpCode.Decompiler.Tests/TestCases/Pretty/NamedArguments.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,34 @@ internal ClassWithNamedArgCtor()
3232
}
3333
}
3434

35+
private class MustNotUseNamedArgsInCtor
36+
{
37+
public MustNotUseNamedArgsInCtor(string start = "", bool enable = false)
38+
{
39+
}
40+
41+
public MustNotUseNamedArgsInCtor(bool enable, string start = "")
42+
{
43+
}
44+
45+
public static MustNotUseNamedArgsInCtor Use()
46+
{
47+
// second overload
48+
MustNotUseNamedArgsInCall(true);
49+
// first overload
50+
MustNotUseNamedArgsInCall();
51+
return new MustNotUseNamedArgsInCtor(true);
52+
}
53+
54+
public static void MustNotUseNamedArgsInCall(string start = "", bool enable = false)
55+
{
56+
}
57+
58+
public static void MustNotUseNamedArgsInCall(bool enable, string start = "")
59+
{
60+
}
61+
}
62+
3563
public void Use(int a, int b, int c)
3664
{
3765
}

ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1310,7 +1310,7 @@ EntityDeclaration DoDecompile(ITypeDefinition typeDef, DecompileRun decompileRun
13101310
decompileRun.RecordDecompilers.Add(typeDef, recordDecompiler);
13111311

13121312
// With C# 9 records, the relative order of fields and properties matters:
1313-
IEnumerable<IMember> fieldsAndProperties = typeDef.IsRecord
1313+
IEnumerable<IMember> fieldsAndProperties = isRecord
13141314
? recordDecompiler.FieldsAndProperties
13151315
: typeDef.Fields.Concat<IMember>(typeDef.Properties);
13161316

ICSharpCode.Decompiler/CSharp/CallBuilder.cs

Lines changed: 49 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,30 @@ private int GetActualArgumentCount()
6464
return FirstOptionalArgumentIndex;
6565
}
6666

67+
public string[] GetArgumentNames(int skipCount = 0)
68+
{
69+
string[] argumentNames = ArgumentNames;
70+
if (AddNamesToPrimitiveValues && IsPrimitiveValue.Any() && !IsExpandedForm
71+
&& !ParameterNames.Any(string.IsNullOrEmpty))
72+
{
73+
Debug.Assert(skipCount == 0);
74+
if (argumentNames == null)
75+
{
76+
argumentNames = new string[Arguments.Length];
77+
}
78+
79+
for (int i = 0; i < Arguments.Length; i++)
80+
{
81+
if (IsPrimitiveValue[i] && argumentNames[i] == null)
82+
{
83+
argumentNames[i] = ParameterNames[i];
84+
}
85+
}
86+
}
87+
88+
return argumentNames;
89+
}
90+
6791
public IList<ResolveResult> GetArgumentResolveResults(int skipCount = 0)
6892
{
6993
var expectedParameters = ExpectedParameters;
@@ -95,33 +119,17 @@ public IList<ResolveResult> GetArgumentResolveResultsDirect(int skipCount = 0)
95119

96120
public IEnumerable<Expression> GetArgumentExpressions(int skipCount = 0)
97121
{
98-
if (AddNamesToPrimitiveValues && IsPrimitiveValue.Any() && !IsExpandedForm
99-
&& !ParameterNames.Any(p => string.IsNullOrEmpty(p)))
100-
{
101-
Debug.Assert(skipCount == 0);
102-
if (ArgumentNames == null)
103-
{
104-
ArgumentNames = new string[Arguments.Length];
105-
}
106-
107-
for (int i = 0; i < Arguments.Length; i++)
108-
{
109-
if (IsPrimitiveValue[i] && ArgumentNames[i] == null)
110-
{
111-
ArgumentNames[i] = ParameterNames[i];
112-
}
113-
}
114-
}
122+
var argumentNames = GetArgumentNames(skipCount);
115123
int argumentCount = GetActualArgumentCount();
116124
var useImplicitlyTypedOut = UseImplicitlyTypedOut;
117-
if (ArgumentNames == null)
125+
if (argumentNames == null)
118126
{
119127
return Arguments.Skip(skipCount).Take(argumentCount).Select(arg => AddAnnotations(arg.Expression));
120128
}
121129
else
122130
{
123131
Debug.Assert(skipCount == 0);
124-
return Arguments.Take(argumentCount).Zip(ArgumentNames.Take(argumentCount),
132+
return Arguments.Take(argumentCount).Zip(argumentNames.Take(argumentCount),
125133
(arg, name) => {
126134
if (name == null)
127135
return AddAnnotations(arg.Expression);
@@ -531,6 +539,10 @@ public ExpressionWithResolveResult Build(OpCode callOpCode, IMethod method,
531539
Expression targetExpr;
532540
string methodName = method.Name;
533541
AstNodeCollection<AstType> typeArgumentList;
542+
if ((transform & CallTransformation.NoNamedArgsForPrettiness) != 0)
543+
{
544+
argumentList.AddNamesToPrimitiveValues = false;
545+
}
534546
if ((transform & CallTransformation.NoOptionalArgumentAllowed) != 0)
535547
{
536548
argumentList.FirstOptionalArgumentIndex = -1;
@@ -674,7 +686,7 @@ public ExpressionWithResolveResult BuildCollectionInitializerExpression(OpCode c
674686
argumentList.UseImplicitlyTypedOut = false;
675687
var transform = GetRequiredTransformationsForCall(expectedTargetDetails, method, ref unused,
676688
ref argumentList, CallTransformation.None, out _);
677-
Debug.Assert(transform == CallTransformation.None || transform == CallTransformation.NoOptionalArgumentAllowed);
689+
Debug.Assert((transform & ~(CallTransformation.NoOptionalArgumentAllowed | CallTransformation.NoNamedArgsForPrettiness)) == 0);
678690

679691
// Calls with only one argument do not need an array initializer expression to wrap them.
680692
// Any special cases are handled by the caller (i.e., ExpressionBuilder.TranslateObjectAndCollectionInitializer)
@@ -1121,7 +1133,8 @@ enum CallTransformation
11211133
/// Add calls to AsRefReadOnly for in parameters that did not have an explicit DirectionExpression yet.
11221134
/// </summary>
11231135
EnforceExplicitIn = 8,
1124-
All = 0xf,
1136+
NoNamedArgsForPrettiness = 0x10,
1137+
All = 0x1f,
11251138
}
11261139

11271140
private CallTransformation GetRequiredTransformationsForCall(ExpectedTargetDetails expectedTargetDetails, IMethod method,
@@ -1198,7 +1211,7 @@ private CallTransformation GetRequiredTransformationsForCall(ExpectedTargetDetai
11981211
bool skipTargetCast = method.Accessibility <= Accessibility.Protected && expressionBuilder.IsBaseTypeOfCurrentType(method.DeclaringTypeDefinition);
11991212
OverloadResolutionErrors errors;
12001213
while ((errors = IsUnambiguousCall(expectedTargetDetails, method, targetResolveResult, typeArguments,
1201-
argumentList.GetArgumentResolveResults().ToArray(), argumentList.ArgumentNames, argumentList.FirstOptionalArgumentIndex, out foundMethod,
1214+
argumentList.GetArgumentResolveResults().ToArray(), argumentList.GetArgumentNames(), argumentList.FirstOptionalArgumentIndex, out foundMethod,
12021215
out var bestCandidateIsExpandedForm)) != OverloadResolutionErrors.None || bestCandidateIsExpandedForm != argumentList.IsExpandedForm)
12031216
{
12041217
switch (errors)
@@ -1228,7 +1241,11 @@ private CallTransformation GetRequiredTransformationsForCall(ExpectedTargetDetai
12281241
default:
12291242
// TODO : implement some more intelligent algorithm that decides which of these fixes (cast args, add target, cast target, add type args)
12301243
// is best in this case. Additionally we should not cast all arguments at once, but step-by-step try to add only a minimal number of casts.
1231-
if (argumentList.FirstOptionalArgumentIndex >= 0)
1244+
if (argumentList.AddNamesToPrimitiveValues)
1245+
{
1246+
argumentList.AddNamesToPrimitiveValues = false;
1247+
}
1248+
else if (argumentList.FirstOptionalArgumentIndex >= 0)
12321249
{
12331250
argumentList.FirstOptionalArgumentIndex = -1;
12341251
}
@@ -1293,6 +1310,8 @@ private CallTransformation GetRequiredTransformationsForCall(ExpectedTargetDetai
12931310
transform |= CallTransformation.RequireTypeArguments;
12941311
if (argumentList.FirstOptionalArgumentIndex < 0)
12951312
transform |= CallTransformation.NoOptionalArgumentAllowed;
1313+
if (!argumentList.AddNamesToPrimitiveValues)
1314+
transform |= CallTransformation.NoNamedArgsForPrettiness;
12961315
return transform;
12971316
}
12981317

@@ -1438,7 +1457,7 @@ private ExpressionWithResolveResult HandleImplicitConversion(IMethod method, Tra
14381457
var conversions = CSharpConversions.Get(expressionBuilder.compilation);
14391458
IType targetType = method.ReturnType;
14401459
var conv = conversions.ImplicitConversion(argument.Type, targetType);
1441-
if (!(conv.IsUserDefined && conv.IsValid && conv.Method.Equals(method)))
1460+
if (!(conv.IsUserDefined && conv.IsValid && conv.Method.Equals(method, NormalizeTypeVisitor.TypeErasure)))
14421461
{
14431462
// implicit conversion to targetType isn't directly possible, so first insert a cast to the argument type
14441463
argument = argument.ConvertTo(method.Parameters[0].Type, expressionBuilder);
@@ -1766,9 +1785,14 @@ ExpressionWithResolveResult HandleConstructorCall(ExpectedTargetDetails expected
17661785
{
17671786
while (IsUnambiguousCall(expectedTargetDetails, method, null, Empty<IType>.Array,
17681787
argumentList.GetArgumentResolveResults().ToArray(),
1769-
argumentList.ArgumentNames, argumentList.FirstOptionalArgumentIndex, out _,
1788+
argumentList.GetArgumentNames(), argumentList.FirstOptionalArgumentIndex, out _,
17701789
out var bestCandidateIsExpandedForm) != OverloadResolutionErrors.None || bestCandidateIsExpandedForm != argumentList.IsExpandedForm)
17711790
{
1791+
if (argumentList.AddNamesToPrimitiveValues)
1792+
{
1793+
argumentList.AddNamesToPrimitiveValues = false;
1794+
continue;
1795+
}
17721796
if (argumentList.FirstOptionalArgumentIndex >= 0)
17731797
{
17741798
argumentList.FirstOptionalArgumentIndex = -1;

0 commit comments

Comments
 (0)