mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
refactor(transformer/es2015): move all entry points to implementation of Traverse trait (#5187)
This commit is contained in:
parent
d51a9549f7
commit
260c9d2712
3 changed files with 143 additions and 139 deletions
|
|
@ -65,7 +65,7 @@ use oxc_allocator::Vec;
|
|||
use oxc_ast::ast::*;
|
||||
use oxc_span::SPAN;
|
||||
use oxc_syntax::{scope::ScopeFlags, symbol::SymbolFlags};
|
||||
use oxc_traverse::TraverseCtx;
|
||||
use oxc_traverse::{Traverse, TraverseCtx};
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::{context::Ctx, helpers::bindings::BoundIdentifier};
|
||||
|
|
@ -94,23 +94,14 @@ impl<'a> ArrowFunctions<'a> {
|
|||
pub fn new(options: ArrowFunctionsOptions, ctx: Ctx<'a>) -> Self {
|
||||
Self { ctx, _options: options, this_var: None, stacks: vec![], this_statements: vec![] }
|
||||
}
|
||||
}
|
||||
|
||||
fn is_inside_arrow_function(&self) -> bool {
|
||||
self.stacks.last().copied().unwrap_or(false)
|
||||
}
|
||||
|
||||
fn get_this_name(&mut self, ctx: &mut TraverseCtx<'a>) -> BoundIdentifier<'a> {
|
||||
if self.this_var.is_none() {
|
||||
self.this_var = Some(BoundIdentifier::new_uid_in_current_scope(
|
||||
"this",
|
||||
SymbolFlags::FunctionScopedVariable,
|
||||
ctx,
|
||||
));
|
||||
}
|
||||
self.this_var.as_ref().unwrap().clone()
|
||||
}
|
||||
|
||||
pub fn transform_statements(&mut self, _stmts: &mut Vec<'a, Statement<'a>>) {
|
||||
impl<'a> Traverse<'a> for ArrowFunctions<'a> {
|
||||
fn enter_statements(
|
||||
&mut self,
|
||||
_stmts: &mut Vec<'a, Statement<'a>>,
|
||||
_ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
self.this_statements.push(None);
|
||||
}
|
||||
|
||||
|
|
@ -125,7 +116,7 @@ impl<'a> ArrowFunctions<'a> {
|
|||
/// }
|
||||
/// ```
|
||||
/// Insert the var _this = this; statement outside the arrow function
|
||||
pub fn transform_statements_on_exit(&mut self, stmts: &mut Vec<'a, Statement<'a>>) {
|
||||
fn exit_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, _ctx: &mut TraverseCtx<'a>) {
|
||||
// Insert the var _this = this;
|
||||
if let Some(Some(stmt)) = self.this_statements.pop() {
|
||||
stmts.insert(0, stmt);
|
||||
|
|
@ -171,11 +162,7 @@ impl<'a> ArrowFunctions<'a> {
|
|||
}
|
||||
|
||||
/// Change <this></this> to <_this></_this>, and mark it as found
|
||||
pub fn transform_jsx_element_name(
|
||||
&mut self,
|
||||
name: &mut JSXElementName<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
fn enter_jsx_element_name(&mut self, name: &mut JSXElementName<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
if !self.is_inside_arrow_function() {
|
||||
return;
|
||||
}
|
||||
|
|
@ -199,6 +186,75 @@ impl<'a> ArrowFunctions<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn enter_expression(&mut self, expr: &mut Expression<'a>, _ctx: &mut TraverseCtx<'a>) {
|
||||
match expr {
|
||||
Expression::ArrowFunctionExpression(_) => {
|
||||
self.stacks.push(true);
|
||||
}
|
||||
Expression::FunctionExpression(_) => self.stacks.push(false),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn exit_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
match expr {
|
||||
Expression::ThisExpression(this_expr) => {
|
||||
if !self.is_inside_arrow_function() {
|
||||
return;
|
||||
}
|
||||
|
||||
let ident =
|
||||
self.get_this_name(ctx).create_spanned_read_reference(this_expr.span, ctx);
|
||||
*expr = self.ctx.ast.expression_from_identifier_reference(ident);
|
||||
}
|
||||
Expression::ArrowFunctionExpression(arrow_function_expr) => {
|
||||
*expr = self.transform_arrow_function_expression(arrow_function_expr, ctx);
|
||||
self.stacks.pop();
|
||||
}
|
||||
Expression::FunctionExpression(_) => {
|
||||
self.stacks.pop();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn enter_declaration(&mut self, decl: &mut Declaration<'a>, _ctx: &mut TraverseCtx<'a>) {
|
||||
if let Declaration::FunctionDeclaration(_) = decl {
|
||||
self.stacks.push(false);
|
||||
}
|
||||
}
|
||||
|
||||
fn exit_declaration(&mut self, decl: &mut Declaration<'a>, _ctx: &mut TraverseCtx<'a>) {
|
||||
if let Declaration::FunctionDeclaration(_) = decl {
|
||||
self.stacks.pop();
|
||||
}
|
||||
}
|
||||
|
||||
fn enter_class(&mut self, _class: &mut Class<'a>, _ctx: &mut TraverseCtx<'a>) {
|
||||
self.stacks.push(false);
|
||||
}
|
||||
|
||||
fn exit_class(&mut self, _class: &mut Class<'a>, _ctx: &mut TraverseCtx<'a>) {
|
||||
self.stacks.pop();
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ArrowFunctions<'a> {
|
||||
fn is_inside_arrow_function(&self) -> bool {
|
||||
self.stacks.last().copied().unwrap_or(false)
|
||||
}
|
||||
|
||||
fn get_this_name(&mut self, ctx: &mut TraverseCtx<'a>) -> BoundIdentifier<'a> {
|
||||
if self.this_var.is_none() {
|
||||
self.this_var = Some(BoundIdentifier::new_uid_in_current_scope(
|
||||
"this",
|
||||
SymbolFlags::FunctionScopedVariable,
|
||||
ctx,
|
||||
));
|
||||
}
|
||||
self.this_var.as_ref().unwrap().clone()
|
||||
}
|
||||
|
||||
fn transform_arrow_function_expression(
|
||||
&mut self,
|
||||
arrow_function_expr: &mut ArrowFunctionExpression<'a>,
|
||||
|
|
@ -259,60 +315,4 @@ impl<'a> ArrowFunctions<'a> {
|
|||
// `() => {};` => `(function () {});`
|
||||
self.ctx.ast.expression_parenthesized(SPAN, expr)
|
||||
}
|
||||
|
||||
pub fn transform_expression(&mut self, expr: &mut Expression<'a>) {
|
||||
match expr {
|
||||
Expression::ArrowFunctionExpression(_) => {
|
||||
self.stacks.push(true);
|
||||
}
|
||||
Expression::FunctionExpression(_) => self.stacks.push(false),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn transform_expression_on_exit(
|
||||
&mut self,
|
||||
expr: &mut Expression<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
match expr {
|
||||
Expression::ThisExpression(this_expr) => {
|
||||
if !self.is_inside_arrow_function() {
|
||||
return;
|
||||
}
|
||||
|
||||
let ident =
|
||||
self.get_this_name(ctx).create_spanned_read_reference(this_expr.span, ctx);
|
||||
*expr = self.ctx.ast.expression_from_identifier_reference(ident);
|
||||
}
|
||||
Expression::ArrowFunctionExpression(arrow_function_expr) => {
|
||||
*expr = self.transform_arrow_function_expression(arrow_function_expr, ctx);
|
||||
self.stacks.pop();
|
||||
}
|
||||
Expression::FunctionExpression(_) => {
|
||||
self.stacks.pop();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn transform_declaration(&mut self, decl: &mut Declaration<'a>) {
|
||||
if let Declaration::FunctionDeclaration(_) = decl {
|
||||
self.stacks.push(false);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn transform_declaration_on_exit(&mut self, decl: &mut Declaration<'a>) {
|
||||
if let Declaration::FunctionDeclaration(_) = decl {
|
||||
self.stacks.pop();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn transform_class(&mut self, _class: &mut Class<'a>) {
|
||||
self.stacks.push(false);
|
||||
}
|
||||
|
||||
pub fn transform_class_on_exit(&mut self, _class: &mut Class<'a>) {
|
||||
self.stacks.pop();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ pub use arrow_functions::{ArrowFunctions, ArrowFunctionsOptions};
|
|||
pub use options::ES2015Options;
|
||||
use oxc_allocator::Vec;
|
||||
use oxc_ast::ast::*;
|
||||
use oxc_traverse::TraverseCtx;
|
||||
use oxc_traverse::{Traverse, TraverseCtx};
|
||||
|
||||
use crate::context::Ctx;
|
||||
|
||||
|
|
@ -31,66 +31,70 @@ impl<'a> ES2015<'a> {
|
|||
options,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn enter_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>) {
|
||||
impl<'a> Traverse<'a> for ES2015<'a> {
|
||||
fn enter_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, ctx: &mut TraverseCtx<'a>) {
|
||||
if self.options.arrow_function.is_some() {
|
||||
self.arrow_functions.transform_statements(stmts);
|
||||
self.arrow_functions.enter_statements(stmts, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn exit_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>) {
|
||||
fn exit_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, ctx: &mut TraverseCtx<'a>) {
|
||||
if self.options.arrow_function.is_some() {
|
||||
self.arrow_functions.transform_statements_on_exit(stmts);
|
||||
self.arrow_functions.exit_statements(stmts, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn transform_jsx_element_name(
|
||||
fn enter_jsx_element_name(&mut self, elem: &mut JSXElementName<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
if self.options.arrow_function.is_some() {
|
||||
self.arrow_functions.enter_jsx_element_name(elem, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
fn enter_declaration(&mut self, decl: &mut Declaration<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
if self.options.arrow_function.is_some() {
|
||||
self.arrow_functions.enter_declaration(decl, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
fn enter_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
if self.options.arrow_function.is_some() {
|
||||
self.arrow_functions.enter_expression(expr, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
fn exit_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
if self.options.arrow_function.is_some() {
|
||||
self.arrow_functions.exit_expression(expr, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
fn exit_declaration(&mut self, decl: &mut Declaration<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
if self.options.arrow_function.is_some() {
|
||||
self.arrow_functions.exit_declaration(decl, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
fn enter_class(&mut self, class: &mut Class<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
if self.options.arrow_function.is_some() {
|
||||
self.arrow_functions.enter_class(class, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
fn exit_class(&mut self, class: &mut Class<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
if self.options.arrow_function.is_some() {
|
||||
self.arrow_functions.exit_class(class, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
fn enter_variable_declarator(
|
||||
&mut self,
|
||||
elem: &mut JSXElementName<'a>,
|
||||
node: &mut VariableDeclarator<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
if self.options.arrow_function.is_some() {
|
||||
self.arrow_functions.transform_jsx_element_name(elem, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn transform_declaration(&mut self, decl: &mut Declaration<'a>) {
|
||||
if self.options.arrow_function.is_some() {
|
||||
self.arrow_functions.transform_declaration(decl);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn transform_expression(&mut self, expr: &mut Expression<'a>) {
|
||||
if self.options.arrow_function.is_some() {
|
||||
self.arrow_functions.transform_expression(expr);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn transform_expression_on_exit(
|
||||
&mut self,
|
||||
expr: &mut Expression<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
if self.options.arrow_function.is_some() {
|
||||
self.arrow_functions.transform_expression_on_exit(expr, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn transform_declaration_on_exit(&mut self, decl: &mut Declaration<'a>) {
|
||||
if self.options.arrow_function.is_some() {
|
||||
self.arrow_functions.transform_declaration_on_exit(decl);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn transform_class(&mut self, class: &mut Class<'a>) {
|
||||
if self.options.arrow_function.is_some() {
|
||||
self.arrow_functions.transform_class(class);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn transform_class_on_exit(&mut self, class: &mut Class<'a>) {
|
||||
if self.options.arrow_function.is_some() {
|
||||
self.arrow_functions.transform_class_on_exit(class);
|
||||
self.arrow_functions.enter_variable_declarator(node, ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,13 +144,13 @@ impl<'a> Traverse<'a> for Transformer<'a> {
|
|||
self.x1_react.transform_call_expression(expr, ctx);
|
||||
}
|
||||
|
||||
fn enter_class(&mut self, class: &mut Class<'a>, _ctx: &mut TraverseCtx<'a>) {
|
||||
fn enter_class(&mut self, class: &mut Class<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.transform_class(class);
|
||||
self.x3_es2015.transform_class(class);
|
||||
self.x3_es2015.enter_class(class, ctx);
|
||||
}
|
||||
|
||||
fn exit_class(&mut self, class: &mut Class<'a>, _ctx: &mut TraverseCtx<'a>) {
|
||||
self.x3_es2015.transform_class_on_exit(class);
|
||||
fn exit_class(&mut self, class: &mut Class<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x3_es2015.exit_class(class, ctx);
|
||||
}
|
||||
|
||||
fn enter_class_body(&mut self, body: &mut ClassBody<'a>, _ctx: &mut TraverseCtx<'a>) {
|
||||
|
|
@ -170,12 +170,12 @@ impl<'a> Traverse<'a> for Transformer<'a> {
|
|||
self.x2_es2021.enter_expression(expr, ctx);
|
||||
self.x2_es2020.enter_expression(expr, ctx);
|
||||
self.x2_es2016.enter_expression(expr, ctx);
|
||||
self.x3_es2015.transform_expression(expr);
|
||||
self.x3_es2015.enter_expression(expr, ctx);
|
||||
}
|
||||
|
||||
fn exit_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x1_react.transform_expression_on_exit(expr, ctx);
|
||||
self.x3_es2015.transform_expression_on_exit(expr, ctx);
|
||||
self.x3_es2015.exit_expression(expr, ctx);
|
||||
}
|
||||
|
||||
fn enter_simple_assignment_target(
|
||||
|
|
@ -224,7 +224,7 @@ impl<'a> Traverse<'a> for Transformer<'a> {
|
|||
}
|
||||
|
||||
fn enter_jsx_element_name(&mut self, elem: &mut JSXElementName<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x3_es2015.transform_jsx_element_name(elem, ctx);
|
||||
self.x3_es2015.enter_jsx_element_name(elem, ctx);
|
||||
}
|
||||
|
||||
fn enter_method_definition(
|
||||
|
|
@ -261,7 +261,7 @@ impl<'a> Traverse<'a> for Transformer<'a> {
|
|||
self.x2_es2021.enter_statements(stmts, ctx);
|
||||
self.x2_es2020.enter_statements(stmts, ctx);
|
||||
self.x2_es2016.enter_statements(stmts, ctx);
|
||||
self.x3_es2015.enter_statements(stmts);
|
||||
self.x3_es2015.enter_statements(stmts, ctx);
|
||||
}
|
||||
|
||||
fn exit_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, ctx: &mut TraverseCtx<'a>) {
|
||||
|
|
@ -270,7 +270,7 @@ impl<'a> Traverse<'a> for Transformer<'a> {
|
|||
self.x2_es2021.exit_statements(stmts, ctx);
|
||||
self.x2_es2020.exit_statements(stmts, ctx);
|
||||
self.x2_es2016.exit_statements(stmts, ctx);
|
||||
self.x3_es2015.exit_statements(stmts);
|
||||
self.x3_es2015.exit_statements(stmts, ctx);
|
||||
}
|
||||
|
||||
fn enter_tagged_template_expression(
|
||||
|
|
@ -287,11 +287,11 @@ impl<'a> Traverse<'a> for Transformer<'a> {
|
|||
|
||||
fn enter_declaration(&mut self, decl: &mut Declaration<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x0_typescript.transform_declaration(decl, ctx);
|
||||
self.x3_es2015.transform_declaration(decl);
|
||||
self.x3_es2015.enter_declaration(decl, ctx);
|
||||
}
|
||||
|
||||
fn exit_declaration(&mut self, decl: &mut Declaration<'a>, _ctx: &mut TraverseCtx<'a>) {
|
||||
self.x3_es2015.transform_declaration_on_exit(decl);
|
||||
fn exit_declaration(&mut self, decl: &mut Declaration<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
self.x3_es2015.exit_declaration(decl, ctx);
|
||||
}
|
||||
|
||||
fn enter_if_statement(&mut self, stmt: &mut IfStatement<'a>, ctx: &mut TraverseCtx<'a>) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue