@@ -622,25 +622,23 @@ private final class TokenStreamCreator: SyntaxVisitor {
622
622
}
623
623
624
624
func visit( _ node: FunctionCallExprSyntax ) -> SyntaxVisitorContinueKind {
625
- var argumentIterator = node. argumentList. makeIterator ( )
626
- let firstArgument = argumentIterator. next ( )
627
-
628
- if firstArgument != nil {
625
+ if shouldBreakAroundArgumentList ( of: node) {
629
626
// If there is a trailing closure, force the right parenthesis down to the next line so it
630
627
// stays with the open curly brace.
631
628
let breakBeforeRightParen = node. trailingClosure != nil
632
629
633
630
after ( node. leftParen, tokens: . break( . open, size: 0 ) , . open( argumentListConsistency ( ) ) )
634
631
before (
635
- node. rightParen,
636
- tokens: . break( . close( mustBreak: breakBeforeRightParen) , size: 0 ) , . close)
632
+ node. rightParen, tokens: . break( . close( mustBreak: breakBeforeRightParen) , size: 0 ) , . close)
637
633
}
638
634
before ( node. trailingClosure? . leftBrace, tokens: . break( . reset) )
639
635
return . visitChildren
640
636
}
641
637
642
638
func visit( _ node: FunctionCallArgumentSyntax ) -> SyntaxVisitorContinueKind {
643
- before ( node. firstToken, tokens: . open)
639
+ if node. colon != nil {
640
+ before ( node. firstToken, tokens: . open)
641
+ }
644
642
645
643
// If we have an open delimiter following the colon, use a space instead of a continuation
646
644
// break so that we don't awkwardly shift the delimiter down and indent it further if it
@@ -649,8 +647,12 @@ private final class TokenStreamCreator: SyntaxVisitor {
649
647
after ( node. colon, tokens: tokenAfterColon)
650
648
651
649
if let trailingComma = node. trailingComma {
652
- after ( trailingComma, tokens: . close, . break( . same) )
653
- } else {
650
+ var afterTrailingComma : [ Token ] = [ . break( . same) ]
651
+ if node. colon != nil {
652
+ afterTrailingComma. insert ( . close, at: 0 )
653
+ }
654
+ after ( trailingComma, tokens: afterTrailingComma)
655
+ } else if node. colon != nil {
654
656
after ( node. lastToken, tokens: . close)
655
657
}
656
658
return . visitChildren
@@ -1939,6 +1941,28 @@ private final class TokenStreamCreator: SyntaxVisitor {
1939
1941
default : return false
1940
1942
}
1941
1943
}
1944
+
1945
+ /// Returns true if open/close breaks should be inserted around the entire argument list of the
1946
+ /// given function call expression.
1947
+ private func shouldBreakAroundArgumentList( of node: FunctionCallExprSyntax ) -> Bool {
1948
+ let argumentCount = node. argumentList. count
1949
+
1950
+ // If there are no arguments, there's no reason to break.
1951
+ if argumentCount == 0 { return false }
1952
+
1953
+ // If there is more than one argument, we must open/close break around the whole list.
1954
+ if argumentCount > 1 { return true }
1955
+
1956
+ // At this point, we know there is only one argument in the list. If it's unlabeled and it's an
1957
+ // array, dictionary, or closure literal, we shouldn't open/close break around it; it will look
1958
+ // better if we keep the neighboring parentheses and brackets together and wrap inside them
1959
+ // instead.
1960
+ let firstArgument = node. argumentList. first!
1961
+ let expression = firstArgument. expression
1962
+ return firstArgument. colon != nil
1963
+ || !( expression is ArrayExprSyntax || expression is DictionaryExprSyntax
1964
+ || expression is ClosureExprSyntax )
1965
+ }
1942
1966
}
1943
1967
1944
1968
extension Syntax {
0 commit comments