@@ -69,7 +69,9 @@ public final class NoEmptyLinesOpeningClosingBraces: SyntaxFormatRule {
69
69
}
70
70
71
71
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
+ )
73
75
if trimmedLeadingTrivia. sourceLength != token. leadingTriviaLength {
74
76
diagnose ( . removeEmptyLinesBefore( count) , on: token, anchor: . start)
75
77
return token. with ( \. leadingTrivia, trimmedLeadingTrivia)
@@ -83,7 +85,7 @@ public final class NoEmptyLinesOpeningClosingBraces: SyntaxFormatRule {
83
85
if let first = collection. first, first. leadingTrivia. containsNewlines,
84
86
let index = collection. index ( of: first)
85
87
{
86
- let ( trimmedLeadingTrivia, count) = first. leadingTrivia. trimmingSuperfluousNewlines ( )
88
+ let ( trimmedLeadingTrivia, count) = first. leadingTrivia. trimmingSuperfluousNewlines ( fromClosingBrace : false )
87
89
if trimmedLeadingTrivia. sourceLength != first. leadingTriviaLength {
88
90
diagnose ( . removeEmptyLinesAfter( count) , on: first, anchor: . leadingTrivia( 0 ) )
89
91
var first = first
@@ -96,24 +98,49 @@ public final class NoEmptyLinesOpeningClosingBraces: SyntaxFormatRule {
96
98
}
97
99
98
100
extension Trivia {
99
- func trimmingSuperfluousNewlines( ) -> ( Trivia , Int ) {
101
+ func trimmingSuperfluousNewlines( fromClosingBrace : Bool ) -> ( Trivia , Int ) {
100
102
var trimmmed = 0
103
+ var pendingNewlineCount = 0
101
104
let pieces = self . indices. reduce ( [ TriviaPiece] ( ) ) { ( partialResult, index) in
102
105
let piece = self [ index]
103
106
// Collapse consecutive newlines into a single one
104
107
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
+ }
108
117
} 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
+ }
111
128
}
112
129
}
113
130
// Remove spaces/tabs surrounded by newlines
114
131
if piece. isSpaceOrTab, index > 0 , index < self . count - 1 , self [ index - 1 ] . isNewline, self [ index + 1 ] . isNewline {
115
132
return partialResult
116
133
}
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
+ }
117
144
// Retain other trivia pieces
118
145
return partialResult + [ piece]
119
146
}
0 commit comments