Skip to content

Commit b2c6854

Browse files
Use continue instead of break after failing to match a closing delimiter in canRecoverTo
1 parent f8b6353 commit b2c6854

File tree

4 files changed

+50
-167
lines changed

4 files changed

+50
-167
lines changed

Sources/SwiftParser/Recovery.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ extension Parser.Lookahead {
127127
if let closingDelimiter = currentTokenPrecedence.closingTokenKind {
128128
let closingDelimiterSpec = TokenSpec(closingDelimiter)
129129
guard self.canRecoverTo(closingDelimiterSpec) != nil else {
130-
break
130+
continue
131131
}
132132
self.eat(closingDelimiterSpec)
133133
}

Tests/SwiftBasicFormatTest/BasicFormatTests.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,15 @@ fileprivate func assertFormattingRoundTrips(
5353
}
5454

5555
final class BasicFormatTest: XCTestCase {
56+
func testClosureParameter() {
57+
let source = """
58+
myFunc({
59+
return true
60+
})
61+
"""
62+
assertFormatted(source: source, expected: source)
63+
}
64+
5665
func testNotIndented() {
5766
assertFormatted(
5867
source: """

Tests/SwiftParserTest/DeclarationTests.swift

Lines changed: 5 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,47 +1301,13 @@ final class DeclarationTests: ParserTestCase {
13011301
func testExpressionMember() {
13021302
assertParse(
13031303
"""
1304-
struct S 1️⃣{2️⃣
1305-
3️⃣/4️⃣ ###line 25 "line-directive.swift"5️⃣
1306-
6️⃣}
1304+
struct S {
1305+
1️⃣/ ###line 25 "line-directive.swift"
1306+
}
13071307
""",
13081308
diagnostics: [
1309-
DiagnosticSpec(
1310-
locationMarker: "2️⃣",
1311-
message: "expected '}' to end struct",
1312-
notes: [NoteSpec(locationMarker: "1️⃣", message: "to match this opening '{'")],
1313-
fixIts: ["insert '}'"]
1314-
),
1315-
DiagnosticSpec(
1316-
locationMarker: "4️⃣",
1317-
message: "bare slash regex literal may not start with space",
1318-
fixIts: [
1319-
"convert to extended regex literal with '#'",
1320-
#"insert '\'"#,
1321-
]
1322-
),
1323-
DiagnosticSpec(
1324-
locationMarker: "5️⃣",
1325-
message: "expected '/' to end regex literal",
1326-
notes: [NoteSpec(locationMarker: "3️⃣", message: "to match this opening '/'")],
1327-
fixIts: ["insert '/'"]
1328-
),
1329-
DiagnosticSpec(
1330-
locationMarker: "6️⃣",
1331-
message: "extraneous brace at top level"
1332-
),
1333-
],
1334-
applyFixIts: [
1335-
"insert '}'",
1336-
#"insert '\'"#,
1337-
"insert '/'",
1338-
],
1339-
fixedSource: #"""
1340-
struct S {
1341-
}
1342-
/\ ###line 25 "line-directive.swift"/
1343-
}
1344-
"""#
1309+
DiagnosticSpec(message: #"unexpected code '/ ###line 25 "line-directive.swift"' in struct"#)
1310+
]
13451311
)
13461312
}
13471313

Tests/SwiftParserTest/translated/RecoveryTests.swift

Lines changed: 35 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -1838,44 +1838,31 @@ final class RecoveryTests: ParserTestCase {
18381838
func testRecovery100() {
18391839
assertParse(
18401840
"""
1841-
struct ErrorInFunctionSignatureResultArrayType1 1️⃣{
1842-
func foo() -> Int2️⃣[ {
1841+
struct ErrorInFunctionSignatureResultArrayType1 {
1842+
func foo() -> Int1️⃣[ {
18431843
return [0]
1844-
}3️⃣
1845-
func bar() -> Int4️⃣] {
1844+
}
1845+
func bar() -> Int2️⃣] {
18461846
return [0]
18471847
}
1848-
5️⃣}
1848+
}
18491849
""",
18501850
diagnostics: [
18511851
DiagnosticSpec(
1852-
locationMarker: "2️⃣",
1853-
message: "expected '}' to end struct",
1854-
notes: [NoteSpec(locationMarker: "1️⃣", message: "to match this opening '{'")],
1855-
fixIts: ["insert '}'"]
1856-
),
1857-
DiagnosticSpec(
1858-
locationMarker: "3️⃣",
1859-
message: "expected ']' to end array",
1860-
notes: [NoteSpec(locationMarker: "2️⃣", message: "to match this opening '['")],
1861-
fixIts: ["insert ']'"]
1852+
locationMarker: "1️⃣",
1853+
message: "unexpected code '[' in function"
18621854
),
18631855
DiagnosticSpec(
1864-
locationMarker: "4️⃣",
1856+
locationMarker: "2️⃣",
18651857
message: "unexpected ']' in type; did you mean to write an array type?",
18661858
fixIts: ["insert '['"]
18671859
),
1868-
DiagnosticSpec(
1869-
locationMarker: "5️⃣",
1870-
message: "extraneous brace at top level"
1871-
),
18721860
],
18731861
fixedSource: """
18741862
struct ErrorInFunctionSignatureResultArrayType1 {
1875-
func foo() -> Int
1876-
}[ {
1863+
func foo() -> Int[ {
18771864
return [0]
1878-
}]
1865+
}
18791866
func bar() -> [Int] {
18801867
return [0]
18811868
}
@@ -1887,45 +1874,15 @@ final class RecoveryTests: ParserTestCase {
18871874
func testRecovery101() {
18881875
assertParse(
18891876
"""
1890-
struct ErrorInFunctionSignatureResultArrayType2 1️⃣{
1891-
func foo() -> Int2️⃣[03️⃣ {
1877+
struct ErrorInFunctionSignatureResultArrayType2 {
1878+
func foo() -> Int1️⃣[0 {
18921879
return [0]
1893-
}4️⃣
1894-
5️⃣}
1880+
}
1881+
}
18951882
""",
18961883
diagnostics: [
1897-
// TODO: Old parser expected error to add `]` on line 2, but we should just recover to
1898-
// `{` with `[0` becoming unexpected.
1899-
DiagnosticSpec(
1900-
locationMarker: "2️⃣",
1901-
message: "expected '}' to end struct",
1902-
notes: [NoteSpec(locationMarker: "1️⃣", message: "to match this opening '{'")],
1903-
fixIts: ["insert '}'"]
1904-
),
1905-
DiagnosticSpec(
1906-
locationMarker: "3️⃣",
1907-
message: "expected ',' in array element",
1908-
fixIts: ["insert ','"]
1909-
),
1910-
DiagnosticSpec(
1911-
locationMarker: "4️⃣",
1912-
message: "expected ']' to end array",
1913-
notes: [NoteSpec(locationMarker: "2️⃣", message: "to match this opening '['")],
1914-
fixIts: ["insert ']'"]
1915-
),
1916-
DiagnosticSpec(
1917-
locationMarker: "5️⃣",
1918-
message: "extraneous brace at top level"
1919-
),
1920-
],
1921-
fixedSource: """
1922-
struct ErrorInFunctionSignatureResultArrayType2 {
1923-
func foo() -> Int
1924-
}[0, {
1925-
return [0]
1926-
}]
1927-
}
1928-
"""
1884+
DiagnosticSpec(message: "unexpected code '[0' in function")
1885+
]
19291886
)
19301887
}
19311888

@@ -1977,37 +1934,21 @@ final class RecoveryTests: ParserTestCase {
19771934
func testRecovery105() {
19781935
assertParse(
19791936
"""
1980-
struct ErrorInFunctionSignatureResultArrayType11 ℹ️{
1981-
func foo() -> Int1️⃣[(a){a++}]2️⃣ {
1937+
struct ErrorInFunctionSignatureResultArrayType11 {
1938+
func foo() -> Int1️⃣[(a){a++}2️⃣] {
19821939
}
1983-
3️⃣}
1940+
}
19841941
""",
19851942
diagnostics: [
1986-
// TODO: We should just recover to `{` with `[(a){a++}]` becoming unexpected.
19871943
DiagnosticSpec(
19881944
locationMarker: "1️⃣",
1989-
message: "expected '}' to end struct",
1990-
notes: [NoteSpec(message: "to match this opening '{'")],
1991-
fixIts: ["insert '}'"]
1945+
message: "unexpected code '[(a)' in function"
19921946
),
19931947
DiagnosticSpec(
19941948
locationMarker: "2️⃣",
1995-
message: "consecutive statements on a line must be separated by newline or ';'",
1996-
fixIts: ["insert newline", "insert ';'"]
1997-
),
1998-
DiagnosticSpec(
1999-
locationMarker: "3️⃣",
2000-
message: "extraneous brace at top level"
2001-
),
2002-
],
2003-
fixedSource: """
2004-
struct ErrorInFunctionSignatureResultArrayType11 {
2005-
func foo() -> Int
2006-
}[(a){a++}]
2007-
{
2008-
}
2009-
}
2010-
"""
1949+
message: "unexpected code in struct"
1950+
)
1951+
]
20111952
)
20121953
}
20131954

@@ -2513,50 +2454,32 @@ final class RecoveryTests: ParserTestCase {
25132454
assertParse(
25142455
"""
25152456
#if true
2516-
struct Foo19605164 1️⃣{
2517-
func a2️⃣(s: S3️⃣[{{g4️⃣) -> Int {}
2518-
}}5️⃣}
2457+
struct Foo19605164 {
2458+
func a1️⃣(s: S2️⃣3️⃣[{{g4️⃣) -> Int {}
2459+
}}}
25192460
#endif
25202461
""",
25212462
diagnostics: [
25222463
DiagnosticSpec(
2523-
locationMarker: "3️⃣",
2464+
locationMarker: "2️⃣",
25242465
message: "expected ')' to end parameter clause",
2525-
notes: [NoteSpec(locationMarker: "2️⃣", message: "to match this opening '('")],
2466+
notes: [NoteSpec(locationMarker: "1️⃣", message: "to match this opening '('")],
25262467
fixIts: ["insert ')'"]
25272468
),
25282469
DiagnosticSpec(
25292470
locationMarker: "3️⃣",
2530-
message: "expected '}' to end struct",
2531-
notes: [NoteSpec(locationMarker: "1️⃣", message: "to match this opening '{'")],
2532-
fixIts: ["insert '}'"]
2471+
message: "unexpected code '[' in function"
25332472
),
25342473
DiagnosticSpec(
25352474
locationMarker: "4️⃣",
25362475
message: "unexpected code ') -> Int {}' in closure"
25372476
),
2538-
DiagnosticSpec(
2539-
locationMarker: "5️⃣",
2540-
message: "expected ',' in array element",
2541-
fixIts: ["insert ','"]
2542-
),
2543-
DiagnosticSpec(
2544-
locationMarker: "5️⃣",
2545-
message: "expected ']' to end array",
2546-
notes: [NoteSpec(locationMarker: "3️⃣", message: "to match this opening '['")],
2547-
fixIts: ["insert ']'"]
2548-
),
2549-
DiagnosticSpec(
2550-
locationMarker: "5️⃣",
2551-
message: "unexpected brace in conditional compilation block"
2552-
),
25532477
],
25542478
fixedSource: """
25552479
#if true
25562480
struct Foo19605164 {
2557-
func a(s: S)
2558-
}[{{g) -> Int {}
2559-
}},]}
2481+
func a(s: S) [{{g) -> Int {}
2482+
}}}
25602483
#endif
25612484
"""
25622485
)
@@ -3211,28 +3134,13 @@ final class RecoveryTests: ParserTestCase {
32113134
func testRecovery179() {
32123135
assertParse(
32133136
"""
3214-
func testSkipUnbalancedParen() ℹ️{1️⃣
3215-
2️⃣?(
3137+
func testSkipUnbalancedParen() {
3138+
1️⃣?(
32163139
}
32173140
""",
32183141
diagnostics: [
3219-
DiagnosticSpec(
3220-
locationMarker: "1️⃣",
3221-
message: "expected '}' to end function",
3222-
notes: [NoteSpec(message: "to match this opening '{'")],
3223-
fixIts: ["insert '}'"]
3224-
),
3225-
DiagnosticSpec(
3226-
locationMarker: "2️⃣",
3227-
message: "extraneous code at top level"
3228-
),
3229-
],
3230-
fixedSource: """
3231-
func testSkipUnbalancedParen() {
3232-
}
3233-
?(
3234-
}
3235-
"""
3142+
DiagnosticSpec(message: "unexpected code '?(' in function")
3143+
]
32363144
)
32373145
}
32383146

0 commit comments

Comments
 (0)