Skip to content

Commit b32df0e

Browse files
committed
Replace the manually maintained TokenSpecSet TypeSpecifier by the generated TypeSpecifierSyntax.SpecifierOptions
The two `TokenSpecSet`s had already diverged. Instead of manually maintaining the `TypeSpecifier` spec set, we should allow all keywors specified in the syntax tree definition.
1 parent e51d851 commit b32df0e

File tree

11 files changed

+914
-87
lines changed

11 files changed

+914
-87
lines changed

CodeGeneration/Sources/SyntaxSupport/Child.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@ public enum TokenChoice: Equatable {
2424
case .token: return false
2525
}
2626
}
27+
28+
public var varOrCaseName: TokenSyntax {
29+
switch self {
30+
case .keyword(let keyword):
31+
return keyword.spec.varOrCaseName
32+
case .token(let token):
33+
return token.spec.varOrCaseName
34+
}
35+
}
2736
}
2837

2938
public enum ChildKind {

CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -34,36 +34,6 @@ public let TYPE_NODES: [Node] = [
3434
]
3535
),
3636

37-
Node(
38-
kind: .typeSpecifier,
39-
base: .syntax,
40-
nameForDiagnostics: nil,
41-
documentation: "A specifier that can be attached to a type to eg. mark a parameter as `inout` or `consuming`",
42-
children: [
43-
Child(
44-
name: "specifier",
45-
kind: .token(choices: [
46-
.keyword(.inout),
47-
.keyword(.__shared),
48-
.keyword(.__owned),
49-
.keyword(.isolated),
50-
.keyword(._const),
51-
.keyword(.borrowing),
52-
.keyword(.consuming),
53-
.keyword(.transferring),
54-
.keyword(._resultDependsOn),
55-
])
56-
)
57-
]
58-
),
59-
60-
Node(
61-
kind: .typeSpecifierList,
62-
base: .syntaxCollection,
63-
nameForDiagnostics: nil,
64-
elementChoices: [.typeSpecifier]
65-
),
66-
6737
Node(
6838
kind: .attributedType,
6939
base: .type,
@@ -74,15 +44,18 @@ public let TYPE_NODES: [Node] = [
7444
children: [
7545
Child(
7646
name: "specifiers",
77-
kind: .collection(kind: .typeSpecifierList, collectionElementName: "Specifier", defaultsToEmpty: true)
47+
kind: .collection(kind: .typeSpecifierList, collectionElementName: "Specifier", defaultsToEmpty: true),
48+
documentation: "A list of specifiers that can be attached to the type, such as `inout`, `isolated`, or `consuming`."
7849
),
7950
Child(
8051
name: "attributes",
81-
kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true)
52+
kind: .collection(kind: .attributeList, collectionElementName: "Attribute", defaultsToEmpty: true),
53+
documentation: "A list of attributes that can be attached to the type, such as `@escaping`."
8254
),
8355
Child(
8456
name: "baseType",
85-
kind: .node(kind: .type)
57+
kind: .node(kind: .type),
58+
documentation: "The type to with the specifiers and attributes are applied."
8659
),
8760
]
8861
),
@@ -522,4 +495,34 @@ public let TYPE_NODES: [Node] = [
522495
]
523496
),
524497

498+
Node(
499+
kind: .typeSpecifier,
500+
base: .syntax,
501+
nameForDiagnostics: nil,
502+
documentation: "A specifier that can be attached to a type to eg. mark a parameter as `inout` or `consuming`",
503+
children: [
504+
Child(
505+
name: "specifier",
506+
kind: .token(choices: [
507+
.keyword(.inout),
508+
.keyword(.__shared),
509+
.keyword(.__owned),
510+
.keyword(.isolated),
511+
.keyword(._const),
512+
.keyword(.borrowing),
513+
.keyword(.consuming),
514+
.keyword(.transferring),
515+
.keyword(._resultDependsOn),
516+
]),
517+
documentation: "The specifier token that's attached to the type."
518+
)
519+
]
520+
),
521+
522+
Node(
523+
kind: .typeSpecifierList,
524+
base: .syntaxCollection,
525+
nameForDiagnostics: nil,
526+
elementChoices: [.typeSpecifier]
527+
),
525528
]

CodeGeneration/Sources/generate-swift-syntax/templates/swiftparser/ParserTokenSpecSetFile.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,17 @@ let parserTokenSpecSetFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
8383
}
8484
}
8585

