Browse Source

Assign names to parameters. Closes #41, #81.

pull/100/head
Daniel Grunwald 15 years ago
parent
commit
892996f079
  1. 4
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  2. 43
      ICSharpCode.Decompiler/Ast/NameVariables.cs

4
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -64,8 +64,8 @@ namespace ICSharpCode.Decompiler.Ast
bodyGraph.Optimize(context, ilMethod); bodyGraph.Optimize(context, ilMethod);
context.CancellationToken.ThrowIfCancellationRequested(); context.CancellationToken.ThrowIfCancellationRequested();
var allVariables = ilMethod.GetSelfAndChildrenRecursive<ILExpression>(e => e.Operand is ILVariable).Select(e => (ILVariable)e.Operand).Where(v => !v.IsGenerated).Distinct(); var allVariables = ilMethod.GetSelfAndChildrenRecursive<ILExpression>(e => e.Operand is ILVariable).Select(e => (ILVariable)e.Operand).Distinct();
NameVariables.AssignNamesToVariables(methodDef.Parameters.Select(p => p.Name), allVariables, ilMethod); NameVariables.AssignNamesToVariables(methodDef.Parameters, allVariables, ilMethod);
context.CancellationToken.ThrowIfCancellationRequested(); context.CancellationToken.ThrowIfCancellationRequested();
Ast.BlockStatement astBlock = TransformBlock(ilMethod); Ast.BlockStatement astBlock = TransformBlock(ilMethod);

43
ICSharpCode.Decompiler/Ast/NameVariables.cs

@ -31,12 +31,19 @@ namespace ICSharpCode.Decompiler.Ast
}; };
public static void AssignNamesToVariables(IEnumerable<string> existingNames, IEnumerable<ILVariable> variables, ILBlock methodBody) public static void AssignNamesToVariables(IEnumerable<ParameterDefinition> parameters, IEnumerable<ILVariable> variables, ILBlock methodBody)
{ {
NameVariables nv = new NameVariables(); NameVariables nv = new NameVariables();
nv.AddExistingNames(existingNames); nv.AddExistingNames(parameters.Select(p => p.Name));
nv.AddExistingNames(variables.Where(v => v.IsGenerated).Select(v => v.Name));
foreach (ParameterDefinition p in parameters) {
if (string.IsNullOrEmpty(p.Name))
p.Name = nv.GenerateNameForVariableOrParameter(p, p.ParameterType, methodBody);
}
foreach (ILVariable varDef in variables) { foreach (ILVariable varDef in variables) {
nv.AssignNameToVariable(varDef, methodBody.GetSelfAndChildrenRecursive<ILExpression>()); if (!varDef.IsGenerated) {
varDef.Name = nv.GenerateNameForVariableOrParameter(varDef, varDef.Type, methodBody);
}
} }
} }
@ -69,29 +76,31 @@ namespace ICSharpCode.Decompiler.Ast
} }
} }
void AssignNameToVariable(ILVariable varDef, IEnumerable<ILExpression> allExpressions) string GenerateNameForVariableOrParameter(object variableOrParameter, TypeReference varType, ILBlock methodBody)
{ {
string proposedName = null; var proposedNameForStores =
foreach (ILExpression expr in allExpressions) { (from expr in methodBody.GetSelfAndChildrenRecursive<ILExpression>()
if (expr.Operand != varDef) where expr.Code == ILCode.Stloc && expr.Operand == variableOrParameter
continue; select GetNameFromExpression(expr.Arguments.Single()) into name
if (expr.Code == ILCode.Stloc) { where !string.IsNullOrEmpty(name)
proposedName = GetNameFromExpression(expr.Arguments.Single()); select name).Distinct().ToList();
}
if (proposedName != null) string proposedName;
break; if (proposedNameForStores.Count == 1) {
proposedName = proposedNameForStores[0];
} else {
// TODO: infer proposed names from loads
proposedName = GetNameByType(varType);
} }
if (proposedName == null)
proposedName = GetNameByType(varDef.Type);
if (!typeNames.ContainsKey(proposedName)) { if (!typeNames.ContainsKey(proposedName)) {
typeNames.Add(proposedName, 0); typeNames.Add(proposedName, 0);
} }
int count = ++typeNames[proposedName]; int count = ++typeNames[proposedName];
if (count > 1) { if (count > 1) {
varDef.Name = proposedName + count.ToString(); return proposedName + count.ToString();
} else { } else {
varDef.Name = proposedName; return proposedName;
} }
} }

Loading…
Cancel
Save