diff --git a/ICSharpCode.NRefactory.CSharp/Formatter/AstFormattingVisitor.cs b/ICSharpCode.NRefactory.CSharp/Formatter/AstFormattingVisitor.cs
index f8f12fa782..6f9484cb33 100644
--- a/ICSharpCode.NRefactory.CSharp/Formatter/AstFormattingVisitor.cs
+++ b/ICSharpCode.NRefactory.CSharp/Formatter/AstFormattingVisitor.cs
@@ -205,7 +205,15 @@ namespace ICSharpCode.NRefactory.CSharp
public override void VisitSyntaxTree(SyntaxTree unit)
{
- base.VisitSyntaxTree(unit);
+ AstNode next;
+ for (var child = unit.FirstChild; child != null; child = next) {
+ // Store next to allow the loop to continue
+ // if the visitor removes/replaces child.
+ next = child.NextSibling;
+ if (child is EntityDeclaration)
+ FormatAttributedNode(child);
+ child.AcceptVisitor (this);
+ }
}
public void EnsureBlankLinesAfter(AstNode node, int blankLines)
@@ -294,7 +302,17 @@ namespace ICSharpCode.NRefactory.CSharp
if (policy.IndentNamespaceBody) {
curIndent.Push(IndentType.Block);
}
- base.VisitNamespaceDeclaration(namespaceDeclaration);
+
+ AstNode next;
+ for (var child = namespaceDeclaration.FirstChild; child != null; child = next) {
+ // Store next to allow the loop to continue
+ // if the visitor removes/replaces child.
+ next = child.NextSibling;
+ if (child is EntityDeclaration)
+ FormatAttributedNode(child);
+ child.AcceptVisitor (this);
+ }
+
if (policy.IndentNamespaceBody) {
curIndent.Pop ();
}
@@ -303,7 +321,6 @@ namespace ICSharpCode.NRefactory.CSharp
public override void VisitTypeDeclaration(TypeDeclaration typeDeclaration)
{
- FormatAttributedNode(typeDeclaration);
BraceStyle braceStyle;
bool indentBody = false;
switch (typeDeclaration.ClassType) {
@@ -332,7 +349,17 @@ namespace ICSharpCode.NRefactory.CSharp
if (indentBody) {
curIndent.Push(IndentType.Block);
}
- base.VisitTypeDeclaration(typeDeclaration);
+
+ AstNode next;
+ for (var child = typeDeclaration.FirstChild; child != null; child = next) {
+ // Store next to allow the loop to continue
+ // if the visitor removes/replaces child.
+ next = child.NextSibling;
+ if (child is EntityDeclaration)
+ FormatAttributedNode(child);
+ child.AcceptVisitor (this);
+ }
+
if (indentBody) {
curIndent.Pop ();
}
@@ -498,7 +525,6 @@ namespace ICSharpCode.NRefactory.CSharp
public override void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)
{
- FormatAttributedNode(propertyDeclaration);
bool oneLine = false;
switch (policy.PropertyFormatting) {
case PropertyFormatting.AllowOneLine:
@@ -620,7 +646,6 @@ namespace ICSharpCode.NRefactory.CSharp
FormatParameters(indexerDeclaration);
- FormatAttributedNode(indexerDeclaration);
EnforceBraceStyle(policy.PropertyBraceStyle, indexerDeclaration.LBraceToken, indexerDeclaration.RBraceToken);
if (policy.IndentPropertyBody) {
curIndent.Push(IndentType.Block);
@@ -664,7 +689,6 @@ namespace ICSharpCode.NRefactory.CSharp
public override void VisitCustomEventDeclaration(CustomEventDeclaration eventDeclaration)
{
- FormatAttributedNode(eventDeclaration);
EnforceBraceStyle(policy.EventBraceStyle, eventDeclaration.LBraceToken, eventDeclaration.RBraceToken);
if (policy.IndentEventBody) {
curIndent.Push(IndentType.Block);
@@ -708,13 +732,6 @@ namespace ICSharpCode.NRefactory.CSharp
public override void VisitEventDeclaration(EventDeclaration eventDeclaration)
{
- FormatAttributedNode(eventDeclaration);
- if (eventDeclaration.NextSibling is EventDeclaration && IsSimpleEvent(eventDeclaration) && IsSimpleEvent(eventDeclaration.NextSibling)) {
- EnsureBlankLinesAfter(eventDeclaration, policy.BlankLinesBetweenEventFields);
- } else if (IsMember(eventDeclaration.NextSibling)) {
- EnsureBlankLinesAfter(eventDeclaration, policy.BlankLinesBetweenMembers);
- }
-
var lastLoc = eventDeclaration.StartLocation;
curIndent.Push(IndentType.Block);
foreach (var initializer in eventDeclaration.Variables) {
@@ -725,8 +742,14 @@ namespace ICSharpCode.NRefactory.CSharp
initializer.AcceptVisitor(this);
}
curIndent.Pop ();
+ if (eventDeclaration.NextSibling is EventDeclaration && IsSimpleEvent(eventDeclaration) && IsSimpleEvent(eventDeclaration.NextSibling)) {
+ EnsureBlankLinesAfter(eventDeclaration, policy.BlankLinesBetweenEventFields);
+ } else if (IsMember(eventDeclaration.NextSibling)) {
+ EnsureBlankLinesAfter(eventDeclaration, policy.BlankLinesBetweenMembers);
+ }
}
+
public override void VisitAccessor(Accessor accessor)
{
FixIndentationForceNewLine(accessor.StartLocation);
@@ -735,7 +758,6 @@ namespace ICSharpCode.NRefactory.CSharp
public override void VisitFieldDeclaration(FieldDeclaration fieldDeclaration)
{
- FormatAttributedNode(fieldDeclaration);
fieldDeclaration.ReturnType.AcceptVisitor(this);
FormatCommas(fieldDeclaration, policy.SpaceBeforeFieldDeclarationComma, policy.SpaceAfterFieldDeclarationComma);
if (fieldDeclaration.NextSibling is FieldDeclaration || fieldDeclaration.NextSibling is FixedFieldDeclaration) {
@@ -758,7 +780,6 @@ namespace ICSharpCode.NRefactory.CSharp
public override void VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration)
{
- FormatAttributedNode(fixedFieldDeclaration);
FormatCommas(fixedFieldDeclaration, policy.SpaceBeforeFieldDeclarationComma, policy.SpaceAfterFieldDeclarationComma);
if (fixedFieldDeclaration.NextSibling is FieldDeclaration || fixedFieldDeclaration.NextSibling is FixedFieldDeclaration) {
EnsureBlankLinesAfter(fixedFieldDeclaration, policy.BlankLinesBetweenFields);
@@ -780,14 +801,11 @@ namespace ICSharpCode.NRefactory.CSharp
public override void VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration)
{
- FormatAttributedNode(enumMemberDeclaration);
base.VisitEnumMemberDeclaration(enumMemberDeclaration);
}
public override void VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration)
{
- FormatAttributedNode(delegateDeclaration);
-
ForceSpacesBefore(delegateDeclaration.LParToken, policy.SpaceBeforeDelegateDeclarationParentheses);
if (delegateDeclaration.Parameters.Any()) {
ForceSpacesAfter(delegateDeclaration.LParToken, policy.SpaceWithinDelegateDeclarationParentheses);
@@ -942,8 +960,6 @@ namespace ICSharpCode.NRefactory.CSharp
public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration)
{
- FormatAttributedNode(methodDeclaration);
-
ForceSpacesBefore(methodDeclaration.LParToken, policy.SpaceBeforeMethodDeclarationParentheses);
if (methodDeclaration.Parameters.Any()) {
ForceSpacesAfter(methodDeclaration.LParToken, policy.SpaceWithinMethodDeclarationParentheses);
@@ -964,8 +980,6 @@ namespace ICSharpCode.NRefactory.CSharp
public override void VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration)
{
- FormatAttributedNode(operatorDeclaration);
-
ForceSpacesBefore(operatorDeclaration.LParToken, policy.SpaceBeforeMethodDeclarationParentheses);
if (operatorDeclaration.Parameters.Any()) {
ForceSpacesAfter(operatorDeclaration.LParToken, policy.SpaceWithinMethodDeclarationParentheses);
@@ -986,8 +1000,6 @@ namespace ICSharpCode.NRefactory.CSharp
public override void VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration)
{
- FormatAttributedNode(constructorDeclaration);
-
ForceSpacesBefore(constructorDeclaration.LParToken, policy.SpaceBeforeConstructorDeclarationParentheses);
if (constructorDeclaration.Parameters.Any()) {
ForceSpacesAfter(constructorDeclaration.LParToken, policy.SpaceWithinConstructorDeclarationParentheses);
@@ -1008,8 +1020,6 @@ namespace ICSharpCode.NRefactory.CSharp
public override void VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration)
{
- FormatAttributedNode(destructorDeclaration);
-
CSharpTokenNode lParen = destructorDeclaration.LParToken;
int offset = this.document.GetOffset(lParen.StartLocation);
ForceSpaceBefore(offset, policy.SpaceBeforeConstructorDeclarationParentheses);
@@ -1654,7 +1664,8 @@ namespace ICSharpCode.NRefactory.CSharp
public override void VisitAnonymousMethodExpression(AnonymousMethodExpression anonymousMethodExpression)
{
if (!anonymousMethodExpression.Body.IsNull) {
- EnforceBraceStyle(policy.AnonymousMethodBraceStyle, anonymousMethodExpression.Body.LBraceToken, anonymousMethodExpression.Body.RBraceToken);
+ if (anonymousMethodExpression.Body.LBraceToken.StartLocation.Line != anonymousMethodExpression.Body.RBraceToken.StartLocation.Line)
+ EnforceBraceStyle(policy.AnonymousMethodBraceStyle, anonymousMethodExpression.Body.LBraceToken, anonymousMethodExpression.Body.RBraceToken);
VisitBlockWithoutFixingBraces(anonymousMethodExpression.Body, policy.IndentBlocks);
return;
}
@@ -2174,7 +2185,12 @@ namespace ICSharpCode.NRefactory.CSharp
} else if (ch == '\r') {
start--;
}
- AddChange(start, offset - start, this.options.EolMarker + indentString);
+ if (changes.Count > 0 && changes[changes.Count - 1].Offset == start) {
+ // may be overlapping with "blank line" changes
+ changes[changes.Count - 1] = new TextReplaceAction (start, changes[changes.Count - 1].RemovalLength, changes[changes.Count - 1].NewText + this.options.EolMarker + indentString);
+ } else {
+ AddChange(start, offset - start, this.options.EolMarker + indentString);
+ }
}
}
}
diff --git a/ICSharpCode.NRefactory.Tests/FormattingTests/TestTypeLevelIndentation.cs b/ICSharpCode.NRefactory.Tests/FormattingTests/TestTypeLevelIndentation.cs
index 38aae69620..4fe1d3c99e 100644
--- a/ICSharpCode.NRefactory.Tests/FormattingTests/TestTypeLevelIndentation.cs
+++ b/ICSharpCode.NRefactory.Tests/FormattingTests/TestTypeLevelIndentation.cs
@@ -574,13 +574,13 @@ set;
}");
}
- [Test()]
+ [Test]
public void TestPropertyCorrection()
{
CSharpFormattingOptions policy = FormattingOptionsFactory.CreateMono();
policy.PropertyFormatting = PropertyFormatting.ForceNewLine;
Test(policy,
-@"class Test
+ @"class Test
{
public int Prop { get; private set; }
}", @"class Test
@@ -591,10 +591,8 @@ set;
}
}");
}
-
-
- [Test()]
+ [Test]
public void TestIndentEventBody ()
{
CSharpFormattingOptions policy = FormattingOptionsFactory.CreateMono ();
@@ -637,5 +635,25 @@ remove {
}
}");
}
+
+
+ ///
+ /// Bug 9990 - Formatting a document on save splits event into 'e vent'
+ ///
+ [Test]
+ public void TestBug9990()
+ {
+ CSharpFormattingOptions policy = FormattingOptionsFactory.CreateMono();
+ policy.PropertyFormatting = PropertyFormatting.ForceNewLine;
+ Test(policy,
+ @"class Test
+{
+ public event EventHandler UpdateStarted = delegate { }; public event EventHandler UpdateFinished = delegate { };
+}", @"class Test
+{
+ public event EventHandler UpdateStarted = delegate { };
+ public event EventHandler UpdateFinished = delegate { };
+}");
+ }
}
}