@@ -1965,13 +1965,18 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
1965
1965
1966
1966
// If the rhs starts with a parenthesized expression, stack indentation around it.
1967
1967
// Otherwise, use regular continuation breaks.
1968
- if let ( unindentingNode, _, breakKind, _ ) =
1968
+ if let ( unindentingNode, _, breakKind, shouldGroup ) =
1969
1969
stackedIndentationBehavior ( after: binOp, rhs: rhs)
1970
1970
{
1971
1971
beforeTokens = [ . break( . open( kind: breakKind) ) ]
1972
+ var afterTokens : [ Token ] = [ . break( . close( mustBreak: false ) , size: 0 ) ]
1973
+ if shouldGroup {
1974
+ beforeTokens. append ( . open)
1975
+ afterTokens. append ( . close)
1976
+ }
1972
1977
after (
1973
1978
unindentingNode. lastToken ( viewMode: . sourceAccurate) ,
1974
- tokens: [ . break ( . close ( mustBreak : false ) , size : 0 ) ] )
1979
+ tokens: afterTokens )
1975
1980
} else {
1976
1981
beforeTokens = [ . break( . continue) ]
1977
1982
}
@@ -2121,9 +2126,17 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
2121
2126
if let initializer = node. initializer {
2122
2127
let expr = initializer. value
2123
2128
2124
- if let ( unindentingNode, _, breakKind, _) = stackedIndentationBehavior ( rhs: expr) {
2125
- after ( initializer. equal, tokens: . break( . open( kind: breakKind) ) )
2126
- after ( unindentingNode. lastToken ( viewMode: . sourceAccurate) , tokens: . break( . close( mustBreak: false ) , size: 0 ) )
2129
+ if let ( unindentingNode, _, breakKind, shouldGroup) = stackedIndentationBehavior ( rhs: expr) {
2130
+ var openTokens : [ Token ] = [ . break( . open( kind: breakKind) ) ]
2131
+ if shouldGroup {
2132
+ openTokens. append ( . open)
2133
+ }
2134
+ after ( initializer. equal, tokens: openTokens)
2135
+ var closeTokens : [ Token ] = [ . break( . close( mustBreak: false ) , size: 0 ) ]
2136
+ if shouldGroup {
2137
+ closeTokens. append ( . close)
2138
+ }
2139
+ after ( unindentingNode. lastToken ( viewMode: . sourceAccurate) , tokens: closeTokens)
2127
2140
} else {
2128
2141
after ( initializer. equal, tokens: . break( . continue) )
2129
2142
}
@@ -2290,9 +2303,13 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
2290
2303
override func visit( _ node: InitializerClauseSyntax ) -> SyntaxVisitorContinueKind {
2291
2304
before ( node. equal, tokens: . space)
2292
2305
2293
- // InitializerClauses that are children of a PatternBindingSyntax are already handled in the
2294
- // latter node, to ensure that continuations stack appropriately.
2295
- if node. parent == nil || !node. parent!. is ( PatternBindingSyntax . self) {
2306
+ // InitializerClauses that are children of a PatternBindingSyntax or
2307
+ // OptionalBindingConditionSyntax are already handled in the latter node, to ensure that
2308
+ // continuations stack appropriately.
2309
+ if let parent = node. parent,
2310
+ !parent. is ( PatternBindingSyntax . self)
2311
+ && !parent. is ( OptionalBindingConditionSyntax . self)
2312
+ {
2296
2313
after ( node. equal, tokens: . break)
2297
2314
}
2298
2315
return . visitChildren
@@ -2474,6 +2491,26 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
2474
2491
after ( typeAnnotation. lastToken ( viewMode: . sourceAccurate) , tokens: . break( . close( mustBreak: false ) , size: 0 ) )
2475
2492
}
2476
2493
2494
+ if let initializer = node. initializer {
2495
+ if let ( unindentingNode, _, breakKind, shouldGroup) =
2496
+ stackedIndentationBehavior ( rhs: initializer. value)
2497
+ {
2498
+ var openTokens : [ Token ] = [ . break( . open( kind: breakKind) ) ]
2499
+ if shouldGroup {
2500
+ openTokens. append ( . open)
2501
+ }
2502
+ after ( initializer. equal, tokens: openTokens)
2503
+
2504
+ var closeTokens : [ Token ] = [ . break( . close( mustBreak: false ) , size: 0 ) ]
2505
+ if shouldGroup {
2506
+ closeTokens. append ( . close)
2507
+ }
2508
+ after ( unindentingNode. lastToken ( viewMode: . sourceAccurate) , tokens: closeTokens)
2509
+ } else {
2510
+ after ( initializer. equal, tokens: . break( . continue) )
2511
+ }
2512
+ }
2513
+
2477
2514
return . visitChildren
2478
2515
}
2479
2516
@@ -3389,47 +3426,63 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
3389
3426
}
3390
3427
}
3391
3428
3392
- /// Walks the expression and returns the leftmost multiline string literal (which might be the
3393
- /// expression itself) if the leftmost child is a multiline string literal or if it is a unary
3394
- /// operation applied to a multiline string literal .
3429
+ /// Walks the expression and returns the leftmost subexpression (which might be the expression
3430
+ /// itself) if the leftmost child is a node of the given type or if it is a unary operation
3431
+ /// applied to a node of the given type .
3395
3432
///
3396
- /// - Parameter expr: The expression whose leftmost multiline string literal should be returned.
3397
- /// - Returns: The leftmost multiline string literal, or nil if the leftmost subexpression was
3398
- /// not a multiline string literal.
3399
- private func leftmostMultilineStringLiteral( of expr: ExprSyntax ) -> StringLiteralExprSyntax ? {
3433
+ /// - Parameter expr: The expression whose leftmost matching subexpression should be returned.
3434
+ /// - Returns: The leftmost subexpression, or nil if the leftmost subexpression was not the
3435
+ /// desired type.
3436
+ private func leftmostExpr(
3437
+ of expr: ExprSyntax ,
3438
+ ifMatching predicate: ( ExprSyntax ) -> Bool
3439
+ ) -> ExprSyntax ? {
3440
+ if predicate ( expr) {
3441
+ return expr
3442
+ }
3400
3443
switch Syntax ( expr) . as ( SyntaxEnum . self) {
3401
- case . stringLiteralExpr( let stringLiteralExpr)
3402
- where stringLiteralExpr. openQuote. tokenKind == . multilineStringQuote:
3403
- return stringLiteralExpr
3404
3444
case . infixOperatorExpr( let infixOperatorExpr) :
3405
- return leftmostMultilineStringLiteral ( of: infixOperatorExpr. leftOperand)
3445
+ return leftmostExpr ( of: infixOperatorExpr. leftOperand, ifMatching : predicate )
3406
3446
case . asExpr( let asExpr) :
3407
- return leftmostMultilineStringLiteral ( of: asExpr. expression)
3447
+ return leftmostExpr ( of: asExpr. expression, ifMatching : predicate )
3408
3448
case . isExpr( let isExpr) :
3409
- return leftmostMultilineStringLiteral ( of: isExpr. expression)
3449
+ return leftmostExpr ( of: isExpr. expression, ifMatching : predicate )
3410
3450
case . forcedValueExpr( let forcedValueExpr) :
3411
- return leftmostMultilineStringLiteral ( of: forcedValueExpr. expression)
3451
+ return leftmostExpr ( of: forcedValueExpr. expression, ifMatching : predicate )
3412
3452
case . optionalChainingExpr( let optionalChainingExpr) :
3413
- return leftmostMultilineStringLiteral ( of: optionalChainingExpr. expression)
3453
+ return leftmostExpr ( of: optionalChainingExpr. expression, ifMatching : predicate )
3414
3454
case . postfixUnaryExpr( let postfixUnaryExpr) :
3415
- return leftmostMultilineStringLiteral ( of: postfixUnaryExpr. expression)
3455
+ return leftmostExpr ( of: postfixUnaryExpr. expression, ifMatching : predicate )
3416
3456
case . prefixOperatorExpr( let prefixOperatorExpr) :
3417
- return leftmostMultilineStringLiteral ( of: prefixOperatorExpr. postfixExpression)
3457
+ return leftmostExpr ( of: prefixOperatorExpr. postfixExpression, ifMatching : predicate )
3418
3458
case . ternaryExpr( let ternaryExpr) :
3419
- return leftmostMultilineStringLiteral ( of: ternaryExpr. conditionExpression)
3459
+ return leftmostExpr ( of: ternaryExpr. conditionExpression, ifMatching : predicate )
3420
3460
case . functionCallExpr( let functionCallExpr) :
3421
- return leftmostMultilineStringLiteral ( of: functionCallExpr. calledExpression)
3461
+ return leftmostExpr ( of: functionCallExpr. calledExpression, ifMatching : predicate )
3422
3462
case . subscriptExpr( let subscriptExpr) :
3423
- return leftmostMultilineStringLiteral ( of: subscriptExpr. calledExpression)
3463
+ return leftmostExpr ( of: subscriptExpr. calledExpression, ifMatching : predicate )
3424
3464
case . memberAccessExpr( let memberAccessExpr) :
3425
- return memberAccessExpr. base. flatMap { leftmostMultilineStringLiteral ( of: $0) }
3465
+ return memberAccessExpr. base. flatMap { leftmostExpr ( of: $0, ifMatching : predicate ) }
3426
3466
case . postfixIfConfigExpr( let postfixIfConfigExpr) :
3427
- return postfixIfConfigExpr. base. flatMap { leftmostMultilineStringLiteral ( of: $0) }
3467
+ return postfixIfConfigExpr. base. flatMap { leftmostExpr ( of: $0, ifMatching : predicate ) }
3428
3468
default :
3429
3469
return nil
3430
3470
}
3431
3471
}
3432
3472
3473
+ /// Walks the expression and returns the leftmost multiline string literal (which might be the
3474
+ /// expression itself) if the leftmost child is a multiline string literal or if it is a unary
3475
+ /// operation applied to a multiline string literal.
3476
+ ///
3477
+ /// - Parameter expr: The expression whose leftmost multiline string literal should be returned.
3478
+ /// - Returns: The leftmost multiline string literal, or nil if the leftmost subexpression was
3479
+ /// not a multiline string literal.
3480
+ private func leftmostMultilineStringLiteral( of expr: ExprSyntax ) -> StringLiteralExprSyntax ? {
3481
+ return leftmostExpr ( of: expr) {
3482
+ $0. as ( StringLiteralExprSyntax . self) ? . openQuote. tokenKind == . multilineStringQuote
3483
+ } ? . as ( StringLiteralExprSyntax . self)
3484
+ }
3485
+
3433
3486
/// Returns the outermost node enclosing the given node whose closing delimiter(s) must be kept
3434
3487
/// alongside the last token of the given node. Any tokens between `node.lastToken` and the
3435
3488
/// returned node's `lastToken` are delimiter tokens that shouldn't be preceded by a break.
@@ -3520,7 +3573,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
3520
3573
unindentingNode: unindentingParenExpr,
3521
3574
shouldReset: true ,
3522
3575
breakKind: . continuation,
3523
- shouldGroup: true
3576
+ shouldGroup: false
3524
3577
)
3525
3578
}
3526
3579
@@ -3536,7 +3589,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
3536
3589
unindentingNode: Syntax ( parenthesizedExpr) ,
3537
3590
shouldReset: false ,
3538
3591
breakKind: . continuation,
3539
- shouldGroup: true
3592
+ shouldGroup: false
3540
3593
)
3541
3594
}
3542
3595
@@ -3552,6 +3605,17 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
3552
3605
)
3553
3606
}
3554
3607
3608
+ if let leftmostExpr = leftmostExpr ( of: rhs, ifMatching: {
3609
+ $0. is ( IfExprSyntax . self) || $0. is ( SwitchExprSyntax . self)
3610
+ } ) {
3611
+ return (
3612
+ unindentingNode: Syntax ( leftmostExpr) ,
3613
+ shouldReset: false ,
3614
+ breakKind: . block,
3615
+ shouldGroup: true
3616
+ )
3617
+ }
3618
+
3555
3619
// Otherwise, don't stack--use regular continuation breaks instead.
3556
3620
return nil
3557
3621
}
0 commit comments