@@ -69,7 +69,9 @@ public final class NoEmptyLinesOpeningClosingBraces: SyntaxFormatRule {
6969 }
7070
7171 func rewritten( _ token: TokenSyntax ) -> TokenSyntax {
72- let ( trimmedLeadingTrivia, count) = token. leadingTrivia. trimmingSuperfluousNewlines ( )
72+ let ( trimmedLeadingTrivia, count) = token. leadingTrivia. trimmingSuperfluousNewlines (
73+ fromClosingBrace: token. tokenKind == . rightBrace
74+ )
7375 if trimmedLeadingTrivia. sourceLength != token. leadingTriviaLength {
7476 diagnose ( . removeEmptyLinesBefore( count) , on: token, anchor: . start)
7577 return token. with ( \. leadingTrivia, trimmedLeadingTrivia)
@@ -83,7 +85,7 @@ public final class NoEmptyLinesOpeningClosingBraces: SyntaxFormatRule {
8385 if let first = collection. first, first. leadingTrivia. containsNewlines,
8486 let index = collection. index ( of: first)
8587 {
86- let ( trimmedLeadingTrivia, count) = first. leadingTrivia. trimmingSuperfluousNewlines ( )
88+ let ( trimmedLeadingTrivia, count) = first. leadingTrivia. trimmingSuperfluousNewlines ( fromClosingBrace : false )
8789 if trimmedLeadingTrivia. sourceLength != first. leadingTriviaLength {
8890 diagnose ( . removeEmptyLinesAfter( count) , on: first, anchor: . leadingTrivia( 0 ) )
8991 var first = first
@@ -96,24 +98,49 @@ public final class NoEmptyLinesOpeningClosingBraces: SyntaxFormatRule {
9698}
9799
98100extension Trivia {
99- func trimmingSuperfluousNewlines( ) -> ( Trivia , Int ) {
101+ func trimmingSuperfluousNewlines( fromClosingBrace : Bool ) -> ( Trivia , Int ) {
100102 var trimmmed = 0
103+ var pendingNewlineCount = 0
101104 let pieces = self . indices. reduce ( [ TriviaPiece] ( ) ) { ( partialResult, index) in
102105 let piece = self [ index]
103106 // Collapse consecutive newlines into a single one
104107 if case . newlines( let count) = piece {
105- if let last = partialResult. last, last. isNewline {
106- trimmmed += count
107- return partialResult
108+ if fromClosingBrace {
109+ if index == self . count - 1 {
110+ // For the last index(newline right before the closing brace), collapse into a single newline
111+ trimmmed += count - 1
112+ return partialResult + [ . newlines( 1 ) ]
113+ } else {
114+ pendingNewlineCount += count
115+ return partialResult
116+ }
108117 } else {
109- trimmmed += count - 1
110- return partialResult + [ . newlines( 1 ) ]
118+ if let last = partialResult. last, last. isNewline {
119+ trimmmed += count
120+ return partialResult
121+ } else if index == 0 {
122+ // For leading trivia not associated with a closing brace, collapse the first newline into a single one
123+ trimmmed += count - 1
124+ return partialResult + [ . newlines( 1 ) ]
125+ } else {
126+ return partialResult + [ piece]
127+ }
111128 }
112129 }
113130 // Remove spaces/tabs surrounded by newlines
114131 if piece. isSpaceOrTab, index > 0 , index < self . count - 1 , self [ index - 1 ] . isNewline, self [ index + 1 ] . isNewline {
115132 return partialResult
116133 }
134+ // Handle pending newlines if there are any
135+ if pendingNewlineCount > 0 {
136+ if index < self . count - 1 {
137+ let newlines = TriviaPiece . newlines ( pendingNewlineCount)
138+ pendingNewlineCount = 0
139+ return partialResult + [ newlines] + [ piece]
140+ } else {
141+ return partialResult + [ . newlines( 1 ) ] + [ piece]
142+ }
143+ }
117144 // Retain other trivia pieces
118145 return partialResult + [ piece]
119146 }
0 commit comments