Browse Source

Annotate VariableInitializers with ILVariable when possible

pull/262/head
jbevain 14 years ago
parent
commit
96c7204789
  1. 1
      ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  2. 23
      ICSharpCode.Decompiler/Ast/Transforms/DeclareVariables.cs

1
ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -128,6 +128,7 @@ namespace ICSharpCode.Decompiler.Ast
else
type = AstBuilder.ConvertType(v.Type);
var newVarDecl = new VariableDeclarationStatement(type, v.Name);
newVarDecl.Variables.Single().AddAnnotation(v);
astBlock.Statements.InsertBefore(insertionPoint, newVarDecl);
}

23
ICSharpCode.Decompiler/Ast/Transforms/DeclareVariables.cs

@ -21,6 +21,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using ICSharpCode.Decompiler.ILAst;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.Analysis;
@ -35,6 +36,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
{
public AstType Type;
public string Name;
public ILVariable ILVariable;
public AssignmentExpression ReplacedAssignment;
public Statement InsertionPoint;
@ -67,9 +69,10 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
if (v.ReplacedAssignment != null) {
// We clone the right expression so that it doesn't get removed from the old ExpressionStatement,
// which might be still in use by the definite assignment graph.
VariableInitializer initializer = new VariableInitializer(v.Name, v.ReplacedAssignment.Right.Detach()).CopyAnnotationsFrom(v.ReplacedAssignment).WithAnnotation(v.ILVariable);
VariableDeclarationStatement varDecl = new VariableDeclarationStatement {
Type = (AstType)v.Type.Clone(),
Variables = { new VariableInitializer(v.Name, v.ReplacedAssignment.Right.Detach()).CopyAnnotationsFrom(v.ReplacedAssignment) }
Variables = { initializer }
};
ExpressionStatement es = v.ReplacedAssignment.Parent as ExpressionStatement;
if (es != null) {
@ -100,9 +103,11 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
daa = new DefiniteAssignmentAnalysis(block, cancellationToken);
}
foreach (VariableDeclarationStatement varDecl in variables) {
string variableName = varDecl.Variables.Single().Name;
bool allowPassIntoLoops = varDecl.Variables.Single().Annotation<DelegateConstruction.CapturedVariableAnnotation>() == null;
DeclareVariableInBlock(daa, block, varDecl.Type, variableName, allowPassIntoLoops);
VariableInitializer initializer = varDecl.Variables.Single();
string variableName = initializer.Name;
ILVariable v = initializer.Annotation<ILVariable>();
bool allowPassIntoLoops = initializer.Annotation<DelegateConstruction.CapturedVariableAnnotation>() == null;
DeclareVariableInBlock(daa, block, varDecl.Type, variableName, v, allowPassIntoLoops);
}
}
}
@ -111,7 +116,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
}
}
void DeclareVariableInBlock(DefiniteAssignmentAnalysis daa, BlockStatement block, AstType type, string variableName, bool allowPassIntoLoops)
void DeclareVariableInBlock(DefiniteAssignmentAnalysis daa, BlockStatement block, AstType type, string variableName, ILVariable v, bool allowPassIntoLoops)
{
// declarationPoint: The point where the variable would be declared, if we decide to declare it in this block
Statement declarationPoint = null;
@ -139,10 +144,10 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
foreach (AstNode child in stmt.Children) {
BlockStatement subBlock = child as BlockStatement;
if (subBlock != null) {
DeclareVariableInBlock(daa, subBlock, type, variableName, allowPassIntoLoops);
DeclareVariableInBlock(daa, subBlock, type, variableName, v, allowPassIntoLoops);
} else if (HasNestedBlocks(child)) {
foreach (BlockStatement nestedSubBlock in child.Children.OfType<BlockStatement>()) {
DeclareVariableInBlock(daa, nestedSubBlock, type, variableName, allowPassIntoLoops);
DeclareVariableInBlock(daa, nestedSubBlock, type, variableName, v, allowPassIntoLoops);
}
}
}
@ -151,7 +156,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
// Try converting an assignment expression into a VariableDeclarationStatement
if (!TryConvertAssignmentExpressionIntoVariableDeclaration(declarationPoint, type, variableName)) {
// Declare the variable in front of declarationPoint
variablesToDeclare.Add(new VariableToDeclare { Type = type, Name = variableName, InsertionPoint = declarationPoint });
variablesToDeclare.Add(new VariableToDeclare { Type = type, Name = variableName, ILVariable = v, InsertionPoint = declarationPoint });
}
}
}
@ -172,7 +177,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms
if (ae != null && ae.Operator == AssignmentOperatorType.Assign) {
IdentifierExpression ident = ae.Left as IdentifierExpression;
if (ident != null && ident.Identifier == variableName) {
variablesToDeclare.Add(new VariableToDeclare { Type = type, Name = variableName, ReplacedAssignment = ae });
variablesToDeclare.Add(new VariableToDeclare { Type = type, Name = variableName, ILVariable = ident.Annotation<ILVariable>(), ReplacedAssignment = ae });
return true;
}
}

Loading…
Cancel
Save