Skip to content

Commit a40a033

Browse files
Merge pull request #3416 from icsharpcode/variable-naming
Add scopes to AssignVariableName
2 parents 73e9771 + 355a039 commit a40a033

File tree

19 files changed

+617
-381
lines changed

19 files changed

+617
-381
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: 8 additions & 8 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,
@@ -50,9 +50,9 @@ public void MethodUnknownGenericClass()
5050
//IL_00e1: Expected O, but got Unknown
5151
//IL_00e1: Expected O, but got Unknown
5252
UnknownGenericClass<UnknownEventArgs> val = new UnknownGenericClass<UnknownEventArgs>();
53-
UnknownEventArgs val2 = (val.UnknownProperty = val.UnknownProperty);
53+
UnknownEventArgs e = (val.UnknownProperty = val.UnknownProperty);
5454
List<object> list = new List<object> {
55-
val[((object)val2).GetHashCode()] ?? "",
55+
val[((object)e).GetHashCode()] ?? "",
5656
val.NotProperty,
5757
val.get_NotPropertyWithGeneric<string>(42),
5858
val[42],
@@ -61,10 +61,10 @@ public void MethodUnknownGenericClass()
6161
};
6262
val.OnEvent += Instance_OnEvent;
6363
val.OnEvent -= Instance_OnEvent;
64-
UnknownEventArgs val3 = val[(UnknownEventArgs)null];
65-
val[new UnknownEventArgs()] = val3;
66-
UnknownEventArgs val4 = val[new UnknownEventArgs(), new UnknownEventArgs()];
67-
val[new UnknownEventArgs(), new UnknownEventArgs()] = val4;
64+
UnknownEventArgs e2 = val[(UnknownEventArgs)null];
65+
val[new UnknownEventArgs()] = e2;
66+
UnknownEventArgs e3 = val[new UnknownEventArgs(), new UnknownEventArgs()];
67+
val[new UnknownEventArgs(), new UnknownEventArgs()] = e3;
6868
}
6969

7070
public void MethodUnknownStatic()

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4943,8 +4943,8 @@ public void Issue1552StmtTwice(CustomStruct a, CustomStruct b)
49434943

49444944
public void Issue1779(int value)
49454945
{
4946-
CustomStruct2 @struct = GetStruct();
4947-
@struct.IntProp += value;
4946+
CustomStruct2 customStruct = GetStruct();
4947+
customStruct.IntProp += value;
49484948
}
49494949
}
49504950
}

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

Lines changed: 36 additions & 3 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
@@ -377,10 +395,10 @@ public static void NameConflict()
377395
public static void NameConflict2(int j)
378396
{
379397
List<Action<int>> list = new List<Action<int>>();
380-
for (int k = 0; k < 10; k++)
398+
for (int i = 0; i < 10; i++)
381399
{
382-
list.Add(delegate (int i) {
383-
Console.WriteLine(i);
400+
list.Add(delegate (int k) {
401+
Console.WriteLine(k);
384402
});
385403
}
386404
}
@@ -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/Pretty/ExceptionHandling.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -418,9 +418,9 @@ public void GenericException<TException>(int input) where TException : Exception
418418
{
419419
Console.WriteLine(input);
420420
}
421-
catch (TException val)
421+
catch (TException ex)
422422
{
423-
Console.WriteLine(val.Message);
423+
Console.WriteLine(ex.Message);
424424
throw;
425425
}
426426
}
@@ -452,9 +452,9 @@ public void GenericExceptionWithCondition<TException>(int input) where TExceptio
452452
{
453453
Console.WriteLine(input);
454454
}
455-
catch (TException val) when (val.Message.Contains("Test"))
455+
catch (TException ex) when (ex.Message.Contains("Test"))
456456
{
457-
Console.WriteLine(val.Message);
457+
Console.WriteLine(ex.Message);
458458
throw;
459459
}
460460
}
@@ -465,9 +465,9 @@ public void GenericException2WithCondition<TException>(int input) where TExcepti
465465
{
466466
Console.WriteLine(input);
467467
}
468-
catch (TException val) when (val.Message.Contains("Test"))
468+
catch (TException ex) when (ex.Message.Contains("Test"))
469469
{
470-
Console.WriteLine("{0} {1}", val, val.ToString());
470+
Console.WriteLine("{0} {1}", ex, ex.ToString());
471471
}
472472
}
473473

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,11 @@ public void CallOnRefReturn()
182182
GetRef<ReadOnlyStruct>().Method();
183183

184184
// call on a copy, not the original ref:
185-
NormalStruct @ref = GetRef<NormalStruct>();
186-
@ref.Method();
185+
NormalStruct normalStruct = GetRef<NormalStruct>();
186+
normalStruct.Method();
187187

188-
ReadOnlyStruct ref2 = GetRef<ReadOnlyStruct>();
189-
ref2.Method();
188+
ReadOnlyStruct readOnlyStruct = GetRef<ReadOnlyStruct>();
189+
readOnlyStruct.Method();
190190
}
191191

192192
public void CallOnReadOnlyRefReturn()
@@ -293,13 +293,13 @@ public void CallSiteTests(NormalStruct s, ReadOnlyStruct r, ReadOnlyRefStruct rr
293293

294294
public void RefReassignment(ref NormalStruct s)
295295
{
296-
ref NormalStruct @ref = ref GetRef<NormalStruct>();
297-
RefReassignment(ref @ref);
296+
ref NormalStruct reference = ref GetRef<NormalStruct>();
297+
RefReassignment(ref reference);
298298
if (s.GetHashCode() == 0)
299299
{
300-
@ref = ref GetRef<NormalStruct>();
300+
reference = ref GetRef<NormalStruct>();
301301
}
302-
RefReassignment(ref @ref.GetHashCode() == 4 ? ref @ref : ref s);
302+
RefReassignment(ref reference.GetHashCode() == 4 ? ref reference : ref s);
303303
}
304304

305305
public static void Main(string[] args)

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: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2547,15 +2547,18 @@ IEnumerable<ParameterDeclaration> MakeParameters(IReadOnlyList<IParameter> param
25472547
foreach (var parameter in parameters)
25482548
{
25492549
var pd = astBuilder.ConvertParameter(parameter);
2550+
if (variables.TryGetValue(i, out var v))
2551+
{
2552+
pd.AddAnnotation(new ILVariableResolveResult(v, parameters[i].Type));
2553+
pd.Name = v.Name;
2554+
}
25502555
if (string.IsNullOrEmpty(pd.Name) && !pd.Type.IsArgList())
25512556
{
2552-
// needs to be consistent with logic in ILReader.CreateILVarable(ParameterDefinition)
2557+
// needs to be consistent with logic in ILReader.CreateILVariable
25532558
pd.Name = "P_" + i;
25542559
}
25552560
if (settings.AnonymousTypes && parameter.Type.ContainsAnonymousType())
25562561
pd.Type = null;
2557-
if (variables.TryGetValue(i, out var v))
2558-
pd.AddAnnotation(new ILVariableResolveResult(v, parameters[i].Type));
25592562
yield return pd;
25602563
i++;
25612564
}

0 commit comments

Comments
 (0)