Skip to content

Commit 80cf536

Browse files
authored
Merge pull request #1741 from kimdv/kimdv/generate-token-spec-set
Generate token spec sets
2 parents ab682d8 + 34724b5 commit 80cf536

File tree

11 files changed

+2197
-242
lines changed

11 files changed

+2197
-242
lines changed

CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,6 @@ public let DECL_NODES: [Node] = [
534534
.keyword(text: "public"),
535535
.keyword(text: "reasync"),
536536
.keyword(text: "required"),
537-
.keyword(text: "setter_access"),
538537
.keyword(text: "static"),
539538
.keyword(text: "unowned"),
540539
.keyword(text: "weak"),

CodeGeneration/Sources/generate-swiftsyntax/GenerateSwiftSyntax.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ struct GenerateSwiftSyntax: ParsableCommand {
8989
// SwiftParser
9090
GeneratedFileSpec(swiftParserGeneratedDir + ["IsLexerClassified.swift"], isLexerClassifiedFile),
9191
GeneratedFileSpec(swiftParserGeneratedDir + ["Parser+Entry.swift"], parserEntryFile),
92+
GeneratedFileSpec(swiftParserGeneratedDir + ["Parser+TokenSpecSet.swift"], parserTokenSpecSetFile),
9293
GeneratedFileSpec(swiftParserGeneratedDir + ["TokenSpecStaticMembers.swift"], tokenSpecStaticMembersFile),
9394

9495
// SwiftParserDiagnostics
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import SwiftSyntax
14+
import SwiftSyntaxBuilder
15+
import SyntaxSupport
16+
import Utils
17+
18+
let parserTokenSpecSetFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
19+
DeclSyntax("@_spi(RawSyntax) import SwiftSyntax")
20+
21+
for layoutNode in SYNTAX_NODES.compactMap(\.layoutNode) {
22+
for child in layoutNode.children {
23+
if case let .token(choices, _, _) = child.kind, choices.count > 1 {
24+
try! ExtensionDeclSyntax("extension \(raw: layoutNode.kind.syntaxType)") {
25+
try EnumDeclSyntax("enum \(raw: child.name)Options: TokenSpecSet") {
26+
for choice in choices {
27+
switch choice {
28+
case .keyword(let keywordText):
29+
let keyword = KEYWORDS.first(where: { $0.name == keywordText })!
30+
DeclSyntax("case \(raw: keyword.escapedName)")
31+
case .token(let tokenText):
32+
let token = SYNTAX_TOKEN_MAP[tokenText]!
33+
DeclSyntax("case \(raw: token.swiftKind)")
34+
}
35+
}
36+
37+
try InitializerDeclSyntax("init?(lexeme: Lexer.Lexeme)") {
38+
try SwitchExprSyntax("switch PrepareForKeywordMatch(lexeme)") {
39+
for choice in choices {
40+
switch choice {
41+
case .keyword(let keywordText):
42+
let keyword = KEYWORDS.first(where: { $0.name == keywordText })!
43+
SwitchCaseSyntax("case TokenSpec(.\(raw: keyword.escapedName)): self = .\(raw: keyword.escapedName)")
44+
case .token(let tokenText):
45+
let token = SYNTAX_TOKEN_MAP[tokenText]!
46+
SwitchCaseSyntax(
47+
"case TokenSpec(.\(raw: token.swiftKind)): self = .\(raw: token.swiftKind)"
48+
)
49+
}
50+
}
51+
SwitchCaseSyntax("default: return nil")
52+
}
53+
}
54+
55+
try VariableDeclSyntax("var spec: TokenSpec") {
56+
try SwitchExprSyntax("switch self") {
57+
for choice in choices {
58+
switch choice {
59+
case .keyword(let keywordText):
60+
let keyword = KEYWORDS.first(where: { $0.name == keywordText })!
61+
SwitchCaseSyntax(
62+
"case .\(raw: keyword.escapedName): return .keyword(.\(raw: keyword.escapedName))"
63+
)
64+
case .token(let tokenText):
65+
let token = SYNTAX_TOKEN_MAP[tokenText]!
66+
SwitchCaseSyntax(
67+
"case .\(raw: token.swiftKind): return .\(raw: token.swiftKind)"
68+
)
69+
}
70+
}
71+
}
72+
}
73+
}
74+
}
75+
}
76+
}
77+
}
78+
}

Sources/SwiftParser/Attributes.swift

Lines changed: 2 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -363,33 +363,10 @@ extension Parser {
363363
)
364364
}
365365

