@@ -1948,13 +1948,18 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
1948
1948
1949
1949
// If the rhs starts with a parenthesized expression, stack indentation around it.
1950
1950
// Otherwise, use regular continuation breaks.
1951
- if let ( unindentingNode, _, breakKind, _ ) =
1951
+ if let ( unindentingNode, _, breakKind, shouldGroup ) =
1952
1952
stackedIndentationBehavior ( after: binOp, rhs: rhs)
1953
1953
{
1954
1954
beforeTokens = [ . break( . open( kind: breakKind) ) ]
1955
+ var afterTokens : [ Token ] = [ . break( . close( mustBreak: false ) , size: 0 ) ]
1956
+ if shouldGroup {
1957
+ beforeTokens. append ( . open)
1958
+ afterTokens. append ( . close)
1959
+ }
1955
1960
after (
1956
1961
unindentingNode. lastToken ( viewMode: . sourceAccurate) ,
1957
- tokens: [ . break ( . close ( mustBreak : false ) , size : 0 ) ] )
1962
+ tokens: afterTokens )
1958
1963
} else {
1959
1964
beforeTokens = [ . break( . continue) ]
1960
1965
}
@@ -2104,9 +2109,17 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
2104
2109
if let initializer = node. initializer {
2105
2110
let expr = initializer. value
2106
2111
2107
- if let ( unindentingNode, _, breakKind, _) = stackedIndentationBehavior ( rhs: expr) {
2108
- after ( initializer. equal, tokens: . break( . open( kind: breakKind) ) )
2109
- after ( unindentingNode. lastToken ( viewMode: . sourceAccurate) , tokens: . break( . close( mustBreak: false ) , size: 0 ) )
2112
+ if let ( unindentingNode, _, breakKind, shouldGroup) = stackedIndentationBehavior ( rhs: expr) {
2113
+ var openTokens : [ Token ] = [ . break( . open( kind: breakKind) ) ]
2114
+ if shouldGroup {
2115
+ openTokens. append ( . open)
2116
+ }
2117
+ after ( initializer. equal, tokens: openTokens)
2118
+ var closeTokens : [ Token ] = [ . break( . close( mustBreak: false ) , size: 0 ) ]
2119
+ if shouldGroup {
2120
+ closeTokens. append ( . close)
2121
+ }
2122
+ after ( unindentingNode. lastToken ( viewMode: . sourceAccurate) , tokens: closeTokens)
2110
2123
} else {
2111
2124
after ( initializer. equal, tokens: . break( . continue) )
2112
2125
}
@@ -2273,9 +2286,13 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
2273
2286
override func visit( _ node: InitializerClauseSyntax ) -> SyntaxVisitorContinueKind {
2274
2287
before ( node. equal, tokens: . space)
2275
2288
2276
- // InitializerClauses that are children of a PatternBindingSyntax are already handled in the
2277
- // latter node, to ensure that continuations stack appropriately.
2278
- if node. parent == nil || !node. parent!. is ( PatternBindingSyntax . self) {
2289
+ // InitializerClauses that are children of a PatternBindingSyntax or
2290
+ // OptionalBindingConditionSyntax are already handled in the latter node, to ensure that
2291
+ // continuations stack appropriately.
2292
+ if let parent = node. parent,
2293
+ !parent. is ( PatternBindingSyntax . self)
2294
+ && !parent. is ( OptionalBindingConditionSyntax . self)
2295
+ {
2279
2296
after ( node. equal, tokens: . break)
2280
2297
}
2281
2298
return . visitChildren
@@ -2457,6 +2474,26 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
2457
2474
after ( typeAnnotation. lastToken ( viewMode: . sourceAccurate) , tokens: . break( . close( mustBreak: false ) , size: 0 ) )
2458
2475
}
2459
2476
2477
+ if let initializer = node. initializer {
2478
+ if let ( unindentingNode, _, breakKind, shouldGroup) =
2479
+ stackedIndentationBehavior ( rhs: initializer. value)
2480
+ {
2481
+ var openTokens : [ Token ] = [ . break( . open( kind: breakKind) ) ]
2482
+ if shouldGroup {
2483
+ openTokens. append ( . open)
2484
+ }
2485
+ after ( initializer. equal, tokens: openTokens)
2486
+
2487
+ var closeTokens : [ Token ] = [ . break( . close( mustBreak: false ) , size: 0 ) ]
2488
+ if shouldGroup {
2489
+ closeTokens. append ( . close)
2490
+ }
2491
+ after ( unindentingNode. lastToken ( viewMode: . sourceAccurate) , tokens: closeTokens)
2492
+ } else {
2493
+ after ( initializer. equal, tokens: . break( . continue) )
2494
+ }
2495
+ }
2496
+
2460
2497
return . visitChildren
2461
2498
}
2462
2499
@@ -3372,47 +3409,63 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
3372
3409
}
3373
3410
}
3374
3411
3375
- /// Walks the expression and returns the leftmost multiline string literal (which might be the
3376
- /// expression itself) if the leftmost child is a multiline string literal or if it is a unary
3377
- /// operation applied to a multiline string literal .
3412
+ /// Walks the expression and returns the leftmost subexpression (which might be the expression
3413
+ /// itself) if the leftmost child is a node of the given type or if it is a unary operation
3414
+ /// applied to a node of the given type .
3378
3415
///
3379
- /// - Parameter expr: The expression whose leftmost multiline string literal should be returned.
3380
- /// - Returns: The leftmost multiline string literal, or nil if the leftmost subexpression was
3381
- /// not a multiline string literal.
3382
- private func leftmostMultilineStringLiteral( of expr: ExprSyntax ) -> StringLiteralExprSyntax ? {
3416
+ /// - Parameter expr: The expression whose leftmost matching subexpression should be returned.
3417
+ /// - Returns: The leftmost subexpression, or nil if the leftmost subexpression was not the
3418
+ /// desired type.
3419
+ private func leftmostExpr(
3420
+ of expr: ExprSyntax ,
3421
+ ifMatching predicate: ( ExprSyntax ) -> Bool
3422
+ ) -> ExprSyntax ? {
3423
+ if predicate ( expr) {
3424
+ return expr
3425
+ }
3383
3426
switch Syntax ( expr) . as ( SyntaxEnum . self) {
3384
- case . stringLiteralExpr( let stringLiteralExpr)
3385
- where stringLiteralExpr. openQuote. tokenKind == . multilineStringQuote:
3386
- return stringLiteralExpr
3387
3427
case . infixOperatorExpr( let infixOperatorExpr) :
3388
- return leftmostMultilineStringLiteral ( of: infixOperatorExpr. leftOperand)
3428
+ return leftmostExpr ( of: infixOperatorExpr. leftOperand, ifMatching : predicate )
3389
3429
case . asExpr( let asExpr) :
3390
- return leftmostMultilineStringLiteral ( of: asExpr. expression)
3430
+ return leftmostExpr ( of: asExpr. expression, ifMatching : predicate )
3391
3431
case . isExpr( let isExpr) :
3392
- return leftmostMultilineStringLiteral ( of: isExpr. expression)
3432
+ return leftmostExpr ( of: isExpr. expression, ifMatching : predicate )
3393
3433
case . forcedValueExpr( let forcedValueExpr) :
3394
- return leftmostMultilineStringLiteral ( of: forcedValueExpr. expression)
3434
+ return leftmostExpr ( of: forcedValueExpr. expression, ifMatching : predicate )
3395
3435
case . optionalChainingExpr( let optionalChainingExpr) :
3396
- return leftmostMultilineStringLiteral ( of: optionalChainingExpr. expression)
3436
+ return leftmostExpr ( of: optionalChainingExpr. expression, ifMatching : predicate )
3397
3437
case . postfixUnaryExpr( let postfixUnaryExpr) :
3398
- return leftmostMultilineStringLiteral ( of: postfixUnaryExpr. expression)
3438
+ return leftmostExpr ( of: postfixUnaryExpr. expression, ifMatching : predicate )
3399
3439
case . prefixOperatorExpr( let prefixOperatorExpr) :
3400
- return leftmostMultilineStringLiteral ( of: prefixOperatorExpr. postfixExpression)
3440
+ return leftmostExpr ( of: prefixOperatorExpr. postfixExpression, ifMatching : predicate )
3401
3441
case . ternaryExpr( let ternaryExpr) :
3402
- return leftmostMultilineStringLiteral ( of: ternaryExpr. conditionExpression)
3442
+ return leftmostExpr ( of: ternaryExpr. conditionExpression, ifMatching : predicate )
3403
3443
case . functionCallExpr( let functionCallExpr) :
3404
- return leftmostMultilineStringLiteral ( of: functionCallExpr. calledExpression)
3444
+ return leftmostExpr ( of: functionCallExpr. calledExpression, ifMatching : predicate )
3405
3445
case . subscriptExpr( let subscriptExpr) :
3406
- return leftmostMultilineStringLiteral ( of: subscriptExpr. calledExpression)
3446
+ return leftmostExpr ( of: subscriptExpr. calledExpression, ifMatching : predicate )
3407
3447
case . memberAccessExpr( let memberAccessExpr) :
3408
- return memberAccessExpr. base. flatMap { leftmostMultilineStringLiteral ( of: $0) }
3448
+ return memberAccessExpr. base. flatMap { leftmostExpr ( of: $0, ifMatching : predicate ) }
3409
3449
case . postfixIfConfigExpr( let postfixIfConfigExpr) :
3410
- return postfixIfConfigExpr. base. flatMap { leftmostMultilineStringLiteral ( of: $0) }
3450
+ return postfixIfConfigExpr. base. flatMap { leftmostExpr ( of: $0, ifMatching : predicate ) }
3411
3451
default :
3412
3452
return nil
3413
3453
}
3414
3454
}
3415
3455
3456
+ /// Walks the expression and returns the leftmost multiline string literal (which might be the
3457
+ /// expression itself) if the leftmost child is a multiline string literal or if it is a unary
3458
+ /// operation applied to a multiline string literal.
3459
+ ///
3460
+ /// - Parameter expr: The expression whose leftmost multiline string literal should be returned.
3461
+ /// - Returns: The leftmost multiline string literal, or nil if the leftmost subexpression was
3462
+ /// not a multiline string literal.
3463
+ private func leftmostMultilineStringLiteral( of expr: ExprSyntax ) -> StringLiteralExprSyntax ? {
3464
+ return leftmostExpr ( of: expr) {
3465
+ $0. as ( StringLiteralExprSyntax . self) ? . openQuote. tokenKind == . multilineStringQuote
3466
+ } ? . as ( StringLiteralExprSyntax . self)
3467
+ }
3468
+
3416
3469
/// Returns the outermost node enclosing the given node whose closing delimiter(s) must be kept
3417
3470
/// alongside the last token of the given node. Any tokens between `node.lastToken` and the
3418
3471
/// returned node's `lastToken` are delimiter tokens that shouldn't be preceded by a break.
@@ -3503,7 +3556,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
3503
3556
unindentingNode: unindentingParenExpr,
3504
3557
shouldReset: true ,
3505
3558
breakKind: . continuation,
3506
- shouldGroup: true
3559
+ shouldGroup: false
3507
3560
)
3508
3561
}
3509
3562
@@ -3519,7 +3572,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
3519
3572
unindentingNode: Syntax ( parenthesizedExpr) ,
3520
3573
shouldReset: false ,
3521
3574
breakKind: . continuation,
3522
- shouldGroup: true
3575
+ shouldGroup: false
3523
3576
)
3524
3577
}
3525
3578
@@ -3535,6 +3588,17 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
3535
3588
)
3536
3589
}
3537
3590
3591
+ if let leftmostExpr = leftmostExpr ( of: rhs, ifMatching: {
3592
+ $0. is ( IfExprSyntax . self) || $0. is ( SwitchExprSyntax . self)
3593
+ } ) {
3594
+ return (
3595
+ unindentingNode: Syntax ( leftmostExpr) ,
3596
+ shouldReset: false ,
3597
+ breakKind: . block,
3598
+ shouldGroup: true
3599
+ )
3600
+ }
3601
+
3538
3602
// Otherwise, don't stack--use regular continuation breaks instead.
3539
3603
return nil
3540
3604
}
0 commit comments