|
|
@ -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; |
|
|
|
} |
|
|
|
} |
|
|
|