Skip to content

Commit

Permalink
refactor(transform): transformer use Traverse (#3182)
Browse files Browse the repository at this point in the history
Sliced off from #3152.

This switches the transformer over to use `Traverse` instead of
`VisitMut`.

This is incomplete - scopes are not implemented yet. At present, no
transforms use scopes anyway, so all tests pass, but regardless I don't
think should be merged until the implementation is complete.
  • Loading branch information
overlookmotel authored May 8, 2024
1 parent 5683ace commit be958ce
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 82 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/oxc_transformer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ oxc_span = { workspace = true }
oxc_allocator = { workspace = true }
oxc_diagnostics = { workspace = true }
oxc_syntax = { workspace = true, features = ["to_js_string"] }
oxc_traverse = { workspace = true }

rustc-hash = { workspace = true }
indexmap = { workspace = true }
Expand Down
161 changes: 81 additions & 80 deletions crates/oxc_transformer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,11 @@ use std::{path::Path, rc::Rc};

use es2015::ES2015;
use oxc_allocator::{Allocator, Vec};
use oxc_ast::{
ast::*,
visit::{walk_mut, VisitMut},
Trivias,
};
use oxc_ast::{ast::*, Trivias};
use oxc_diagnostics::Error;
use oxc_span::SourceType;
use oxc_syntax::scope::ScopeFlags;
// use oxc_syntax::scope::ScopeFlags;
use oxc_traverse::{traverse_mut, Traverse, TraverseCtx};

pub use crate::{
compiler_assumptions::CompilerAssumptions, es2015::ES2015Options, options::TransformOptions,
Expand Down Expand Up @@ -82,7 +79,9 @@ impl<'a> Transformer<'a> {
///
/// Returns `Vec<Error>` if any errors were collected during the transformation.
pub fn build(mut self, program: &mut Program<'a>) -> Result<(), std::vec::Vec<Error>> {
self.visit_program(program);
let allocator = self.ctx.ast.allocator;
traverse_mut(&mut self, program, allocator);

let errors = self.ctx.take_errors();
if errors.is_empty() {
Ok(())
Expand All @@ -92,167 +91,169 @@ impl<'a> Transformer<'a> {
}
}

impl<'a> VisitMut<'a> for Transformer<'a> {
fn visit_program(&mut self, program: &mut Program<'a>) {
impl<'a> Traverse<'a> for Transformer<'a> {
fn enter_program(&mut self, program: &mut Program<'a>, _ctx: &TraverseCtx<'a>) {
self.x0_typescript.transform_program(program);
}

walk_mut::walk_program_mut(self, program);

fn exit_program(&mut self, program: &mut Program<'a>, _ctx: &TraverseCtx<'a>) {
self.x1_react.transform_program_on_exit(program);
self.x0_typescript.transform_program_on_exit(program);
}

// ALPHASORT

fn visit_arrow_expression(&mut self, expr: &mut ArrowFunctionExpression<'a>) {
fn enter_arrow_function_expression(
&mut self,
expr: &mut ArrowFunctionExpression<'a>,
_ctx: &TraverseCtx<'a>,
) {
self.x0_typescript.transform_arrow_expression(expr);

walk_mut::walk_arrow_expression_mut(self, expr);
}

fn visit_binding_pattern(&mut self, pat: &mut BindingPattern<'a>) {
fn enter_binding_pattern(&mut self, pat: &mut BindingPattern<'a>, _ctx: &TraverseCtx<'a>) {
self.x0_typescript.transform_binding_pattern(pat);

walk_mut::walk_binding_pattern_mut(self, pat);
}

fn visit_call_expression(&mut self, expr: &mut CallExpression<'a>) {
fn enter_call_expression(&mut self, expr: &mut CallExpression<'a>, _ctx: &TraverseCtx<'a>) {
self.x0_typescript.transform_call_expression(expr);

walk_mut::walk_call_expression_mut(self, expr);
}

fn visit_class(&mut self, class: &mut Class<'a>) {
fn enter_class(&mut self, class: &mut Class<'a>, _ctx: &TraverseCtx<'a>) {
self.x0_typescript.transform_class(class);
self.x3_es2015.transform_class(class);
}

walk_mut::walk_class_mut(self, class);

fn exit_class(&mut self, class: &mut Class<'a>, _ctx: &TraverseCtx<'a>) {
self.x3_es2015.transform_class_on_exit(class);
}

fn visit_class_body(&mut self, body: &mut ClassBody<'a>) {
fn enter_class_body(&mut self, body: &mut ClassBody<'a>, _ctx: &TraverseCtx<'a>) {
self.x0_typescript.transform_class_body(body);

walk_mut::walk_class_body_mut(self, body);
}

fn visit_export_default_declaration(&mut self, decl: &mut ExportDefaultDeclaration<'a>) {
fn enter_export_default_declaration(
&mut self,
decl: &mut ExportDefaultDeclaration<'a>,
_ctx: &TraverseCtx<'a>,
) {
self.x1_react.transform_export_default_declaration(decl);

walk_mut::walk_export_default_declaration_mut(self, decl);
}

fn visit_export_named_declaration(&mut self, decl: &mut ExportNamedDeclaration<'a>) {
fn enter_export_named_declaration(
&mut self,
decl: &mut ExportNamedDeclaration<'a>,
_ctx: &TraverseCtx<'a>,
) {
self.x0_typescript.transform_export_named_declaration(decl);

walk_mut::walk_export_named_declaration_mut(self, decl);
}

fn visit_expression(&mut self, expr: &mut Expression<'a>) {
fn enter_expression(&mut self, expr: &mut Expression<'a>, _ctx: &TraverseCtx<'a>) {
self.x0_typescript.transform_expression(expr);
self.x1_react.transform_expression(expr);
self.x3_es2015.transform_expression(expr);
}

walk_mut::walk_expression_mut(self, expr);

fn exit_expression(&mut self, expr: &mut Expression<'a>, _ctx: &TraverseCtx<'a>) {
self.x3_es2015.transform_expression_on_exit(expr);
}

fn visit_formal_parameter(&mut self, param: &mut FormalParameter<'a>) {
fn enter_formal_parameter(&mut self, param: &mut FormalParameter<'a>, _ctx: &TraverseCtx<'a>) {
self.x0_typescript.transform_formal_parameter(param);

walk_mut::walk_formal_parameter_mut(self, param);
}

fn visit_function(&mut self, func: &mut Function<'a>, flags: Option<ScopeFlags>) {
fn enter_function(&mut self, func: &mut Function<'a>, _ctx: &TraverseCtx<'a>) {
// TODO: Scope flags
// Was a function param: flags: Option<ScopeFlags>,
let flags = None;
self.x0_typescript.transform_function(func, flags);

walk_mut::walk_function_mut(self, func, flags);
}

fn visit_import_declaration(&mut self, decl: &mut ImportDeclaration<'a>) {
walk_mut::walk_import_declaration_mut(self, decl);
}

fn visit_jsx_opening_element(&mut self, elem: &mut JSXOpeningElement<'a>) {
fn enter_jsx_opening_element(
&mut self,
elem: &mut JSXOpeningElement<'a>,
_ctx: &TraverseCtx<'a>,
) {
self.x0_typescript.transform_jsx_opening_element(elem);
self.x1_react.transform_jsx_opening_element(elem);
self.x3_es2015.transform_jsx_opening_element(elem);
walk_mut::walk_jsx_opening_element_mut(self, elem);
}

fn visit_method_definition(&mut self, def: &mut MethodDefinition<'a>) {
fn enter_method_definition(&mut self, def: &mut MethodDefinition<'a>, _ctx: &TraverseCtx<'a>) {
self.x0_typescript.transform_method_definition(def);
}

walk_mut::walk_method_definition_mut(self, def);

fn exit_method_definition(&mut self, def: &mut MethodDefinition<'a>, _ctx: &TraverseCtx<'a>) {
self.x0_typescript.transform_method_definition_on_exit(def);
}

fn visit_new_expression(&mut self, expr: &mut NewExpression<'a>) {
fn enter_new_expression(&mut self, expr: &mut NewExpression<'a>, _ctx: &TraverseCtx<'a>) {
self.x0_typescript.transform_new_expression(expr);

walk_mut::walk_new_expression_mut(self, expr);
}

fn visit_object_property(&mut self, prop: &mut ObjectProperty<'a>) {
fn enter_object_property(&mut self, prop: &mut ObjectProperty<'a>, _ctx: &TraverseCtx<'a>) {
self.x1_react.transform_object_property(prop);

walk_mut::walk_object_property_mut(self, prop);
}

fn visit_property_definition(&mut self, def: &mut PropertyDefinition<'a>) {
fn enter_property_definition(
&mut self,
def: &mut PropertyDefinition<'a>,
_ctx: &TraverseCtx<'a>,
) {
self.x0_typescript.transform_property_definition(def);

walk_mut::walk_property_definition_mut(self, def);
}

fn visit_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>) {
walk_mut::walk_statements_mut(self, stmts);

fn exit_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, _ctx: &TraverseCtx<'a>) {
self.x0_typescript.transform_statements_on_exit(stmts);
self.x3_es2015.transform_statements_on_exit(stmts);
}

fn visit_tagged_template_expression(&mut self, expr: &mut TaggedTemplateExpression<'a>) {
fn enter_tagged_template_expression(
&mut self,
expr: &mut TaggedTemplateExpression<'a>,
_ctx: &TraverseCtx<'a>,
) {
self.x0_typescript.transform_tagged_template_expression(expr);

walk_mut::walk_tagged_template_expression_mut(self, expr);
}

fn visit_variable_declarator(&mut self, declarator: &mut VariableDeclarator<'a>) {
fn enter_variable_declarator(
&mut self,
declarator: &mut VariableDeclarator<'a>,
_ctx: &TraverseCtx<'a>,
) {
self.x1_react.transform_variable_declarator(declarator);

walk_mut::walk_variable_declarator_mut(self, declarator);
}

fn visit_identifier_reference(&mut self, ident: &mut IdentifierReference<'a>) {
self.x0_typescript.transform_identifier_reference(ident);
walk_mut::walk_identifier_reference_mut(self, ident);
fn enter_identifier_reference(
&mut self,
ident: &mut IdentifierReference<'a>,
ctx: &TraverseCtx<'a>,
) {
self.x0_typescript.transform_identifier_reference(ident, ctx);
}

fn visit_statement(&mut self, stmt: &mut Statement<'a>) {
fn enter_statement(&mut self, stmt: &mut Statement<'a>, _ctx: &TraverseCtx<'a>) {
self.x0_typescript.transform_statement(stmt);
walk_mut::walk_statement_mut(self, stmt);
}

fn visit_declaration(&mut self, decl: &mut Declaration<'a>) {
fn enter_declaration(&mut self, decl: &mut Declaration<'a>, _ctx: &TraverseCtx<'a>) {
self.x0_typescript.transform_declaration(decl);
self.x3_es2015.transform_declaration(decl);
}

walk_mut::walk_declaration_mut(self, decl);

fn exit_declaration(&mut self, decl: &mut Declaration<'a>, _ctx: &TraverseCtx<'a>) {
self.x3_es2015.transform_declaration_on_exit(decl);
}

fn visit_if_statement(&mut self, stmt: &mut IfStatement<'a>) {
fn enter_if_statement(&mut self, stmt: &mut IfStatement<'a>, _ctx: &TraverseCtx<'a>) {
self.x0_typescript.transform_if_statement(stmt);
walk_mut::walk_if_statement_mut(self, stmt);
}

fn visit_module_declaration(&mut self, decl: &mut ModuleDeclaration<'a>) {
fn enter_module_declaration(
&mut self,
decl: &mut ModuleDeclaration<'a>,
_ctx: &TraverseCtx<'a>,
) {
self.x0_typescript.transform_module_declaration(decl);
walk_mut::walk_module_declaration_mut(self, decl);
}
}
11 changes: 9 additions & 2 deletions crates/oxc_transformer/src/typescript/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use serde::Deserialize;
use oxc_allocator::Vec;
use oxc_ast::ast::*;
use oxc_syntax::scope::ScopeFlags;
use oxc_traverse::TraverseCtx;

use crate::context::Ctx;

Expand Down Expand Up @@ -184,8 +185,14 @@ impl<'a> TypeScript<'a> {
self.annotations.transform_tagged_template_expression(expr);
}

pub fn transform_identifier_reference(&mut self, ident: &mut IdentifierReference<'a>) {
self.reference_collector.visit_identifier_reference(ident);
pub fn transform_identifier_reference(
&mut self,
ident: &mut IdentifierReference<'a>,
ctx: &TraverseCtx,
) {
if !ctx.parent().is_ts_interface_heritage() && !ctx.parent().is_ts_type_reference() {
self.reference_collector.visit_identifier_reference(ident);
}
}

pub fn transform_declaration(&mut self, decl: &mut Declaration<'a>) {
Expand Down

0 comments on commit be958ce

Please sign in to comment.