Skip to content

Commit 45ba983

Browse files
authored
Merge pull request #2149 from mininny/limit-parser-func-decl-inference
Limit conditions for inferencing a possible FuncDecl
2 parents b4e72de + 622c997 commit 45ba983

File tree

2 files changed

+69
-18
lines changed

2 files changed

+69
-18
lines changed

Sources/SwiftParser/Declarations.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -281,9 +281,10 @@ extension Parser {
281281
)
282282
}
283283

284-
let isProbablyFuncDecl = self.at(.identifier, .wildcard) || self.at(anyIn: Operator.self) != nil
285-
286-
if isProbablyFuncDecl {
284+
let isPossibleFuncIdentifier = self.at(.identifier, .wildcard)
285+
let isPossibleFuncParen = self.peek(isAt: .leftParen, .binaryOperator)
286+
// Treat operators specially because they're likely to be functions.
287+
if (isPossibleFuncIdentifier && isPossibleFuncParen) || self.at(anyIn: Operator.self) != nil {
287288
return RawDeclSyntax(self.parseFuncDeclaration(attrs, .missing(.keyword(.func))))
288289
}
289290
}

Tests/SwiftParserTest/DeclarationTests.swift

Lines changed: 65 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,61 @@ final class DeclarationTests: ParserTestCase {
9191
type: IdentifierTypeSyntax(name: .identifier("Int"))
9292
)
9393
)
94+
95+
assertParse(
96+
"""
97+
class MyClass {
98+
1️⃣foo()
99+
}
100+
""",
101+
diagnostics: [
102+
DiagnosticSpec(
103+
locationMarker: "1️⃣",
104+
message: "expected 'func' in function",
105+
fixIts: ["insert 'func'"]
106+
)
107+
],
108+
fixedSource: """
109+
class MyClass {
110+
func foo()
111+
}
112+
"""
113+
)
114+
115+
assertParse(
116+
"""
117+
class MyClass {
118+
1️⃣foo<Int>2️⃣
119+
}
120+
""",
121+
diagnostics: [
122+
DiagnosticSpec(
123+
locationMarker: "1️⃣",
124+
message: "expected 'func' in function",
125+
fixIts: ["insert 'func'"]
126+
),
127+
DiagnosticSpec(locationMarker: "2️⃣", message: "expected parameter clause in function signature", fixIts: ["insert parameter clause"]),
128+
],
129+
fixedSource: """
130+
class MyClass {
131+
func foo<Int>()
132+
}
133+
"""
134+
)
135+
136+
assertParse(
137+
"""
138+
class MyClass {
139+
1️⃣foo
140+
}
141+
""",
142+
diagnostics: [
143+
DiagnosticSpec(
144+
locationMarker: "1️⃣",
145+
message: "unexpected code 'foo' in class"
146+
)
147+
]
148+
)
94149
}
95150

96151
func testFuncAfterUnbalancedClosingBrace() {
@@ -1822,19 +1877,17 @@ final class DeclarationTests: ParserTestCase {
18221877
"""
18231878
struct Foo {
18241879
#1️⃣
1825-
2️⃣myMacroName3️⃣
1880+
2️⃣myMacroName
18261881
}
18271882
""",
18281883
diagnostics: [
18291884
DiagnosticSpec(locationMarker: "1️⃣", message: "expected identifier in macro expansion", fixIts: ["insert identifier"]),
1830-
DiagnosticSpec(locationMarker: "2️⃣", message: "expected 'func' in function", fixIts: ["insert 'func'"]),
1831-
DiagnosticSpec(locationMarker: "3️⃣", message: "expected parameter clause in function signature", fixIts: ["insert parameter clause"]),
1885+
DiagnosticSpec(locationMarker: "2️⃣", message: "unexpected code 'myMacroName' in struct"),
18321886
],
18331887
fixedSource: """
18341888
struct Foo {
18351889
#<#identifier#>
1836-
func
1837-
myMacroName()
1890+
myMacroName
18381891
}
18391892
"""
18401893
)
@@ -2360,27 +2413,24 @@ final class DeclarationTests: ParserTestCase {
23602413
class A ℹ️{
23612414
1️⃣^
23622415
}
2363-
unowned 2️⃣B 3️⃣{
2364-
}4️⃣
2416+
unowned 2️⃣B {
2417+
}
23652418
""",
23662419
diagnostics: [
23672420
DiagnosticSpec(locationMarker: "1️⃣", message: "unexpected code before modifier"),
2368-
DiagnosticSpec(locationMarker: "2️⃣", message: "expected 'func' in function", fixIts: ["insert 'func'"]),
2369-
DiagnosticSpec(locationMarker: "3️⃣", message: "expected parameter clause in function signature", fixIts: ["insert parameter clause"]),
23702421
DiagnosticSpec(
2371-
locationMarker: "4️⃣",
2372-
message: "expected '}' to end class",
2373-
notes: [NoteSpec(message: "to match this opening '{'")],
2374-
fixIts: ["insert '}'"]
2422+
locationMarker: "2️⃣",
2423+
message: "expected declaration and '}' after 'unowned' modifier",
2424+
fixIts: ["insert declaration and '}'"]
23752425
),
23762426
],
23772427
fixedSource:
23782428
"""
23792429
class A {
23802430
^
23812431
}
2382-
unowned func B() {
2383-
}
2432+
unowned <#declaration#>
2433+
}B {
23842434
}
23852435
"""
23862436
)

0 commit comments

Comments
 (0)