44
55module lang ::textmate ::Conversion
66
7- import IO ;
8-
97import Grammar ;
108import ParseTree ;
119import String ;
@@ -15,6 +13,7 @@ import util::Monitor;
1513import lang ::oniguruma ::Conversion ;
1614import lang ::oniguruma ::RegExp ;
1715import lang ::rascal ::grammar ::Util ;
16+ import lang ::rascal ::grammar ::analyze ::Categories ;
1817import lang ::rascal ::grammar ::analyze ::Delimiters ;
1918import lang ::rascal ::grammar ::analyze ::Dependencies ;
2019import lang ::rascal ::grammar ::analyze ::Newlines ;
@@ -169,28 +168,36 @@ private RscGrammar replaceLegacySemanticTokenTypes(RscGrammar rsc)
169168
170169list [ConversionUnit ] analyze (RscGrammar rsc , str name ) {
171170 str jobLabel = "Analyzing<name == "" ? "" : " (<name > )" > " ;
172- jobStart (jobLabel , work = 4 );
171+ jobStart (jobLabel , work = 6 );
173172
174- // Analyze dependencies among productions
173+ // Analyze productions
175174 jobStep (jobLabel , "Analyzing productions" );
176- Graph [Production ] graph = toGraph (rsc );
177- Production marker = prod (\empty (), [], {});
178-
179- bool hasCategory (Production p )
180- = /\tag ("category" (_)) := p ;
181- bool hasActiveCategory (Production p )
182- = hasCategory (p ) && marker in getClosestAncestors (graph , hasCategory , p , \default = just (marker ));
183- bool isNonEmpty (prod (def , _, _))
184- = !tryParse (rsc , delabel (def ), "" );
185-
186- list [Production ] prods = deps (graph )
187- .retainProds (hasActiveCategory )
188- .retainProds (isNonEmpty )
189- .getProds ();
175+ list [Production ] prods = [p | /p : prod (_, _, _) <- rsc ];
176+
177+ // Analyze categories
178+ jobStep (jobLabel , "Analyzing categories" );
179+ prods = for (p <- prods ) {
180+
181+ // If `p` has 0 or >=2 categories, then ignore `p` (unclear which
182+ // category should be used for highlighting)
183+ set [str ] categories = getCategories (rsc , p );
184+ if ({_} !:= categories || {NO_CATEGORY } == categories ) {
185+ continue ;
186+ }
190187
191- // for (p <- prods) {
192- // println("<p.def>");
193- // }
188+ // If each parent of `p` has a category, then ignore `p` (the parents of
189+ // `p` will be used for highlighting instead)
190+ set [Production ] parents = lookdown (rsc , delabel (p .def ));
191+ if (!any (parent <- parents , NO_CATEGORY in getCategories (rsc , parent ))) {
192+ continue ;
193+ }
194+
195+ append p ;
196+ }
197+
198+ // Analyze emptiness
199+ jobStep (jobLabel , "Analyzing emptiness" );
200+ prods = [p | p <- prods , !tryParse (rsc , delabel (p .def ), "" )];
194201
195202 // Analyze delimiters
196203 jobStep (jobLabel , "Analyzing delimiters" );
@@ -215,10 +222,6 @@ list[ConversionUnit] analyze(RscGrammar rsc, str name) {
215222 units += {unit (rsc , p , false , false , <nothing (), nothing ()> , <nothing (), nothing ()> ) | p <- prodsDelimiters + prodsKeywords , !isEmptyProd (p )};
216223 list [ConversionUnit ] ret = sort ([*removeStrictPrefixes (units )]);
217224
218- // for (u <- units) {
219- // println("<u.prod.def>: <u.recursive>");
220- // }
221-
222225 // Return
223226 jobEnd (jobLabel );
224227 return ret ;
0 commit comments