Repository: apple/swift-syntax (swift)

Issue:
Wrong spacing around `:` in Fix-It for ternary expressions
### Description

https://github.com/apple/swift-syntax/pull/1549#discussion_r1179887649
Test case `testVariableDeclarations`

### Steps to Reproduce

_No response_

Pull request:
This pull request addresses #1607

Patch:
diff --git a/Sources/SwiftBasicFormat/BasicFormat.swift b/Sources/SwiftBasicFormat/BasicFormat.swift
index 43ad368d5d0..ba2e3f5b72a 100644
--- a/Sources/SwiftBasicFormat/BasicFormat.swift
+++ b/Sources/SwiftBasicFormat/BasicFormat.swift
@@ -223,7 +223,6 @@ open class BasicFormat: SyntaxRewriter {
       (.singleQuote, .rawStringDelimiter),  // closing raw string delimiter should never be separate by a space
       (.stringQuote, .rawStringDelimiter),  // closing raw string delimiter should never be separate by a space
       (.stringSegment, _),
-      (_, .colon),
       (_, .comma),
       (_, .ellipsis),
       (_, .eof),
@@ -237,6 +236,12 @@ open class BasicFormat: SyntaxRewriter {
       (_, nil),
       (nil, _):
       return false
+    case (_, .colon):
+      if second?.keyPathInParent != \TernaryExprSyntax.colonMark
+        && second?.keyPathInParent != \UnresolvedTernaryExprSyntax.colonMark
+      {
+        return false
+      }
     case (.leftAngle, _) where second?.tokenKind != .rightAngle:  // `<` and `>` need to be separated by a space because otherwise they become an operator
       return false
     case (_, .rightAngle) where first?.tokenKind != .leftAngle:  // `<` and `>` need to be separated by a space because otherwise they become an operator


Test patch:
diff --git a/Tests/SwiftParserTest/DeclarationTests.swift b/Tests/SwiftParserTest/DeclarationTests.swift
index 36f4ae707f3..19f24b3de25 100644
--- a/Tests/SwiftParserTest/DeclarationTests.swift
+++ b/Tests/SwiftParserTest/DeclarationTests.swift
@@ -256,7 +256,7 @@ final class DeclarationTests: XCTestCase {
         DiagnosticSpec(message: "expected ':' and expression after '? ...' in ternary expression", fixIts: ["insert ':' and expression"])
       ],
       fixedSource: """
-        _ = foo/* */?.description: <#expression#>
+        _ = foo/* */?.description : <#expression#>
         """
     )
 
diff --git a/Tests/SwiftParserTest/ExpressionTests.swift b/Tests/SwiftParserTest/ExpressionTests.swift
index affbe886b95..f43a92fc2c7 100644
--- a/Tests/SwiftParserTest/ExpressionTests.swift
+++ b/Tests/SwiftParserTest/ExpressionTests.swift
@@ -836,7 +836,7 @@ final class ExpressionTests: XCTestCase {
         DiagnosticSpec(message: "expected ':' and expression after '? ...' in ternary expression", fixIts: ["insert ':' and expression"])
       ],
       fixedSource: """
-        foo ? 1: <#expression#>
+        foo ? 1 : <#expression#>
         """
     )
   }
diff --git a/Tests/SwiftParserTest/translated/InvalidIfExprTests.swift b/Tests/SwiftParserTest/translated/InvalidIfExprTests.swift
index 337c344a742..bc9acf35685 100644
--- a/Tests/SwiftParserTest/translated/InvalidIfExprTests.swift
+++ b/Tests/SwiftParserTest/translated/InvalidIfExprTests.swift
@@ -23,7 +23,7 @@ final class InvalidIfExprTests: XCTestCase {
       diagnostics: [
         DiagnosticSpec(message: "expected ':' and expression after '? ...' in ternary expression", fixIts: ["insert ':' and expression"])
       ],
-      fixedSource: "(a ? b: <#expression#>)"
+      fixedSource: "(a ? b : <#expression#>)"
     )
   }
 
@@ -35,7 +35,7 @@ final class InvalidIfExprTests: XCTestCase {
       diagnostics: [
         DiagnosticSpec(message: "expected ':' and expression after '? ...' in ternary expression", fixIts: ["insert ':' and expression"])
       ],
-      fixedSource: "(a ? b : c ? d: <#expression#>)"
+      fixedSource: "(a ? b : c ? d : <#expression#>)"
     )
   }
 
@@ -52,7 +52,7 @@ final class InvalidIfExprTests: XCTestCase {
           fixIts: ["insert ')'"]
         ),
       ],
-      fixedSource: "(a ? b ? c : d: <#expression#>)"
+      fixedSource: "(a ? b ? c : d : <#expression#>)"
     )
   }
 
@@ -65,7 +65,7 @@ final class InvalidIfExprTests: XCTestCase {
         DiagnosticSpec(message: "expected ':' and expression after '? ...' in ternary expression", fixIts: ["insert ':' and expression"]),
         DiagnosticSpec(message: "expected ':' and expression after '? ...' in ternary expression", fixIts: ["insert ':' and expression"]),
       ],
-      fixedSource: "(a ? b ? c: <#expression#>: <#expression#>)"
+      fixedSource: "(a ? b ? c : <#expression#> : <#expression#>)"
     )
   }
 
diff --git a/Tests/SwiftSyntaxBuilderTest/TernaryExprTests.swift b/Tests/SwiftSyntaxBuilderTest/TernaryExprTests.swift
index ba6521c0abe..fa34e3f9434 100644
--- a/Tests/SwiftSyntaxBuilderTest/TernaryExprTests.swift
+++ b/Tests/SwiftSyntaxBuilderTest/TernaryExprTests.swift
@@ -15,7 +15,7 @@ import SwiftSyntax
 import SwiftSyntaxBuilder
 
 final class TernaryExprTests: XCTestCase {
-  func testTernaryExpr() {
+  func testStringLiteralTernaryExpr() {
     let buildable = ExprSyntax("true ? a : b")
     assertBuildResult(
       buildable,
@@ -24,4 +24,32 @@ final class TernaryExprTests: XCTestCase {
       """
     )
   }
+
+  func testTernarySequenceExpr() {
+    let buildable = SequenceExprSyntax {
+      BooleanLiteralExprSyntax(true)
+      UnresolvedTernaryExprSyntax(firstChoice: IntegerLiteralExprSyntax(1))
+      IntegerLiteralExprSyntax(0)
+    }
+    assertBuildResult(
+      buildable,
+      """
+      true ? 1 : 0
+      """
+    )
+  }
+
+  func testTernaryExpr() {
+    let buildable = TernaryExprSyntax(
+      conditionExpression: BooleanLiteralExprSyntax(true),
+      firstChoice: IntegerLiteralExprSyntax(1),
+      secondChoice: IntegerLiteralExprSyntax(0)
+    )
+    assertBuildResult(
+      buildable,
+      """
+      true ? 1 : 0
+      """
+    )
+  }
 }