mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
refactor(ast): fix the lifetime annotations around Vist and VisitMut (#973)
This commit is contained in:
parent
c38a00b453
commit
903854dac0
10 changed files with 528 additions and 535 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -1820,6 +1820,7 @@ dependencies = [
|
|||
"oxc_ast",
|
||||
"oxc_formatter",
|
||||
"oxc_parser",
|
||||
"oxc_semantic",
|
||||
"oxc_span",
|
||||
"oxc_syntax",
|
||||
]
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -84,7 +84,7 @@ impl<'a> Compressor<'a> {
|
|||
Self { ast: AstBuilder::new(allocator), options, prepass: Prepass::new(allocator) }
|
||||
}
|
||||
|
||||
pub fn build<'b>(mut self, program: &'b mut Program<'a>) {
|
||||
pub fn build(mut self, program: &mut Program<'a>) {
|
||||
self.prepass.visit_program(program);
|
||||
self.visit_program(program);
|
||||
}
|
||||
|
|
@ -113,7 +113,7 @@ impl<'a> Compressor<'a> {
|
|||
/// Remove block from single line blocks
|
||||
/// `{ block } -> block`
|
||||
#[allow(clippy::only_used_in_recursion)] // `&self` is only used in recursion
|
||||
fn compress_block<'b>(&self, stmt: &'b mut Statement<'a>) {
|
||||
fn compress_block(&self, stmt: &mut Statement<'a>) {
|
||||
if let Statement::BlockStatement(block) = stmt {
|
||||
// Avoid compressing `if (x) { var x = 1 }` to `if (x) var x = 1` due to different
|
||||
// semantics according to AnnexB, which lead to different semantics.
|
||||
|
|
@ -126,18 +126,18 @@ impl<'a> Compressor<'a> {
|
|||
|
||||
/// Drop `drop_debugger` statement.
|
||||
/// Enabled by `compress.drop_debugger`
|
||||
fn drop_debugger<'b>(&mut self, stmt: &'b Statement<'a>) -> bool {
|
||||
fn drop_debugger(&mut self, stmt: &Statement<'a>) -> bool {
|
||||
matches!(stmt, Statement::DebuggerStatement(_)) && self.options.drop_debugger
|
||||
}
|
||||
|
||||
/// Drop `console.*` expressions.
|
||||
/// Enabled by `compress.drop_console
|
||||
fn drop_console<'b>(&mut self, stmt: &'b Statement<'a>) -> bool {
|
||||
fn drop_console(&mut self, stmt: &Statement<'a>) -> bool {
|
||||
self.options.drop_console
|
||||
&& matches!(stmt, Statement::ExpressionStatement(expr) if util::is_console(&expr.expression))
|
||||
}
|
||||
|
||||
fn compress_console<'b>(&mut self, expr: &'b mut Expression<'a>) -> bool {
|
||||
fn compress_console(&mut self, expr: &mut Expression<'a>) -> bool {
|
||||
if self.options.drop_console && util::is_console(expr) {
|
||||
*expr = self.create_void_0();
|
||||
true
|
||||
|
|
@ -147,7 +147,7 @@ impl<'a> Compressor<'a> {
|
|||
}
|
||||
|
||||
/// Join consecutive var statements
|
||||
fn join_vars<'b>(&mut self, stmts: &'b mut Vec<'a, Statement<'a>>) {
|
||||
fn join_vars(&mut self, stmts: &mut Vec<'a, Statement<'a>>) {
|
||||
// Collect all the consecutive ranges that contain joinable vars.
|
||||
// This is required because Rust prevents in-place vec mutation.
|
||||
let mut ranges = vec![];
|
||||
|
|
@ -201,7 +201,7 @@ impl<'a> Compressor<'a> {
|
|||
}
|
||||
|
||||
/// Transforms `while(expr)` to `for(;expr;)`
|
||||
fn compress_while<'b>(&mut self, stmt: &'b mut Statement<'a>) {
|
||||
fn compress_while(&mut self, stmt: &mut Statement<'a>) {
|
||||
let Statement::WhileStatement(while_stmt) = stmt else { return };
|
||||
if self.options.loops {
|
||||
let dummy_test = self.ast.this_expression(SPAN);
|
||||
|
|
@ -214,7 +214,7 @@ impl<'a> Compressor<'a> {
|
|||
/* Expressions */
|
||||
|
||||
/// Transforms `undefined` => `void 0`
|
||||
fn compress_undefined<'b>(&mut self, expr: &'b mut Expression<'a>) -> bool {
|
||||
fn compress_undefined(&mut self, expr: &mut Expression<'a>) -> bool {
|
||||
let Expression::Identifier(ident) = expr else { return false };
|
||||
if ident.name == "undefined" {
|
||||
// if let Some(reference_id) = ident.reference_id.clone().into_inner() {
|
||||
|
|
@ -228,7 +228,7 @@ impl<'a> Compressor<'a> {
|
|||
|
||||
/// Transforms `Infinity` => `1/0`
|
||||
#[allow(unused)]
|
||||
fn compress_infinity<'b>(&mut self, expr: &'b mut Expression<'a>) -> bool {
|
||||
fn compress_infinity(&mut self, expr: &mut Expression<'a>) -> bool {
|
||||
let Expression::Identifier(ident) = expr else { return false };
|
||||
if ident.name == "Infinity" {
|
||||
// if let Some(reference_id) = ident.reference_id.clone().into_inner() {
|
||||
|
|
@ -242,7 +242,7 @@ impl<'a> Compressor<'a> {
|
|||
|
||||
/// Transforms boolean expression `true` => `!0` `false` => `!1`
|
||||
/// Enabled by `compress.booleans`
|
||||
fn compress_boolean<'b>(&mut self, expr: &'b mut Expression<'a>) -> bool {
|
||||
fn compress_boolean(&mut self, expr: &mut Expression<'a>) -> bool {
|
||||
let Expression::BooleanLiteral(lit) = expr else { return false };
|
||||
if self.options.booleans {
|
||||
let num = self.ast.number_literal(
|
||||
|
|
@ -260,7 +260,7 @@ impl<'a> Compressor<'a> {
|
|||
|
||||
/// Transforms `typeof foo == "undefined"` into `foo === void 0`
|
||||
/// Enabled by `compress.typeofs`
|
||||
fn compress_typeof_undefined<'b>(&mut self, expr: &'b mut BinaryExpression<'a>) {
|
||||
fn compress_typeof_undefined(&mut self, expr: &mut BinaryExpression<'a>) {
|
||||
if expr.operator.is_equality() && self.options.typeofs {
|
||||
if let Expression::UnaryExpression(unary_expr) = &expr.left {
|
||||
if unary_expr.operator == UnaryOperator::Typeof {
|
||||
|
|
@ -281,13 +281,13 @@ impl<'a> Compressor<'a> {
|
|||
///
|
||||
/// `return undefined` -> `return`
|
||||
/// `return void 0` -> `return`
|
||||
fn compress_return_statement<'b>(&mut self, stmt: &'b mut ReturnStatement<'a>) {
|
||||
fn compress_return_statement(&mut self, stmt: &mut ReturnStatement<'a>) {
|
||||
if stmt.argument.as_ref().is_some_and(|expr| expr.is_undefined() || expr.is_void_0()) {
|
||||
stmt.argument = None;
|
||||
}
|
||||
}
|
||||
|
||||
fn compress_variable_declarator<'b>(&mut self, decl: &'b mut VariableDeclarator<'a>) {
|
||||
fn compress_variable_declarator(&mut self, decl: &mut VariableDeclarator<'a>) {
|
||||
if decl.kind.is_const() {
|
||||
return;
|
||||
}
|
||||
|
|
@ -303,7 +303,7 @@ impl<'a> Compressor<'a> {
|
|||
/// After reordering, expressions like 0 === x and 0 === y may have higher
|
||||
/// compression together than their original counterparts.
|
||||
#[allow(unused)]
|
||||
fn reorder_constant_expression<'b>(&self, expr: &'b mut BinaryExpression<'a>) {
|
||||
fn reorder_constant_expression(&self, expr: &mut BinaryExpression<'a>) {
|
||||
let operator = expr.operator;
|
||||
if operator.is_equality()
|
||||
|| operator.is_compare()
|
||||
|
|
@ -322,8 +322,8 @@ impl<'a> Compressor<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> VisitMut<'a, 'b> for Compressor<'a> {
|
||||
fn visit_statements(&mut self, stmts: &'b mut Vec<'a, Statement<'a>>) {
|
||||
impl<'a> VisitMut<'a> for Compressor<'a> {
|
||||
fn visit_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>) {
|
||||
stmts.retain(|stmt| {
|
||||
if self.drop_debugger(stmt) {
|
||||
return false;
|
||||
|
|
@ -341,14 +341,14 @@ impl<'a, 'b> VisitMut<'a, 'b> for Compressor<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_statement(&mut self, stmt: &'b mut Statement<'a>) {
|
||||
fn visit_statement(&mut self, stmt: &mut Statement<'a>) {
|
||||
self.compress_block(stmt);
|
||||
self.compress_while(stmt);
|
||||
self.fold_condition(stmt);
|
||||
self.visit_statement_match(stmt);
|
||||
}
|
||||
|
||||
fn visit_return_statement(&mut self, stmt: &'b mut ReturnStatement<'a>) {
|
||||
fn visit_return_statement(&mut self, stmt: &mut ReturnStatement<'a>) {
|
||||
if let Some(arg) = &mut stmt.argument {
|
||||
self.visit_expression(arg);
|
||||
}
|
||||
|
|
@ -356,14 +356,14 @@ impl<'a, 'b> VisitMut<'a, 'b> for Compressor<'a> {
|
|||
self.compress_return_statement(stmt);
|
||||
}
|
||||
|
||||
fn visit_variable_declaration(&mut self, decl: &'b mut VariableDeclaration<'a>) {
|
||||
fn visit_variable_declaration(&mut self, decl: &mut VariableDeclaration<'a>) {
|
||||
for declarator in decl.declarations.iter_mut() {
|
||||
self.visit_variable_declarator(declarator);
|
||||
self.compress_variable_declarator(declarator);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_expression(&mut self, expr: &'b mut Expression<'a>) {
|
||||
fn visit_expression(&mut self, expr: &mut Expression<'a>) {
|
||||
self.visit_expression_match(expr);
|
||||
self.compress_console(expr);
|
||||
self.fold_expression(expr);
|
||||
|
|
@ -372,7 +372,7 @@ impl<'a, 'b> VisitMut<'a, 'b> for Compressor<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_binary_expression(&mut self, expr: &'b mut BinaryExpression<'a>) {
|
||||
fn visit_binary_expression(&mut self, expr: &mut BinaryExpression<'a>) {
|
||||
self.visit_expression(&mut expr.left);
|
||||
self.visit_expression(&mut expr.right);
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ impl<'a> Prepass<'a> {
|
|||
Self { ast: AstBuilder::new(allocator) }
|
||||
}
|
||||
|
||||
fn strip_parenthesized_expression<'b>(&self, expr: &'b mut Expression<'a>) {
|
||||
fn strip_parenthesized_expression(&self, expr: &mut Expression<'a>) {
|
||||
if let Expression::ParenthesizedExpression(paren_expr) = expr {
|
||||
*expr = self.ast.move_expression(&mut paren_expr.expression);
|
||||
self.strip_parenthesized_expression(expr);
|
||||
|
|
@ -20,15 +20,15 @@ impl<'a> Prepass<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> VisitMut<'a, 'b> for Prepass<'a> {
|
||||
fn visit_statements(&mut self, stmts: &'b mut Vec<'a, Statement<'a>>) {
|
||||
impl<'a> VisitMut<'a> for Prepass<'a> {
|
||||
fn visit_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>) {
|
||||
stmts.retain(|stmt| !matches!(stmt, Statement::EmptyStatement(_)));
|
||||
for stmt in stmts.iter_mut() {
|
||||
self.visit_statement(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_expression(&mut self, expr: &'b mut Expression<'a>) {
|
||||
fn visit_expression(&mut self, expr: &mut Expression<'a>) {
|
||||
self.strip_parenthesized_expression(expr);
|
||||
self.visit_expression_match(expr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ impl<'a> SemanticBuilder<'a> {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn build(mut self, program: &'a Program<'a>) -> SemanticBuilderReturn<'a> {
|
||||
pub fn build(mut self, program: &Program<'a>) -> SemanticBuilderReturn<'a> {
|
||||
if !self.source_type.is_typescript_definition() {
|
||||
self.visit_program(program);
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ oxc_ast = { workspace = true }
|
|||
oxc_span = { workspace = true }
|
||||
oxc_allocator = { workspace = true }
|
||||
oxc_syntax = { workspace = true }
|
||||
oxc_semantic = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
oxc_parser = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use std::{env, path::Path};
|
|||
use oxc_allocator::Allocator;
|
||||
use oxc_formatter::{Formatter, FormatterOptions};
|
||||
use oxc_parser::Parser;
|
||||
use oxc_semantic::SemanticBuilder;
|
||||
use oxc_span::SourceType;
|
||||
use oxc_transformer::{TransformOptions, TransformReactOptions, TransformTarget, Transformer};
|
||||
|
||||
|
|
@ -28,11 +29,12 @@ fn main() {
|
|||
}
|
||||
|
||||
let formatter_options = FormatterOptions::default();
|
||||
let program = allocator.alloc(ret.program);
|
||||
let printed = Formatter::new(source_text.len(), formatter_options.clone()).build(program);
|
||||
let printed = Formatter::new(source_text.len(), formatter_options.clone()).build(&ret.program);
|
||||
println!("Original:\n");
|
||||
println!("{printed}");
|
||||
|
||||
let program = allocator.alloc(ret.program);
|
||||
let _ = SemanticBuilder::new(&source_text, source_type).build(program);
|
||||
let transform_options = TransformOptions {
|
||||
target: TransformTarget::ES2015,
|
||||
react: Some(TransformReactOptions::default()),
|
||||
|
|
|
|||
|
|
@ -84,13 +84,13 @@ impl<'a> Transformer<'a> {
|
|||
t
|
||||
}
|
||||
|
||||
pub fn build<'b>(mut self, program: &'b mut Program<'a>) {
|
||||
pub fn build(mut self, program: &mut Program<'a>) {
|
||||
self.visit_program(program);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> VisitMut<'a, 'b> for Transformer<'a> {
|
||||
fn visit_expression(&mut self, expr: &'b mut Expression<'a>) {
|
||||
impl<'a> VisitMut<'a> for Transformer<'a> {
|
||||
fn visit_expression(&mut self, expr: &mut Expression<'a>) {
|
||||
// self.typescript.as_mut().map(|t| t.transform_expression(expr));
|
||||
// self.react_jsx.as_mut().map(|t| t.transform_expression(expr));
|
||||
self.es2021_logical_assignment_operators.as_mut().map(|t| t.transform_expression(expr));
|
||||
|
|
@ -100,7 +100,7 @@ impl<'a, 'b> VisitMut<'a, 'b> for Transformer<'a> {
|
|||
self.visit_expression_match(expr);
|
||||
}
|
||||
|
||||
fn visit_catch_clause(&mut self, clause: &'b mut CatchClause<'a>) {
|
||||
fn visit_catch_clause(&mut self, clause: &mut CatchClause<'a>) {
|
||||
self.es2019_optional_catch_binding.as_mut().map(|t| t.transform_catch_clause(clause));
|
||||
|
||||
if let Some(param) = &mut clause.param {
|
||||
|
|
@ -109,7 +109,7 @@ impl<'a, 'b> VisitMut<'a, 'b> for Transformer<'a> {
|
|||
self.visit_statements(&mut clause.body.body);
|
||||
}
|
||||
|
||||
fn visit_object_property(&mut self, prop: &'b mut ObjectProperty<'a>) {
|
||||
fn visit_object_property(&mut self, prop: &mut ObjectProperty<'a>) {
|
||||
self.es2015_shorthand_properties.as_mut().map(|t| t.transform_object_property(prop));
|
||||
|
||||
self.visit_property_key(&mut prop.key);
|
||||
|
|
@ -119,7 +119,7 @@ impl<'a, 'b> VisitMut<'a, 'b> for Transformer<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_class_body(&mut self, class_body: &'b mut ClassBody<'a>) {
|
||||
fn visit_class_body(&mut self, class_body: &mut ClassBody<'a>) {
|
||||
self.es2022_class_static_block.as_mut().map(|t| t.transform_class_body(class_body));
|
||||
|
||||
class_body.body.iter_mut().for_each(|class_element| {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ const UNICORN_TEST_PATH: &str =
|
|||
|
||||
struct TestCase<'a> {
|
||||
source_text: &'a str,
|
||||
code: Option<Cow<'a, str>>,
|
||||
code: Option<String>,
|
||||
test_code: Option<Cow<'a, str>>,
|
||||
}
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ impl<'a> TestCase<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Visit<'a> for TestCase<'a> {
|
||||
fn visit_expression(&mut self, expr: &'a Expression<'a>) {
|
||||
fn visit_expression(&mut self, expr: &Expression<'a>) {
|
||||
match expr {
|
||||
Expression::StringLiteral(lit) => self.visit_string_literal(lit),
|
||||
Expression::TemplateLiteral(lit) => self.visit_template_literal(lit),
|
||||
|
|
@ -87,7 +87,7 @@ impl<'a> Visit<'a> for TestCase<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_call_expression(&mut self, expr: &'a CallExpression<'a>) {
|
||||
fn visit_call_expression(&mut self, expr: &CallExpression<'a>) {
|
||||
if let Expression::MemberExpression(member_expr) = &expr.callee {
|
||||
if let Expression::ArrayExpression(array_expr) = member_expr.object() {
|
||||
// ['class A {', '}'].join('\n')
|
||||
|
|
@ -100,19 +100,19 @@ impl<'a> Visit<'a> for TestCase<'a> {
|
|||
code.push_str(lit.value.as_str());
|
||||
code.push('\n');
|
||||
}
|
||||
self.code = Some(Cow::Owned(code));
|
||||
self.code = Some(code);
|
||||
self.test_code = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_object_expression(&mut self, expr: &'a ObjectExpression<'a>) {
|
||||
fn visit_object_expression(&mut self, expr: &ObjectExpression<'a>) {
|
||||
for obj_prop in &expr.properties {
|
||||
match obj_prop {
|
||||
ObjectPropertyKind::ObjectProperty(prop) => match &prop.key {
|
||||
PropertyKey::Identifier(ident) if ident.name == "code" => {
|
||||
self.code = match &prop.value {
|
||||
Expression::StringLiteral(s) => Some(Cow::Borrowed(s.value.as_str())),
|
||||
Expression::StringLiteral(s) => Some(s.value.to_string()),
|
||||
// eslint-plugin-jest use dedent to strips indentation from multi-line strings
|
||||
Expression::TaggedTemplateExpression(tag_expr) => {
|
||||
let Expression::Identifier(ident) = &tag_expr.tag else {
|
||||
|
|
@ -121,10 +121,10 @@ impl<'a> Visit<'a> for TestCase<'a> {
|
|||
if ident.name != "dedent" {
|
||||
continue;
|
||||
}
|
||||
tag_expr.quasi.quasi().map(|s| Cow::Borrowed(s.as_str()))
|
||||
tag_expr.quasi.quasi().map(ToString::to_string)
|
||||
}
|
||||
Expression::TemplateLiteral(tag_expr) => {
|
||||
tag_expr.quasi().map(|s| Cow::Borrowed(s.as_str()))
|
||||
tag_expr.quasi().map(ToString::to_string)
|
||||
}
|
||||
// handle code like ["{", "a: 1", "}"].join("\n")
|
||||
Expression::CallExpression(call_expr) => {
|
||||
|
|
@ -146,7 +146,7 @@ impl<'a> Visit<'a> for TestCase<'a> {
|
|||
let Expression::ArrayExpression(array_expr) = &member.object else {
|
||||
continue;
|
||||
};
|
||||
Some(Cow::Owned(
|
||||
Some(
|
||||
array_expr
|
||||
.elements
|
||||
.iter()
|
||||
|
|
@ -158,7 +158,7 @@ impl<'a> Visit<'a> for TestCase<'a> {
|
|||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n"),
|
||||
))
|
||||
)
|
||||
}
|
||||
_ => continue,
|
||||
}
|
||||
|
|
@ -176,24 +176,24 @@ impl<'a> Visit<'a> for TestCase<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_template_literal(&mut self, lit: &'a TemplateLiteral<'a>) {
|
||||
self.code = Some(Cow::Borrowed(lit.quasi().unwrap().as_str()));
|
||||
fn visit_template_literal(&mut self, lit: &TemplateLiteral<'a>) {
|
||||
self.code = Some(lit.quasi().unwrap().to_string());
|
||||
self.test_code = None;
|
||||
}
|
||||
|
||||
fn visit_string_literal(&mut self, lit: &'a StringLiteral) {
|
||||
self.code = Some(Cow::Borrowed(lit.value.as_str()));
|
||||
fn visit_string_literal(&mut self, lit: &StringLiteral) {
|
||||
self.code = Some(lit.value.to_string());
|
||||
self.test_code = None;
|
||||
}
|
||||
|
||||
fn visit_tagged_template_expression(&mut self, expr: &'a TaggedTemplateExpression<'a>) {
|
||||
fn visit_tagged_template_expression(&mut self, expr: &TaggedTemplateExpression<'a>) {
|
||||
let Expression::Identifier(ident) = &expr.tag else {
|
||||
return;
|
||||
};
|
||||
if ident.name != "dedent" {
|
||||
return;
|
||||
}
|
||||
self.code = expr.quasi.quasi().map(|s| Cow::Borrowed(s.as_str()));
|
||||
self.code = expr.quasi.quasi().map(std::string::ToString::to_string);
|
||||
self.test_code = None;
|
||||
}
|
||||
}
|
||||
|
|
@ -246,23 +246,23 @@ impl<'a> State<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Visit<'a> for State<'a> {
|
||||
fn visit_program(&mut self, program: &'a Program<'a>) {
|
||||
fn visit_program(&mut self, program: &Program<'a>) {
|
||||
for stmt in &program.body {
|
||||
self.visit_statement(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_statement(&mut self, stmt: &'a Statement<'a>) {
|
||||
fn visit_statement(&mut self, stmt: &Statement<'a>) {
|
||||
if let Statement::ExpressionStatement(expr_stmt) = stmt {
|
||||
self.visit_expression_statement(expr_stmt);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_expression_statement(&mut self, stmt: &'a ExpressionStatement<'a>) {
|
||||
fn visit_expression_statement(&mut self, stmt: &ExpressionStatement<'a>) {
|
||||
self.visit_expression(&stmt.expression);
|
||||
}
|
||||
|
||||
fn visit_expression(&mut self, expr: &'a Expression<'a>) {
|
||||
fn visit_expression(&mut self, expr: &Expression<'a>) {
|
||||
if let Expression::CallExpression(call_expr) = expr {
|
||||
for arg in &call_expr.arguments {
|
||||
self.visit_argument(arg);
|
||||
|
|
@ -270,7 +270,7 @@ impl<'a> Visit<'a> for State<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_argument(&mut self, arg: &'a Argument<'a>) {
|
||||
fn visit_argument(&mut self, arg: &Argument<'a>) {
|
||||
if let Argument::Expression(Expression::ObjectExpression(obj_expr)) = arg {
|
||||
for obj_prop in &obj_expr.properties {
|
||||
let ObjectPropertyKind::ObjectProperty(prop) = obj_prop else { return };
|
||||
|
|
@ -279,17 +279,17 @@ impl<'a> Visit<'a> for State<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_object_property(&mut self, prop: &'a ObjectProperty<'a>) {
|
||||
fn visit_object_property(&mut self, prop: &ObjectProperty<'a>) {
|
||||
let PropertyKey::Identifier(ident) = &prop.key else { return };
|
||||
match ident.name.as_str() {
|
||||
"valid" => {
|
||||
if let Expression::ArrayExpression(array_expr) = &prop.value {
|
||||
self.valid_tests.push(array_expr);
|
||||
self.valid_tests.push(self.alloc(array_expr));
|
||||
}
|
||||
}
|
||||
"invalid" => {
|
||||
if let Expression::ArrayExpression(array_expr) = &prop.value {
|
||||
self.invalid_tests.push(array_expr);
|
||||
self.invalid_tests.push(self.alloc(array_expr));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
|
|
|||
Loading…
Reference in a new issue