Skip to content
This repository was archived by the owner on Jul 12, 2022. It is now read-only.

Commit 9195533

Browse files
committed
Combined the brace rules
Combined the rules around open and close braces into a single rule. The logic here is extremely similar, makes sense to keep it in one place. Also expanded upon the unit tests here to capture a couple of new scenarios.
1 parent 2b6c2c1 commit 9195533

File tree

7 files changed

+192
-138
lines changed

7 files changed

+192
-138
lines changed

src/Microsoft.DotNet.CodeFormatting.Tests/Microsoft.DotNet.CodeFormatting.Tests.csproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,12 @@
105105
</ItemGroup>
106106
<ItemGroup>
107107
<Compile Include="CodeFormattingTestBase.cs" />
108+
<Compile Include="Rules\BracesRuleTests.cs" />
108109
<Compile Include="Rules\ExplicitThisRuleTests.cs" />
109110
<Compile Include="Rules\ExplicitVisibilityRuleTests.cs" />
110111
<Compile Include="Rules\HasNewLineBeforeFirstNamespaceFormattingRuleTests.cs" />
111112
<Compile Include="Rules\HasNoIllegalHeadersFormattingRuleTests.cs" />
112113
<Compile Include="Rules\HasNewLineBeforeFirstUsingFormattingRuleTests.cs" />
113-
<Compile Include="Rules\HasNoNewLineAfterOpenBraceFormattingRuleTests.cs" />
114-
<Compile Include="Rules\HasNoNewLineBeforeEndBraceFormattingRuleTests.cs" />
115114
<Compile Include="Rules\PrivateFieldNamingRuleTests.cs" />
116115
<Compile Include="Rules\NonAsciiCharactersAreEscapedInLiteralsRuleTests.cs" />
117116
<Compile Include="Rules\UsesXunitForTestsFormattingRuleTests.cs" />
Lines changed: 139 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,13 @@
55

66
namespace Microsoft.DotNet.CodeFormatting.Tests
77
{
8-
public class HasNoNewLineBeforeEndBraceFormattingRuleTests : CodeFormattingTestBase
8+
public class BraceNewLineTests : CodeFormattingTestBase
99
{
10+
internal override IFormattingRule GetFormattingRule()
11+
{
12+
return new Rules.BraceNewLineRule();
13+
}
14+
1015
[Fact]
1116
public void TestNoNewLineBeforeEndBrace01()
1217
{
@@ -131,9 +136,140 @@ class S
131136
Verify(text, expected);
132137
}
133138

134-
internal override IFormattingRule GetFormattingRule()
139+
[Fact]
140+
public void TestRemoveNewLinesBetweenPragmaAndCloseBrace()
141+
{
142+
var text = @"
143+
class U
144+
{
145+
146+
// some comment
147+
148+
149+
#pragma warning disable 1591
150+
151+
}
152+
";
153+
var expected = @"
154+
class U
155+
{
156+
// some comment
157+
158+
159+
#pragma warning disable 1591
160+
}
161+
";
162+
163+
Verify(text, expected);
164+
}
165+
166+
[Fact]
167+
public void TestBracesWithJustCommentBody()
135168
{
136-
return new Rules.HasNoNewLineBeforeEndBraceFormattingRule();
169+
var text = @"
170+
class U
171+
{
172+
// some comment
173+
}
174+
";
175+
var expected = @"
176+
class U
177+
{
178+
// some comment
179+
}
180+
";
181+
182+
Verify(text, expected);
183+
}
184+
185+
[Fact]
186+
public void MethodWithSingleLine()
187+
{
188+
var text = @"
189+
class U
190+
{
191+
void M()
192+
{
193+
N();
194+
}
195+
}
196+
";
197+
var expected = @"
198+
class U
199+
{
200+
void M()
201+
{
202+
N();
203+
}
204+
}
205+
";
206+
207+
Verify(text, expected);
208+
209+
}
210+
211+
[Fact]
212+
public void NewLineBeforeCloseBraceOnClass()
213+
{
214+
var text = @"
215+
class C {
216+
}
217+
";
218+
var expected = @"
219+
class C
220+
{
221+
}
222+
";
223+
Verify(text, expected);
224+
}
225+
226+
[Fact]
227+
public void TestNoNewLineAfterOpenBrace01()
228+
{
229+
var text = @"
230+
using System;
231+
class T
232+
{
233+
234+
}
235+
class K { }
236+
class S {
237+
238+
}
239+
class R
240+
{
241+
242+
// some comment
243+
}
244+
class U
245+
{
246+
247+
#pragma warning disable 1591
248+
}
249+
class L {
250+
}";
251+
var expected = @"
252+
using System;
253+
class T
254+
{
255+
}
256+
class K { }
257+
class S
258+
{
259+
}
260+
class R
261+
{
262+
// some comment
263+
}
264+
class U
265+
{
266+
#pragma warning disable 1591
267+
}
268+
class L
269+
{
270+
}";
271+
272+
Verify(text, expected);
137273
}
138274
}
139275
}

src/Microsoft.DotNet.CodeFormatting.Tests/Rules/HasNoNewLineAfterOpenBraceFormattingRuleTests.cs

Lines changed: 0 additions & 64 deletions
This file was deleted.

