Browse Source

[CodeActions] Cleanups in StatementsToInitializerConverter.

newNRvisualizers
Simon Lindgren 13 years ago
parent
commit
903e46d1f8
  1. 107
      ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertToInitializer/StatementsToInitializerConverter.cs

107
ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/ConvertToInitializer/StatementsToInitializerConverter.cs

@ -70,7 +70,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
initializers [mainInitializerPath] = variableInitializer.Initializer.Clone(); initializers [mainInitializerPath] = variableInitializer.Initializer.Clone();
Convert(statements); Convert(statements);
statements = initializers [mainInitializerPath].GetReplacedNodes(); statements = ReplacementNodeHelper.GetReplacedNodes(initializers [mainInitializerPath]);
return new VariableInitializer(mainInitializerPath.RootName, initializers [mainInitializerPath]); return new VariableInitializer(mainInitializerPath.RootName, initializers [mainInitializerPath]);
} }
@ -87,7 +87,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
initializers [mainInitializerPath] = assignmentExpression.Right.Clone(); initializers [mainInitializerPath] = assignmentExpression.Right.Clone();
Convert(statements); Convert(statements);
statements = initializers [mainInitializerPath].GetReplacedNodes(); statements = ReplacementNodeHelper.GetReplacedNodes(initializers [mainInitializerPath]);
return new AssignmentExpression(new IdentifierExpression(mainInitializerPath.RootName), initializers [mainInitializerPath]); return new AssignmentExpression(new IdentifierExpression(mainInitializerPath.RootName), initializers [mainInitializerPath]);
} }
@ -96,24 +96,17 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
foreach (var node in originalStatements) { foreach (var node in originalStatements) {
var comment = node as Comment; var comment = node as Comment;
if (comment != null) { if (comment != null) {
comments.Add((Comment)comment.CloneWithReplacementAnnotation(node)); comments.Add((Comment)ReplacementNodeHelper.CloneWithReplacementAnnotation(comment, node));
continue; continue;
} }
VariableInitializer variableInitializer; var success = TryHandleInitializer(node);
if (TryGetVariableInitializer(node, out variableInitializer)) { if (success) {
var targetResolveResult = context.Resolve(variableInitializer) as LocalResolveResult;
var sourceResolveResult = context.Resolve(variableInitializer.Initializer) as LocalResolveResult;
if (!HasDependency(variableInitializer.Initializer) || CanReplaceDependent(sourceResolveResult)) {
PushNewVariable(targetResolveResult.Variable, variableInitializer.Initializer, node);
} else {
break;
}
continue; continue;
} }
var expressionStatement = node as ExpressionStatement; var expressionStatement = node as ExpressionStatement;
if (expressionStatement == null) if (expressionStatement == null)
break; break;
bool success = TryHandleAssignmentExpression(expressionStatement); success = TryHandleAssignmentExpression(expressionStatement);
if (success) { if (success) {
continue; continue;
} }
@ -125,6 +118,25 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
} }
} }
bool TryHandleInitializer(AstNode node)
{
VariableInitializer variableInitializer;
var variableDeclarationStatement = node as VariableDeclarationStatement;
if (variableDeclarationStatement == null) {
variableInitializer = VariableInitializer.Null;
return false;
}
variableInitializer = variableDeclarationStatement.Variables.FirstOrNullObject();
if (variableInitializer.IsNull)
return false;
var sourceResolveResult = context.Resolve(variableInitializer.Initializer) as LocalResolveResult;
if (HasDependency(variableInitializer.Initializer) && !CanReplaceDependent(sourceResolveResult))
return false;
var targetResolveResult = context.Resolve(variableInitializer) as LocalResolveResult;
AddNewVariable(targetResolveResult.Variable, variableInitializer.Initializer, node);
return true;
}
bool TryHandleAddCall(ExpressionStatement expressionStatement) bool TryHandleAddCall(ExpressionStatement expressionStatement)
{ {
var invocationExpression = expressionStatement.Expression as InvocationExpression; var invocationExpression = expressionStatement.Expression as InvocationExpression;
@ -144,9 +156,9 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
if (argumentLocalResolveResult != null) { if (argumentLocalResolveResult != null) {
var initializerPath = InitializerPath.FromResolveResult(argumentLocalResolveResult); var initializerPath = InitializerPath.FromResolveResult(argumentLocalResolveResult);
argument = initializers [initializerPath]; argument = initializers [initializerPath];
argument.AddReplacementAnnotation(expressionStatement); ReplacementNodeHelper.AddReplacementAnnotation(argument, expressionStatement);
} else { } else {
argument = argument.CloneWithReplacementAnnotation(expressionStatement); argument = ReplacementNodeHelper.CloneWithReplacementAnnotation(argument, expressionStatement);
} }
var targetPath = InitializerPath.FromResolveResult(targetResult); var targetPath = InitializerPath.FromResolveResult(targetResult);
@ -170,23 +182,10 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
bool CanReplaceDependent(ResolveResult resolveResult) bool CanReplaceDependent(ResolveResult resolveResult)
{ {
if (resolveResult == null)
return false;
return resolveResult is LocalResolveResult; return resolveResult is LocalResolveResult;
} }
bool TryGetVariableInitializer(AstNode node, out VariableInitializer variableInitializer) void AddNewVariable(IVariable variable, Expression initializer, AstNode node)
{
var variableDeclarationStatement = node as VariableDeclarationStatement;
if (variableDeclarationStatement == null) {
variableInitializer = VariableInitializer.Null;
return false;
}
variableInitializer = variableDeclarationStatement.Variables.FirstOrNullObject();
return !variableInitializer.IsNull;
}
void PushNewVariable(IVariable variable, Expression initializer, AstNode node)
{ {
var variablePath = new InitializerPath(variable); var variablePath = new InitializerPath(variable);
var rightResolveResult = context.Resolve(initializer) as LocalResolveResult; var rightResolveResult = context.Resolve(initializer) as LocalResolveResult;
@ -200,7 +199,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
mainInitializerPath = variablePath; mainInitializerPath = variablePath;
} }
} else { } else {
initializers [variablePath] = initializer.CloneWithReplacementAnnotation(node); initializers [variablePath] = ReplacementNodeHelper.CloneWithReplacementAnnotation(initializer, node);
} }
} }
@ -208,7 +207,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
{ {
if (targetPath != null) { if (targetPath != null) {
if (initializers.ContainsKey(targetPath)) { if (initializers.ContainsKey(targetPath)) {
foreach (var astNode in initializers[targetPath].GetAllReplacementAnnotations()) { foreach (var astNode in ReplacementNodeHelper.GetAllReplacementAnnotations(initializers[targetPath])) {
initializer.AddAnnotation(astNode); initializer.AddAnnotation(astNode);
} }
} }
@ -218,6 +217,8 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
bool PushAssignment(Expression left, Expression right, AstNode node) bool PushAssignment(Expression left, Expression right, AstNode node)
{ {
var rightResolveResult = context.Resolve(right) as LocalResolveResult; var rightResolveResult = context.Resolve(right) as LocalResolveResult;
var leftResolveResult = context.Resolve(left);
var leftPath = InitializerPath.FromResolveResult(leftResolveResult);
Expression initializer; Expression initializer;
if (rightResolveResult != null) { if (rightResolveResult != null) {
var rightPath = InitializerPath.FromResolveResult(rightResolveResult); var rightPath = InitializerPath.FromResolveResult(rightResolveResult);
@ -229,12 +230,12 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
} else { } else {
initializer = right.Clone(); initializer = right.Clone();
} }
var leftResolveResult = context.Resolve(left); // Move replacement annotations over, in case this is the second assignment
var leftPath = InitializerPath.FromResolveResult(leftResolveResult); // to the same variable.
AddOldAnnotationsToInitializer(leftPath, initializer); AddOldAnnotationsToInitializer(leftPath, initializer);
if (leftResolveResult is LocalResolveResult) { if (leftResolveResult is LocalResolveResult) {
AstNodeExtensions.AddReplacementAnnotation(initializer, node); ReplacementNodeHelper.AddReplacementAnnotation(initializer, node);
initializers [leftPath] = initializer; initializers [leftPath] = initializer;
return true; return true;
} }
@ -255,7 +256,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
comments.Clear(); comments.Clear();
AddToInitializer(parentInitializer, new NamedExpression(member.Name, initializer)); AddToInitializer(parentInitializer, new NamedExpression(member.Name, initializer));
AstNodeExtensions.AddReplacementAnnotation(initializer, node); ReplacementNodeHelper.AddReplacementAnnotation(initializer, node);
initializers [leftPath] = initializer; initializers [leftPath] = initializer;
return true; return true;
} }
@ -370,46 +371,44 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring
public AstNode ReplacedNode { get; set; } public AstNode ReplacedNode { get; set; }
} }
static class AstNodeExtensions class ReplacementNodeHelper
{ {
public static void AddReplacementAnnotation(this AstNode node, AstNode replacedNode) public static void AddReplacementAnnotation(AstNode node, AstNode replacedNode)
{ {
node.AddAnnotation(new ReplacementNodeAnnotation() { node.AddAnnotation(new ReplacementNodeAnnotation() {
ReplacedNode = replacedNode ReplacedNode = replacedNode
}); });
} }
public static AstNode CloneWithReplacementAnnotation(this AstNode node, AstNode replacedNode) public static AstNode CloneWithReplacementAnnotation(AstNode node, AstNode replacedNode)
{ {
var newNode = node.Clone(); var newNode = node.Clone();
newNode.AddReplacementAnnotation(replacedNode); AddReplacementAnnotation(newNode, replacedNode);
return newNode; return newNode;
} }
public static Expression CloneWithReplacementAnnotation(this Expression expression, AstNode replacedNode) public static Expression CloneWithReplacementAnnotation(Expression expression, AstNode replacedNode)
{ {
var newNode = expression.Clone(); var newExpression = expression.Clone();
newNode.AddReplacementAnnotation(replacedNode); AddReplacementAnnotation(newExpression, replacedNode);
return newNode; return newExpression;
} }
public static IEnumerable<ReplacementNodeAnnotation> GetAllReplacementAnnotations(this AstNode node) public static IEnumerable<ReplacementNodeAnnotation> GetAllReplacementAnnotations(AstNode node)
{ {
foreach (var n in node.DescendantsAndSelf) { return
var annotations = n.Annotations.Where(a => a is ReplacementNodeAnnotation) from n in node.DescendantsAndSelf
.Select<object, ReplacementNodeAnnotation>(a2 => (ReplacementNodeAnnotation)a2); from annotation in n.Annotations
foreach (var annotation in annotations) { let replacementAnnotation = annotation as ReplacementNodeAnnotation
yield return annotation; where replacementAnnotation != null
} select replacementAnnotation;
}
} }
public static IList<AstNode> GetReplacedNodes(this Expression expression) public static IList<AstNode> GetReplacedNodes(AstNode expression)
{ {
return GetAllReplacementAnnotations(expression) return GetAllReplacementAnnotations(expression)
.Select<ReplacementNodeAnnotation, AstNode>(a => a.ReplacedNode) .Select(a => a.ReplacedNode)
.ToList(); .ToList();
} }
} }
} }

Loading…
Cancel
Save