86+
try InitializerDeclSyntax("public init?(token: TokenSyntax)") {
87+
try SwitchExprSyntax("switch token") {
88+
for choice in choices {
89+
SwitchCaseSyntax(
90+
"case TokenSpec(.\(choice.varOrCaseName)): self = .\(choice.varOrCaseName)"
91+
)
92+
}
93+
SwitchCaseSyntax("default: return nil")
94+
}
95+
}
96+
8697
try VariableDeclSyntax("var spec: TokenSpec") {
8798
try SwitchExprSyntax("switch self") {
8899
for choice in choices {

Sources/SwiftParser/Parameters.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ extension Parser {
261261
mutating func parseMisplacedSpecifiers() -> [RawTokenSyntax] {
262262
var misplacedSpecifiers: [RawTokenSyntax] = []
263263
if self.withLookahead({ !$0.startsParameterName(isClosure: false, allowMisplacedSpecifierRecovery: false) }) {
264-
while canHaveParameterSpecifier, let specifier = self.consume(ifAnyIn: TypeSpecifier.self) {
264+
while canHaveParameterSpecifier, let specifier = self.consume(ifAnyIn: TypeSpecifierSyntax.SpecifierOptions.self) {
265265
misplacedSpecifiers.append(specifier)
266266
}
267267
}

Sources/SwiftParser/Patterns.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ extension Parser.Lookahead {
340340
mutating func startsParameterName(isClosure: Bool, allowMisplacedSpecifierRecovery: Bool) -> Bool {
341341
if allowMisplacedSpecifierRecovery {
342342
while canHaveParameterSpecifier,
343-
self.consume(ifAnyIn: TypeSpecifier.self) != nil
343+
self.consume(ifAnyIn: TypeSpecifierSyntax.SpecifierOptions.self) != nil
344344
{}
345345
}
346346

Sources/SwiftParser/TokenSpecSet.swift

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -691,52 +691,6 @@ enum TypeAttribute: TokenSpecSet {
691691
}
692692
}
693693

694-
@_spi(Diagnostics)
695-
public enum TypeSpecifier: TokenSpecSet {
696-
case `inout`
697-
case owned
698-
case shared
699-
case borrowing
700-
case consuming
701-
case transferring
702-
703-
init?(lexeme: Lexer.Lexeme, experimentalFeatures: Parser.ExperimentalFeatures) {
704-
switch PrepareForKeywordMatch(lexeme) {
705-
case TokenSpec(.inout): self = .inout
706-
case TokenSpec(.__owned): self = .owned
707-
case TokenSpec(.__shared): self = .shared
708-
case TokenSpec(.consuming): self = .consuming
709-
case TokenSpec(.borrowing): self = .borrowing
710-
case TokenSpec(.transferring): self = .transferring
711-
default: return nil
712-
}
713-
}
714-
715-
@_spi(Diagnostics)
716-
public init?(token: TokenSyntax) {
717-
switch token {
718-
case TokenSpec(.inout): self = .inout
719-
case TokenSpec(.__owned): self = .owned
720-
case TokenSpec(.__shared): self = .shared
721-
case TokenSpec(.consuming): self = .shared
722-
case TokenSpec(.borrowing): self = .shared
723-
case TokenSpec(.transferring): self = .transferring
724-
default: return nil
725-
}
726-
}
727-
728-
var spec: TokenSpec {
729-
switch self {
730-
case .inout: return .keyword(.inout)
731-
case .owned: return .keyword(.__owned)
732-
case .shared: return .keyword(.__shared)
733-
case .borrowing: return .keyword(.borrowing)
734-
case .consuming: return .keyword(.consuming)
735-
case .transferring: return .keyword(.transferring)
736-
}
737-
}
738-
}
739-
740694
// MARK: Expression start
741695

742696
enum ExpressionModifierKeyword: TokenSpecSet {

Sources/SwiftParser/Types.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ extension Parser {
468468
var misplacedSpecifiers: [RawTokenSyntax] = []
469469
if self.withLookahead({ $0.startsParameterName(isClosure: false, allowMisplacedSpecifierRecovery: true) }) {
470470
while canHaveParameterSpecifier,
471-
let specifier = self.consume(ifAnyIn: TypeSpecifier.self)
471+
let specifier = self.consume(ifAnyIn: TypeSpecifierSyntax.SpecifierOptions.self)
472472
{
473473
misplacedSpecifiers.append(specifier)
474474
}
@@ -623,7 +623,7 @@ extension Parser.Lookahead {
623623
var specifierProgress = LoopProgressCondition()
624624
// TODO: Can we model isolated/_const so that they're specified in both canParse* and parse*?
625625
while canHaveParameterSpecifier,
626-
self.at(anyIn: TypeSpecifier.self) != nil || self.at(.keyword(.isolated)) || self.at(.keyword(._const)),
626+
self.at(anyIn: TypeSpecifierSyntax.SpecifierOptions.self) != nil || self.at(.keyword(.isolated)) || self.at(.keyword(._const)),
627627
self.hasProgressed(&specifierProgress)
628628
{
629629
self.consumeAnyToken()

0 commit comments

Comments
 (0)