@@ -22,7 +22,12 @@ let parserTokenSpecSetFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
2222 for child in layoutNode. children {
2323 if case let . token( choices, _, _) = child. kind, choices. count > 1 {
2424 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+ ) {
2631 for choice in choices {
2732 switch choice {
2833 case . keyword( let keywordText) :
@@ -70,6 +75,39 @@ let parserTokenSpecSetFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
7075 }
7176 }
7277 }
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+ }
73111 }
74112 }
75113 }
0 commit comments