|
|
@ -51,6 +51,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms |
|
|
|
ILTransformContext context; |
|
|
|
ILTransformContext context; |
|
|
|
string[] currentFieldNames; |
|
|
|
string[] currentFieldNames; |
|
|
|
Dictionary<string, int> reservedVariableNames; |
|
|
|
Dictionary<string, int> reservedVariableNames; |
|
|
|
|
|
|
|
HashSet<ILVariable> loopCounters; |
|
|
|
const char maxLoopVariableName = 'n'; |
|
|
|
const char maxLoopVariableName = 'n'; |
|
|
|
|
|
|
|
|
|
|
|
public void Run(ILFunction function, ILTransformContext context) |
|
|
|
public void Run(ILFunction function, ILTransformContext context) |
|
|
@ -58,6 +59,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms |
|
|
|
this.context = context; |
|
|
|
this.context = context; |
|
|
|
currentFieldNames = function.Method.DeclaringType.Fields.Select(f => f.Name).ToArray(); |
|
|
|
currentFieldNames = function.Method.DeclaringType.Fields.Select(f => f.Name).ToArray(); |
|
|
|
reservedVariableNames = new Dictionary<string, int>(); |
|
|
|
reservedVariableNames = new Dictionary<string, int>(); |
|
|
|
|
|
|
|
loopCounters = CollectLoopCounters(function); |
|
|
|
foreach (var p in function.Descendants.OfType<ILFunction>().Select(f => f.Method).SelectMany(m => m.Parameters)) |
|
|
|
foreach (var p in function.Descendants.OfType<ILFunction>().Select(f => f.Method).SelectMany(m => m.Parameters)) |
|
|
|
AddExistingName(p.Name); |
|
|
|
AddExistingName(p.Name); |
|
|
|
foreach (ILFunction f in function.Descendants.OfType<ILFunction>().Reverse()) { |
|
|
|
foreach (ILFunction f in function.Descendants.OfType<ILFunction>().Reverse()) { |
|
|
@ -67,6 +69,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms |
|
|
|
|
|
|
|
|
|
|
|
void PerformAssignment(ILFunction function) |
|
|
|
void PerformAssignment(ILFunction function) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
// remove unused variables before assigning names
|
|
|
|
|
|
|
|
function.Variables.RemoveDead(); |
|
|
|
foreach (var v in function.Variables) { |
|
|
|
foreach (var v in function.Variables) { |
|
|
|
switch (v.Kind) { |
|
|
|
switch (v.Kind) { |
|
|
|
case VariableKind.Parameter: // ignore
|
|
|
|
case VariableKind.Parameter: // ignore
|
|
|
@ -138,20 +142,26 @@ namespace ICSharpCode.Decompiler.IL.Transforms |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
string GenerateNameForVariable(ILVariable variable, ILInstruction methodBody) |
|
|
|
HashSet<ILVariable> CollectLoopCounters(ILFunction function) |
|
|
|
{ |
|
|
|
{ |
|
|
|
string proposedName = null; |
|
|
|
var loopCounters = new HashSet<ILVariable>(); |
|
|
|
if (variable.Type.IsKnownType(KnownTypeCode.Int32)) { |
|
|
|
|
|
|
|
// test whether the variable might be a loop counter
|
|
|
|
foreach (BlockContainer possibleLoop in function.Descendants.OfType<BlockContainer>()) { |
|
|
|
bool isLoopCounter = false; |
|
|
|
|
|
|
|
foreach (BlockContainer possibleLoop in methodBody.Descendants.OfType<BlockContainer>().Reverse()) { |
|
|
|
|
|
|
|
if (possibleLoop.EntryPoint.IncomingEdgeCount == 1) continue; |
|
|
|
if (possibleLoop.EntryPoint.IncomingEdgeCount == 1) continue; |
|
|
|
var loop = DetectedLoop.DetectLoop(possibleLoop); |
|
|
|
var loop = DetectedLoop.DetectLoop(possibleLoop); |
|
|
|
if (loop.Kind != LoopKind.For || loop.IncrementTarget == null) continue; |
|
|
|
if (loop.Kind != LoopKind.For || loop.IncrementTarget == null) continue; |
|
|
|
if (loop.IncrementTarget == variable) |
|
|
|
loopCounters.Add(loop.IncrementTarget); |
|
|
|
isLoopCounter = true; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return loopCounters; |
|
|
|
} |
|
|
|
} |
|
|
|
if (isLoopCounter) { |
|
|
|
|
|
|
|
|
|
|
|
string GenerateNameForVariable(ILVariable variable, ILInstruction methodBody) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
string proposedName = null; |
|
|
|
|
|
|
|
if (variable.Type.IsKnownType(KnownTypeCode.Int32)) { |
|
|
|
|
|
|
|
// test whether the variable might be a loop counter
|
|
|
|
|
|
|
|
if (loopCounters.Contains(variable)) { |
|
|
|
// For loop variables, use i,j,k,l,m,n
|
|
|
|
// For loop variables, use i,j,k,l,m,n
|
|
|
|
for (char c = 'i'; c <= maxLoopVariableName; c++) { |
|
|
|
for (char c = 'i'; c <= maxLoopVariableName; c++) { |
|
|
|
if (!reservedVariableNames.ContainsKey(c.ToString())) { |
|
|
|
if (!reservedVariableNames.ContainsKey(c.ToString())) { |
|
|
|