Skip to content

Commit 8ac9b96

Browse files
authored
Merge pull request #2927 from kimdv/kimdv/fix-issue-2254
Fix parsing invalid function parameters
2 parents d84bd2f + dfbc52e commit 8ac9b96

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

Sources/SwiftParser/Parameters.swift

+24-2
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,33 @@ extension Parser {
9696
let modifiers = parseParameterModifiers(isClosure: false)
9797
let misplacedSpecifiers = parseMisplacedSpecifiers()
9898

99-
var names = self.parseParameterNames()
100-
let (unexpectedBeforeColon, colon) = self.expect(.colon)
99+
var names: ParameterNames
101100

101+
let unexpectedBeforeColon: RawUnexpectedNodesSyntax?
102+
let colon: RawTokenSyntax
102103
let type: RawTypeSyntax
103104

105+
// try to parse the type regardless of the presence of the preceding colon
106+
// to tackle any unnamed parameter or missing colon
107+
// e.g. [X], (:[X]) or (x [X])
108+
let canParseType = withLookahead {
109+
$0.currentToken.tokenText.isStartingWithUppercase && $0.canParseType() && $0.at(.comma, .rightParen)
110+
}
111+
112+
if canParseType {
113+
names = ParameterNames(
114+
unexpectedBeforeFirstName: nil,
115+
firstName: nil,
116+
unexpectedBeforeSecondName: nil,
117+
secondName: nil
118+
)
119+
unexpectedBeforeColon = nil
120+
colon = missingToken(.colon)
121+
} else {
122+
names = self.parseParameterNames()
123+
(unexpectedBeforeColon, colon) = self.expect(.colon)
124+
}
125+
104126
if colon.presence == .missing,
105127
let secondName = names.secondName,
106128
secondName.tokenKind == .identifier,

Tests/SwiftParserTest/ExpressionTests.swift

+26
Original file line numberDiff line numberDiff line change
@@ -3403,4 +3403,30 @@ final class StatementExpressionTests: ParserTestCase {
34033403
substructureAfterMarker: "1️⃣"
34043404
)
34053405
}
3406+
3407+
func testFunctionParameterWithMalformedParameters() {
3408+
assertParse(
3409+
"""
3410+
init(1️⃣String.Index, x:(Int) -> Int) rethrows
3411+
""",
3412+
diagnostics: [
3413+
DiagnosticSpec(message: "expected identifier and ':' in parameter", fixIts: ["insert identifier and ':'"])
3414+
],
3415+
fixedSource: """
3416+
init(<#identifier#>: String.Index, x:(Int) -> Int) rethrows
3417+
"""
3418+
)
3419+
3420+
assertParse(
3421+
"""
3422+
init(1️⃣String.Index) rethrows
3423+
""",
3424+
diagnostics: [
3425+
DiagnosticSpec(message: "expected identifier and ':' in parameter", fixIts: ["insert identifier and ':'"])
3426+
],
3427+
fixedSource: """
3428+
init(<#identifier#>: String.Index) rethrows
3429+
"""
3430+
)
3431+
}
34063432
}

0 commit comments

Comments
 (0)