@@ -54,13 +54,75 @@ TmGrammar toTmGrammar(RscGrammar rsc, str name, NameGeneration nameGeneration =
5454}
5555
5656RscGrammar preprocess (RscGrammar rsc ) {
57- // Replace occurrences of singleton ranges with just the corresponding
58- // literal. This makes it easier to identify delimiters.
59- return visit (rsc ) {
57+ rsc = replaceSingletonRanges (rsc );
58+ rsc = replaceCurrentSemanticTokenTypes (rsc );
59+ rsc = replaceLegacySemanticTokenTypes (rsc );
60+ return rsc ;
61+ }
62+
63+ // Replace occurrences of singleton ranges with just the corresponding literal.
64+ // This makes it easier to identify delimiters.
65+ private RscGrammar replaceSingletonRanges (RscGrammar rsc )
66+ = visit (rsc ) {
6067 case \char -class ([range (char , char )]) => d
6168 when d := \lit ("<stringChar (char )> " ), isDelimiter (d )
62- }
63- }
69+ };
70+
71+ // Replace current semantic token types with TextMate scopes based on:
72+ // - https://github.com/microsoft/vscode/blob/9f3a7b5bc8a2758584b33d0385b227f25ae8d3fb/src/vs/platform/theme/common/tokenClassificationRegistry.ts#L543-L571
73+ private RscGrammar replaceCurrentSemanticTokenTypes (RscGrammar rsc )
74+ = visit (rsc ) {
75+ case \tag ("category" ("comment" )) => \tag ("category" ("comment" ))
76+ case \tag ("category" ("string" )) => \tag ("category" ("string" ))
77+ case \tag ("category" ("keyword" )) => \tag ("category" ("keyword.control" ))
78+ case \tag ("category" ("number" )) => \tag ("category" ("constant.numeric" ))
79+ case \tag ("category" ("regexp" )) => \tag ("category" ("constant.regexp" ))
80+ case \tag ("category" ("operator" )) => \tag ("category" ("keyword.operator" ))
81+ case \tag ("category" ("namespace" )) => \tag ("category" ("entity.name.namespace" ))
82+ case \tag ("category" ("type" )) => \tag ("category" ("support.type" )) // Alternative: support.type
83+ case \tag ("category" ("struct" )) => \tag ("category" ("entity.name.type.struct" ))
84+ case \tag ("category" ("class" )) => \tag ("category" ("entity.name.type.class" )) // Alternative: support.class
85+ case \tag ("category" ("interface" )) => \tag ("category" ("entity.name.type.interface" ))
86+ case \tag ("category" ("enum" )) => \tag ("category" ("entity.name.type.enum" ))
87+ case \tag ("category" ("typeParameter" )) => \tag ("category" ("entity.name.type.parameter" ))
88+ case \tag ("category" ("function" )) => \tag ("category" ("entity.name.function" )) // Alternative: support.function
89+ case \tag ("category" ("method" )) => \tag ("category" ("entity.name.function.member" )) // Alternative: support.function
90+ case \tag ("category" ("macro" )) => \tag ("category" ("entity.name.function.preprocessor" ))
91+ case \tag ("category" ("variable" )) => \tag ("category" ("variable.other.readwrite" )) // Alternative: entity.name.variable
92+ case \tag ("category" ("parameter" )) => \tag ("category" ("variable.parameter" ))
93+ case \tag ("category" ("property" )) => \tag ("category" ("variable.other.property" ))
94+ case \tag ("category" ("enumMember" )) => \tag ("category" ("variable.other.enummember" ))
95+ case \tag ("category" ("event" )) => \tag ("category" ("variable.other.event" ))
96+ case \tag ("category" ("decorator" )) => \tag ("category" ("entity.name.decorator" )) // Alternative: entity.name.function
97+ // Note: Categories types `member` and `label` are deprecated/undefined
98+ // and therefore excluded from this mapping
99+ };
100+
101+ // Replace legacy semantic token types with TextMate scopes based on:
102+ // - https://github.com/usethesource/rascal/blob/83023f60a6eb9df7a19ccc7a4194b513ac7b7157/src/org/rascalmpl/values/parsetrees/TreeAdapter.java#L44-L59
103+ // - https://github.com/usethesource/rascal-language-servers/blob/752fea3ea09101e5b22ee426b11c5e36db880225/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/util/SemanticTokenizer.java#L121-L142
104+ // With updates based on:
105+ // - https://github.com/eclipse-lsp4j/lsp4j/blob/f235e91fbe2e45f62e185bbb9f6d21bed48eb2b9/org.eclipse.lsp4j/src/main/java/org/eclipse/lsp4j/Protocol.xtend#L5639-L5695
106+ // - https://github.com/usethesource/rascal-language-servers/blob/88be4a326128da8c81d581c2b918b4927f2185be/rascal-lsp/src/main/java/org/rascalmpl/vscode/lsp/util/SemanticTokenizer.java#L134-L152
107+ private RscGrammar replaceLegacySemanticTokenTypes (RscGrammar rsc )
108+ = visit (rsc ) {
109+ case \tag ("category" ("Normal" )) => \tag ("category" ("source" ))
110+ case \tag ("category" ("Type" )) => \tag ("category" ("type" )) // Updated (before: storage.type)
111+ case \tag ("category" ("Identifier" )) => \tag ("category" ("variable" ))
112+ case \tag ("category" ("Variable" )) => \tag ("category" ("variable" ))
113+ case \tag ("category" ("Constant" )) => \tag ("category" ("string" )) // Updated (before: constant)
114+ case \tag ("category" ("Comment" )) => \tag ("category" ("comment" ))
115+ case \tag ("category" ("Todo" )) => \tag ("category" ("comment" ))
116+ case \tag ("category" ("Quote" )) => \tag ("category" ("string" )) // Updated (before: meta.string)
117+ case \tag ("category" ("MetaAmbiguity" )) => \tag ("category" ("invalid" ))
118+ case \tag ("category" ("MetaVariable" )) => \tag ("category" ("variable" ))
119+ case \tag ("category" ("MetaKeyword" )) => \tag ("category" ("keyword" )) // Updated (before: keyword.other)
120+ case \tag ("category" ("MetaSkipped" )) => \tag ("category" ("string" ))
121+ case \tag ("category" ("NonterminalLabel" )) => \tag ("category" ("variable" )) // Updated (before: variable.parameter)
122+ case \tag ("category" ("Result" )) => \tag ("category" ("string" )) // Updated (before: text)
123+ case \tag ("category" ("StdOut" )) => \tag ("category" ("string" )) // Updated (before: text)
124+ case \tag ("category" ("StdErr" )) => \tag ("category" ("string" )) // Updated (before: text)
125+ };
64126
65127@synoposis {
66128 Analyzes Rascal grammar `rsc`. Returns a list of productions, in the form of
0 commit comments