@@ -1760,6 +1760,30 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
17601760 }
17611761
17621762 override func visit( _ node: KeyPathExprSyntax ) -> SyntaxVisitorContinueKind {
1763+ before ( node. backslash, tokens: . open)
1764+ after ( node. lastToken ( viewMode: . sourceAccurate) , tokens: . close)
1765+ return . visitChildren
1766+ }
1767+
1768+ override func visit( _ node: KeyPathComponentSyntax ) -> SyntaxVisitorContinueKind {
1769+ // If this is the first component (immediately after the backslash), allow a break after the
1770+ // slash only if a typename follows it. Do not break in the middle of `\.`.
1771+ var breakBeforePeriod = true
1772+ if let keyPathComponents = node. parent? . as ( KeyPathComponentListSyntax . self) ,
1773+ let keyPathExpr = keyPathComponents. parent? . as ( KeyPathExprSyntax . self) ,
1774+ node == keyPathExpr. components. first, keyPathExpr. root == nil
1775+ {
1776+ breakBeforePeriod = false
1777+ }
1778+ if breakBeforePeriod {
1779+ before ( node. period, tokens: . break( . continue, size: 0 ) )
1780+ }
1781+ return . visitChildren
1782+ }
1783+
1784+ override func visit( _ node: KeyPathSubscriptComponentSyntax ) -> SyntaxVisitorContinueKind {
1785+ after ( node. leftBracket, tokens: . break( . open, size: 0 ) , . open)
1786+ before ( node. rightBracket, tokens: . break( . close, size: 0 ) , . close)
17631787 return . visitChildren
17641788 }
17651789
@@ -1847,24 +1871,6 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
18471871 }
18481872
18491873 override func visit( _ node: InfixOperatorExprSyntax ) -> SyntaxVisitorContinueKind {
1850- // FIXME: This is a workaround/hack for https://github.com/apple/swift-syntax/issues/928. For
1851- // keypaths like `\.?.foo`, they get represented (after folding) as an infix operator expression
1852- // with an empty keypath, followed by the "binary operator" `.?.`, followed by other
1853- // expressions. We can detect this and treat the whole thing as a verbatim node, which mimics
1854- // what we do today for keypaths (i.e., nothing).
1855- if let keyPathExpr = node. leftOperand. as ( KeyPathExprSyntax . self) ,
1856- keyPathExpr. components. isEmpty
1857- {
1858- // If there were spaces in the trailing trivia of the previous token, they would have been
1859- // ignored (since this expression would be expected to insert its own preceding breaks).
1860- // Preserve that whitespace verbatim for now.
1861- if let previousToken = node. firstToken ( viewMode: . sourceAccurate) ? . previousToken ( viewMode: . sourceAccurate) {
1862- appendTrailingTrivia ( previousToken, forced: true )
1863- }
1864- verbatimToken ( Syntax ( node) , indentingBehavior: . none)
1865- return . skipChildren
1866- }
1867-
18681874 let binOp = node. operatorOperand
18691875 if binOp. is ( ArrowExprSyntax . self) {
18701876 // `ArrowExprSyntax` nodes occur when a function type is written in an expression context;
0 commit comments