mirror of
https://github.com/danbulant/oxc
synced 2026-05-21 05:08:45 +00:00
refactor(transformer): move Semantic into Transformer (#1130)
This commit is contained in:
parent
fa4e0cae81
commit
69150d812c
9 changed files with 36 additions and 52 deletions
|
|
@ -72,6 +72,10 @@ impl<'a> Semantic<'a> {
|
|||
&self.scopes
|
||||
}
|
||||
|
||||
pub fn scopes_mut(&mut self) -> &mut ScopeTree {
|
||||
&mut self.scopes
|
||||
}
|
||||
|
||||
pub fn trivias(&self) -> &TriviasMap {
|
||||
&self.trivias
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::{cell::RefCell, env, path::Path, rc::Rc};
|
||||
use std::{env, path::Path};
|
||||
|
||||
use oxc_allocator::Allocator;
|
||||
use oxc_codegen::{Codegen, CodegenOptions};
|
||||
|
|
@ -36,9 +36,6 @@ fn main() {
|
|||
println!("{printed}\n");
|
||||
|
||||
let semantic = SemanticBuilder::new(&source_text, source_type).build(&ret.program).semantic;
|
||||
let (symbols, scopes) = semantic.into_symbol_table_and_scope_tree();
|
||||
let symbols = Rc::new(RefCell::new(symbols));
|
||||
let scopes = Rc::new(RefCell::new(scopes));
|
||||
|
||||
let program = allocator.alloc(ret.program);
|
||||
let transform_options = TransformOptions {
|
||||
|
|
@ -49,7 +46,7 @@ fn main() {
|
|||
}),
|
||||
..TransformOptions::default()
|
||||
};
|
||||
Transformer::new(&allocator, source_type, &symbols, &scopes, transform_options).build(program);
|
||||
Transformer::new(&allocator, source_type, semantic, transform_options).build(program);
|
||||
let printed = Codegen::<false>::new(source_text.len(), codegen_options).build(program);
|
||||
println!("Transformed:\n");
|
||||
println!("{printed}");
|
||||
|
|
|
|||
|
|
@ -1,30 +1,37 @@
|
|||
use std::{
|
||||
cell::{Ref, RefCell},
|
||||
cell::{Ref, RefCell, RefMut},
|
||||
rc::Rc,
|
||||
};
|
||||
|
||||
use oxc_ast::AstBuilder;
|
||||
use oxc_semantic::{ScopeId, ScopeTree, SymbolId, SymbolTable};
|
||||
use oxc_semantic::{ScopeId, ScopeTree, Semantic, SymbolId, SymbolTable};
|
||||
use oxc_span::Atom;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TransformerCtx<'a> {
|
||||
pub ast: Rc<AstBuilder<'a>>,
|
||||
pub symbols: Rc<RefCell<SymbolTable>>,
|
||||
pub scopes: Rc<RefCell<ScopeTree>>,
|
||||
semantic: Rc<RefCell<Semantic<'a>>>,
|
||||
}
|
||||
|
||||
impl<'a> TransformerCtx<'a> {
|
||||
pub fn symbols(&self) -> Ref<SymbolTable> {
|
||||
self.symbols.borrow()
|
||||
pub fn new(ast: Rc<AstBuilder<'a>>, semantic: Rc<RefCell<Semantic<'a>>>) -> Self {
|
||||
Self { ast, semantic }
|
||||
}
|
||||
|
||||
pub fn scopes(&self) -> Ref<ScopeTree> {
|
||||
self.scopes.borrow()
|
||||
pub fn symbols(&self) -> Ref<'_, SymbolTable> {
|
||||
Ref::map(self.semantic.borrow(), |semantic| semantic.symbols())
|
||||
}
|
||||
|
||||
pub fn scopes(&self) -> Ref<'_, ScopeTree> {
|
||||
Ref::map(self.semantic.borrow(), |semantic| semantic.scopes())
|
||||
}
|
||||
|
||||
pub fn scopes_mut(&self) -> RefMut<'_, ScopeTree> {
|
||||
RefMut::map(self.semantic.borrow_mut(), |semantic| semantic.scopes_mut())
|
||||
}
|
||||
|
||||
pub fn add_binding(&self, name: Atom) {
|
||||
// TODO: use the correct scope and symbol id
|
||||
self.scopes.borrow_mut().add_binding(ScopeId::new(0), name, SymbolId::new(0));
|
||||
self.scopes_mut().add_binding(ScopeId::new(0), name, SymbolId::new(0));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ impl<'a> ExponentiationOperator<'a> {
|
|||
if ident
|
||||
.reference_id
|
||||
.get()
|
||||
.is_some_and(|reference_id| self.ctx.symbols.borrow().has_binding(reference_id))
|
||||
.is_some_and(|reference_id| self.ctx.symbols().has_binding(reference_id))
|
||||
{
|
||||
// this variable is declared in scope so we can be 100% sure
|
||||
// that evaluating it multiple times won't trigger a getter
|
||||
|
|
@ -185,7 +185,7 @@ impl<'a> ExponentiationOperator<'a> {
|
|||
// Super cannot be directly assigned so lets return it also
|
||||
if matches!(expr, Expression::Super(_))
|
||||
|| matches!(&expr, Expression::Identifier(ident) if
|
||||
ident.reference_id.get().is_some_and(|reference_id| self.ctx.symbols.borrow().has_binding(reference_id)))
|
||||
ident.reference_id.get().is_some_and(|reference_id| self.ctx.symbols().has_binding(reference_id)))
|
||||
{
|
||||
return Some(expr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ use std::{cell::RefCell, rc::Rc};
|
|||
|
||||
use oxc_allocator::{Allocator, Vec};
|
||||
use oxc_ast::{ast::*, AstBuilder, VisitMut};
|
||||
use oxc_semantic::{ScopeTree, SymbolTable};
|
||||
use oxc_semantic::Semantic;
|
||||
use oxc_span::SourceType;
|
||||
|
||||
use crate::{
|
||||
|
|
@ -66,16 +66,14 @@ impl<'a> Transformer<'a> {
|
|||
pub fn new(
|
||||
allocator: &'a Allocator,
|
||||
source_type: SourceType,
|
||||
symbols: &Rc<RefCell<SymbolTable>>,
|
||||
scopes: &Rc<RefCell<ScopeTree>>,
|
||||
semantic: Semantic<'a>,
|
||||
options: TransformOptions,
|
||||
) -> Self {
|
||||
let ast = Rc::new(AstBuilder::new(allocator));
|
||||
let ctx = TransformerCtx {
|
||||
ast: Rc::clone(&ast),
|
||||
symbols: Rc::clone(symbols),
|
||||
scopes: Rc::clone(scopes),
|
||||
};
|
||||
let ctx = TransformerCtx::new(
|
||||
Rc::clone(&ast),
|
||||
Rc::new(RefCell::new(semantic)),
|
||||
);
|
||||
Self {
|
||||
// TODO: pass verbatim_module_syntax from user config
|
||||
typescript: source_type.is_typescript().then(|| TypeScript::new(Rc::clone(&ast), ctx.clone(), false)),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use oxc_allocator::Allocator;
|
||||
use oxc_codegen::{Codegen, CodegenOptions};
|
||||
use oxc_parser::Parser;
|
||||
|
|
@ -32,15 +30,9 @@ impl Tester {
|
|||
|
||||
fn transform(&self, source_text: &str) -> String {
|
||||
let program = Parser::new(&self.allocator, source_text, self.source_type).parse().program;
|
||||
|
||||
let semantic = SemanticBuilder::new(source_text, self.source_type).build(&program).semantic;
|
||||
let (symbols, scopes) = semantic.into_symbol_table_and_scope_tree();
|
||||
let symbols = Rc::new(RefCell::new(symbols));
|
||||
let scopes = Rc::new(RefCell::new(scopes));
|
||||
|
||||
let program = self.allocator.alloc(program);
|
||||
Transformer::new(&self.allocator, self.source_type, &symbols, &scopes, self.options)
|
||||
.build(program);
|
||||
Transformer::new(&self.allocator, self.source_type, semantic, self.options).build(program);
|
||||
Codegen::<false>::new(source_text.len(), CodegenOptions).build(program)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -213,12 +213,9 @@ impl Oxc {
|
|||
// FIXME: this should not be duplicated with the linter semantic,
|
||||
// we need to fix the API so symbols and scopes can be shared.
|
||||
let semantic = SemanticBuilder::new(source_text, source_type).build(program).semantic;
|
||||
let (symbols, scopes) = semantic.into_symbol_table_and_scope_tree();
|
||||
let symbols = Rc::new(RefCell::new(symbols));
|
||||
let scopes = Rc::new(RefCell::new(scopes));
|
||||
let options =
|
||||
TransformOptions { target: TransformTarget::ES2015, ..TransformOptions::default() };
|
||||
Transformer::new(&allocator, source_type, &symbols, &scopes, options).build(program);
|
||||
Transformer::new(&allocator, source_type, semantic, options).build(program);
|
||||
}
|
||||
|
||||
let program = allocator.alloc(program);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ static GLOBAL: jemallocator::Jemalloc = jemallocator::Jemalloc;
|
|||
#[global_allocator]
|
||||
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
|
||||
|
||||
use std::{cell::RefCell, fs, hint::black_box, rc::Rc};
|
||||
use std::{fs, hint::black_box};
|
||||
|
||||
use oxc_allocator::Allocator;
|
||||
use oxc_benchmark::{criterion_group, criterion_main, BenchmarkId, Criterion};
|
||||
|
|
@ -35,12 +35,9 @@ fn bench_transformer(criterion: &mut Criterion) {
|
|||
let program = Parser::new(&allocator, source_text, source_type).parse().program;
|
||||
let semantic =
|
||||
SemanticBuilder::new(source_text, source_type).build(&program).semantic;
|
||||
let (symbols, scopes) = semantic.into_symbol_table_and_scope_tree();
|
||||
let symbols = Rc::new(RefCell::new(symbols));
|
||||
let scopes = Rc::new(RefCell::new(scopes));
|
||||
let program = allocator.alloc(program);
|
||||
let transform_options = TransformOptions::default();
|
||||
Transformer::new(&allocator, source_type, &symbols, &scopes, transform_options)
|
||||
Transformer::new(&allocator, source_type, semantic, transform_options)
|
||||
.build(black_box(program));
|
||||
allocator
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
use std::{
|
||||
cell::RefCell,
|
||||
fs,
|
||||
path::{Path, PathBuf},
|
||||
rc::Rc,
|
||||
};
|
||||
|
||||
use oxc_allocator::Allocator;
|
||||
|
|
@ -144,12 +142,9 @@ pub trait TestCase {
|
|||
|
||||
let semantic =
|
||||
SemanticBuilder::new(&source_text, source_type).build(&transformed_program).semantic;
|
||||
let (symbols, scopes) = semantic.into_symbol_table_and_scope_tree();
|
||||
let symbols = Rc::new(RefCell::new(symbols));
|
||||
let scopes = Rc::new(RefCell::new(scopes));
|
||||
let transformed_program = allocator.alloc(transformed_program);
|
||||
|
||||
Transformer::new(&allocator, source_type, &symbols, &scopes, self.transform_options())
|
||||
Transformer::new(&allocator, source_type, semantic, self.transform_options())
|
||||
.build(transformed_program);
|
||||
Codegen::<false>::new(source_text.len(), CodegenOptions).build(transformed_program)
|
||||
}
|
||||
|
|
@ -197,11 +192,8 @@ impl TestCase for ConformanceTestCase {
|
|||
// Transform input.js
|
||||
let program = Parser::new(&allocator, &input, source_type).parse().program;
|
||||
let semantic = SemanticBuilder::new(&input, source_type).build(&program).semantic;
|
||||
let (symbols, scopes) = semantic.into_symbol_table_and_scope_tree();
|
||||
let symbols = Rc::new(RefCell::new(symbols));
|
||||
let scopes = Rc::new(RefCell::new(scopes));
|
||||
let program = allocator.alloc(program);
|
||||
Transformer::new(&allocator, source_type, &symbols, &scopes, self.transform_options())
|
||||
Transformer::new(&allocator, source_type, semantic, self.transform_options())
|
||||
.build(program);
|
||||
let transformed_code = Codegen::<false>::new(input.len(), CodegenOptions).build(program);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue