Skip to content

Commit a5831b5

Browse files
committed
Fix parsing invalid function parameters
#2254
1 parent eae92fe commit a5831b5

File tree

2 files changed

+48
-2
lines changed

2 files changed

+48
-2
lines changed

Sources/SwiftParser/Parameters.swift

+22-2
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,31 @@ 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 { $0.canParseType() && $0.at(.comma, .rightParen) }
109+
110+
if canParseType {
111+
names = ParameterNames(
112+
unexpectedBeforeFirstName: nil,
113+
firstName: nil,
114+
unexpectedBeforeSecondName: nil,
115+
secondName: nil
116+
)
117+
unexpectedBeforeColon = nil
118+
colon = missingToken(.colon)
119+
} else {
120+
names = self.parseParameterNames()
121+
(unexpectedBeforeColon, colon) = self.expect(.colon)
122+
}
123+
104124
if colon.presence == .missing,
105125
let secondName = names.secondName,
106126
secondName.tokenKind == .identifier,

Tests/SwiftParserTest/ExpressionTests.swift

+26
Original file line numberDiff line numberDiff line change
@@ -3369,4 +3369,30 @@ final class StatementExpressionTests: ParserTestCase {
33693369
substructureAfterMarker: "1️⃣"
33703370
)
33713371
}
3372+
3373+
func testFunctionParameterWithMalformedParameters() {
3374+
assertParse(
3375+
"""
3376+
init(1️⃣String.Index, x:(Int) -> Int) rethrows
3377+
""",
3378+
diagnostics: [
3379+
DiagnosticSpec(message: "expected identifier and ':' in parameter", fixIts: ["insert identifier and ':'"])
3380+
],
3381+
fixedSource: """
3382+
init(<#identifier#>: String.Index, x:(Int) -> Int) rethrows
3383+
"""
3384+
)
3385+
3386+
assertParse(
3387+
"""
3388+
init(1️⃣String.Index) rethrows
3389+
""",
3390+
diagnostics: [
3391+
DiagnosticSpec(message: "expected identifier and ':' in parameter", fixIts: ["insert identifier and ':'"])
3392+
],
3393+
fixedSource: """
3394+
init(<#identifier#>: String.Index) rethrows
3395+
"""
3396+
)
3397+
}
33723398
}

0 commit comments

Comments
 (0)