Skip to content

Commit

Permalink
Merge pull request #210 from karwa/SR-13194
Browse files Browse the repository at this point in the history
[SR-13194] DoNotUseSemicolons should not strip semicolons which separate a 'do' blocks from 'while' blocks.
  • Loading branch information
allevato committed Jul 13, 2020
2 parents 2b4364b + 33b3383 commit cb4e621
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 1 deletion.
15 changes: 14 additions & 1 deletion Sources/SwiftFormatRules/DoNotUseSemicolons.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public final class DoNotUseSemicolons: SyntaxFormatRule {
}

var newItem = visitedItem
defer { newItems[idx] = newItem }

// Check if the leading trivia for this statement needs a new line.
if previousHadSemicolon, let firstToken = newItem.firstToken,
Expand All @@ -68,6 +69,19 @@ public final class DoNotUseSemicolons: SyntaxFormatRule {

// If there's a semicolon, diagnose and remove it.
if let semicolon = item.semicolon {

// Exception: do not remove the semicolon if it is separating a 'do' statement from a 'while' statement.
if Syntax(item).as(CodeBlockItemSyntax.self)?.children.first?.is(DoStmtSyntax.self) == true,
idx < node.count - 1
{
let nextItem = node.children[node.children.index(after: item.index)]
if Syntax(nextItem).as(CodeBlockItemSyntax.self)?
.children.first?.is(WhileStmtSyntax.self) == true
{
continue
}
}

// This discards any trailingTrivia from the semicolon. That trivia is at most some spaces,
// and the pretty printer adds any necessary spaces so it's safe to discard.
newItem = newItem.withSemicolon(nil)
Expand All @@ -77,7 +91,6 @@ public final class DoNotUseSemicolons: SyntaxFormatRule {
diagnose(.removeSemicolon, on: semicolon)
}
}
newItems[idx] = newItem
}
return nodeCreator(newItems)
}
Expand Down
37 changes: 37 additions & 0 deletions Tests/SwiftFormatRulesTests/DoNotUseSemicolonsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,41 @@ final class DoNotUseSemicolonsTests: LintOrFormatRuleTestCase {
print("7")
""")
}

func testSemicolonsSeparatingDoWhile() {
XCTAssertFormatting(
DoNotUseSemicolons.self,
input: """
do { f() };
while someCondition { g() }
do {
f()
};
// Comment and whitespace separating blocks.
while someCondition {
g()
}
do { f() };
for _ in 0..<10 { g() }
""",
expected: """
do { f() };
while someCondition { g() }
do {
f()
};
// Comment and whitespace separating blocks.
while someCondition {
g()
}
do { f() }
for _ in 0..<10 { g() }
""")
}
}

0 comments on commit cb4e621

Please sign in to comment.