Skip to content

Commit 9df5d69

Browse files
authored
Merge pull request #1436 from ahoppen/ahoppen/token-kind-mismatches
Fix multiple cases where the parser produced token kinds that didn’t match the token kinds in the syntax node definitions
2 parents ced4443 + aea4442 commit 9df5d69

File tree

15 files changed

+57
-135
lines changed

15 files changed

+57
-135
lines changed

CodeGeneration/Sources/SyntaxSupport/AttributeNodes.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ public let ATTRIBUTE_NODES: [Node] = [
301301
children: [
302302
Child(
303303
name: "DeclBaseName",
304-
kind: .token(choices: [.token(tokenKind: "IdentifierToken"), .token(tokenKind: "PrefixOperatorToken"), .keyword(text: "init")]),
304+
kind: .token(choices: [.token(tokenKind: "IdentifierToken"), .token(tokenKind: "BinaryOperatorToken"), .keyword(text: "init"), .keyword(text: "self"), .keyword(text: "Self")]),
305305
nameForDiagnostics: "base name",
306306
description: "The base name of the protocol's requirement."
307307
),
@@ -468,7 +468,7 @@ public let ATTRIBUTE_NODES: [Node] = [
468468
children: [
469469
Child(
470470
name: "DiffKind",
471-
kind: .token(choices: [.keyword(text: "forward"), .keyword(text: "reverse"), .keyword(text: "linear")]),
471+
kind: .token(choices: [.keyword(text: "_forward"), .keyword(text: "reverse"), .keyword(text: "_linear")]),
472472
isOptional: true
473473
),
474474
Child(
@@ -644,7 +644,7 @@ public let ATTRIBUTE_NODES: [Node] = [
644644
children: [
645645
Child(
646646
name: "Label",
647-
kind: .token(choices: [.token(tokenKind: "IdentifierToken"), .keyword(text: "available"), .keyword(text: "exported"), .keyword(text: "kind"), .keyword(text: "spi"), .keyword(text: "spiModule")]),
647+
kind: .node(kind: "Token"),
648648
nameForDiagnostics: "label",
649649
description: "The label of the argument"
650650
),
@@ -677,7 +677,7 @@ public let ATTRIBUTE_NODES: [Node] = [
677677
children: [
678678
Child(
679679
name: "Name",
680-
kind: .token(choices: [.token(tokenKind: "IdentifierToken")]),
680+
kind: .node(kind: "Token"),
681681
nameForDiagnostics: "name",
682682
isOptional: true
683683
),
@@ -779,7 +779,7 @@ public let ATTRIBUTE_NODES: [Node] = [
779779
),
780780
Child(
781781
name: "Name",
782-
kind: .token(choices: [.token(tokenKind: "IdentifierToken"), .token(tokenKind: "BinaryOperatorToken"), .token(tokenKind: "PrefixOperatorToken"), .token(tokenKind: "PostfixOperatorToken")]),
782+
kind: .token(choices: [.token(tokenKind: "IdentifierToken"), .keyword(text: "self"), .keyword(text: "Self"), .keyword(text: "init"), .token(tokenKind: "BinaryOperatorToken")]),
783783
nameForDiagnostics: "base name",
784784
description: "The base name of the referenced function."
785785
),

CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public let DECL_NODES: [Node] = [
1919
children: [
2020
Child(
2121
name: "Name",
22-
kind: .token(choices: [.token(tokenKind: "IdentifierToken")]),
22+
kind: .token(choices: [.token(tokenKind: "IdentifierToken"), .token(tokenKind: "BinaryOperatorToken"), .token(tokenKind: "PrefixOperatorToken"), .token(tokenKind: "PostfixOperatorToken")]),
2323
nameForDiagnostics: "name"
2424
),
2525
Child(

Sources/SwiftParser/Attributes.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -575,11 +575,12 @@ extension Parser {
575575
let (unexpectedBetweenOfLabelAndColon, colon) = self.expect(.colon)
576576
let originalDeclName = self.parseQualifiedDeclarationName()
577577
let period = self.consume(if: .period)
578+
let unexpectedBeforeAccessor: RawUnexpectedNodesSyntax?
578579
let accessor: RawTokenSyntax?
579580
if period != nil {
580-
accessor = self.parseAnyIdentifier()
581+
(unexpectedBeforeAccessor, accessor) = self.expect(.keyword(.get), .keyword(.set), default: .keyword(.get))
581582
} else {
582-
accessor = nil
583+
(unexpectedBeforeAccessor, accessor) = (nil, nil)
583584
}
584585
let comma = self.consume(if: .comma)
585586
let diffParams: RawDifferentiabilityParamsClauseSyntax?
@@ -595,6 +596,7 @@ extension Parser {
595596
colon: colon,
596597
originalDeclName: originalDeclName,
597598
period: period,
599+
unexpectedBeforeAccessor,
598600
accessorKind: accessor,
599601
comma: comma,
600602
diffParams: diffParams,

Sources/SwiftParser/Declarations.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ extension Parser {
476476
// Parse the 'each' keyword for a type parameter pack 'each T'.
477477
var each = self.consume(if: .keyword(.each))
478478

479-
let (unexpectedBetweenEachAndName, name) = self.expectIdentifier()
479+
let (unexpectedBetweenEachAndName, name) = self.expectIdentifier(allowSelfOrCapitalSelfAsIdentifier: true)
480480
if attributes == nil && each == nil && unexpectedBetweenEachAndName == nil && name.isMissing && elements.isEmpty {
481481
break
482482
}
@@ -631,7 +631,7 @@ extension Parser {
631631
body: .sameTypeRequirement(
632632
RawSameTypeRequirementSyntax(
633633
leftTypeIdentifier: RawTypeSyntax(RawMissingTypeSyntax(arena: self.arena)),
634-
equalityToken: missingToken(.equal),
634+
equalityToken: missingToken(.binaryOperator, text: "=="),
635635
rightTypeIdentifier: RawTypeSyntax(RawMissingTypeSyntax(arena: self.arena)),
636636
arena: self.arena
637637
)
@@ -890,7 +890,7 @@ extension Parser {
890890
var loopProgress = LoopProgressCondition()
891891
repeat {
892892
let unexpectedPeriod = self.consume(if: .period)
893-
let (unexpectedBeforeName, name) = self.expectIdentifier(allowIdentifierLikeKeywords: false, keywordRecovery: true)
893+
let (unexpectedBeforeName, name) = self.expectIdentifier(keywordRecovery: true)
894894

895895
let associatedValue: RawParameterClauseSyntax?
896896
if self.at(TokenSpec(.leftParen, allowAtStartOfLine: false)) {
@@ -1916,7 +1916,7 @@ extension Parser {
19161916
// checking.
19171917
let precedenceAndTypes: RawOperatorPrecedenceAndTypesSyntax?
19181918
if let colon = self.consume(if: .colon) {
1919-
let (unexpectedBeforeIdentifier, identifier) = self.expectIdentifier(keywordRecovery: true)
1919+
let (unexpectedBeforeIdentifier, identifier) = self.expectIdentifier(allowSelfOrCapitalSelfAsIdentifier: true)
19201920
var types = [RawDesignatedTypeElementSyntax]()
19211921
while let comma = self.consume(if: .comma) {
19221922
// FIXME: The compiler accepts... anything here. This is a bug.
@@ -2001,7 +2001,7 @@ extension Parser {
20012001
_ handle: RecoveryConsumptionHandle
20022002
) -> RawPrecedenceGroupDeclSyntax {
20032003
let (unexpectedBeforeGroup, group) = self.eat(handle)
2004-
let (unexpectedBeforeIdentifier, identifier) = self.expectIdentifier(keywordRecovery: true)
2004+
let (unexpectedBeforeIdentifier, identifier) = self.expectIdentifier(allowSelfOrCapitalSelfAsIdentifier: true)
20052005
let (unexpectedBeforeLBrace, lbrace) = self.expect(.leftBrace)
20062006

20072007
let groupAttributes = self.parsePrecedenceGroupAttributeListSyntax()

Sources/SwiftParser/Expressions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1796,7 +1796,7 @@ extension Parser {
17961796
let expression: RawExprSyntax
17971797
if self.peek().rawTokenKind == .equal {
17981798
// The name is a new declaration.
1799-
(unexpectedBeforeName, name) = self.expectIdentifier()
1799+
(unexpectedBeforeName, name) = self.expect(.identifier, TokenSpec(.self, remapping: .identifier), default: .identifier)
18001800
(unexpectedBeforeAssignToken, assignToken) = self.expect(.equal)
18011801
expression = self.parseExpression()
18021802
} else {

Sources/SwiftParser/Lookahead.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ extension Parser.Lookahead {
187187
while let _ = self.consume(if: .atSign) {
188188
// Consume qualified names that may or may not involve generic arguments.
189189
repeat {
190-
self.expectIdentifierOrRethrowsWithoutRecovery()
190+
self.consume(if: .identifier, .keyword(.rethrows))
191191
// We don't care whether this succeeds or fails to eat generic
192192
// parameters.
193193
_ = self.consumeGenericArguments()

Sources/SwiftParser/Names.swift

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,20 +63,20 @@ extension Parser {
6363

6464
mutating func parseDeclNameRef(_ flags: DeclNameOptions = []) -> (RawTokenSyntax, RawDeclNameArgumentsSyntax?) {
6565
// Consume the base name.
66-
let ident: RawTokenSyntax
67-
if self.at(.identifier) || self.at(.keyword(.self), .keyword(.Self), .keyword(.`init`)) {
68-
ident = self.expectIdentifierWithoutRecovery()
66+
let base: RawTokenSyntax
67+
if let identOrSelf = self.consume(if: .identifier, .keyword(.self), .keyword(.Self)) ?? self.consume(if: .keyword(.`init`)) {
68+
base = identOrSelf
6969
} else if flags.contains(.operators), let (_, _) = self.at(anyIn: Operator.self) {
70-
ident = self.consumeAnyToken(remapping: .binaryOperator)
70+
base = self.consumeAnyToken(remapping: .binaryOperator)
7171
} else if flags.contains(.keywords) && self.currentToken.isLexerClassifiedKeyword {
72-
ident = self.consumeAnyToken(remapping: .identifier)
72+
base = self.consumeAnyToken(remapping: .identifier)
7373
} else {
74-
ident = self.expectIdentifierWithoutRecovery()
74+
base = missingToken(.identifier)
7575
}
7676

7777
// Parse an argument list, if the flags allow it and it's present.
7878
let args = self.parseArgLabelList(flags)
79-
return (ident, args)
79+
return (base, args)
8080
}
8181

8282
mutating func parseArgLabelList(_ flags: DeclNameOptions) -> RawDeclNameArgumentsSyntax? {
@@ -176,7 +176,7 @@ extension Parser {
176176
var keepGoing: RawTokenSyntax? = nil
177177
var loopProgress = LoopProgressCondition()
178178
repeat {
179-
let (name, _) = self.parseDeclNameRef()
179+
let (unexpectedBeforeName, name) = self.expect(.identifier, .keyword(.self), .keyword(.Self), default: .identifier)
180180
let generics: RawGenericArgumentClauseSyntax?
181181
if self.atContextualPunctuator("<") {
182182
generics = self.parseGenericArguments()
@@ -188,6 +188,7 @@ extension Parser {
188188
RawMemberTypeIdentifierSyntax(
189189
baseType: result!,
190190
period: keepGoing,
191+
unexpectedBeforeName,
191192
name: name,
192193
genericArgumentClause: generics,
193194
arena: self.arena
@@ -196,6 +197,7 @@ extension Parser {
196197
} else {
197198
result = RawTypeSyntax(
198199
RawSimpleTypeIdentifierSyntax(
200+
unexpectedBeforeName,
199201
name: name,
200202
genericArgumentClause: generics,
201203
arena: self.arena

Sources/SwiftParser/Nominals.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ extension Parser {
150150
introucerHandle: RecoveryConsumptionHandle
151151
) -> T where T: NominalTypeDeclarationTrait {
152152
let (unexpectedBeforeIntroducerKeyword, introducerKeyword) = self.eat(introucerHandle)
153-
let (unexpectedBeforeName, name) = self.expectIdentifier(allowIdentifierLikeKeywords: false, keywordRecovery: true)
153+
let (unexpectedBeforeName, name) = self.expectIdentifier(keywordRecovery: true)
154154
if unexpectedBeforeName == nil && name.isMissing && self.currentToken.isAtStartOfLine {
155155
return T.init(
156156
attributes: attrs.attributes,
@@ -258,7 +258,7 @@ extension Parser {
258258
var loopProgress = LoopProgressCondition()
259259
repeat {
260260
// Parse the name of the parameter.
261-
let (unexpectedBeforeName, name) = self.expectIdentifier()
261+
let (unexpectedBeforeName, name) = self.expectIdentifier(allowSelfOrCapitalSelfAsIdentifier: true)
262262
keepGoing = self.consume(if: .comma)
263263
associatedTypes.append(
264264
RawPrimaryAssociatedTypeSyntax(

Sources/SwiftParser/Parser.swift

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -417,18 +417,20 @@ extension Parser {
417417
/// incorrectly used a keyword as an identifier.
418418
/// This should be set if keywords aren't strong recovery marker at this
419419
/// position, e.g. because the parser expects a punctuator next.
420+
///
421+
/// If `allowSelfOrCapitalSelfAsIdentifier` is `true`, then `self` and `Self`
422+
/// are also accepted and remapped to identifiers. This is exclusively used
423+
/// to maintain compatibility with the C++ parser. No new uses of this should
424+
/// be introduced.
420425
mutating func expectIdentifier(
421-
allowIdentifierLikeKeywords: Bool = true,
422-
keywordRecovery: Bool = false
426+
keywordRecovery: Bool = false,
427+
allowSelfOrCapitalSelfAsIdentifier: Bool = false
423428
) -> (RawUnexpectedNodesSyntax?, RawTokenSyntax) {
424-
if allowIdentifierLikeKeywords {
425-
if let (_, handle) = self.canRecoverTo(anyIn: IdentifierTokens.self) {
426-
return self.eat(handle)
427-
}
428-
} else {
429-
if let identifier = self.consume(if: .identifier) {
430-
return (nil, identifier)
431-
}
429+
if let identifier = self.consume(if: .identifier) {
430+
return (nil, identifier)
431+
}
432+
if allowSelfOrCapitalSelfAsIdentifier, let selfOrCapitalSelf = self.consume(if: TokenSpec(.self, remapping: .identifier), TokenSpec(.Self, remapping: .identifier)) {
433+
return (nil, selfOrCapitalSelf)
432434
}
433435
if let unknown = self.consume(if: .unknown) {
434436
return (
@@ -457,22 +459,6 @@ extension Parser {
457459
)
458460
}
459461

460-
mutating func expectIdentifierOrRethrows() -> (RawUnexpectedNodesSyntax?, RawTokenSyntax) {
461-
if let (_, handle) = self.canRecoverTo(anyIn: IdentifierOrRethrowsTokens.self) {
462-
return self.eat(handle)
463-
}
464-
if let unknown = self.consume(if: .unknown) {
465-
return (
466-
RawUnexpectedNodesSyntax(elements: [RawSyntax(unknown)], arena: self.arena),
467-
self.missingToken(.identifier)
468-
)
469-
}
470-
return (
471-
nil,
472-
self.missingToken(.identifier)
473-
)
474-
}
475-
476462
/// Expect a right brace but with a little smart recovery logic:
477463
/// If `leftBrace` is missing, we only recover to a `}` whose indentation is greater or equal to that of `introducer`.
478464
/// That way, if the developer forgot to to type `{`, we won't eat `}` that were most likely intended to close an outer scope.

Sources/SwiftParser/Statements.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -932,7 +932,7 @@ extension Parser {
932932
return nil
933933
}
934934

935-
return self.expectIdentifierWithoutRecovery()
935+
return self.expectWithoutRecovery(.identifier)
936936
}
937937
}
938938

Sources/SwiftParser/TokenConsumer.swift

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -219,22 +219,6 @@ extension TokenConsumer {
219219
// MARK: Convenience functions
220220

221221
extension TokenConsumer {
222-
@inline(__always)
223-
mutating func expectIdentifierWithoutRecovery() -> Token {
224-
if let (_, handle) = self.at(anyIn: IdentifierTokens.self) {
225-
return self.eat(handle)
226-
}
227-
return missingToken(.identifier)
228-
}
229-
230-
@inline(__always)
231-
mutating func expectIdentifierOrRethrowsWithoutRecovery() -> Token {
232-
if let (_, handle) = self.at(anyIn: IdentifierOrRethrowsTokens.self) {
233-
return self.eat(handle)
234-
}
235-
return missingToken(.identifier)
236-
}
237-
238222
var canHaveParameterSpecifier: Bool {
239223
// The parameter specifiers like `isolated`, `consuming`, `borrowing` are
240224
// also valid identifiers and could be the name of a type. Check whether

Sources/SwiftParser/TokenSpecSet.swift

Lines changed: 0 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -298,64 +298,6 @@ enum DeclarationStart: TokenSpecSet {
298298
}
299299
}
300300

301-
enum IdentifierTokens: TokenSpecSet {
302-
case anyKeyword
303-
case capitalSelfKeyword
304-
case identifier
305-
case initKeyword
306-
case selfKeyword
307-
308-
init?(lexeme: Lexer.Lexeme) {
309-
switch PrepareForKeywordMatch(lexeme) {
310-
case TokenSpec(.Any): self = .anyKeyword
311-
case TokenSpec(.Self): self = .capitalSelfKeyword
312-
case TokenSpec(.identifier): self = .identifier
313-
case TokenSpec(.`init`): self = .initKeyword
314-
case TokenSpec(.self): self = .selfKeyword
315-
default: return nil
316-
}
317-
}
318-
319-
var spec: TokenSpec {
320-
switch self {
321-
case .anyKeyword: return .keyword(.Any)
322-
case .capitalSelfKeyword: return .keyword(.Self)
323-
case .identifier: return .identifier
324-
case .initKeyword: return .keyword(.`init`)
325-
case .selfKeyword: return .keyword(.self)
326-
}
327-
}
328-
}
329-
330-
enum IdentifierOrRethrowsTokens: TokenSpecSet {
331-
case anyKeyword
332-
case capitalSelfKeyword
333-
case identifier
334-
case selfKeyword
335-
case rethrowsKeyword
336-
337-
init?(lexeme: Lexer.Lexeme) {
338-
switch PrepareForKeywordMatch(lexeme) {
339-
case TokenSpec(.Any): self = .anyKeyword
340-
case TokenSpec(.Self): self = .capitalSelfKeyword
341-
case TokenSpec(.identifier): self = .identifier
342-
case TokenSpec(.self): self = .selfKeyword
343-
case TokenSpec(.rethrows): self = .rethrowsKeyword
344-
default: return nil
345-
}
346-
}
347-
348-
var spec: TokenSpec {
349-
switch self {
350-
case .anyKeyword: return .keyword(.Any)
351-
case .capitalSelfKeyword: return .keyword(.Self)
352-
case .identifier: return .identifier
353-
case .selfKeyword: return .keyword(.self)
354-
case .rethrowsKeyword: return TokenSpec(.rethrows, remapping: .identifier)
355-
}
356-
}
357-
}
358-
359301
enum Operator: TokenSpecSet {
360302
case binaryOperator
361303
case postfixOperator

Sources/SwiftParser/Types.swift

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ extension Parser {
271271
)
272272
)
273273
} else {
274-
let (name, generics) = self.parseTypeNameWithGenerics(include: .keywords)
274+
let (name, generics) = self.parseTypeNameWithGenerics(allowKeywordAsName: true)
275275
base = RawTypeSyntax(
276276
RawMemberTypeIdentifierSyntax(
277277
baseType: base,
@@ -337,8 +337,15 @@ extension Parser {
337337
)
338338
}
339339

340-
mutating func parseTypeNameWithGenerics(include flags: DeclNameOptions = []) -> (RawTokenSyntax, RawGenericArgumentClauseSyntax?) {
341-
let (name, _) = self.parseDeclNameRef(flags)
340+
mutating func parseTypeNameWithGenerics(allowKeywordAsName: Bool) -> (RawTokenSyntax, RawGenericArgumentClauseSyntax?) {
341+
let name: RawTokenSyntax
342+
if let identOrSelf = self.consume(if: .identifier, .keyword(.self), .keyword(.Self)) {
343+
name = identOrSelf
344+
} else if allowKeywordAsName && self.currentToken.isLexerClassifiedKeyword {
345+
name = self.consumeAnyToken(remapping: .identifier)
346+
} else {
347+
name = missingToken(.identifier)
348+
}
342349
if self.atContextualPunctuator("<") {
343350
return (name, self.parseGenericArguments())
344351
}
@@ -356,7 +363,7 @@ extension Parser {
356363
return RawTypeSyntax(self.parseAnyType())
357364
}
358365

359-
let (name, generics) = parseTypeNameWithGenerics()
366+
let (name, generics) = parseTypeNameWithGenerics(allowKeywordAsName: false)
360367
return RawTypeSyntax(
361368
RawSimpleTypeIdentifierSyntax(
362369
name: name,

0 commit comments

Comments
 (0)