Skip to content

Commit ada5bb3

Browse files
authored
Merge pull request #750 from ahoppen/ahoppen/80-invalid-identifier-diags
Improve diagnostics for invalid identifiers
2 parents 8d5b3b6 + 9a692b4 commit ada5bb3

15 files changed

+208
-118
lines changed

Sources/SwiftParser/Attributes.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ extension Parser {
183183

184184

185185
let (unexpectedBeforeAtSign, atSign) = self.expect(.atSign)
186-
let ident = self.expectIdentifierOrRethrowsWithoutRecovery()
186+
let (unexpectedBeforeIdent, ident) = self.expectIdentifierOrRethrows()
187187
let leftParen = self.consume(if: .leftParen)
188188
let arg: RawSyntax?
189189
let unexpectedBeforeRightParen: RawUnexpectedNodesSyntax?
@@ -204,6 +204,7 @@ extension Parser {
204204
return RawSyntax(RawAttributeSyntax(
205205
unexpectedBeforeAtSign,
206206
atSignToken: atSign,
207+
unexpectedBeforeIdent,
207208
attributeName: ident,
208209
leftParen: leftParen,
209210
argument: arg,
@@ -339,14 +340,15 @@ extension Parser {
339340
}
340341

341342
mutating func parseDifferentiabilityParameters() -> RawDifferentiabilityParamsClauseSyntax {
342-
let wrt = self.expectIdentifierWithoutRecovery()
343+
let (unexpectedBeforeWrt, wrt) = self.expectIdentifier()
343344
let (unexpectedBeforeColon, colon) = self.expect(.colon)
344345

345346
guard let leftParen = self.consume(if: .leftParen) else {
346347
// If no opening '(' for parameter list, parse a single parameter.
347348
let param = self.parseDifferentiabilityParameter().map(RawSyntax.init(_:))
348349
?? RawSyntax(RawMissingSyntax(arena: self.arena))
349350
return RawDifferentiabilityParamsClauseSyntax(
351+
unexpectedBeforeWrt,
350352
wrtLabel: wrt,
351353
unexpectedBeforeColon,
352354
colon: colon,
@@ -692,7 +694,7 @@ extension Parser {
692694
let (unexpectedBeforeAtSign, atSign) = self.expect(.atSign)
693695
let (unexpectedBeforePrivateToken, privateToken) = self.expectContextualKeyword("_private")
694696
let (unexpectedBeforeLeftParen, leftParen) = self.expect(.leftParen)
695-
let label = self.expectIdentifierWithoutRecovery()
697+
let (unexpectedBeforeLabel, label) = self.expectIdentifier()
696698
let (unexpectedBeforeColon, colon) = self.expect(.colon)
697699
let filename = self.consumeAnyToken()
698700
let (unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen)
@@ -704,6 +706,7 @@ extension Parser {
704706
unexpectedBeforeLeftParen,
705707
leftParen: leftParen,
706708
argument: RawSyntax(RawNamedAttributeStringArgumentSyntax(
709+
unexpectedBeforeLabel,
707710
nameTok: label,
708711
unexpectedBeforeColon,
709712
colon: colon,

Sources/SwiftParser/Declarations.swift

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,8 @@ extension Parser {
266266
repeat {
267267
let attributes = self.parseAttributeList()
268268

269-
let name = self.expectIdentifierWithoutRecovery()
270-
if name.isMissing && elements.isEmpty {
269+
let (unexpectedBeforeName, name) = self.expectIdentifier()
270+
if unexpectedBeforeName == nil && name.isMissing && elements.isEmpty {
271271
break
272272
}
273273

@@ -530,13 +530,14 @@ extension Parser {
530530
@_spi(RawSyntax)
531531
public mutating func parseClassDeclaration(_ attrs: DeclAttributes) -> RawClassDeclSyntax {
532532
let (unexpectedBeforeClassKeyword, classKeyword) = self.expect(.classKeyword)
533-
let name = self.expectIdentifierWithoutRecovery()
534-
if name.isMissing {
533+
let (unexpectedBeforeName, name) = self.expectIdentifier()
534+
if unexpectedBeforeName == nil && name.isMissing {
535535
return RawClassDeclSyntax(
536536
attributes: attrs.attributes,
537537
modifiers: attrs.modifiers,
538538
unexpectedBeforeClassKeyword,
539539
classKeyword: classKeyword,
540+
unexpectedBeforeName,
540541
identifier: name,
541542
genericParameterClause: nil,
542543
inheritanceClause: nil,
@@ -577,6 +578,7 @@ extension Parser {
577578
attributes: attrs.attributes,
578579
modifiers: attrs.modifiers,
579580
classKeyword: classKeyword,
581+
unexpectedBeforeName,
580582
identifier: name,
581583
genericParameterClause: generics,
582584
inheritanceClause: inheritance,
@@ -646,13 +648,14 @@ extension Parser {
646648
@_spi(RawSyntax)
647649
public mutating func parseEnumDeclaration(_ attrs: DeclAttributes) -> RawEnumDeclSyntax {
648650
let (unexpectedBeforeEnumKeyword, enumKeyword) = self.expect(.enumKeyword)
649-
let name = self.expectIdentifierWithoutRecovery()
650-
if name.isMissing {
651+
let (unexpectedBeforeName, name) = self.expectIdentifier()
652+
if unexpectedBeforeName == nil, name.isMissing {
651653
return RawEnumDeclSyntax(
652654
attributes: attrs.attributes,
653655
modifiers: attrs.modifiers,
654656
unexpectedBeforeEnumKeyword,
655657
enumKeyword: enumKeyword,
658+
unexpectedBeforeName,
656659
identifier: name,
657660
genericParameters: nil,
658661
inheritanceClause: nil,
@@ -692,6 +695,7 @@ extension Parser {
692695
return RawEnumDeclSyntax(
693696
attributes: attrs.attributes, modifiers: attrs.modifiers,
694697
enumKeyword: enumKeyword,
698+
unexpectedBeforeName,
695699
identifier: name,
696700
genericParameters: generics,
697701
inheritanceClause: inheritance,
@@ -722,7 +726,7 @@ extension Parser {
722726
var keepGoing: RawTokenSyntax? = nil
723727
var loopProgress = LoopProgressCondition()
724728
repeat {
725-
let name = self.expectIdentifierWithoutRecovery()
729+
let (unexpectedBeforeName, name) = self.expectIdentifier()
726730

727731
let associatedValue: RawParameterClauseSyntax?
728732
if self.at(.leftParen, where: { !$0.isAtStartOfLine }) {
@@ -747,6 +751,7 @@ extension Parser {
747751
// Continue through the comma-separated list.
748752
keepGoing = self.consume(if: .comma)
749753
elements.append(RawEnumCaseElementSyntax(
754+
unexpectedBeforeName,
750755
identifier: name,
751756
associatedValue: associatedValue,
752757
rawValue: rawValue,
@@ -781,8 +786,8 @@ extension Parser {
781786
@_spi(RawSyntax)
782787
public mutating func parseStructDeclaration(_ attrs: DeclAttributes) -> RawStructDeclSyntax {
783788
let (unexpectedBeforeStructKeyword, structKeyword) = self.expect(.structKeyword)
784-
let name = self.expectIdentifierWithoutRecovery()
785-
if name.isMissing {
789+
let (unexpectedBeforeName, name) = self.expectIdentifier()
790+
if unexpectedBeforeName == nil && name.isMissing {
786791
return RawStructDeclSyntax(
787792
attributes: attrs.attributes,
788793
modifiers: attrs.modifiers,
@@ -846,9 +851,10 @@ extension Parser {
846851
var loopProgress = LoopProgressCondition()
847852
repeat {
848853
// Parse the name of the parameter.
849-
let name = self.expectIdentifierWithoutRecovery()
854+
let (unexpectedBeforeName, name) = self.expectIdentifier()
850855
keepGoing = self.consume(if: .comma)
851856
associatedTypes.append(RawPrimaryAssociatedTypeSyntax(
857+
unexpectedBeforeName,
852858
name: name,
853859
trailingComma: keepGoing,
854860
arena: self.arena))
@@ -884,8 +890,8 @@ extension Parser {
884890
@_spi(RawSyntax)
885891
public mutating func parseProtocolDeclaration(_ attrs: DeclAttributes) -> RawProtocolDeclSyntax {
886892
let (unexpectedBeforeProtocolKeyword, protocolKeyword) = self.expect(.protocolKeyword)
887-
let name = self.expectIdentifierWithoutRecovery()
888-
if name.isMissing {
893+
let (unexpectedBeforeName, name) = self.expectIdentifier()
894+
if unexpectedBeforeName == nil && name.isMissing {
889895
return RawProtocolDeclSyntax(
890896
attributes: attrs.attributes,
891897
modifiers: attrs.modifiers,
@@ -952,8 +958,8 @@ extension Parser {
952958
@_spi(RawSyntax)
953959
public mutating func parseAssociatedTypeDeclaration(_ attrs: DeclAttributes) -> RawAssociatedtypeDeclSyntax {
954960
let (unexpectedBeforeAssocKeyword, assocKeyword) = self.expect(.associatedtypeKeyword)
955-
let name = self.expectIdentifierWithoutRecovery()
956-
if name.isMissing {
961+
let (unexpecedBeforeName, name) = self.expectIdentifier()
962+
if unexpecedBeforeName == nil && name.isMissing {
957963
return RawAssociatedtypeDeclSyntax(
958964
attributes: attrs.attributes,
959965
modifiers: attrs.modifiers,
@@ -1020,7 +1026,7 @@ extension Parser {
10201026
@_spi(RawSyntax)
10211027
public mutating func parseActorDeclaration(_ attrs: DeclAttributes) -> RawActorDeclSyntax {
10221028
let (unexpectedBeforeActorKeyword, actorKeyword) = self.expectContextualKeyword("actor", precedence: .declKeyword)
1023-
let name = self.expectIdentifierWithoutRecovery()
1029+
let (unexpectedBeforeName, name) = self.expectIdentifier()
10241030

10251031
let generics: RawGenericParameterClauseSyntax?
10261032
if self.currentToken.starts(with: "<") {
@@ -1051,6 +1057,7 @@ extension Parser {
10511057
modifiers: attrs.modifiers,
10521058
unexpectedBeforeActorKeyword,
10531059
actorKeyword: actorKeyword,
1060+
unexpectedBeforeName,
10541061
identifier: name,
10551062
genericParameterClause: generics,
10561063
inheritanceClause: inheritance,
@@ -1271,15 +1278,17 @@ extension Parser {
12711278
@_spi(RawSyntax)
12721279
public mutating func parseFuncDeclaration(_ attrs: DeclAttributes) -> RawFunctionDeclSyntax {
12731280
let (unexpectedBeforeFuncKeyword, funcKeyword) = self.expect(.funcKeyword)
1281+
let unexpectedBeforeIdentifier: RawUnexpectedNodesSyntax?
12741282
let identifier: RawTokenSyntax
12751283
if self.at(anyIn: Operator.self) != nil || self.at(any: [.exclamationMark, .prefixAmpersand]) {
12761284
var name = self.currentToken.tokenText
12771285
if name.count > 1 && name.hasSuffix("<") && self.peek().tokenKind == .identifier {
12781286
name = SyntaxText(rebasing: name.dropLast())
12791287
}
1288+
unexpectedBeforeIdentifier = nil
12801289
identifier = self.consumePrefix(name, as: .spacedBinaryOperator)
12811290
} else {
1282-
identifier = self.expectIdentifierWithoutRecovery()
1291+
(unexpectedBeforeIdentifier, identifier) = self.expectIdentifier()
12831292
}
12841293

12851294
let genericParams: RawGenericParameterClauseSyntax?
@@ -1304,6 +1313,7 @@ extension Parser {
13041313
modifiers: attrs.modifiers,
13051314
unexpectedBeforeFuncKeyword,
13061315
funcKeyword: funcKeyword,
1316+
unexpectedBeforeIdentifier,
13071317
identifier: identifier,
13081318
genericParameterClause: genericParams,
13091319
signature: signature,
@@ -1615,10 +1625,11 @@ extension Parser {
16151625
// set-name ::= '(' identifier ')'
16161626
let parameter: RawAccessorParameterSyntax?
16171627
if [ AccessorKind.set, .willSet, .didSet ].contains(kind), let lparen = self.consume(if: .leftParen) {
1618-
let name = self.expectIdentifierWithoutRecovery()
1628+
let (unexpectedBeforeName, name) = self.expectIdentifier()
16191629
let (unexpectedBeforeRParen, rparen) = self.expect(.rightParen)
16201630
parameter = RawAccessorParameterSyntax(
16211631
leftParen: lparen,
1632+
unexpectedBeforeName,
16221633
name: name,
16231634
unexpectedBeforeRParen,
16241635
rightParen: rparen,
@@ -1677,7 +1688,7 @@ extension Parser {
16771688
@_spi(RawSyntax)
16781689
public mutating func parseTypealiasDeclaration(_ attrs: DeclAttributes) -> RawTypealiasDeclSyntax {
16791690
let (unexpectedBeforeTypealiasKeyword, typealiasKeyword) = self.expect(.typealiasKeyword)
1680-
let name = self.expectIdentifierWithoutRecovery()
1691+
let (unexpectedBeforeName, name) = self.expectIdentifier()
16811692

16821693
// Parse a generic parameter list if it is present.
16831694
let generics: RawGenericParameterClauseSyntax?
@@ -1710,6 +1721,7 @@ extension Parser {
17101721
modifiers: attrs.modifiers,
17111722
unexpectedBeforeTypealiasKeyword,
17121723
typealiasKeyword: typealiasKeyword,
1724+
unexpectedBeforeName,
17131725
identifier: name,
17141726
genericParameterClause: generics,
17151727
initializer: initializer,
@@ -1785,7 +1797,7 @@ extension Parser {
17851797
@_spi(RawSyntax)
17861798
public mutating func parsePrecedenceGroupDeclaration(_ attrs: DeclAttributes) -> RawPrecedenceGroupDeclSyntax {
17871799
let (unexpectedBeforeGroup, group) = self.expect(.precedencegroupKeyword)
1788-
let identifier = self.expectIdentifierWithoutRecovery()
1800+
let (unexpectedBeforeIdentifier, identifier) = self.expectIdentifier()
17891801
let (unexpectedBeforeLBrace, lbrace) = self.expect(.leftBrace)
17901802
var elements = [RawSyntax]()
17911803

@@ -1803,11 +1815,12 @@ extension Parser {
18031815
case (.associativity, let handle)?:
18041816
let associativity = self.eat(handle)
18051817
let (unexpectedBeforeColon, colon) = self.expect(.colon)
1806-
let value = self.expectIdentifierWithoutRecovery()
1818+
let (unexpectedBeforeValue, value) = self.expectIdentifier()
18071819
elements.append(RawSyntax(RawPrecedenceGroupAssociativitySyntax(
18081820
associativityKeyword: associativity,
18091821
unexpectedBeforeColon,
18101822
colon: colon,
1823+
unexpectedBeforeValue,
18111824
value: value,
18121825
arena: self.arena
18131826
)))
@@ -1833,11 +1846,14 @@ extension Parser {
18331846
var keepGoing: RawTokenSyntax? = nil
18341847
var namesProgress = LoopProgressCondition()
18351848
repeat {
1836-
let name = self.expectIdentifierWithoutRecovery()
1849+
let (unexpectedBeforeName, name) = self.expectIdentifier()
18371850
keepGoing = self.consume(if: .comma)
18381851
names.append(RawPrecedenceGroupNameElementSyntax(
1839-
name: name, trailingComma: keepGoing,
1840-
arena: self.arena))
1852+
unexpectedBeforeName,
1853+
name: name,
1854+
trailingComma: keepGoing,
1855+
arena: self.arena
1856+
))
18411857
} while keepGoing != nil && namesProgress.evaluate(currentToken)
18421858
}
18431859
elements.append(RawSyntax(RawPrecedenceGroupRelationSyntax(
@@ -1856,6 +1872,7 @@ extension Parser {
18561872
attributes: attrs.attributes, modifiers: attrs.modifiers,
18571873
unexpectedBeforeGroup,
18581874
precedencegroupKeyword: group,
1875+
unexpectedBeforeIdentifier,
18591876
identifier: identifier,
18601877
unexpectedBeforeLBrace,
18611878
leftBrace: lbrace,

0 commit comments

Comments
 (0)