Skip to content

Commit f97e597

Browse files
Fix #3512: Local function name collides with local variable name
1 parent ddb7171 commit f97e597

File tree

2 files changed

+69
-43
lines changed

2 files changed

+69
-43
lines changed

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,30 @@ private void LocalConflictsWithTypeName()
312312
QualifierTests.i.Test();
313313
}
314314
}
315+
#if CS70
316+
private void LocalConflictsWithLocalFunction()
317+
{
318+
int num = 0;
319+
LocalFunction();
320+
321+
void LocalFunction()
322+
{
323+
QualifierTests qualifierTests2 = qualifierTests();
324+
i.Test();
325+
Z(qualifierTests2);
326+
}
315327

328+
QualifierTests qualifierTests()
329+
{
330+
num.ToString();
331+
return new QualifierTests(new string[0]);
332+
}
333+
}
334+
335+
private void Z(QualifierTests qualifierTests)
336+
{
337+
}
338+
#endif
316339
public QualifierTests(string[] Array)
317340
{
318341
System.Array.Sort(Array);

ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs

Lines changed: 46 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -452,53 +452,15 @@ public void Run(ILFunction function, ILTransformContext context)
452452
{
453453
var (currentFunction, parentContext) = this.workList.Dequeue();
454454

455-
if (currentFunction.Kind == ILFunctionKind.LocalFunction)
456-
{
457-
// assign names to local functions
458-
if (!LocalFunctionDecompiler.ParseLocalFunctionName(currentFunction.Name, out _, out var newName) || !IsValidName(newName))
459-
newName = null;
460-
string nameWithoutNumber;
461-
int number;
462-
if (!string.IsNullOrEmpty(newName))
463-
{
464-
nameWithoutNumber = SplitName(newName, out number);
465-
}
466-
else
467-
{
468-
nameWithoutNumber = "f";
469-
number = 1;
470-
}
471-
int count;
472-
if (!parentContext.IsReservedVariableName(nameWithoutNumber, out int currentIndex))
473-
{
474-
count = 1;
475-
}
476-
else
477-
{
478-
if (currentIndex < number)
479-
count = number;
480-
else
481-
count = Math.Max(number, currentIndex) + 1;
482-
}
483-
parentContext.ReserveVariableName(nameWithoutNumber, count);
484-
if (count > 1)
485-
{
486-
newName = nameWithoutNumber + count.ToString();
487-
}
488-
else
489-
{
490-
newName = nameWithoutNumber;
491-
}
492-
currentFunction.Name = newName;
493-
currentFunction.ReducedMethod.Name = newName;
494-
parentContext.Add((MethodDefinitionHandle)currentFunction.ReducedMethod.MetadataToken, newName);
495-
}
496-
497455
var nestedContext = new VariableScope(currentFunction, this.context, parentContext);
498-
currentFunction.Body.AcceptVisitor(this, nestedContext);
499456

500457
foreach (var localFunction in currentFunction.LocalFunctions)
458+
{
459+
AssignNameToLocalFunction(localFunction, nestedContext);
501460
workList.Enqueue((localFunction, nestedContext));
461+
}
462+
463+
currentFunction.Body.AcceptVisitor(this, nestedContext);
502464

503465
if (currentFunction.Kind != ILFunctionKind.TopLevelFunction)
504466
{
@@ -510,6 +472,47 @@ public void Run(ILFunction function, ILTransformContext context)
510472
}
511473
}
512474

475+
private static void AssignNameToLocalFunction(ILFunction function, VariableScope parentContext)
476+
{
477+
if (!LocalFunctionDecompiler.ParseLocalFunctionName(function.Name, out _, out var newName) || !IsValidName(newName))
478+
newName = null;
479+
string nameWithoutNumber;
480+
int number;
481+
if (!string.IsNullOrEmpty(newName))
482+
{
483+
nameWithoutNumber = SplitName(newName, out number);
484+
}
485+
else
486+
{
487+
nameWithoutNumber = "f";
488+
number = 1;
489+
}
490+
int count;
491+
if (!parentContext.IsReservedVariableName(nameWithoutNumber, out int currentIndex))
492+
{
493+
count = 1;
494+
}
495+
else
496+
{
497+
if (currentIndex < number)
498+
count = number;
499+
else
500+
count = Math.Max(number, currentIndex) + 1;
501+
}
502+
parentContext.ReserveVariableName(nameWithoutNumber, count);
503+
if (count > 1)
504+
{
505+
newName = nameWithoutNumber + count.ToString();
506+
}
507+
else
508+
{
509+
newName = nameWithoutNumber;
510+
}
511+
function.Name = newName;
512+
function.ReducedMethod.Name = newName;
513+
parentContext.Add((MethodDefinitionHandle)function.ReducedMethod.MetadataToken, newName);
514+
}
515+
513516
Unit VisitChildren(ILInstruction inst, VariableScope context)
514517
{
515518
foreach (var child in inst.Children)

0 commit comments

Comments
 (0)