mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
feat(transformer): add transform callback methods (#2929)
For milestone 1, I think it's safe to just layout all the transformations manually. In TypeScript, the transformers are collected dynamically and ran on each ast node; this achieves a single AST pass. https://github.com/microsoft/TypeScript/blob/main/src/compiler/transformer.ts#L129-L145 To maximize performance and reduce confusion, I think it's safe to layout all the transformations manually for milestone 1. The next PR will add transformation context to all presets so we can start adding "context".
This commit is contained in:
parent
8662f4f613
commit
79ca6feca9
4 changed files with 60 additions and 8 deletions
|
|
@ -1,5 +1,7 @@
|
|||
use serde::Deserialize;
|
||||
|
||||
use oxc_ast::ast::*;
|
||||
|
||||
/// Only `"2023-11"` will be implemented because Babel 8 will only support "2023-11" and "legacy".
|
||||
#[derive(Debug, Default, Clone, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
|
|
@ -17,3 +19,8 @@ impl Decorators {
|
|||
Self { options }
|
||||
}
|
||||
}
|
||||
|
||||
// Transformers
|
||||
impl Decorators {
|
||||
pub fn transform_statement(&mut self, _stmt: &mut Statement<'_>) {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
#![allow(clippy::wildcard_imports)]
|
||||
|
||||
//! Transformer / Transpiler
|
||||
//!
|
||||
//! References:
|
||||
|
|
@ -13,7 +15,10 @@ mod react;
|
|||
mod typescript;
|
||||
|
||||
use oxc_allocator::Allocator;
|
||||
use oxc_ast::ast::Program;
|
||||
use oxc_ast::{
|
||||
ast::*,
|
||||
visit::{walk_mut, VisitMut},
|
||||
};
|
||||
use oxc_diagnostics::Error;
|
||||
use oxc_semantic::Semantic;
|
||||
use oxc_span::SourceType;
|
||||
|
|
@ -54,9 +59,10 @@ pub struct Transformer<'a> {
|
|||
semantic: Semantic<'a>,
|
||||
options: TransformOptions,
|
||||
|
||||
decorators: Decorators,
|
||||
typescript: TypeScript,
|
||||
react: React,
|
||||
// NOTE: all callbacks must run in order.
|
||||
x0_typescript: TypeScript,
|
||||
x1_react: React,
|
||||
x2_decorators: Decorators,
|
||||
}
|
||||
|
||||
impl<'a> Transformer<'a> {
|
||||
|
|
@ -71,16 +77,30 @@ impl<'a> Transformer<'a> {
|
|||
source_type,
|
||||
semantic,
|
||||
options,
|
||||
decorators: Decorators::default(),
|
||||
typescript: TypeScript::default(),
|
||||
react: React::default(),
|
||||
x0_typescript: TypeScript::default(),
|
||||
x1_react: React::default(),
|
||||
x2_decorators: Decorators::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns `Vec<Error>` if any errors were collected during the transformation.
|
||||
pub fn build(self, _program: &mut Program<'a>) -> Result<(), Vec<Error>> {
|
||||
pub fn build(mut self, program: &mut Program<'a>) -> Result<(), Vec<Error>> {
|
||||
self.visit_program(program);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> VisitMut<'a> for Transformer<'a> {
|
||||
fn visit_statement(&mut self, stmt: &mut Statement<'a>) {
|
||||
self.x0_typescript.transform_statement(stmt);
|
||||
self.x2_decorators.transform_statement(stmt);
|
||||
walk_mut::walk_statement_mut(self, stmt);
|
||||
}
|
||||
|
||||
fn visit_expression(&mut self, expr: &mut Expression<'a>) {
|
||||
self.x1_react.transform_expression(expr);
|
||||
walk_mut::walk_expression_mut(self, expr);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ mod jsx_self;
|
|||
mod jsx_source;
|
||||
mod options;
|
||||
|
||||
use oxc_ast::ast::*;
|
||||
|
||||
pub use self::{
|
||||
display_name::{ReactDisplayName, ReactDisplayNameOptions},
|
||||
jsx::ReactJsx,
|
||||
|
|
@ -28,6 +30,7 @@ pub struct React {
|
|||
display_name: ReactDisplayName,
|
||||
}
|
||||
|
||||
// Constructors
|
||||
impl React {
|
||||
pub fn new(&mut self, options: ReactOptions) -> &mut Self {
|
||||
self.jsx = ReactJsx::new(options);
|
||||
|
|
@ -49,3 +52,18 @@ impl React {
|
|||
self
|
||||
}
|
||||
}
|
||||
|
||||
// Transformers
|
||||
impl React {
|
||||
pub fn transform_expression(&mut self, expr: &mut Expression<'_>) {
|
||||
match expr {
|
||||
Expression::JSXElement(_e) => {
|
||||
// *expr = unimplemented!();
|
||||
}
|
||||
Expression::JSXFragment(_e) => {
|
||||
// *expr = unimplemented!();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
use serde::Deserialize;
|
||||
|
||||
use oxc_ast::ast::*;
|
||||
|
||||
#[derive(Debug, Default, Clone, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct TypeScriptOptions;
|
||||
|
|
@ -36,3 +38,8 @@ impl TypeScript {
|
|||
Self { options }
|
||||
}
|
||||
}
|
||||
|
||||
// Transformers
|
||||
impl TypeScript {
|
||||
pub fn transform_statement(&mut self, _stmt: &mut Statement<'_>) {}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue