Skip to content

Commit ffcd468

Browse files
Fix #1572: parameters of lambdas and local functions are renamed, if there are with names from outer scopes collisions.
1 parent 0481c7d commit ffcd468

File tree

7 files changed

+143
-78
lines changed

7 files changed

+143
-78
lines changed

ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -233,22 +233,21 @@ public async Task CustomShortCircuitOperators([ValueSource(nameof(defaultOptions
233233
[Test]
234234
public async Task ExceptionHandling([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
235235
{
236-
await RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings {
237-
NullPropagation = false,
236+
await RunForLibrary(cscOptions: cscOptions, configureDecompiler: settings => {
237+
settings.NullPropagation = false;
238238
// legacy csc generates a dead store in debug builds
239-
RemoveDeadStores = (cscOptions == CompilerOptions.None),
240-
FileScopedNamespaces = false,
239+
settings.RemoveDeadStores = (cscOptions == CompilerOptions.None);
240+
settings.FileScopedNamespaces = false;
241241
});
242242
}
243243

244244
[Test]
245245
public async Task Switch([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
246246
{
247-
await RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings {
247+
await RunForLibrary(cscOptions: cscOptions, configureDecompiler: settings => {
248248
// legacy csc generates a dead store in debug builds
249-
RemoveDeadStores = (cscOptions == CompilerOptions.None),
250-
SwitchExpressions = false,
251-
FileScopedNamespaces = false,
249+
settings.RemoveDeadStores = (cscOptions == CompilerOptions.None);
250+
settings.SwitchExpressions = false;
252251
});
253252
}
254253

@@ -267,7 +266,10 @@ public async Task ReduceNesting([ValueSource(nameof(defaultOptions))] CompilerOp
267266
[Test]
268267
public async Task DelegateConstruction([ValueSource(nameof(defaultOptionsWithMcs))] CompilerOptions cscOptions)
269268
{
270-
await RunForLibrary(cscOptions: cscOptions);
269+
await RunForLibrary(cscOptions: cscOptions, configureDecompiler: settings => {
270+
settings.QueryExpressions = false;
271+
settings.NullableReferenceTypes = false;
272+
});
271273
}
272274

273275
[Test]
@@ -293,9 +295,9 @@ public async Task Using([ValueSource(nameof(defaultOptions))] CompilerOptions cs
293295
{
294296
await RunForLibrary(
295297
cscOptions: cscOptions,
296-
decompilerSettings: new DecompilerSettings {
297-
UseEnhancedUsing = false,
298-
FileScopedNamespaces = false,
298+
configureDecompiler: settings => {
299+
settings.UseEnhancedUsing = false;
300+
settings.FileScopedNamespaces = false;
299301
}
300302
);
301303
}
@@ -327,11 +329,11 @@ public async Task Generics([ValueSource(nameof(defaultOptions))] CompilerOptions
327329
[Test]
328330
public async Task Loops([ValueSource(nameof(defaultOptionsWithMcs))] CompilerOptions cscOptions)
329331
{
330-
DecompilerSettings settings = Tester.GetSettings(cscOptions);
331-
// legacy csc generates a dead store in debug builds
332-
settings.RemoveDeadStores = (cscOptions == CompilerOptions.None);
333-
settings.UseExpressionBodyForCalculatedGetterOnlyProperties = false;
334-
await RunForLibrary(cscOptions: cscOptions, decompilerSettings: settings);
332+
await RunForLibrary(cscOptions: cscOptions, configureDecompiler: settings => {
333+
// legacy csc generates a dead store in debug builds
334+
settings.RemoveDeadStores = (cscOptions == CompilerOptions.None);
335+
settings.UseExpressionBodyForCalculatedGetterOnlyProperties = false;
336+
});
335337
}
336338

337339
[Test]
@@ -440,9 +442,7 @@ public async Task VariableNaming([ValueSource(nameof(defaultOptions))] CompilerO
440442
[Test]
441443
public async Task VariableNamingWithoutSymbols([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
442444
{
443-
var settings = Tester.GetSettings(cscOptions);
444-
settings.UseDebugSymbols = false;
445-
await RunForLibrary(cscOptions: cscOptions, decompilerSettings: settings);
445+
await RunForLibrary(cscOptions: cscOptions, configureDecompiler: settings => settings.UseDebugSymbols = false);
446446
}
447447

448448
[Test]
@@ -474,7 +474,7 @@ public async Task AsyncUsing([ValueSource(nameof(roslyn3OrNewerOptions))] Compil
474474
{
475475
await RunForLibrary(
476476
cscOptions: cscOptions,
477-
decompilerSettings: new DecompilerSettings { UseEnhancedUsing = false, FileScopedNamespaces = false }
477+
configureDecompiler: settings => { settings.UseEnhancedUsing = false; }
478478
);
479479
}
480480

@@ -499,7 +499,7 @@ public async Task NativeInts([ValueSource(nameof(roslyn3OrNewerWithNet40Options)
499499
[Test]
500500
public async Task FileScopedNamespaces([ValueSource(nameof(roslyn4OrNewerOptions))] CompilerOptions cscOptions)
501501
{
502-
await RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings());
502+
await RunForLibrary(cscOptions: cscOptions, configureDecompiler: settings => settings.FileScopedNamespaces = true);
503503
}
504504

505505
[Test]
@@ -601,7 +601,7 @@ public async Task ConstantsTests([ValueSource(nameof(defaultOptions))] CompilerO
601601
[Test]
602602
public async Task Issue1080([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
603603
{
604-
await RunForLibrary(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings(CSharp.LanguageVersion.CSharp6));
604+
await RunForLibrary(cscOptions: cscOptions, configureDecompiler: settings => settings.SetLanguageVersion(CSharp.LanguageVersion.CSharp6));
605605
}
606606

607607
[Test]
@@ -712,12 +712,12 @@ public async Task MetadataAttributes([ValueSource(nameof(defaultOptions))] Compi
712712
await RunForLibrary(cscOptions: cscOptions);
713713
}
714714

715-
async Task RunForLibrary([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, DecompilerSettings decompilerSettings = null)
715+
async Task RunForLibrary([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, Action<DecompilerSettings> configureDecompiler = null)
716716
{
717-
await Run(testName, asmOptions | AssemblerOptions.Library, cscOptions | CompilerOptions.Library, decompilerSettings);
717+
await Run(testName, asmOptions | AssemblerOptions.Library, cscOptions | CompilerOptions.Library, configureDecompiler);
718718
}
719719

720-
async Task Run([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, DecompilerSettings decompilerSettings = null)
720+
async Task Run([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, Action<DecompilerSettings> configureDecompiler = null)
721721
{
722722
var csFile = Path.Combine(TestCasePath, testName + ".cs");
723723
var exeFile = TestsAssemblyOutput.GetFilePath(TestCasePath, testName, Tester.GetSuffix(cscOptions) + ".exe");
@@ -739,7 +739,9 @@ async Task Run([CallerMemberName] string testName = null, AssemblerOptions asmOp
739739
}
740740

741741
// 2. Decompile
742-
var decompiled = await Tester.DecompileCSharp(exeFile, decompilerSettings ?? Tester.GetSettings(cscOptions)).ConfigureAwait(false);
742+
var settings = Tester.GetSettings(cscOptions);
743+
configureDecompiler?.Invoke(settings);
744+
var decompiled = await Tester.DecompileCSharp(exeFile, settings).ConfigureAwait(false);
743745

744746
// 3. Compile
745747
CodeAssert.FilesAreEqual(csFile, decompiled, Tester.GetPreprocessorSymbols(cscOptions).Append("EXPECTED_OUTPUT").ToArray());

ICSharpCode.Decompiler.Tests/TestCases/ILPretty/GuessAccessors.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ public void MethodUnknownClass()
1515
//IL_0007: Expected O, but got Unknown
1616
UnknownClass val = new UnknownClass();
1717
int? unknownProperty = val.UnknownProperty;
18-
int? num2 = (val.UnknownProperty = unknownProperty.GetValueOrDefault());
19-
int? num3 = num2;
18+
int? num = (val.UnknownProperty = unknownProperty.GetValueOrDefault());
19+
int? num3 = num;
2020
List<object> list = new List<object> {
2121
val[unknownProperty.Value] ?? "",
2222
val.NotProperty,

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,33 @@
1919
using System;
2020
using System.Collections.Generic;
2121
using System.Linq;
22+
using System.Runtime.CompilerServices;
2223
using System.Threading;
2324
#if CS100
2425
using System.Threading.Tasks;
26+
2527
#endif
2628

2729
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty.DelegateConstruction
2830
{
2931
public static class DelegateConstruction
3032
{
33+
internal class Dummy
34+
{
35+
public int baz;
36+
37+
public List<Dummy> more;
38+
}
39+
40+
[CompilerGenerated]
41+
internal class Helper
42+
{
43+
internal bool HelpMe(Dummy dum)
44+
{
45+
return true;
46+
}
47+
}
48+
3149
private class InstanceTests
3250
{
3351
public struct SomeData
@@ -643,6 +661,21 @@ private void Run(ParameterizedThreadStart del, object x)
643661
{
644662
del(x);
645663
}
664+
665+
public void Issue1572(DelegateConstruction.Dummy dum)
666+
{
667+
#if EXPECTED_OUTPUT
668+
DelegateConstruction.Helper CS_0024_003C_003E8__locals0 = new DelegateConstruction.Helper();
669+
DelegateConstruction.Dummy dummy = dum.more.Where((DelegateConstruction.Dummy dummy2) => true).Where((DelegateConstruction.Dummy dummy2) => true).FirstOrDefault();
670+
Console.WriteLine();
671+
dummy.baz++;
672+
#else
673+
DelegateConstruction.Helper h = new DelegateConstruction.Helper();
674+
DelegateConstruction.Dummy localDummy = dum.more.Where(h.HelpMe).Where(h.HelpMe).FirstOrDefault();
675+
Console.WriteLine();
676+
localDummy.baz++;
677+
#endif
678+
}
646679
}
647680

648681
[AttributeUsage(AttributeTargets.All)]

ICSharpCode.Decompiler.Tests/TestCases/VBPretty/Async.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ public async void AwaitYield()
4040
public async void AwaitDefaultYieldAwaitable()
4141
{
4242
#if LEGACY_VBC || (OPTIMIZE && !ROSLYN4)
43-
YieldAwaitable yieldAwaitable = default(YieldAwaitable);
44-
YieldAwaitable yieldAwaitable2 = yieldAwaitable;
45-
await yieldAwaitable2;
43+
YieldAwaitable yieldAwaitable2 = default(YieldAwaitable);
44+
YieldAwaitable yieldAwaitable = yieldAwaitable2;
45+
await yieldAwaitable;
4646
#else
4747
await default(YieldAwaitable);
4848
#endif
@@ -51,9 +51,9 @@ public async void AwaitDefaultYieldAwaitable()
5151
public async void AwaitDefaultHopToThreadPool()
5252
{
5353
#if LEGACY_VBC || (OPTIMIZE && !ROSLYN4)
54-
HopToThreadPoolAwaitable hopToThreadPoolAwaitable = default(HopToThreadPoolAwaitable);
55-
HopToThreadPoolAwaitable hopToThreadPoolAwaitable2 = hopToThreadPoolAwaitable;
56-
await hopToThreadPoolAwaitable2;
54+
HopToThreadPoolAwaitable hopToThreadPoolAwaitable2 = default(HopToThreadPoolAwaitable);
55+
HopToThreadPoolAwaitable hopToThreadPoolAwaitable = hopToThreadPoolAwaitable2;
56+
await hopToThreadPoolAwaitable;
5757
#else
5858
await default(HopToThreadPoolAwaitable);
5959
#endif

ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1282,7 +1282,7 @@ void FixParameterNames(EntityDeclaration entity)
12821282
{
12831283
if (string.IsNullOrWhiteSpace(parameter.Name) && !parameter.Type.IsArgList())
12841284
{
1285-
// needs to be consistent with logic in ILReader.CreateILVarable
1285+
// needs to be consistent with logic in ILReader.CreateILVariable
12861286
parameter.Name = "P_" + i;
12871287
}
12881288
i++;

ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2554,7 +2554,7 @@ IEnumerable<ParameterDeclaration> MakeParameters(IReadOnlyList<IParameter> param
25542554
}
25552555
if (string.IsNullOrEmpty(pd.Name) && !pd.Type.IsArgList())
25562556
{
2557-
// needs to be consistent with logic in ILReader.CreateILVarable(ParameterDefinition)
2557+
// needs to be consistent with logic in ILReader.CreateILVariable
25582558
pd.Name = "P_" + i;
25592559
}
25602560
if (settings.AnonymousTypes && parameter.Type.ContainsAnonymousType())

0 commit comments

Comments
 (0)