From 8e1ed7e962cd43eb3c1c42e3f8ac02e3fa843e1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Kr=C3=BCger?= Date: Fri, 5 Oct 2012 07:36:38 +0200 Subject: [PATCH] [Refactoring] Format text can now take a node list to format / fixed a formatting issue. --- .../Formatter/AstFormattingVisitor.cs | 17 +++++++++++------ .../CodeActions/IterateViaForeachAction.cs | 2 +- .../Refactoring/DocumentScript.cs | 17 +++++++++++------ .../Refactoring/Script.cs | 16 ++++++++++++---- .../CodeActions/ConvertSwitchToIfTests.cs | 11 ++++++++--- .../CSharp/CodeActions/MoveToOuterScopeTests.cs | 6 +++--- .../SplitDeclarationAndAssignmentTests.cs | 1 + 7 files changed, 47 insertions(+), 23 deletions(-) diff --git a/ICSharpCode.NRefactory.CSharp/Formatter/AstFormattingVisitor.cs b/ICSharpCode.NRefactory.CSharp/Formatter/AstFormattingVisitor.cs index 06c1f6e4b6..a9de1e7295 100644 --- a/ICSharpCode.NRefactory.CSharp/Formatter/AstFormattingVisitor.cs +++ b/ICSharpCode.NRefactory.CSharp/Formatter/AstFormattingVisitor.cs @@ -119,16 +119,20 @@ namespace ICSharpCode.NRefactory.CSharp protected override void VisitChildren (AstNode node) { - if (!FormattingRegion.IsEmpty) { - if (node.EndLocation < FormattingRegion.Begin || node.StartLocation > FormattingRegion.End) - return; - } - AstNode next; for (var child = node.FirstChild; child != null; child = next) { // Store next to allow the loop to continue // if the visitor removes/replaces child. next = child.NextSibling; + + if (!FormattingRegion.IsEmpty) { + if (child.EndLocation < FormattingRegion.Begin) { + continue; + } + if (child.StartLocation > FormattingRegion.End) { + break; + } + } child.AcceptVisitor (this); } } @@ -404,7 +408,8 @@ namespace ICSharpCode.NRefactory.CSharp void ForceSpace(int startOffset, int endOffset, bool forceSpace) { int lastNonWs = SearchLastNonWsChar(startOffset, endOffset); - AddChange(lastNonWs + 1, System.Math.Max(0, endOffset - lastNonWs - 1), forceSpace ? " " : ""); + if (lastNonWs >= 0) + AddChange(lastNonWs + 1, System.Math.Max(0, endOffset - lastNonWs - 1), forceSpace ? " " : ""); } // void ForceSpacesAfter (AstNode n, bool forceSpaces) // { diff --git a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/IterateViaForeachAction.cs b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/IterateViaForeachAction.cs index 0e3fed4fe2..a29a9f62c5 100644 --- a/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/IterateViaForeachAction.cs +++ b/ICSharpCode.NRefactory.CSharp/Refactoring/CodeActions/IterateViaForeachAction.cs @@ -70,7 +70,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring var blockStatement = new BlockStatement(); blockStatement.Statements.Add(iterator); script.Replace(usingStatement.EmbeddedStatement, blockStatement); - script.FormatText(blockStatement); + script.FormatText((AstNode)blockStatement); } else if (usingStatement.EmbeddedStatement is BlockStatement) { var anchorNode = usingStatement.EmbeddedStatement.FirstChild; script.InsertAfter(anchorNode, iterator); diff --git a/ICSharpCode.NRefactory.CSharp/Refactoring/DocumentScript.cs b/ICSharpCode.NRefactory.CSharp/Refactoring/DocumentScript.cs index 537ccf5c28..41af9dd2d2 100644 --- a/ICSharpCode.NRefactory.CSharp/Refactoring/DocumentScript.cs +++ b/ICSharpCode.NRefactory.CSharp/Refactoring/DocumentScript.cs @@ -17,8 +17,10 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Linq; using System.Diagnostics; using ICSharpCode.NRefactory.Editor; +using System.Collections.Generic; namespace ICSharpCode.NRefactory.CSharp.Refactoring { @@ -95,14 +97,17 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring return originalDocument.Version.MoveOffsetTo(currentDocument.Version, originalDocumentOffset); } - public override void FormatText(AstNode node) + public override void FormatText(IEnumerable nodes) { - var segment = GetSegment(node); var syntaxTree = SyntaxTree.Parse(currentDocument, "dummy.cs"); - var formatter = new AstFormattingVisitor(FormattingOptions, currentDocument, Options); - formatter.FormattingRegion = new ICSharpCode.NRefactory.TypeSystem.DomRegion (node.StartLocation, node.EndLocation); - syntaxTree.AcceptVisitor(formatter); - formatter.ApplyChanges(segment.Offset, segment.Length); + foreach (var node in nodes.OrderByDescending (n => n.StartLocation)) { + var segment = GetSegment(node); + var formatter = new AstFormattingVisitor(FormattingOptions, currentDocument, Options); + + formatter.FormattingRegion = new ICSharpCode.NRefactory.TypeSystem.DomRegion (node.StartLocation, node.EndLocation); + syntaxTree.AcceptVisitor(formatter); + formatter.ApplyChanges(segment.Offset, segment.Length); + } } protected override int GetIndentLevelAt(int offset) diff --git a/ICSharpCode.NRefactory.CSharp/Refactoring/Script.cs b/ICSharpCode.NRefactory.CSharp/Refactoring/Script.cs index 51897bf50e..75d92c1c7e 100644 --- a/ICSharpCode.NRefactory.CSharp/Refactoring/Script.cs +++ b/ICSharpCode.NRefactory.CSharp/Refactoring/Script.cs @@ -202,21 +202,28 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring CorrectFormatting (node, node); } + List nodesToFormat = new List (); + void CorrectFormatting(AstNode node, AstNode newNode) { if (node is Identifier || node is IdentifierExpression || node is CSharpTokenNode || node is AstType) return; if (node == null || node.Parent is BlockStatement) { - FormatText(newNode); + nodesToFormat.Add (newNode); } else { - FormatText((node.Parent != null && (node.Parent is Statement || node.Parent is Expression || node.Parent is VariableInitializer)) ? node.Parent : newNode); + nodesToFormat.Add ((node.Parent != null && (node.Parent is Statement || node.Parent is Expression || node.Parent is VariableInitializer)) ? node.Parent : newNode); } } public abstract void Remove (AstNode node, bool removeEmptyLine = true); - public abstract void FormatText (AstNode node); - + public abstract void FormatText (IEnumerable nodes); + + public void FormatText (params AstNode[] node) + { + FormatText ((IEnumerable)node); + } + public virtual void Select (AstNode node) { // default implementation: do nothing @@ -380,6 +387,7 @@ namespace ICSharpCode.NRefactory.CSharp.Refactoring public virtual void Dispose() { + FormatText (nodesToFormat); } public enum NewTypeContext { diff --git a/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertSwitchToIfTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertSwitchToIfTests.cs index 5f2bc4180b..1af817801d 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertSwitchToIfTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/ConvertSwitchToIfTests.cs @@ -138,10 +138,15 @@ class TestClass { if (a == 0) { int b = 1; - } else if (a == 1 || a == 2) { - } else if (a == 3 || a == 4 || a == 5) { - } else { } + else + if (a == 1 || a == 2) { + } + else + if (a == 3 || a == 4 || a == 5) { + } + else { + } } }"); } diff --git a/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/MoveToOuterScopeTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/MoveToOuterScopeTests.cs index c9f40e5503..897d332420 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/MoveToOuterScopeTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/MoveToOuterScopeTests.cs @@ -88,7 +88,7 @@ class A int i = 2; while (true) { int j = 3; - } + } "); } @@ -116,10 +116,10 @@ class A } ", @" int j; - while (true) { + while (true) { int i = 2; j = i; - } + } "); } diff --git a/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/SplitDeclarationAndAssignmentTests.cs b/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/SplitDeclarationAndAssignmentTests.cs index b0eb3566e9..8d5749671a 100644 --- a/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/SplitDeclarationAndAssignmentTests.cs +++ b/ICSharpCode.NRefactory.Tests/CSharp/CodeActions/SplitDeclarationAndAssignmentTests.cs @@ -101,6 +101,7 @@ namespace ICSharpCode.NRefactory.CSharp.CodeActions " {" + Environment.NewLine + " int i;" + Environment.NewLine + " for (i = 1; i < 10; i++) {" + Environment.NewLine + + " " + Environment.NewLine + " }" + Environment.NewLine + " }" + Environment.NewLine + "}", result);