@@ -23,18 +23,18 @@ public extension FormatRule {
2323 formatter. addOrRemoveTrailingComma ( beforeEndOfScope: i, trailingCommaSupported: true , isCollection: true )
2424
2525 case . subscript, . captureList:
26- formatter. addOrRemoveTrailingComma ( beforeEndOfScope: i, trailingCommaSupported: formatter. options. swiftVersion >= " 6.1 " )
26+ let trailingCommaSupported = formatter. options. swiftVersion >= " 6.1 "
27+ formatter. addOrRemoveTrailingComma ( beforeEndOfScope: i, trailingCommaSupported: trailingCommaSupported)
2728
2829 default :
2930 return
3031 }
3132
32- case . endOfScope( " ) " ) :
33- var trailingCommaSupported = false
33+ case . endOfScope( " ) " ) where formatter . options . swiftVersion >= " 6.1 " :
34+ var trailingCommaSupported : Bool ?
3435
3536 // Trailing commas are supported in function calls, function definitions, initializers, and attributes.
36- if formatter. options. swiftVersion >= " 6.1 " ,
37- let identifierIndex = formatter. parseFunctionIdentifier ( beforeStartOfScope: startOfScope) ,
37+ if let identifierIndex = formatter. parseFunctionIdentifier ( beforeStartOfScope: startOfScope) ,
3838 let identifierToken = formatter. token ( at: identifierIndex) ,
3939 identifierToken. isIdentifier || identifierToken. isAttribute || identifierToken. isKeyword,
4040 // If the case of `@escaping` or `@Sendable`, this could be a closure type where trailing commas are not supported.
@@ -59,19 +59,16 @@ public extension FormatRule {
5959
6060 // If the previous token is the closing `>` of a generic list, then this is a function declaration or initializer,
6161 // like `func foo<T>(args...)` or `Foo<Bar>(args...)`.
62- if formatter. options. swiftVersion >= " 6.1 " ,
63- let tokenBeforeStartOfScope = formatter. index ( of: . nonSpaceOrCommentOrLinebreak, before: startOfScope) ,
64- formatter. tokens [ tokenBeforeStartOfScope] == . endOfScope( " > " )
62+ else if let tokenBeforeStartOfScope = formatter. index ( of: . nonSpaceOrCommentOrLinebreak, before: startOfScope) ,
63+ formatter. tokens [ tokenBeforeStartOfScope] == . endOfScope( " > " )
6564 {
6665 trailingCommaSupported = true
6766 }
6867
6968 // In Swift 6.1, trailing commas are also supported in tuple values,
7069 // but not tuple or closure types: https://github.com/swiftlang/swift/issues/81485
7170 // If we know this is a tuple value, then trailing commas are supported.
72- if formatter. options. swiftVersion >= " 6.1 " ,
73- let tokenBeforeStartOfScope = formatter. index ( of: . nonSpaceOrCommentOrLinebreak, before: startOfScope)
74- {
71+ else if let tokenBeforeStartOfScope = formatter. index ( of: . nonSpaceOrCommentOrLinebreak, before: startOfScope) {
7572 // `{ (...) }`, `return (...)` etc are always tuple values
7673 // (except in the case of a typealias, where the rhs is a type)
7774 let tokensPreceedingValuesNotTypes : Set < Token > = [ . startOfScope( " { " ) , . keyword( " return " ) , . keyword( " throw " ) , . keyword( " switch " ) , . endOfScope( " case " ) ]
@@ -97,14 +94,13 @@ public extension FormatRule {
9794
9895 formatter. addOrRemoveTrailingComma ( beforeEndOfScope: i, trailingCommaSupported: trailingCommaSupported)
9996
100- case . endOfScope( " > " ) :
97+ case . endOfScope( " > " ) where formatter . options . swiftVersion >= " 6.1 " :
10198 var trailingCommaSupported = false
10299
103100 // In Swift 6.1, only generic lists in concrete type / function / typealias declarations are allowed.
104101 // https://github.com/swiftlang/swift/issues/81474
105102 // All of these cases have the form `keyword identifier<...>`, like `class Foo<...>` or `func foo<...>`.
106- if formatter. options. swiftVersion >= " 6.1 " ,
107- let identifierIndex = formatter. index ( of: . nonSpaceOrCommentOrLinebreak, before: startOfScope) ,
103+ if let identifierIndex = formatter. index ( of: . nonSpaceOrCommentOrLinebreak, before: startOfScope) ,
108104 formatter. tokens [ identifierIndex] . isIdentifier,
109105 let keywordIndex = formatter. index ( of: . nonSpaceOrCommentOrLinebreak, before: identifierIndex) ,
110106 let keyword = formatter. token ( at: keywordIndex) ,
@@ -116,6 +112,9 @@ public extension FormatRule {
116112
117113 formatter. addOrRemoveTrailingComma ( beforeEndOfScope: i, trailingCommaSupported: trailingCommaSupported)
118114
115+ case . endOfScope( " ) " ) , . endOfScope( " > " ) :
116+ formatter. addOrRemoveTrailingComma ( beforeEndOfScope: i, trailingCommaSupported: false )
117+
119118 default :
120119 break
121120 }
@@ -180,12 +179,16 @@ extension Formatter {
180179 /// Trailing commas can always be removed.
181180 /// - `trailingCommaSupported` indicates whether or not a trailing comma is allowed by the language at this position.
182181 /// - `isCollection` indicates whether this is an array or dictionary literal.
183- func addOrRemoveTrailingComma( beforeEndOfScope endOfListIndex: Int , trailingCommaSupported: Bool , isCollection: Bool = false ) {
182+ func addOrRemoveTrailingComma(
183+ beforeEndOfScope endOfListIndex: Int ,
184+ trailingCommaSupported: Bool ? ,
185+ isCollection: Bool = false
186+ ) {
184187 guard let prevTokenIndex = index ( of: . nonSpaceOrComment, before: endOfListIndex) ,
185188 let startOfScope = startOfScope ( at: endOfListIndex)
186189 else { return }
187190
188- // Decide whether to insert, remove, or preserve the comma in this context based on the enabled option
191+ // Decide whether to insert or remove the comma in this context
189192 enum TrailingCommaMode {
190193 case insert
191194 case remove
@@ -198,9 +201,12 @@ extension Formatter {
198201 trailingCommaMode = . remove
199202
200203 case . always:
201- if trailingCommaSupported {
204+ switch trailingCommaSupported {
205+ case true ? :
202206 trailingCommaMode = . insert
203- } else {
207+ case false ? :
208+ trailingCommaMode = . remove
209+ case nil :
204210 trailingCommaMode = . preserve
205211 }
206212
@@ -212,11 +218,12 @@ extension Formatter {
212218 }
213219
214220 case . multiElementLists:
215- if commaSeparatedElementsInScope ( startOfScope: startOfScope) . count <= 1 {
221+ switch trailingCommaSupported {
222+ case _ where commaSeparatedElementsInScope ( startOfScope: startOfScope) . count <= 1 , false ? :
216223 trailingCommaMode = . remove
217- } else if trailingCommaSupported {
224+ case true ? :
218225 trailingCommaMode = . insert
219- } else {
226+ case nil :
220227 trailingCommaMode = . preserve
221228 }
222229 }
0 commit comments