src/Microsoft.DotNet.CodeFormatting/Microsoft.DotNet.CodeFormatting.csproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,12 @@
8181
<Compile Include="RuleOrderAttribute.cs" />
8282
<Compile Include="Properties\AssemblyInfo.cs" />
8383
<Compile Include="IOrderMetadata.cs" />
84+
<Compile Include="Rules\BraceNewLineRule.cs" />
8485
<Compile Include="Rules\ExplicitVisibilityRule.cs" />
8586
<Compile Include="Rules\HasCopyrightHeaderFormattingRule.cs" />
8687
<Compile Include="Rules\HasNewLineBeforeFirstNamespaceFormattingRule.cs" />
8788
<Compile Include="Rules\HasNewLineBeforeFirstUsingFormattingRule.cs" />
8889
<Compile Include="Rules\HasNoIllegalHeadersFormattingRule.cs" />
89-
<Compile Include="Rules\HasNoNewLineAfterOpenBraceFormattingRule.cs" />
90-
<Compile Include="Rules\HasNoNewLineBeforeEndBraceFormattingRule.cs" />
9190
<Compile Include="Rules\HasNoCustomCopyrightHeaderFormattingRule.cs" />
9291
<Compile Include="Rules\PrivateFieldNamingRule.cs" />
9392
<Compile Include="Rules\HasUsingsOutsideOfNamespaceFormattingRule.cs" />
Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,62 @@
11
// Copyright (c) Microsoft. All rights reserved.
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

4+
using Microsoft.CodeAnalysis;
5+
using Microsoft.CodeAnalysis.CSharp;
46
using System;
57
using System.Collections.Generic;
6-
using System.ComponentModel.Composition;
78
using System.Linq;
9+
using System.Text;
810
using System.Threading;
911
using System.Threading.Tasks;
1012

11-
using Microsoft.CodeAnalysis;
12-
using Microsoft.CodeAnalysis.CSharp;
13-
1413
namespace Microsoft.DotNet.CodeFormatting.Rules
1514
{
16-
[RuleOrder(RuleOrder.HasNoNewLineBeforeEndBraceFormattingRule)]
17-
internal sealed class HasNoNewLineBeforeEndBraceFormattingRule : IFormattingRule
15+
[RuleOrder(RuleOrder.BraceNewLineRule)]
16+
internal sealed class BraceNewLineRule : IFormattingRule
1817
{
1918
public async Task<Document> ProcessAsync(Document document, CancellationToken cancellationToken)
2019
{
21-
var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken) as CSharpSyntaxNode;
22-
if (syntaxRoot == null)
20+
var syntaxNode = await document.GetSyntaxRootAsync(cancellationToken);
21+
if (syntaxNode == null)
22+
{
2323
return document;
24+
}
25+
26+
syntaxNode = FixOpenBraces(syntaxNode);
27+
syntaxNode = FixCloseBraces(syntaxNode);
28+
return document.WithSyntaxRoot(syntaxNode);
29+
}
2430

25-
var closeBraceTokens = syntaxRoot.DescendantTokens().Where((token) => token.CSharpKind() == SyntaxKind.CloseBraceToken);
31+
private static SyntaxNode FixOpenBraces(SyntaxNode syntaxNode)
32+
{
33+
var openBraceTokens = syntaxNode.DescendantTokens().Where((token) => token.CSharpKind() == SyntaxKind.OpenBraceToken);
34+
Func<SyntaxToken, SyntaxToken, SyntaxToken> replacementForTokens = (token, dummy) =>
35+
{
36+
int elementsToRemove = 1;
37+
if (token.LeadingTrivia.Count > 1)
38+
{
39+
while (elementsToRemove < token.LeadingTrivia.Count &&
40+
token.LeadingTrivia.ElementAt(elementsToRemove).CSharpKind() == SyntaxKind.EndOfLineTrivia)
41+
elementsToRemove++;
42+
}
43+
44+
var newToken = token.WithLeadingTrivia(token.LeadingTrivia.Skip(elementsToRemove));
45+
return newToken;
46+
};
47+
48+
var tokensToReplace = openBraceTokens.Where((token) =>
49+
{
50+
var nextToken = token.GetNextToken();
51+
return (nextToken.HasLeadingTrivia && nextToken.LeadingTrivia.First().CSharpKind() == SyntaxKind.EndOfLineTrivia);
52+
}).Select((token) => token.GetNextToken());
53+
54+
return syntaxNode.ReplaceTokens(tokensToReplace, replacementForTokens);
55+
}
56+
57+
private static SyntaxNode FixCloseBraces(SyntaxNode syntaxNode)
58+
{
59+
var closeBraceTokens = syntaxNode.DescendantTokens().Where((token) => token.CSharpKind() == SyntaxKind.CloseBraceToken);
2660
Func<SyntaxToken, SyntaxToken, SyntaxToken> replaceTriviaInTokens = (token, dummy) =>
2761
{
2862
var newTrivia = RemoveNewLinesFromTop(token.LeadingTrivia);
@@ -35,7 +69,7 @@ public async Task<Document> ProcessAsync(Document document, CancellationToken ca
3569
token.LeadingTrivia.Last().CSharpKind() == SyntaxKind.EndOfLineTrivia ||
3670
token.LeadingTrivia.Last().CSharpKind() == SyntaxKind.WhitespaceTrivia));
3771

38-
return document.WithSyntaxRoot(syntaxRoot.ReplaceTokens(tokensToReplace, replaceTriviaInTokens));
72+
return syntaxNode.ReplaceTokens(tokensToReplace, replaceTriviaInTokens);
3973
}
4074

4175
private static IEnumerable<SyntaxTrivia> RemoveNewLinesFromTop(IEnumerable<SyntaxTrivia> trivia)

src/Microsoft.DotNet.CodeFormatting/Rules/HasNoNewLineAfterOpenBraceFormattingRule.cs

Lines changed: 0 additions & 49 deletions
This file was deleted.

0 commit comments

Comments
 (0)