Repository: apple/swift-syntax (swift)

Issue:
swift syntax should be able to recover function parameters without argument labels
### Description

SwiftParser currently can’t handle DocC-style abridged signatures such as:

```
init(String.Index, x:(Int) -> Int) rethrows
```

as they are considered malformed parse trees. 

more details at https://forums.swift.org/t/swiftsyntax-how-to-repair-abbreviated-function-signatures/67602

Pull request description:
Fixes #2254

Patch:
diff --git a/Sources/SwiftParser/Parameters.swift b/Sources/SwiftParser/Parameters.swift
index 3c592f90476..355684d109f 100644
--- a/Sources/SwiftParser/Parameters.swift
+++ b/Sources/SwiftParser/Parameters.swift
@@ -96,11 +96,33 @@ extension Parser {
     let modifiers = parseParameterModifiers(isClosure: false)
     let misplacedSpecifiers = parseMisplacedSpecifiers()
 
-    var names = self.parseParameterNames()
-    let (unexpectedBeforeColon, colon) = self.expect(.colon)
+    var names: ParameterNames
 
+    let unexpectedBeforeColon: RawUnexpectedNodesSyntax?
+    let colon: RawTokenSyntax
     let type: RawTypeSyntax
 
+    // try to parse the type regardless of the presence of the preceding colon
+    // to tackle any unnamed parameter or missing colon
+    // e.g. [X], (:[X]) or (x [X])
+    let canParseType = withLookahead {
+      $0.currentToken.tokenText.isStartingWithUppercase && $0.canParseType() && $0.at(.comma, .rightParen)
+    }
+
+    if canParseType {
+      names = ParameterNames(
+        unexpectedBeforeFirstName: nil,
+        firstName: nil,
+        unexpectedBeforeSecondName: nil,
+        secondName: nil
+      )
+      unexpectedBeforeColon = nil
+      colon = missingToken(.colon)
+    } else {
+      names = self.parseParameterNames()
+      (unexpectedBeforeColon, colon) = self.expect(.colon)
+    }
+
     if colon.presence == .missing,
       let secondName = names.secondName,
       secondName.tokenKind == .identifier,


Test patch:
diff --git a/Tests/SwiftParserTest/ExpressionTests.swift b/Tests/SwiftParserTest/ExpressionTests.swift
index 1038026eb26..ef1b83f699f 100644
--- a/Tests/SwiftParserTest/ExpressionTests.swift
+++ b/Tests/SwiftParserTest/ExpressionTests.swift
@@ -3403,4 +3403,30 @@ final class StatementExpressionTests: ParserTestCase {
       substructureAfterMarker: "1️⃣"
     )
   }
+
+  func testFunctionParameterWithMalformedParameters() {
+    assertParse(
+      """
+      init(1️⃣String.Index, x:(Int) -> Int) rethrows
+      """,
+      diagnostics: [
+        DiagnosticSpec(message: "expected identifier and ':' in parameter", fixIts: ["insert identifier and ':'"])
+      ],
+      fixedSource: """
+        init(<#identifier#>: String.Index, x:(Int) -> Int) rethrows
+        """
+    )
+
+    assertParse(
+      """
+      init(1️⃣String.Index) rethrows
+      """,
+      diagnostics: [
+        DiagnosticSpec(message: "expected identifier and ':' in parameter", fixIts: ["insert identifier and ':'"])
+      ],
+      fixedSource: """
+        init(<#identifier#>: String.Index) rethrows
+        """
+    )
+  }
 }