Skip to content

Commit 8a8abe0

Browse files
committed
refactor(coverage): add a visitor for checking ast nodes
1 parent c44c732 commit 8a8abe0

File tree

1 file changed

+65
-30
lines changed

1 file changed

+65
-30
lines changed

tasks/coverage/src/driver.rs

Lines changed: 65 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,17 @@ use rustc_hash::FxHashSet;
55
use 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

Comments
 (0)