@@ -22,7 +22,12 @@ let parserTokenSpecSetFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
22
22
for child in layoutNode. children {
23
23
if case let . token( choices, _, _) = child. kind, choices. count > 1 {
24
24
try ! ExtensionDeclSyntax ( " extension \( raw: layoutNode. kind. syntaxType) " ) {
25
- try EnumDeclSyntax ( " enum \( raw: child. name) Options: TokenSpecSet " ) {
25
+ try EnumDeclSyntax (
26
+ """
27
+ @_spi(Diagnostics)
28
+ public enum \( raw: child. name) Options: TokenSpecSet
29
+ """
30
+ ) {
26
31
for choice in choices {
27
32
switch choice {
28
33
case . keyword( let keywordText) :
@@ -70,6 +75,39 @@ let parserTokenSpecSetFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
70
75
}
71
76
}
72
77
}
78
+
79
+ try VariableDeclSyntax (
80
+ """
81
+ /// Returns a token that satisfies the `TokenSpec` of this case.
82
+ ///
83
+ /// If the token kind of this spec has variable text, e.g. for an identifier, this returns a token with empty text.
84
+ @_spi(Diagnostics)
85
+ public var tokenSyntax: TokenSyntax
86
+ """
87
+ ) {
88
+ try SwitchExprSyntax ( " switch self " ) {
89
+ for choice in choices {
90
+ switch choice {
91
+ case . keyword( let keywordText) :
92
+ let keyword = KEYWORDS . first ( where: { $0. name == keywordText } ) !
93
+ SwitchCaseSyntax (
94
+ " case . \( raw: keyword. escapedName) : return .keyword(. \( raw: keyword. escapedName) ) "
95
+ )
96
+ case . token( let tokenText) :
97
+ let token = SYNTAX_TOKEN_MAP [ tokenText] !
98
+ if token. text != nil {
99
+ SwitchCaseSyntax (
100
+ " case . \( raw: token. varOrCaseName) : return . \( raw: token. varOrCaseName) Token() "
101
+ )
102
+ } else {
103
+ SwitchCaseSyntax (
104
+ #"case . \#( raw: token. varOrCaseName) : return . \#( raw: token. varOrCaseName) ("")"#
105
+ )
106
+ }
107
+ }
108
+ }
109
+ }
110
+ }
73
111
}
74
112
}
75
113
}
0 commit comments