366-
enum DifferentiabilityKind: TokenSpecSet {
367-
case reverse
368-
case _linear
369-
case _forward
370-
371-
init?(lexeme: Lexer.Lexeme) {
372-
switch PrepareForKeywordMatch(lexeme) {
373-
case TokenSpec(.reverse): self = .reverse
374-
case TokenSpec(._linear): self = ._linear
375-
case TokenSpec(._forward): self = ._forward
376-
default: return nil
377-
}
378-
}
379-
380-
var spec: TokenSpec {
381-
switch self {
382-
case .reverse: return .keyword(.reverse)
383-
case ._linear: return .keyword(._linear)
384-
case ._forward: return .keyword(._forward)
385-
}
386-
}
387-
}
388-
389366
mutating func parseDifferentiableAttributeArguments() -> RawDifferentiableAttributeArgumentsSyntax {
390367
let diffKind: RawTokenSyntax?
391368
let diffKindComma: RawTokenSyntax?
392-
if let (_, handle) = self.at(anyIn: DifferentiabilityKind.self) {
369+
if let (_, handle) = self.at(anyIn: DifferentiableAttributeArgumentsSyntax.DiffKindOptions.self) {
393370
diffKind = self.eat(handle)
394371
diffKindComma = self.consume(if: .comma)
395372
} else {
@@ -474,30 +451,7 @@ extension Parser {
474451
}
475452

476453
mutating func parseDifferentiabilityParameter() -> RawDifferentiabilityParamSyntax? {
477-
enum ExpectedTokenKind: TokenSpecSet {
478-
case identifier
479-
case integerLiteral
480-
case `self`
481-
482-
init?(lexeme: Lexer.Lexeme) {
483-
switch PrepareForKeywordMatch(lexeme) {
484-
case TokenSpec(.identifier): self = .identifier
485-
case TokenSpec(.integerLiteral): self = .integerLiteral
486-
case TokenSpec(.self): self = .self
487-
default: return nil
488-
}
489-
}
490-
491-
var spec: TokenSpec {
492-
switch self {
493-
case .identifier: return .identifier
494-
case .integerLiteral: return .integerLiteral
495-
case .self: return .keyword(.self)
496-
}
497-
}
498-
}
499-
500-
switch self.at(anyIn: ExpectedTokenKind.self) {
454+
switch self.at(anyIn: DifferentiabilityParamSyntax.ParameterOptions.self) {
501455
case (.identifier, let handle)?:
502456
let token = self.eat(handle)
503457
let comma = self.consume(if: .comma)

Sources/SwiftParser/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ add_swift_host_library(SwiftParser
3838

3939
generated/IsLexerClassified.swift
4040
generated/Parser+Entry.swift
41+
generated/Parser+TokenSpecSet.swift
4142
generated/TokenSpecStaticMembers.swift
4243

4344
Lexer/Cursor.swift

Sources/SwiftParser/Declarations.swift

Lines changed: 27 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -339,48 +339,7 @@ extension Parser {
339339
}
340340

341341
mutating func parseImportKind() -> RawTokenSyntax? {
342-
enum ImportKind: TokenSpecSet {
343-
case `typealias`
344-
case `struct`
345-
case `class`
346-
case `enum`
347-
case `protocol`
348-
case `var`
349-
case `let`
350-
case `func`
351-
case `inout`
352-
353-
var spec: TokenSpec {
354-
switch self {
355-
case .typealias: return .keyword(.typealias)
356-
case .struct: return .keyword(.struct)
357-
case .class: return .keyword(.class)
358-
case .enum: return .keyword(.enum)
359-
case .protocol: return .keyword(.protocol)
360-
case .var: return .keyword(.var)
361-
case .let: return .keyword(.let)
362-
case .func: return .keyword(.func)
363-
case .inout: return .keyword(.inout)
364-
}
365-
}
366-
367-
init?(lexeme: Lexer.Lexeme) {
368-
switch PrepareForKeywordMatch(lexeme) {
369-
case TokenSpec(.typealias): self = .typealias
370-
case TokenSpec(.struct): self = .struct
371-
case TokenSpec(.class): self = .class
372-
case TokenSpec(.enum): self = .enum
373-
case TokenSpec(.protocol): self = .protocol
374-
case TokenSpec(.var): self = .var
375-
case TokenSpec(.let): self = .let
376-
case TokenSpec(.func): self = .func
377-
case TokenSpec(.inout): self = .inout
378-
default: return nil
379-
}
380-
}
381-
}
382-
383-
return self.consume(ifAnyIn: ImportKind.self)
342+
return self.consume(ifAnyIn: ImportDeclSyntax.ImportKindOptions.self)
384343
}
385344

386345
mutating func parseImportPath() -> RawImportPathSyntax {
@@ -581,56 +540,6 @@ extension Parser {
581540
)
582541
}
583542

584-
enum LayoutConstraint: TokenSpecSet {
585-
case _Trivial
586-
case _TrivialAtMost
587-
case _UnknownLayout
588-
case _RefCountedObjectLayout
589-
case _NativeRefCountedObjectLayout
590-
case _Class
591-
case _NativeClass
592-
593-
init?(lexeme: Lexer.Lexeme) {
594-
switch PrepareForKeywordMatch(lexeme) {
595-
case TokenSpec(._Trivial): self = ._Trivial
596-
case TokenSpec(._TrivialAtMost): self = ._TrivialAtMost
597-
case TokenSpec(._UnknownLayout): self = ._UnknownLayout
598-
case TokenSpec(._RefCountedObject): self = ._RefCountedObjectLayout
599-
case TokenSpec(._NativeRefCountedObject): self = ._NativeRefCountedObjectLayout
600-
case TokenSpec(._Class): self = ._Class
601-
case TokenSpec(._NativeClass): self = ._NativeClass
602-
default: return nil
603-
}
604-
}
605-
606-
var spec: TokenSpec {
607-
switch self {
608-
case ._Trivial: return .keyword(._Trivial)
609-
case ._TrivialAtMost: return .keyword(._TrivialAtMost)
610-
case ._UnknownLayout: return .keyword(._UnknownLayout)
611-
case ._RefCountedObjectLayout: return .keyword(._RefCountedObject)
612-
case ._NativeRefCountedObjectLayout: return .keyword(._NativeRefCountedObject)
613-
case ._Class: return .keyword(._Class)
614-
case ._NativeClass: return .keyword(._NativeClass)
615-
}
616-
}
617-
618-
var hasArguments: Bool {
619-
switch self {
620-
case ._Trivial,
621-
._TrivialAtMost:
622-
return true
623-
624-
case ._UnknownLayout,
625-
._RefCountedObjectLayout,
626-
._NativeRefCountedObjectLayout,
627-
._Class,
628-
._NativeClass:
629-
return false
630-
}
631-
}
632-
}
633-
634543
mutating func parseGenericWhereClause() -> RawGenericWhereClauseSyntax {
635544
let (unexpectedBeforeWhereKeyword, whereKeyword) = self.expect(.keyword(.where))
636545

@@ -690,7 +599,7 @@ extension Parser {
690599
case (.colon, let handle)?:
691600
let colon = self.eat(handle)
692601
// A conformance-requirement.
693-
if let (layoutConstraint, handle) = self.at(anyIn: LayoutConstraint.self) {
602+
if let (layoutConstraint, handle) = self.at(anyIn: LayoutRequirementSyntax.LayoutConstraintOptions.self) {
694603
// Parse a layout constraint.
695604
let constraint = self.eat(handle)
696605

@@ -701,9 +610,25 @@ extension Parser {
701610
let alignment: RawTokenSyntax?
702611
let unexpectedBeforeRightParen: RawUnexpectedNodesSyntax?
703612
let rightParen: RawTokenSyntax?
613+
614+
var hasArguments: Bool {
615+
switch layoutConstraint {
616+
case ._Trivial,
617+
._TrivialAtMost:
618+
return true
619+
620+
case ._UnknownLayout,
621+
._RefCountedObject,
622+
._NativeRefCountedObject,
623+
._Class,
624+
._NativeClass:
625+
return false
626+
}
627+
}
628+
704629
// Unlike the other layout constraints, _Trivial's argument list
705630
// is optional.
706-
if layoutConstraint.hasArguments && (layoutConstraint != ._Trivial || self.at(.leftParen)) {
631+
if hasArguments && (layoutConstraint != ._Trivial || self.at(.leftParen)) {
707632
(unexpectedBeforeLeftParen, leftParen) = self.expect(.leftParen)
708633
size = self.expectWithoutRecovery(.integerLiteral)
709634
comma = self.consume(if: .comma)
@@ -1296,7 +1221,7 @@ extension Parser {
12961221

12971222
// Parse getter and setter.
12981223
let accessor: RawSubscriptDeclSyntax.Accessor?
1299-
if self.at(.leftBrace) || self.at(anyIn: AccessorKind.self) != nil {
1224+
if self.at(.leftBrace) || self.at(anyIn: AccessorDeclSyntax.AccessorKindOptions.self) != nil {
13001225
accessor = self.parseGetSet()
13011226
} else {
13021227
accessor = nil
@@ -1418,7 +1343,7 @@ extension Parser {
14181343
}
14191344

14201345
let accessor: RawPatternBindingSyntax.Accessor?
1421-
if self.at(.leftBrace) || (inMemberDeclList && self.at(anyIn: AccessorKind.self) != nil && !self.at(.keyword(.`init`))) {
1346+
if self.at(.leftBrace) || (inMemberDeclList && self.at(anyIn: AccessorDeclSyntax.AccessorKindOptions.self) != nil && !self.at(.keyword(.`init`))) {
14221347
switch self.parseGetSet() {
14231348
case .accessors(let accessors):
14241349
accessor = .accessors(accessors)
@@ -1456,19 +1381,19 @@ extension Parser {
14561381
struct AccessorIntroducer {
14571382
var attributes: RawAttributeListSyntax?
14581383
var modifier: RawDeclModifierSyntax?
1459-
var kind: AccessorKind
1384+
var kind: AccessorDeclSyntax.AccessorKindOptions
14601385
var unexpectedBeforeToken: RawUnexpectedNodesSyntax?
14611386
var token: RawTokenSyntax
14621387
}
14631388

14641389
mutating func parseAccessorIntroducer(
1465-
forcedKind: (AccessorKind, TokenConsumptionHandle)? = nil
1390+
forcedKind: (AccessorDeclSyntax.AccessorKindOptions, TokenConsumptionHandle)? = nil
14661391
) -> AccessorIntroducer? {
14671392
// Check there is an identifier before consuming
14681393
var look = self.lookahead()
14691394
let _ = look.consumeAttributeList()
14701395
let hasModifier = look.consume(if: .keyword(.mutating), .keyword(.nonmutating), .keyword(.__consuming)) != nil
1471-
guard let (kind, _) = look.at(anyIn: AccessorKind.self) ?? forcedKind else {
1396+
guard let (kind, _) = look.at(anyIn: AccessorDeclSyntax.AccessorKindOptions.self) ?? forcedKind else {
14721397
return nil
14731398
}
14741399

@@ -1530,7 +1455,7 @@ extension Parser {
15301455
//
15311456
// set-name ::= '(' identifier ')'
15321457
let parameter: RawAccessorParameterSyntax?
1533-
if [AccessorKind.set, .willSet, .didSet, .`init`].contains(introducer.kind), let lparen = self.consume(if: .leftParen) {
1458+
if [AccessorDeclSyntax.AccessorKindOptions.set, .willSet, .didSet, .`init`].contains(introducer.kind), let lparen = self.consume(if: .leftParen) {
15341459
let (unexpectedBeforeName, name) = self.expectIdentifier()
15351460
let (unexpectedBeforeRParen, rparen) = self.expect(.rightParen)
15361461
parameter = RawAccessorParameterSyntax(
@@ -1575,7 +1500,7 @@ extension Parser {
15751500
// Parse getter and setter.
15761501
let unexpectedBeforeLBrace: RawUnexpectedNodesSyntax?
15771502
let lbrace: RawTokenSyntax
1578-
if self.at(anyIn: AccessorKind.self) != nil {
1503+
if self.at(anyIn: AccessorDeclSyntax.AccessorKindOptions.self) != nil {
15791504
unexpectedBeforeLBrace = nil
15801505
lbrace = missingToken(.leftBrace)
15811506
} else {
@@ -1976,7 +1901,7 @@ extension Parser {
19761901
case (.assignment, let handle)?:
19771902
let assignmentKeyword = self.eat(handle)
19781903
let (unexpectedBeforeColon, colon) = self.expect(.colon)
1979-
let (unexpectedBeforeFlag, flag) = self.expect(.keyword(.true), .keyword(.false), default: .keyword(.true))
1904+
let (unexpectedBeforeFlag, flag) = self.expect(anyIn: PrecedenceGroupAssignmentSyntax.FlagOptions.self, default: .true)
19801905
let unexpectedAfterFlag: RawUnexpectedNodesSyntax?
19811906
if flag.isMissing, let unexpectedIdentifier = self.consume(if: TokenSpec(.identifier, allowAtStartOfLine: false)) {
19821907
unexpectedAfterFlag = RawUnexpectedNodesSyntax([unexpectedIdentifier], arena: self.arena)

Sources/SwiftParser/Expressions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2620,7 +2620,7 @@ extension Parser {
26202620
var versionInfo: RawCanImportVersionInfoSyntax?
26212621

26222622
if let comma = self.consume(if: .comma) {
2623-
let (unexpectedBeforeLabel, label) = self.expect(.keyword(._version), .keyword(._underlyingVersion), default: .keyword(._version))
2623+
let (unexpectedBeforeLabel, label) = self.expect(anyIn: CanImportVersionInfoSyntax.LabelOptions.self, default: ._version)
26242624
let (unexpectedBeforeColon, colon) = self.expect(.colon)
26252625

26262626
let version = self.parseVersionTuple(maxComponentCount: 4)

0 commit comments

Comments
 (0)