@@ -1799,8 +1799,23 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
17991799
18001800 override func visit( _ node: AvailabilityLabeledArgumentSyntax ) -> SyntaxVisitorContinueKind {
18011801 before ( node. label, tokens: . open)
1802- after ( node. colon, tokens: . break( . continue, newlines: . elective( ignoresDiscretionary: true ) ) )
1803- after ( node. value. lastToken ( viewMode: . sourceAccurate) , tokens: . close)
1802+
1803+ let tokensAfterColon : [ Token ]
1804+ let endTokens : [ Token ]
1805+
1806+ if case . string( let string) = node. value,
1807+ string. openingQuote. tokenKind == . multilineStringQuote
1808+ {
1809+ tokensAfterColon =
1810+ [ . break( . open( kind: . block) , newlines: . elective( ignoresDiscretionary: true ) ) ]
1811+ endTokens = [ . break( . close( mustBreak: false ) , size: 0 ) , . close]
1812+ } else {
1813+ tokensAfterColon = [ . break( . continue, newlines: . elective( ignoresDiscretionary: true ) ) ]
1814+ endTokens = [ . close]
1815+ }
1816+
1817+ after ( node. colon, tokens: tokensAfterColon)
1818+ after ( node. value. lastToken ( viewMode: . sourceAccurate) , tokens: endTokens)
18041819 return . visitChildren
18051820 }
18061821
@@ -2293,6 +2308,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
22932308
22942309 override func visit( _ node: GenericParameterSyntax ) -> SyntaxVisitorContinueKind {
22952310 before ( node. firstToken ( viewMode: . sourceAccurate) , tokens: . open)
2311+ after ( node. eachKeyword, tokens: . break)
22962312 after ( node. colon, tokens: . break)
22972313 if let trailingComma = node. trailingComma {
22982314 after ( trailingComma, tokens: . close, . break( . same) )
@@ -2312,6 +2328,28 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
23122328 return . visitChildren
23132329 }
23142330
2331+ override func visit( _ node: PackElementExprSyntax ) -> SyntaxVisitorContinueKind {
2332+ // `each` cannot be separated from the following token, or it is parsed as an identifier itself.
2333+ after ( node. eachKeyword, tokens: . space)
2334+ return . visitChildren
2335+ }
2336+
2337+ override func visit( _ node: PackElementTypeSyntax ) -> SyntaxVisitorContinueKind {
2338+ // `each` cannot be separated from the following token, or it is parsed as an identifier itself.
2339+ after ( node. eachKeyword, tokens: . space)
2340+ return . visitChildren
2341+ }
2342+
2343+ override func visit( _ node: PackExpansionExprSyntax ) -> SyntaxVisitorContinueKind {
2344+ after ( node. repeatKeyword, tokens: . break)
2345+ return . visitChildren
2346+ }
2347+
2348+ override func visit( _ node: PackExpansionTypeSyntax ) -> SyntaxVisitorContinueKind {
2349+ after ( node. repeatKeyword, tokens: . break)
2350+ return . visitChildren
2351+ }
2352+
23152353 override func visit( _ node: ExpressionPatternSyntax ) -> SyntaxVisitorContinueKind {
23162354 return . visitChildren
23172355 }
@@ -2353,6 +2391,16 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
23532391 return . visitChildren
23542392 }
23552393
2394+ override func visit( _ node: SimpleStringLiteralExprSyntax ) -> SyntaxVisitorContinueKind {
2395+ if node. openingQuote. tokenKind == . multilineStringQuote {
2396+ after ( node. openingQuote, tokens: . break( . same, size: 0 , newlines: . hard( count: 1 ) ) )
2397+ if !node. segments. isEmpty {
2398+ before ( node. closingQuote, tokens: . break( . same, newlines: . hard( count: 1 ) ) )
2399+ }
2400+ }
2401+ return . visitChildren
2402+ }
2403+
23562404 override func visit( _ node: StringSegmentSyntax ) -> SyntaxVisitorContinueKind {
23572405 // Looks up the correct break kind based on prior context.
23582406 func breakKind( ) -> BreakKind {
@@ -2481,6 +2529,27 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
24812529 return . visitChildren
24822530 }
24832531
2532+ override func visit( _ node: ConsumeExprSyntax ) -> SyntaxVisitorContinueKind {
2533+ // The `consume` keyword cannot be separated from the following token or it will be parsed as
2534+ // an identifier.
2535+ after ( node. consumeKeyword, tokens: . space)
2536+ return . visitChildren
2537+ }
2538+
2539+ override func visit( _ node: CopyExprSyntax ) -> SyntaxVisitorContinueKind {
2540+ // The `copy` keyword cannot be separated from the following token or it will be parsed as an
2541+ // identifier.
2542+ after ( node. copyKeyword, tokens: . space)
2543+ return . visitChildren
2544+ }
2545+
2546+ override func visit( _ node: DiscardStmtSyntax ) -> SyntaxVisitorContinueKind {
2547+ // The `discard` keyword cannot be separated from the following token or it will be parsed as
2548+ // an identifier.
2549+ after ( node. discardKeyword, tokens: . space)
2550+ return . visitChildren
2551+ }
2552+
24842553 override func visit( _ node: InheritanceClauseSyntax ) -> SyntaxVisitorContinueKind {
24852554 // Normally, the open-break is placed before the open token. In this case, it's intentionally
24862555 // ordered differently so that the inheritance list can start on the current line and only
0 commit comments