Skip to content

Commit

Permalink
Merge pull request #911 from ahoppen/merge-main-6.1-2025-01-08
Browse files Browse the repository at this point in the history
Merge `main` into `release/6.1`
  • Loading branch information
ahoppen authored Jan 8, 2025
2 parents 94ce795 + f9c8cf8 commit 8c4e008
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 8 deletions.
43 changes: 35 additions & 8 deletions Sources/SwiftFormat/Rules/NoEmptyLineOpeningClosingBraces.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ public final class NoEmptyLinesOpeningClosingBraces: SyntaxFormatRule {
}

func rewritten(_ token: TokenSyntax) -> TokenSyntax {
let (trimmedLeadingTrivia, count) = token.leadingTrivia.trimmingSuperfluousNewlines()
let (trimmedLeadingTrivia, count) = token.leadingTrivia.trimmingSuperfluousNewlines(
fromClosingBrace: token.tokenKind == .rightBrace
)
if trimmedLeadingTrivia.sourceLength != token.leadingTriviaLength {
diagnose(.removeEmptyLinesBefore(count), on: token, anchor: .start)
return token.with(\.leadingTrivia, trimmedLeadingTrivia)
Expand All @@ -83,7 +85,7 @@ public final class NoEmptyLinesOpeningClosingBraces: SyntaxFormatRule {
if let first = collection.first, first.leadingTrivia.containsNewlines,
let index = collection.index(of: first)
{
let (trimmedLeadingTrivia, count) = first.leadingTrivia.trimmingSuperfluousNewlines()
let (trimmedLeadingTrivia, count) = first.leadingTrivia.trimmingSuperfluousNewlines(fromClosingBrace: false)
if trimmedLeadingTrivia.sourceLength != first.leadingTriviaLength {
diagnose(.removeEmptyLinesAfter(count), on: first, anchor: .leadingTrivia(0))
var first = first
Expand All @@ -96,24 +98,49 @@ public final class NoEmptyLinesOpeningClosingBraces: SyntaxFormatRule {
}

extension Trivia {
func trimmingSuperfluousNewlines() -> (Trivia, Int) {
func trimmingSuperfluousNewlines(fromClosingBrace: Bool) -> (Trivia, Int) {
var trimmmed = 0
var pendingNewlineCount = 0
let pieces = self.indices.reduce([TriviaPiece]()) { (partialResult, index) in
let piece = self[index]
// Collapse consecutive newlines into a single one
if case .newlines(let count) = piece {
if let last = partialResult.last, last.isNewline {
trimmmed += count
return partialResult
if fromClosingBrace {
if index == self.count - 1 {
// For the last index(newline right before the closing brace), collapse into a single newline
trimmmed += count - 1
return partialResult + [.newlines(1)]
} else {
pendingNewlineCount += count
return partialResult
}
} else {
trimmmed += count - 1
return partialResult + [.newlines(1)]
if let last = partialResult.last, last.isNewline {
trimmmed += count
return partialResult
} else if index == 0 {
// For leading trivia not associated with a closing brace, collapse the first newline into a single one
trimmmed += count - 1
return partialResult + [.newlines(1)]
} else {
return partialResult + [piece]
}
}
}
// Remove spaces/tabs surrounded by newlines
if piece.isSpaceOrTab, index > 0, index < self.count - 1, self[index - 1].isNewline, self[index + 1].isNewline {
return partialResult
}
// Handle pending newlines if there are any
if pendingNewlineCount > 0 {
if index < self.count - 1 {
let newlines = TriviaPiece.newlines(pendingNewlineCount)
pendingNewlineCount = 0
return partialResult + [newlines] + [piece]
} else {
return partialResult + [.newlines(1)] + [piece]
}
}
// Retain other trivia pieces
return partialResult + [piece]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,60 @@ final class NoEmptyLinesOpeningClosingBracesTests: LintOrFormatRuleTestCase {
]
)
}

func testNoEmptyLinesOpeningClosingBracesInFunctionBeginningAndEndingWithComment() {
assertFormatting(
NoEmptyLinesOpeningClosingBraces.self,
input: """
func myFunc() {
// Some comment here
// Do a thing
var x = doAThing()
// Do a thing
var y = doAThing()
// Some other comment here
}
""",
expected: """
func myFunc() {
// Some comment here
// Do a thing
var x = doAThing()
// Do a thing
var y = doAThing()
// Some other comment here
}
"""
)
}

func testNoEmptyLinesOpeningClosingBracesInFunctionWithEmptyLinesOnly() {
assertFormatting(
NoEmptyLinesOpeningClosingBraces.self,
input: """
func myFunc() {
1️⃣}
""",
expected: """
func myFunc() {
}
""",
findings: [
FindingSpec("1️⃣", message: "remove empty lines before '}'")
]
)
}
}

0 comments on commit 8c4e008

Please sign in to comment.