Skip to content

Commit 2ea034d

Browse files
committed
Improve recovery if variable or subscript is missing brace wrapping getter and setter
1 parent 8198297 commit 2ea034d

File tree

3 files changed

+52
-11
lines changed

3 files changed

+52
-11
lines changed

Sources/SwiftParser/Declarations.swift

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1690,7 +1690,7 @@ extension Parser {
16901690

16911691
// Parse getter and setter.
16921692
let accessor: RawSyntax?
1693-
if self.at(.leftBrace) {
1693+
if self.at(any: [.leftBrace], contextualKeywords: ["get", "set"]) {
16941694
accessor = self.parseGetSet()
16951695
} else {
16961696
accessor = nil
@@ -1786,7 +1786,7 @@ extension Parser {
17861786
}
17871787

17881788
let accessor: RawSyntax?
1789-
if self.at(.leftBrace) {
1789+
if self.at(any: [.leftBrace], contextualKeywords: ["get", "set"]) {
17901790
accessor = self.parseGetSet()
17911791
} else {
17921792
accessor = nil
@@ -1921,7 +1921,14 @@ extension Parser {
19211921
@_spi(RawSyntax)
19221922
public mutating func parseGetSet() -> RawSyntax {
19231923
// Parse getter and setter.
1924-
let (unexpectedBeforeLBrace, lbrace) = self.expect(.leftBrace)
1924+
let unexpectedBeforeLBrace: RawUnexpectedNodesSyntax?
1925+
let lbrace: RawTokenSyntax
1926+
if self.at(any: [], contextualKeywords: ["get", "set"]) {
1927+
unexpectedBeforeLBrace = nil
1928+
lbrace = missingToken(.leftBrace, text: nil)
1929+
} else {
1930+
(unexpectedBeforeLBrace, lbrace) = self.expect(.leftBrace)
1931+
}
19251932
// Collect all explicit accessors to a list.
19261933
var elements = [RawAccessorDeclSyntax]()
19271934
do {

Tests/SwiftParserTest/Declarations.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,6 +1141,42 @@ final class DeclarationTests: XCTestCase {
11411141
"""
11421142
)
11431143
}
1144+
1145+
func testVariableDeclWithGetSetButNoBrace() {
1146+
AssertParse(
1147+
"""
1148+
var x: Int 1️⃣
1149+
get {
1150+
4
1151+
}
1152+
set {
1153+
x = newValue
1154+
}
1155+
}
1156+
""",
1157+
diagnostics: [
1158+
DiagnosticSpec(message: "expected '{' in variable")
1159+
]
1160+
)
1161+
}
1162+
1163+
func testVariableDeclWithSetGetButNoBrace() {
1164+
AssertParse(
1165+
"""
1166+
var x: Int 1️⃣
1167+
set {
1168+
x = newValue
1169+
}
1170+
get {
1171+
4
1172+
}
1173+
}
1174+
""",
1175+
diagnostics: [
1176+
DiagnosticSpec(message: "expected '{' in variable")
1177+
]
1178+
)
1179+
}
11441180
}
11451181

11461182
extension Parser.DeclAttributes {

Tests/SwiftParserTest/translated/SubscriptingTests.swift

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -362,20 +362,18 @@ final class SubscriptingTests: XCTestCase {
362362
AssertParse(
363363
"""
364364
struct A8 {
365-
subscript(i : Int) -> Int
366-
1️⃣get 2️⃣{
365+
subscript(i : Int) -> Int1️⃣
366+
get {
367367
return stored
368368
}
369-
3️⃣set 4️⃣{
369+
set {
370370
stored = value
371371
}
372-
}
372+
}2️⃣
373373
""",
374374
diagnostics: [
375-
DiagnosticSpec(locationMarker: "1️⃣", message: "expected 'func' in function"),
376-
DiagnosticSpec(locationMarker: "2️⃣", message: "expected parameter clause in function signature"),
377-
DiagnosticSpec(locationMarker: "3️⃣", message: "expected 'func' in function"),
378-
DiagnosticSpec(locationMarker: "4️⃣", message: "expected parameter clause in function signature"),
375+
DiagnosticSpec(locationMarker: "1️⃣", message: "expected '{' in subscript"),
376+
DiagnosticSpec(locationMarker: "2️⃣", message: "expected '}' to end struct"),
379377
]
380378
)
381379
}

0 commit comments

Comments
 (0)