Skip to content

Commit 29b5199

Browse files
authored
Merge pull request #648 from allevato/missing-trivia
Various trivia-related fixes.
2 parents d73b790 + f9b2ab9 commit 29b5199

File tree

5 files changed

+99
-43
lines changed

5 files changed

+99
-43
lines changed

Sources/SwiftFormat/PrettyPrint/TokenStreamCreator.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -1516,7 +1516,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
15161516

15171517
override func visit(_ node: SourceFileSyntax) -> SyntaxVisitorContinueKind {
15181518
if shouldFormatterIgnore(file: node) {
1519-
appendFormatterIgnored(node: Syntax(node))
1519+
appendToken(.verbatim(Verbatim(text: "\(node)", indentingBehavior: .none)))
15201520
return .skipChildren
15211521
}
15221522
after(node.shebang, tokens: .break(.same, newlines: .soft))

Sources/SwiftFormat/Rules/NoParensAroundConditions.swift

+10-5
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import SwiftSyntax
2828
public final class NoParensAroundConditions: SyntaxFormatRule {
2929
public override func visit(_ node: IfExprSyntax) -> ExprSyntax {
3030
var result = node
31-
result.ifKeyword.trailingTrivia = [.spaces(1)]
31+
fixKeywordTrailingTrivia(&result.ifKeyword.trailingTrivia)
3232
result.conditions = visit(node.conditions)
3333
result.body = visit(node.body)
3434
if let elseBody = node.elseBody {
@@ -52,7 +52,7 @@ public final class NoParensAroundConditions: SyntaxFormatRule {
5252

5353
public override func visit(_ node: GuardStmtSyntax) -> StmtSyntax {
5454
var result = node
55-
result.guardKeyword.trailingTrivia = [.spaces(1)]
55+
fixKeywordTrailingTrivia(&result.guardKeyword.trailingTrivia)
5656
result.conditions = visit(node.conditions)
5757
result.body = visit(node.body)
5858
return StmtSyntax(result)
@@ -64,7 +64,7 @@ public final class NoParensAroundConditions: SyntaxFormatRule {
6464
}
6565

6666
var result = node
67-
result.switchKeyword.trailingTrivia = [.spaces(1)]
67+
fixKeywordTrailingTrivia(&result.switchKeyword.trailingTrivia)
6868
result.subject = newSubject
6969
result.cases = visit(node.cases)
7070
return ExprSyntax(result)
@@ -76,20 +76,25 @@ public final class NoParensAroundConditions: SyntaxFormatRule {
7676
}
7777

7878
var result = node
79-
result.whileKeyword.trailingTrivia = [.spaces(1)]
79+
fixKeywordTrailingTrivia(&result.whileKeyword.trailingTrivia)
8080
result.condition = newCondition
8181
result.body = visit(node.body)
8282
return StmtSyntax(result)
8383
}
8484

8585
public override func visit(_ node: WhileStmtSyntax) -> StmtSyntax {
8686
var result = node
87-
result.whileKeyword.trailingTrivia = [.spaces(1)]
87+
fixKeywordTrailingTrivia(&result.whileKeyword.trailingTrivia)
8888
result.conditions = visit(node.conditions)
8989
result.body = visit(node.body)
9090
return StmtSyntax(result)
9191
}
9292

93+
private func fixKeywordTrailingTrivia(_ trivia: inout Trivia) {
94+
guard trivia.isEmpty else { return }
95+
trivia = [.spaces(1)]
96+
}
97+
9398
private func minimalSingleExpression(_ original: ExprSyntax) -> ExprSyntax? {
9499
guard
95100
let tuple = original.as(TupleExprSyntax.self),

Sources/SwiftFormat/Rules/OrderedImports.swift

+9-11
Original file line numberDiff line numberDiff line change
@@ -342,20 +342,18 @@ fileprivate func generateLines(codeBlockItemList: CodeBlockItemListSyntax, conte
342342
/// replacing the trivia appropriately to ensure comments appear in the right location.
343343
fileprivate func convertToCodeBlockItems(lines: [Line]) -> [CodeBlockItemSyntax] {
344344
var output: [CodeBlockItemSyntax] = []
345-
var triviaBuffer: [TriviaPiece] = []
345+
var pendingLeadingTrivia: [TriviaPiece] = []
346346

347347
for line in lines {
348-
triviaBuffer += line.leadingTrivia
348+
pendingLeadingTrivia += line.leadingTrivia
349349

350350
func append(codeBlockItem: CodeBlockItemSyntax) {
351-
// Comments and newlines are always located in the leading trivia of an AST node, so we need
352-
// not deal with trailing trivia.
353351
var codeBlockItem = codeBlockItem
354-
codeBlockItem.leadingTrivia = Trivia(pieces: triviaBuffer)
352+
codeBlockItem.leadingTrivia = Trivia(pieces: pendingLeadingTrivia)
353+
codeBlockItem.trailingTrivia = Trivia(pieces: line.trailingTrivia)
355354
output.append(codeBlockItem)
356355

357-
triviaBuffer = []
358-
triviaBuffer += line.trailingTrivia
356+
pendingLeadingTrivia = []
359357
}
360358

361359
if let syntaxNode = line.syntaxNode {
@@ -367,11 +365,11 @@ fileprivate func convertToCodeBlockItems(lines: [Line]) -> [CodeBlockItemSyntax]
367365
}
368366
}
369367

370-
// Merge multiple newlines together into a single trivia piece by updating it's N value.
371-
if let lastPiece = triviaBuffer.last, case .newlines(let N) = lastPiece {
372-
triviaBuffer[triviaBuffer.endIndex - 1] = TriviaPiece.newlines(N + 1)
368+
// Merge multiple newlines together into a single trivia piece by updating its count.
369+
if let lastPiece = pendingLeadingTrivia.last, case .newlines(let count) = lastPiece {
370+
pendingLeadingTrivia[pendingLeadingTrivia.endIndex - 1] = .newlines(count + 1)
373371
} else {
374-
triviaBuffer.append(TriviaPiece.newlines(1))
372+
pendingLeadingTrivia.append(.newlines(1))
375373
}
376374
}
377375

Tests/SwiftFormatTests/PrettyPrint/IgnoreNodeTests.swift

+8-26
Original file line numberDiff line numberDiff line change
@@ -318,36 +318,18 @@ final class IgnoreNodeTests: PrettyPrintTestCase {
318318
{
319319
var bazzle = 0 }
320320
"""
321+
assertPrettyPrintEqual(input: input, expected: input, linelength: 50)
322+
}
321323

322-
let expected =
324+
func testIgnoreWholeFileDoesNotTouchWhitespace() {
325+
let input =
323326
"""
324327
// swift-format-ignore-file
325-
import Zoo
326-
import Aoo
327-
import foo
328-
329-
struct Foo {
330-
private var baz: Bool {
331-
return foo +
332-
bar + // poorly placed comment
333-
false
334-
}
335-
336-
var a = true // line comment
337-
// aligned line comment
338-
var b = false // correct trailing comment
339-
340-
var c = 0 +
341-
1
342-
+ (2 + 3)
343-
}
344-
345-
class Bar
346-
{
347-
var bazzle = 0 }
328+
/// foo bar
329+
\u{0020}
330+
// baz
348331
"""
349-
350-
assertPrettyPrintEqual(input: input, expected: expected, linelength: 50)
332+
assertPrettyPrintEqual(input: input, expected: input, linelength: 100)
351333
}
352334

353335
func testIgnoreWholeFileInNestedNode() {

Tests/SwiftFormatTests/Rules/NoParensAroundConditionsTests.swift

+71
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,77 @@ final class NoParensAroundConditionsTests: LintOrFormatRuleTestCase {
263263
FindingSpec("7️⃣", message: "remove the parentheses around this expression"),
264264
]
265265
)
266+
}
266267

268+
func testBlockCommentsBeforeConditionArePreserved() {
269+
assertFormatting(
270+
NoParensAroundConditions.self,
271+
input: """
272+
if/*foo*/1️⃣(x) {}
273+
while/*foo*/2️⃣(x) {}
274+
guard/*foo*/3️⃣(x), /*foo*/4️⃣(y), /*foo*/5️⃣(x == 3) else {}
275+
repeat {} while/*foo*/6️⃣(x)
276+
switch/*foo*/7️⃣(4) { default: break }
277+
""",
278+
expected: """
279+
if/*foo*/x {}
280+
while/*foo*/x {}
281+
guard/*foo*/x, /*foo*/y, /*foo*/x == 3 else {}
282+
repeat {} while/*foo*/x
283+
switch/*foo*/4 { default: break }
284+
""",
285+
findings: [
286+
FindingSpec("1️⃣", message: "remove the parentheses around this expression"),
287+
FindingSpec("2️⃣", message: "remove the parentheses around this expression"),
288+
FindingSpec("3️⃣", message: "remove the parentheses around this expression"),
289+
FindingSpec("4️⃣", message: "remove the parentheses around this expression"),
290+
FindingSpec("5️⃣", message: "remove the parentheses around this expression"),
291+
FindingSpec("6️⃣", message: "remove the parentheses around this expression"),
292+
FindingSpec("7️⃣", message: "remove the parentheses around this expression"),
293+
]
294+
)
295+
}
296+
297+
func testCommentsAfterKeywordArePreserved() {
298+
assertFormatting(
299+
NoParensAroundConditions.self,
300+
input: """
301+
if /*foo*/ // bar
302+
1️⃣(x) {}
303+
while /*foo*/ // bar
304+
2️⃣(x) {}
305+
guard /*foo*/ // bar
306+
3️⃣(x), /*foo*/ // bar
307+
4️⃣(y), /*foo*/ // bar
308+
5️⃣(x == 3) else {}
309+
repeat {} while /*foo*/ // bar
310+
6️⃣(x)
311+
switch /*foo*/ // bar
312+
7️⃣(4) { default: break }
313+
""",
314+
expected: """
315+
if /*foo*/ // bar
316+
x {}
317+
while /*foo*/ // bar
318+
x {}
319+
guard /*foo*/ // bar
320+
x, /*foo*/ // bar
321+
y, /*foo*/ // bar
322+
x == 3 else {}
323+
repeat {} while /*foo*/ // bar
324+
x
325+
switch /*foo*/ // bar
326+
4 { default: break }
327+
""",
328+
findings: [
329+
FindingSpec("1️⃣", message: "remove the parentheses around this expression"),
330+
FindingSpec("2️⃣", message: "remove the parentheses around this expression"),
331+
FindingSpec("3️⃣", message: "remove the parentheses around this expression"),
332+
FindingSpec("4️⃣", message: "remove the parentheses around this expression"),
333+
FindingSpec("5️⃣", message: "remove the parentheses around this expression"),
334+
FindingSpec("6️⃣", message: "remove the parentheses around this expression"),
335+
FindingSpec("7️⃣", message: "remove the parentheses around this expression"),
336+
]
337+
)
267338
}
268339
}

0 commit comments

Comments
 (0)