Skip to content

Commit ea09dab

Browse files
authored
Merge pull request #1381 from StevenWong12/diagnostics-for-bogus-specifier-before-arrow-and-leftbrace
2 parents 902ef0b + 396ca71 commit ea09dab

File tree

7 files changed

+34
-12
lines changed

7 files changed

+34
-12
lines changed

Sources/SwiftParser/Declarations.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1375,7 +1375,8 @@ extension Parser {
13751375
var effectSpecifiers = self.parseDeclEffectSpecifiers()
13761376

13771377
let output: RawReturnClauseSyntax?
1378-
if self.at(.arrow) {
1378+
1379+
if self.at(.arrow) || self.canRecoverTo(TokenSpec(.arrow, allowAtStartOfLine: false)) != nil {
13791380
output = self.parseFunctionReturnClause(effectSpecifiers: &effectSpecifiers, allowNamedOpaqueResultType: true)
13801381
} else {
13811382
output = nil

Sources/SwiftParser/Recovery.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,10 @@ extension Parser.Lookahead {
7070
let initialTokensConsumed = self.tokensConsumed
7171

7272
let recoveryPrecedence = min(spec1.recoveryPrecedence, spec2.recoveryPrecedence, spec3.recoveryPrecedence)
73+
let shouldSkipOverNewlines = recoveryPrecedence.shouldSkipOverNewlines && spec1.allowAtStartOfLine && spec2.allowAtStartOfLine && spec3.allowAtStartOfLine
7374

7475
while !self.at(.eof) {
75-
if !recoveryPrecedence.shouldSkipOverNewlines, self.currentToken.isAtStartOfLine {
76+
if !shouldSkipOverNewlines, self.currentToken.isAtStartOfLine {
7677
break
7778
}
7879
let matchedSpec: TokenSpec?

Sources/SwiftParser/TopLevel.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ extension Parser {
9898
/// This function is used when parsing places where function bodies are
9999
/// optional - like the function requirements in protocol declarations.
100100
mutating func parseOptionalCodeBlock(allowInitDecl: Bool = true) -> RawCodeBlockSyntax? {
101-
guard self.at(.leftBrace) else {
101+
guard self.at(.leftBrace) || self.canRecoverTo(TokenSpec(.leftBrace, allowAtStartOfLine: false)) != nil else {
102102
return nil
103103
}
104104
return self.parseCodeBlock(allowInitDecl: allowInitDecl)

Sources/SwiftSyntax/generated/Keyword.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,7 @@ public enum Keyword: UInt8, Hashable {
735735
}
736736
}
737737

738-
/// Whether the token kind is switched from being an identifier to being an identifier to a keyword in the lexer.
738+
/// Whether the token kind is switched from being an identifier to a keyword in the lexer.
739739
/// This is true for keywords that used to be considered non-contextual.
740740
public var isLexerClassified: Bool {
741741
switch self {

Tests/SwiftParserTest/translated/EffectfulPropertiesTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ final class EffectfulPropertiesTests: XCTestCase {
231231
}
232232
""",
233233
diagnostics: [
234-
DiagnosticSpec(message: "unexpected code 'bogus {}' in variable")
234+
DiagnosticSpec(message: "unexpected code 'bogus' in accessor")
235235
]
236236
)
237237
}
@@ -257,7 +257,7 @@ final class EffectfulPropertiesTests: XCTestCase {
257257
}
258258
""",
259259
diagnostics: [
260-
DiagnosticSpec(message: "unexpected code '-> Int { 0 }' in variable")
260+
DiagnosticSpec(message: "unexpected code '-> Int' in accessor")
261261
]
262262
)
263263
}

Tests/SwiftParserTest/translated/InvalidTests.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,8 @@ final class InvalidTests: XCTestCase {
205205
DiagnosticSpec(locationMarker: "2️⃣", message: "expected ')' in function type"),
206206
DiagnosticSpec(locationMarker: "3️⃣", message: "expected return type in function type"),
207207
DiagnosticSpec(locationMarker: "3️⃣", message: "expected ')' to end parameter clause"),
208-
DiagnosticSpec(locationMarker: "4️⃣", message: "extraneous code ') {}' at top level"),
208+
DiagnosticSpec(locationMarker: "3️⃣", message: "unexpected code '<T>()' in function signature"),
209+
DiagnosticSpec(locationMarker: "4️⃣", message: "unexpected code ')' in function"),
209210
]
210211
)
211212
}
@@ -484,6 +485,7 @@ final class InvalidTests: XCTestCase {
484485
diagnostics: [
485486
DiagnosticSpec(locationMarker: "1️⃣", message: "expected '(' to start parameter clause"),
486487
DiagnosticSpec(locationMarker: "2️⃣", message: "expected ')' to end parameter clause"),
488+
DiagnosticSpec(locationMarker: "2️⃣", message: "unexpected code '()' in function"),
487489
]
488490
)
489491
}
@@ -497,6 +499,7 @@ final class InvalidTests: XCTestCase {
497499
diagnostics: [
498500
DiagnosticSpec(locationMarker: "1️⃣", message: "expected '(' to start parameter clause"),
499501
DiagnosticSpec(locationMarker: "2️⃣", message: "expected ')' to end parameter clause"),
502+
DiagnosticSpec(locationMarker: "2️⃣", message: "unexpected code '(x: T)' in function"),
500503
]
501504
)
502505
}

Tests/SwiftParserTest/translated/RecoveryTests.swift

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,13 +1206,14 @@ final class RecoveryTests: XCTestCase {
12061206
func bar() -> Int3️⃣] {
12071207
return [0]
12081208
}
1209-
}
1209+
4️⃣}
12101210
""",
12111211
diagnostics: [
12121212
DiagnosticSpec(locationMarker: "1️⃣", message: "expected '}' to end struct"),
12131213
DiagnosticSpec(locationMarker: "2️⃣", message: "expected ']' to end array"),
12141214
// TODO: Old parser expected error on line 5: unexpected ']' in type; did you mean to write an array type?, Fix-It replacements: 17 - 17 = '['
1215-
DiagnosticSpec(locationMarker: "3️⃣", message: "extraneous code at top level"),
1215+
DiagnosticSpec(locationMarker: "3️⃣", message: "unexpected code ']' in function"),
1216+
DiagnosticSpec(locationMarker: "4️⃣", message: "extraneous brace at top level"),
12161217
]
12171218
)
12181219
}
@@ -1247,7 +1248,7 @@ final class RecoveryTests: XCTestCase {
12471248
""",
12481249
diagnostics: [
12491250
// TODO: Old parser expected error on line 2: array types are now written with the brackets around the element type, Fix-It replacements: 17 - 17 = '[', 20 - 21 = ''
1250-
DiagnosticSpec(message: "unexpected code in struct")
1251+
DiagnosticSpec(message: "unexpected code '[0]' in function")
12511252
]
12521253
)
12531254
}
@@ -1263,7 +1264,7 @@ final class RecoveryTests: XCTestCase {
12631264
""",
12641265
diagnostics: [
12651266
// TODO: Old parser expected error on line 2: array types are now written with the brackets around the element type, Fix-It replacements: 17 - 17 = '[', 20 - 21 = ''
1266-
DiagnosticSpec(message: "unexpected code in struct")
1267+
DiagnosticSpec(message: "unexpected code '[0_1]' in function")
12671268
]
12681269
)
12691270
}
@@ -1279,7 +1280,7 @@ final class RecoveryTests: XCTestCase {
12791280
""",
12801281
diagnostics: [
12811282
// TODO: Old parser expected error on line 2: array types are now written with the brackets around the element type, Fix-It replacements: 17 - 17 = '[', 20 - 21 = ''
1282-
DiagnosticSpec(message: "unexpected code in struct")
1283+
DiagnosticSpec(message: "unexpected code '[0b1]' in function")
12831284
]
12841285
)
12851286
}
@@ -2205,4 +2206,20 @@ final class RecoveryTests: XCTestCase {
22052206
)
22062207
}
22072208

2209+
func testRecovery182() {
2210+
AssertParse(
2211+
"func foo() 1️⃣bogus {}",
2212+
diagnostics: [
2213+
DiagnosticSpec(message: "unexpected code 'bogus' in function")
2214+
]
2215+
)
2216+
2217+
AssertParse(
2218+
"func foo() 1️⃣bogus -> Int {}",
2219+
diagnostics: [
2220+
DiagnosticSpec(message: "unexpected code 'bogus' in function signature")
2221+
]
2222+
)
2223+
}
2224+
22082225
}

0 commit comments

Comments
 (0)