From 4b49cf8ce483a07f698eb04292489e537419e575 Mon Sep 17 00:00:00 2001 From: Boshen <1430279+Boshen@users.noreply.github.com> Date: Thu, 22 Aug 2024 16:06:31 +0000 Subject: [PATCH] feat(transformer): always pass in symbols and scopes (#5087) We no longer need to build semantic data inside the transformer. The caller should be responsible for handling semantic data and its errors. The best way to achieve this in via `CompilerInterface`. closes #3565 --- Cargo.lock | 1 + crates/oxc_transformer/examples/transformer.rs | 9 ++++++++- crates/oxc_transformer/src/lib.rs | 12 +----------- crates/oxc_wasm/src/lib.rs | 6 +++++- napi/transform/Cargo.toml | 1 + napi/transform/src/transformer.rs | 7 ++++++- tasks/benchmark/Cargo.toml | 2 +- tasks/benchmark/benches/transformer.rs | 7 ++++++- 8 files changed, 29 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5993ef8842219..b768466b6d31b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1905,6 +1905,7 @@ dependencies = [ "oxc_diagnostics", "oxc_isolated_declarations", "oxc_parser", + "oxc_semantic", "oxc_sourcemap", "oxc_span", "oxc_transformer", diff --git a/crates/oxc_transformer/examples/transformer.rs b/crates/oxc_transformer/examples/transformer.rs index 08fa0a5418c89..cdb7eb0142f80 100644 --- a/crates/oxc_transformer/examples/transformer.rs +++ b/crates/oxc_transformer/examples/transformer.rs @@ -4,6 +4,7 @@ use std::{env, path::Path}; use oxc_allocator::Allocator; use oxc_codegen::CodeGenerator; use oxc_parser::Parser; +use oxc_semantic::SemanticBuilder; use oxc_span::SourceType; use oxc_transformer::{ ArrowFunctionsOptions, ES2015Options, ReactOptions, TransformOptions, Transformer, @@ -47,6 +48,12 @@ fn main() { }, ..Default::default() }; + + let (symbols, scopes) = SemanticBuilder::new(&source_text, source_type) + .build(&program) + .semantic + .into_symbol_table_and_scope_tree(); + let _ = Transformer::new( &allocator, path, @@ -55,7 +62,7 @@ fn main() { ret.trivias.clone(), transform_options, ) - .build(&mut program); + .build_with_symbols_and_scopes(symbols, scopes, &mut program); let printed = CodeGenerator::new().build(&program).source_text; println!("Transformed:\n"); diff --git a/crates/oxc_transformer/src/lib.rs b/crates/oxc_transformer/src/lib.rs index 8e17f8bf379e9..3d7f98a279dd8 100644 --- a/crates/oxc_transformer/src/lib.rs +++ b/crates/oxc_transformer/src/lib.rs @@ -36,7 +36,7 @@ use es2021::ES2021; use oxc_allocator::{Allocator, Vec}; use oxc_ast::{ast::*, Trivias}; use oxc_diagnostics::OxcDiagnostic; -use oxc_semantic::{ScopeTree, SemanticBuilder, SymbolTable}; +use oxc_semantic::{ScopeTree, SymbolTable}; use oxc_span::SourceType; use oxc_traverse::{traverse_mut, Traverse, TraverseCtx}; @@ -102,16 +102,6 @@ impl<'a> Transformer<'a> { } } - pub fn build(mut self, program: &mut Program<'a>) -> TransformerReturn { - let (symbols, scopes) = SemanticBuilder::new(self.ctx.source_text, self.ctx.source_type) - .build(program) - .semantic - .into_symbol_table_and_scope_tree(); - let allocator: &'a Allocator = self.ctx.ast.allocator; - let (symbols, scopes) = traverse_mut(&mut self, allocator, program, symbols, scopes); - TransformerReturn { errors: self.ctx.take_errors(), symbols, scopes } - } - pub fn build_with_symbols_and_scopes( mut self, symbols: SymbolTable, diff --git a/crates/oxc_wasm/src/lib.rs b/crates/oxc_wasm/src/lib.rs index 3e7b349f85643..adcaed21fb73a 100644 --- a/crates/oxc_wasm/src/lib.rs +++ b/crates/oxc_wasm/src/lib.rs @@ -241,6 +241,10 @@ impl Oxc { } if run_options.transform() { + let (symbols, scopes) = SemanticBuilder::new(source_text, source_type) + .build(program) + .semantic + .into_symbol_table_and_scope_tree(); let options = TransformOptions::default(); let result = Transformer::new( &allocator, @@ -250,7 +254,7 @@ impl Oxc { ret.trivias.clone(), options, ) - .build(program); + .build_with_symbols_and_scopes(symbols, scopes, program); if !result.errors.is_empty() { let errors = result.errors.into_iter().map(Error::from).collect::>(); self.save_diagnostics(errors); diff --git a/napi/transform/Cargo.toml b/napi/transform/Cargo.toml index 7fafd98fb35fe..921b3dfef54c2 100644 --- a/napi/transform/Cargo.toml +++ b/napi/transform/Cargo.toml @@ -30,6 +30,7 @@ oxc_parser = { workspace = true } oxc_span = { workspace = true } oxc_sourcemap = { workspace = true } oxc_transformer = { workspace = true } +oxc_semantic = { workspace = true } napi = { workspace = true } napi-derive = { workspace = true } diff --git a/napi/transform/src/transformer.rs b/napi/transform/src/transformer.rs index 6bdbc9de64818..ef337ea18474b 100644 --- a/napi/transform/src/transformer.rs +++ b/napi/transform/src/transformer.rs @@ -3,6 +3,7 @@ use napi_derive::napi; use crate::{context::TransformContext, isolated_declaration, SourceMap, TransformOptions}; use oxc_allocator::Allocator; use oxc_codegen::CodegenReturn; +use oxc_semantic::SemanticBuilder; use oxc_span::SourceType; use oxc_transformer::Transformer; @@ -97,6 +98,10 @@ pub fn transform( } fn transpile(ctx: &TransformContext<'_>) -> CodegenReturn { + let (symbols, scopes) = SemanticBuilder::new(ctx.source_text(), ctx.source_type()) + .build(&ctx.program()) + .semantic + .into_symbol_table_and_scope_tree(); let ret = Transformer::new( ctx.allocator, ctx.file_path(), @@ -105,7 +110,7 @@ fn transpile(ctx: &TransformContext<'_>) -> CodegenReturn { ctx.trivias.clone(), ctx.oxc_options(), ) - .build(&mut ctx.program_mut()); + .build_with_symbols_and_scopes(symbols, scopes, &mut ctx.program_mut()); ctx.add_diagnostics(ret.errors); ctx.codegen().build(&ctx.program()) diff --git a/tasks/benchmark/Cargo.toml b/tasks/benchmark/Cargo.toml index 59b4040f65b93..4db9eed5162e6 100644 --- a/tasks/benchmark/Cargo.toml +++ b/tasks/benchmark/Cargo.toml @@ -109,7 +109,7 @@ codspeed_napi = ["criterion2/codspeed", "dep:serde", "dep:serde_json"] # e.g. `cargo build --release -p oxc_benchmark --bench parser --no-default-features --features parser` lexer = ["dep:oxc_allocator", "dep:oxc_parser", "dep:oxc_span", "dep:oxc_tasks_common"] parser = ["dep:oxc_allocator", "dep:oxc_parser", "dep:oxc_span", "dep:oxc_tasks_common"] -transformer = ["dep:oxc_allocator", "dep:oxc_parser", "dep:oxc_span", "dep:oxc_tasks_common", "dep:oxc_transformer"] +transformer = ["dep:oxc_allocator", "dep:oxc_parser", "dep:oxc_span", "dep:oxc_tasks_common", "dep:oxc_transformer", "dep:oxc_semantic"] semantic = ["dep:oxc_allocator", "dep:oxc_parser", "dep:oxc_semantic", "dep:oxc_span", "dep:oxc_tasks_common"] minifier = ["dep:oxc_allocator", "dep:oxc_minifier", "dep:oxc_parser", "dep:oxc_span", "dep:oxc_tasks_common"] codegen = ["dep:oxc_allocator", "dep:oxc_codegen", "dep:oxc_parser", "dep:oxc_span", "dep:oxc_tasks_common"] diff --git a/tasks/benchmark/benches/transformer.rs b/tasks/benchmark/benches/transformer.rs index 2cabd95cce92d..aeffeee2155c2 100644 --- a/tasks/benchmark/benches/transformer.rs +++ b/tasks/benchmark/benches/transformer.rs @@ -3,6 +3,7 @@ use std::path::Path; use oxc_allocator::Allocator; use oxc_benchmark::{criterion_group, criterion_main, BenchmarkId, Criterion}; use oxc_parser::{Parser, ParserReturn}; +use oxc_semantic::SemanticBuilder; use oxc_span::SourceType; use oxc_tasks_common::TestFiles; use oxc_transformer::{TransformOptions, Transformer}; @@ -23,6 +24,10 @@ fn bench_transformer(criterion: &mut Criterion) { Parser::new(&allocator, source_text, source_type).parse(); let transform_options = TransformOptions::default(); let program = allocator.alloc(program); + let (symbols, scopes) = SemanticBuilder::new(source_text, source_type) + .build(program) + .semantic + .into_symbol_table_and_scope_tree(); Transformer::new( &allocator, Path::new(&file.file_name), @@ -31,7 +36,7 @@ fn bench_transformer(criterion: &mut Criterion) { trivias, transform_options, ) - .build(program); + .build_with_symbols_and_scopes(symbols, scopes, program); allocator }); });