@@ -5,13 +5,17 @@ use rustc_hash::FxHashSet;
55use oxc:: {
66 CompilerInterface ,
77 allocator:: Allocator ,
8- ast:: { AstKind , Comment , ast:: Program } ,
8+ ast:: {
9+ AstKind , Comment ,
10+ ast:: { Program , RegExpLiteral } ,
11+ } ,
12+ ast_visit:: { Visit , walk} ,
913 codegen:: { CodegenOptions , CodegenReturn } ,
1014 diagnostics:: OxcDiagnostic ,
1115 minifier:: CompressOptions ,
1216 parser:: { ParseOptions , ParserReturn } ,
1317 regular_expression:: { LiteralParser , Options } ,
14- semantic:: { Semantic , SemanticBuilderReturn } ,
18+ semantic:: SemanticBuilderReturn ,
1519 span:: { ContentEq , SourceType , Span } ,
1620 transformer:: { TransformOptions , TransformerReturn } ,
1721} ;
@@ -69,6 +73,7 @@ impl CompilerInterface for Driver {
6973 fn after_parse ( & mut self , parser_return : & mut ParserReturn ) -> ControlFlow < ( ) > {
7074 let ParserReturn { program, panicked, errors, .. } = parser_return;
7175 self . panicked = * panicked;
76+ self . check_ast_nodes ( program) ;
7277 if self . check_comments ( & program. comments ) {
7378 return ControlFlow :: Break ( ( ) ) ;
7479 }
@@ -93,7 +98,6 @@ impl CompilerInterface for Driver {
9398 return ControlFlow :: Break ( ( ) ) ;
9499 }
95100 }
96- self . check_regular_expressions ( & ret. semantic ) ;
97101 ControlFlow :: Continue ( ( ) )
98102 }
99103
@@ -157,39 +161,70 @@ impl Driver {
157161 false
158162 }
159163
164+ fn check_ast_nodes ( & mut self , program : & Program < ' _ > ) {
165+ CheckASTNodes :: new ( self , program. source_text ) . check ( program) ;
166+ }
167+ }
168+
169+ struct CheckASTNodes < ' a > {
170+ driver : & ' a mut Driver ,
171+ source_text : & ' a str ,
172+ allocator : Allocator ,
173+ }
174+
175+ impl < ' a > CheckASTNodes < ' a > {
176+ fn new ( driver : & ' a mut Driver , source_text : & ' a str ) -> Self {
177+ Self { driver, source_text, allocator : Allocator :: default ( ) }
178+ }
179+
180+ fn check ( & mut self , program : & Program < ' a > ) {
181+ self . visit_program ( program) ;
182+ }
183+ }
184+
185+ impl < ' a > Visit < ' a > for CheckASTNodes < ' a > {
186+ // TODO: This is too slow
187+ // fn visit_span(&mut self, span: &Span) {
188+ // let Span { start, end, .. } = span;
189+ // if *end >= *start {
190+ // self.driver.errors.push(
191+ // OxcDiagnostic::error(format!("Span end {end} >= start {start}",)).with_label(*span),
192+ // );
193+ // }
194+ // }
195+
160196 /// Idempotency test for printing regular expressions.
161- fn check_regular_expressions ( & mut self , semantic : & Semantic < ' _ > ) {
162- let allocator = Allocator :: default ( ) ;
163- for literal in semantic . nodes ( ) . iter ( ) . filter_map ( |node| node . kind ( ) . as_reg_exp_literal ( ) ) {
164- let Some ( pattern) = literal. regex . pattern . as_pattern ( ) else {
165- continue ;
166- } ;
167- let printed1 = pattern. to_string ( ) ;
168- let flags = literal. regex . flags . to_inline_string ( ) ;
169- match LiteralParser :: new ( & allocator, & printed1, Some ( & flags) , Options :: default ( ) )
170- . parse ( )
171- {
172- Ok ( pattern2) => {
173- let printed2 = pattern2. to_string ( ) ;
174- if !pattern2. content_eq ( pattern) {
175- self . errors . push ( OxcDiagnostic :: error ( format ! (
197+ fn visit_reg_exp_literal ( & mut self , literal : & RegExpLiteral < ' a > ) {
198+ walk :: walk_reg_exp_literal ( self , literal ) ;
199+
200+ let Some ( pattern) = literal. regex . pattern . as_pattern ( ) else {
201+ return ;
202+ } ;
203+ let printed1 = pattern. to_string ( ) ;
204+ let flags = literal. regex . flags . to_inline_string ( ) ;
205+ match LiteralParser :: new ( & self . allocator , & printed1, Some ( & flags) , Options :: default ( ) )
206+ . parse ( )
207+ {
208+ Ok ( pattern2) => {
209+ let printed2 = pattern2. to_string ( ) ;
210+ if !pattern2. content_eq ( pattern) {
211+ self . driver . errors . push ( OxcDiagnostic :: error ( format ! (
176212 "Regular Expression content mismatch for `{}`: `{pattern}` == `{pattern2}`" ,
177- literal. span. source_text( semantic. source_text( ) )
178- ) ) ) ;
179- }
180- if printed1 != printed2 {
181- self . errors . push ( OxcDiagnostic :: error ( format ! (
182- "Regular Expression mismatch: {printed1} {printed2}"
183- ) ) ) ;
184- }
213+ literal. span. source_text( self . source_text)
214+ ) ) ) ;
185215 }
186- Err ( error) => {
187- self . errors . push ( OxcDiagnostic :: error ( format ! (
188- "Failed to re-parse `{}`, printed as `/{printed1}/{flags}`, {error}" ,
189- literal. span. source_text( semantic. source_text( ) ) ,
216+ if printed1 != printed2 {
217+ self . driver . errors . push ( OxcDiagnostic :: error ( format ! (
218+ "Regular Expression mismatch: {printed1} {printed2}"
190219 ) ) ) ;
191220 }
192221 }
222+ Err ( error) => {
223+ self . driver . errors . push ( OxcDiagnostic :: error ( format ! (
224+ "Failed to re-parse `{}`, printed as `/{printed1}/{flags}`, {error}" ,
225+ literal. span. source_text( self . source_text) ,
226+ ) ) ) ;
227+ }
193228 }
194229 }
195230}
0 commit comments