Skip to content

Commit

Permalink
refactor(transformer/es2015): move all entry points to implementation…
Browse files Browse the repository at this point in the history
… of Traverse trait
  • Loading branch information
Dunqing committed Aug 25, 2024
1 parent 7b821ec commit 557a744
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 122 deletions.
158 changes: 79 additions & 79 deletions crates/oxc_transformer/src/es2015/arrow_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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);
}

Expand All @@ -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);
Expand Down Expand Up @@ -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;
}
Expand All @@ -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>,
Expand Down Expand Up @@ -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();
}
}
56 changes: 25 additions & 31 deletions crates/oxc_transformer/src/es2015/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ mod options;

use std::rc::Rc;

pub use arrow_functions::{ArrowFunctions, ArrowFunctionsOptions};
pub use options::ES2015Options;
use arrow_functions::{ArrowFunctions, ArrowFunctionsOptions};
use options::ES2015Options;
use oxc_allocator::Vec;
use oxc_ast::ast::*;
use oxc_traverse::TraverseCtx;
use oxc_traverse::{Traverse, TraverseCtx};

use crate::context::Ctx;

#[allow(dead_code)]
pub struct ES2015<'a> {
struct ES2015<'a> {
ctx: Ctx<'a>,
options: ES2015Options,

Expand All @@ -21,7 +21,7 @@ pub struct ES2015<'a> {
}

impl<'a> ES2015<'a> {
pub fn new(options: ES2015Options, ctx: Ctx<'a>) -> Self {
fn new(options: ES2015Options, ctx: Ctx<'a>) -> Self {
Self {
arrow_functions: ArrowFunctions::new(
options.arrow_function.clone().unwrap_or_default(),
Expand All @@ -31,66 +31,60 @@ 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(
&mut self,
elem: &mut JSXElementName<'a>,
ctx: &mut TraverseCtx<'a>,
) {
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.transform_jsx_element_name(elem, ctx);
self.arrow_functions.enter_jsx_element_name(elem, ctx);
}
}

pub fn transform_declaration(&mut self, decl: &mut Declaration<'a>) {
fn enter_declaration(&mut self, decl: &mut Declaration<'a>, ctx: &mut TraverseCtx<'a>) {
if self.options.arrow_function.is_some() {
self.arrow_functions.transform_declaration(decl);
self.arrow_functions.enter_declaration(decl, ctx);
}
}

pub fn transform_expression(&mut self, expr: &mut Expression<'a>) {
fn enter_expression(&mut self, expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) {
if self.options.arrow_function.is_some() {
self.arrow_functions.transform_expression(expr);
self.arrow_functions.enter_expression(expr, ctx);
}
}

pub fn transform_expression_on_exit(
&mut self,
expr: &mut Expression<'a>,
ctx: &mut TraverseCtx<'a>,
) {
fn exit_expression(&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);
self.arrow_functions.exit_expression(expr, ctx);
}
}

pub fn transform_declaration_on_exit(&mut self, decl: &mut Declaration<'a>) {
fn exit_declaration(&mut self, decl: &mut Declaration<'a>, ctx: &mut TraverseCtx<'a>) {
if self.options.arrow_function.is_some() {
self.arrow_functions.transform_declaration_on_exit(decl);
self.arrow_functions.exit_declaration(decl, ctx);
}
}

pub fn transform_class(&mut self, class: &mut Class<'a>) {
fn enter_class(&mut self, class: &mut Class<'a>, ctx: &mut TraverseCtx<'a>) {
if self.options.arrow_function.is_some() {
self.arrow_functions.transform_class(class);
self.arrow_functions.enter_class(class, ctx);
}
}

pub fn transform_class_on_exit(&mut self, class: &mut Class<'a>) {
fn exit_class(&mut self, class: &mut Class<'a>, ctx: &mut TraverseCtx<'a>) {
if self.options.arrow_function.is_some() {
self.arrow_functions.transform_class_on_exit(class);
self.arrow_functions.exit_class(class, ctx);
}
}
}
24 changes: 12 additions & 12 deletions crates/oxc_transformer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>) {
Expand All @@ -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(
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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>) {
Expand All @@ -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(
Expand All @@ -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>) {
Expand Down

0 comments on commit 557a744

Please sign in to comment.