Skip to content

Commit 7e3dc35

Browse files
authored
Merge pull request #967 from ahoppen/ahoppen/enumtests
Resolve TODOs in EnumTests
2 parents 1eaa18c + 5ddcaa7 commit 7e3dc35

File tree

4 files changed

+43
-78
lines changed

4 files changed

+43
-78
lines changed

Sources/SwiftParser/Declarations.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -870,7 +870,8 @@ extension Parser {
870870
var keepGoing: RawTokenSyntax? = nil
871871
var loopProgress = LoopProgressCondition()
872872
repeat {
873-
let (unexpectedBeforeName, name) = self.expectIdentifier(keywordRecovery: true)
873+
let unexpectedPeriod = self.consume(ifAny: [.period, .prefixPeriod])
874+
let (unexpectedBeforeName, name) = self.expectIdentifier(allowIdentifierLikeKeywords: false, keywordRecovery: true)
874875

875876
let associatedValue: RawParameterClauseSyntax?
876877
if self.at(.leftParen, where: { !$0.isAtStartOfLine }) {
@@ -895,7 +896,7 @@ extension Parser {
895896
// Continue through the comma-separated list.
896897
keepGoing = self.consume(if: .comma)
897898
elements.append(RawEnumCaseElementSyntax(
898-
unexpectedBeforeName,
899+
RawUnexpectedNodesSyntax([unexpectedPeriod.map(RawSyntax.init)] + (unexpectedBeforeName?.elements ?? []), arena: self.arena),
899900
identifier: name,
900901
associatedValue: associatedValue,
901902
rawValue: rawValue,

Sources/SwiftParser/Parser.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -377,9 +377,15 @@ extension Parser {
377377
/// This should be set if keywords aren't strong recovery marker at this
378378
/// position, e.g. because the parser expects a punctuator next.
379379
@_spi(RawSyntax)
380-
public mutating func expectIdentifier(keywordRecovery: Bool = false) -> (RawUnexpectedNodesSyntax?, Token) {
381-
if let (_, handle) = self.canRecoverTo(anyIn: IdentifierTokens.self) {
382-
return self.eat(handle)
380+
public mutating func expectIdentifier(allowIdentifierLikeKeywords: Bool = true, keywordRecovery: Bool = false) -> (RawUnexpectedNodesSyntax?, Token) {
381+
if allowIdentifierLikeKeywords {
382+
if let (_, handle) = self.canRecoverTo(anyIn: IdentifierTokens.self) {
383+
return self.eat(handle)
384+
}
385+
} else {
386+
if let identifier = self.consume(if: .identifier) {
387+
return (nil, identifier)
388+
}
383389
}
384390
if let unknown = self.consume(if: .unknown) {
385391
return (

Tests/SwiftParserTest/translated/EnumElementPatternSwift4Tests.swift

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,7 @@ final class EnumElementPatternSwift4Tests: XCTestCase {
2929
}
3030
}
3131
}
32-
""",
33-
diagnostics: [
34-
// TODO: Old parser expected error on line 5: cannot specialize a non-generic definition
35-
// TODO: Old parser expected note on line 5: while parsing this '<' as a type parameter bracket
36-
// TODO: Old parser expected error on line 7: cannot specialize a non-generic definition
37-
// TODO: Old parser expected note on line 7: while parsing this '<' as a type parameter bracket
38-
]
32+
"""
3933
)
4034
}
4135

@@ -61,13 +55,7 @@ final class EnumElementPatternSwift4Tests: XCTestCase {
6155
case .D(let payload) = e
6256
else { return }
6357
}
64-
""",
65-
diagnostics: [
66-
// TODO: Old parser expected error on line 3: cannot specialize a non-generic definition
67-
// TODO: Old parser expected note on line 3: while parsing this '<' as a type parameter bracket
68-
// TODO: Old parser expected error on line 5: cannot specialize a non-generic definition
69-
// TODO: Old parser expected note on line 5: while parsing this '<' as a type parameter bracket
70-
]
58+
"""
7159
)
7260
}
7361

Tests/SwiftParserTest/translated/EnumTests.swift

Lines changed: 29 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -292,13 +292,16 @@ final class EnumTests: XCTestCase {
292292
}
293293
""",
294294
diagnostics: [
295-
// TODO: Old parser expected error on line 2: 'case' label can only appear inside a 'switch' statement
296295
DiagnosticSpec(locationMarker: "1️⃣", message: "expected name in enum case"),
297296
DiagnosticSpec(locationMarker: "2️⃣", message: "expected ':' and type in function parameter"),
298297
DiagnosticSpec(locationMarker: "3️⃣", message: "expected type in function parameter"),
299298
DiagnosticSpec(locationMarker: "3️⃣", message: "unexpected code '0' in parameter clause"),
300299
DiagnosticSpec(locationMarker: "4️⃣", message: "unexpected code ':' in enum"),
301-
]
300+
], fixedSource: """
301+
enum SwitchEnvy {
302+
case <#identifier#>(_, var x: <#type#>, <#type#>0):
303+
}
304+
"""
302305
)
303306
}
304307

@@ -330,10 +333,7 @@ final class EnumTests: XCTestCase {
330333
case Mopsy
331334
var ivar : Int
332335
}
333-
""",
334-
diagnostics: [
335-
// TODO: Old parser expected error on line 4: enums must not contain stored properties
336-
]
336+
"""
337337
)
338338
}
339339

@@ -348,7 +348,6 @@ final class EnumTests: XCTestCase {
348348
}
349349
""",
350350
diagnostics: [
351-
// TODO: Old parser expected error on line 3: expected identifier after comma in enum 'case' declaration
352351
DiagnosticSpec(message: "expected name in enum case"),
353352
]
354353
)
@@ -362,8 +361,6 @@ final class EnumTests: XCTestCase {
362361
}
363362
""",
364363
diagnostics: [
365-
// TODO: Old parser expected error on line 2: 'case' label can only appear inside a 'switch' statement
366-
// TODO: Old parser expected error on line 2: expected pattern
367364
DiagnosticSpec(message: "expected name in enum case"),
368365
DiagnosticSpec(message: "unexpected code ':' in enum"),
369366
]
@@ -378,7 +375,6 @@ final class EnumTests: XCTestCase {
378375
}
379376
""",
380377
diagnostics: [
381-
// TODO: Old parser expected error on line 2: 'case' label can only appear inside a 'switch' statement
382378
DiagnosticSpec(message: "unexpected code ':' in enum"),
383379
]
384380
)
@@ -392,7 +388,6 @@ final class EnumTests: XCTestCase {
392388
}
393389
""",
394390
diagnostics: [
395-
// TODO: Old parser expected error on line 2: 'case' label can only appear inside a 'switch' statement
396391
DiagnosticSpec(message: "unexpected code ':' in enum"),
397392
]
398393
)
@@ -402,16 +397,12 @@ final class EnumTests: XCTestCase {
402397
AssertParse(
403398
"""
404399
enum Recovery4 {
405-
case Self 1️⃣Self
400+
case 1️⃣Self 2️⃣Self
406401
}
407402
""",
408403
diagnostics: [
409-
// TODO: Old parser expected note on line 1: in declaration of 'Recovery4'
410-
// TODO: Old parser expected error on line 2: keyword 'Self' cannot be used as an identifier here
411-
// TODO: Old parser expected note on line 2: if this name is unavoidable, use backticks to escape it, Fix-It replacements: 8 - 12 = '`Self`'
412-
// TODO: Old parser expected error on line 2: consecutive declarations on a line must be separated by ';', Fix-It replacements: 12 - 12 = ';'
413-
// TODO: Old parser expected error on line 2: expected declaration
414-
DiagnosticSpec(message: "unexpected code 'Self' in enum"),
404+
DiagnosticSpec(locationMarker: "1️⃣", message: "keyword 'Self' cannot be used as an identifier here"),
405+
DiagnosticSpec(locationMarker: "2️⃣", message: "unexpected code 'Self' in enum"),
415406
]
416407
)
417408
}
@@ -421,17 +412,13 @@ final class EnumTests: XCTestCase {
421412
"""
422413
enum Recovery5 {
423414
case 1️⃣.UE3
424-
case 2️⃣.UE4, .UE5
415+
case 2️⃣.UE4, 3️⃣.UE5
425416
}
426417
""",
427418
diagnostics: [
428-
// TODO: Old parser expected error on line 2: extraneous code '.' in enum 'case' declaration, Fix-It replacements: 8 - 9 = ''
429-
DiagnosticSpec(locationMarker: "1️⃣", message: "expected name in enum case"),
430-
DiagnosticSpec(locationMarker: "1️⃣", message: "unexpected code '.UE3' before enum case"),
431-
// TODO: Old parser expected error on line 3: extraneous code '.' in enum 'case' declaration, Fix-It replacements: 8 - 9 = ''
432-
// TODO: Old parser expected error on line 3: extraneous code '.' in enum 'case' declaration, Fix-It replacements: 14 - 15 = ''
433-
DiagnosticSpec(locationMarker: "2️⃣", message: "expected name in enum case"),
434-
DiagnosticSpec(locationMarker: "2️⃣", message: "unexpected code '.UE4, .UE5' in enum"),
419+
DiagnosticSpec(locationMarker: "1️⃣", message: "unexpected code '.' in enum case"),
420+
DiagnosticSpec(locationMarker: "2️⃣", message: "unexpected code '.' in enum case"),
421+
DiagnosticSpec(locationMarker: "3️⃣", message: "unexpected code '.' in enum case"),
435422
]
436423
)
437424
}
@@ -448,7 +435,6 @@ final class EnumTests: XCTestCase {
448435
diagnostics: [
449436
DiagnosticSpec(locationMarker: "1️⃣", message: "'_' cannot be used as an identifier here"),
450437
DiagnosticSpec(locationMarker: "2️⃣", message: "'_' cannot be used as an identifier here"),
451-
// TODO: Old parser expected error on line 20: expected identifier after comma in enum 'case' declaration
452438
DiagnosticSpec(locationMarker: "3️⃣", message: "expected name in enum case"),
453439
]
454440
)
@@ -478,10 +464,7 @@ final class EnumTests: XCTestCase {
478464
enum MultiRawType : Int64, Int32 {
479465
case Couch, Davis
480466
}
481-
""",
482-
diagnostics: [
483-
// TODO: Old parser expected error on line 1: multiple enum raw types 'Int64' and 'Int32'
484-
]
467+
"""
485468
)
486469
}
487470

@@ -834,10 +817,7 @@ final class EnumTests: XCTestCase {
834817
enum NonliteralRawValue : Int {
835818
case Yeon = 100 + 20 + 3
836819
}
837-
""",
838-
diagnostics: [
839-
// TODO: Old parser expected error on line 2: raw value for enum case must be a literal
840-
]
820+
"""
841821
)
842822
}
843823

@@ -914,10 +894,7 @@ final class EnumTests: XCTestCase {
914894
case Foo = 1
915895
case Foo = 1 + 1
916896
}
917-
""",
918-
diagnostics: [
919-
// TODO: Old parser expected error on line 3: raw value for enum case must be a literal
920-
]
897+
"""
921898
)
922899
}
923900

@@ -1194,10 +1171,7 @@ final class EnumTests: XCTestCase {
11941171
self = SE0036.B(SE0036_Auxiliary())
11951172
}
11961173
}
1197-
""",
1198-
diagnostics: [
1199-
// TODO: Old parser expected error on line 25: '_' can only appear in a pattern or on the left side of an assignment
1200-
]
1174+
"""
12011175
)
12021176
}
12031177

@@ -1218,10 +1192,17 @@ final class EnumTests: XCTestCase {
12181192
}
12191193
}
12201194
}
1221-
""",
1222-
diagnostics: [
1223-
// TODO: Old parser expected error on line 5: '_' can only appear in a pattern or on the left side of an assignment
1224-
]
1195+
"""
1196+
)
1197+
}
1198+
1199+
func testEnum81b() {
1200+
AssertParse(
1201+
"""
1202+
switch self {
1203+
case A(_): break
1204+
}
1205+
"""
12251206
)
12261207
}
12271208

@@ -1242,12 +1223,7 @@ final class EnumTests: XCTestCase {
12421223
enum SE0155 {
12431224
case emptyArgs()
12441225
}
1245-
""",
1246-
diagnostics: [
1247-
// TODO: Old parser expected warning on line 2: enum element with associated values must have at least one associated value
1248-
// TODO: Old parser expected note on line 2: did you mean to remove the empty associated value list?, Fix-It replacements: 17 - 19 = ''
1249-
// TODO: Old parser expected note on line 2: did you mean to explicitly add a 'Void' associated value?, Fix-It replacements: 18 - 18 = 'Void'
1250-
]
1226+
"""
12511227
)
12521228
}
12531229

@@ -1312,8 +1288,6 @@ final class EnumTests: XCTestCase {
13121288
}
13131289
""",
13141290
diagnostics: [
1315-
// TODO: Old parser expected error on line 2: keyword 'func' cannot be used as an identifier here
1316-
// TODO: Old parser expected note on line 2: if this name is unavoidable, use backticks to escape it, Fix-It replacements: 17 - 21 = '`func`'
13171291
DiagnosticSpec(message: "keyword 'func' cannot be used as an identifier here"),
13181292
]
13191293
)
@@ -1331,8 +1305,6 @@ final class EnumTests: XCTestCase {
13311305
""",
13321306
diagnostics: [
13331307
DiagnosticSpec(message: "expected name in enum case"),
1334-
// TODO: Old parser expected error on line 5: keyword 'case' cannot be used as an identifier here
1335-
// TODO: Old parser expected note on line 5: if this name is unavoidable, use backticks to escape it, Fix-It replacements: 3 - 7 = '`case`'
13361308
]
13371309
)
13381310
}
@@ -1374,9 +1346,7 @@ final class EnumTests: XCTestCase {
13741346
}
13751347
"""#,
13761348
diagnostics: [
1377-
// TODO: Old parser expected error on line 2: expected identifier after comma in enum 'case' declaration
13781349
DiagnosticSpec(locationMarker: "1️⃣", message: "expected name in enum case"),
1379-
// TODO: Old parser expected error on line 3: expected identifier after comma in enum 'case' declaration
13801350
DiagnosticSpec(locationMarker: "2️⃣", message: "expected name in enum case"),
13811351
]
13821352
)

0 commit comments

Comments
 (0)