mirror of
https://github.com/danbulant/oxc
synced 2026-05-25 04:42:10 +00:00
refactor(transformer): remove the requirement of Semantic (#3140)
It seems like we need to rebuild the scopes and symbols while traversing. We can't utilize the scopes and symbols built by semantic because they are immutable.
This commit is contained in:
parent
733361822e
commit
a63a45d5b2
17 changed files with 88 additions and 113 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -1631,7 +1631,6 @@ dependencies = [
|
||||||
"oxc_codegen",
|
"oxc_codegen",
|
||||||
"oxc_diagnostics",
|
"oxc_diagnostics",
|
||||||
"oxc_parser",
|
"oxc_parser",
|
||||||
"oxc_semantic",
|
|
||||||
"oxc_span",
|
"oxc_span",
|
||||||
"oxc_tasks_common",
|
"oxc_tasks_common",
|
||||||
"oxc_transformer",
|
"oxc_transformer",
|
||||||
|
|
@ -1651,7 +1650,6 @@ dependencies = [
|
||||||
"oxc_codegen",
|
"oxc_codegen",
|
||||||
"oxc_diagnostics",
|
"oxc_diagnostics",
|
||||||
"oxc_parser",
|
"oxc_parser",
|
||||||
"oxc_semantic",
|
|
||||||
"oxc_span",
|
"oxc_span",
|
||||||
"oxc_syntax",
|
"oxc_syntax",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ doctest = false
|
||||||
oxc_ast = { workspace = true }
|
oxc_ast = { workspace = true }
|
||||||
oxc_span = { workspace = true }
|
oxc_span = { workspace = true }
|
||||||
oxc_allocator = { workspace = true }
|
oxc_allocator = { workspace = true }
|
||||||
oxc_semantic = { workspace = true }
|
|
||||||
oxc_diagnostics = { workspace = true }
|
oxc_diagnostics = { workspace = true }
|
||||||
oxc_syntax = { workspace = true, features = ["to_js_string"] }
|
oxc_syntax = { workspace = true, features = ["to_js_string"] }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,8 @@
|
||||||
use std::{
|
use std::{env, path::Path};
|
||||||
env,
|
|
||||||
path::{Path, PathBuf},
|
|
||||||
};
|
|
||||||
|
|
||||||
use oxc_allocator::Allocator;
|
use oxc_allocator::Allocator;
|
||||||
use oxc_codegen::{Codegen, CodegenOptions};
|
use oxc_codegen::{Codegen, CodegenOptions};
|
||||||
use oxc_parser::Parser;
|
use oxc_parser::Parser;
|
||||||
use oxc_semantic::SemanticBuilder;
|
|
||||||
use oxc_span::SourceType;
|
use oxc_span::SourceType;
|
||||||
use oxc_transformer::{TransformOptions, Transformer};
|
use oxc_transformer::{TransformOptions, Transformer};
|
||||||
|
|
||||||
|
|
@ -35,18 +31,14 @@ fn main() {
|
||||||
println!("Original:\n");
|
println!("Original:\n");
|
||||||
println!("{source_text}\n");
|
println!("{source_text}\n");
|
||||||
|
|
||||||
let semantic = SemanticBuilder::new(&source_text, source_type)
|
let mut program = ret.program;
|
||||||
.with_trivias(ret.trivias)
|
|
||||||
.build_module_record(PathBuf::new(), &ret.program)
|
|
||||||
.build(&ret.program)
|
|
||||||
.semantic;
|
|
||||||
|
|
||||||
let program = allocator.alloc(ret.program);
|
|
||||||
let transform_options = TransformOptions::default();
|
let transform_options = TransformOptions::default();
|
||||||
Transformer::new(&allocator, path, semantic, transform_options).build(program).unwrap();
|
Transformer::new(&allocator, path, source_type, &source_text, &ret.trivias, transform_options)
|
||||||
|
.build(&mut program)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let printed = Codegen::<false>::new("", &source_text, CodegenOptions::default())
|
let printed = Codegen::<false>::new("", &source_text, CodegenOptions::default())
|
||||||
.build(program)
|
.build(&program)
|
||||||
.source_text;
|
.source_text;
|
||||||
println!("Transformed:\n");
|
println!("Transformed:\n");
|
||||||
println!("{printed}");
|
println!("{printed}");
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,8 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use oxc_allocator::Allocator;
|
use oxc_allocator::Allocator;
|
||||||
use oxc_ast::AstBuilder;
|
use oxc_ast::{AstBuilder, Trivias};
|
||||||
use oxc_diagnostics::Error;
|
use oxc_diagnostics::Error;
|
||||||
use oxc_semantic::Semantic;
|
|
||||||
use oxc_span::SourceType;
|
use oxc_span::SourceType;
|
||||||
|
|
||||||
use crate::{helpers::module_imports::ModuleImports, TransformOptions};
|
use crate::{helpers::module_imports::ModuleImports, TransformOptions};
|
||||||
|
|
@ -16,17 +15,21 @@ use crate::{helpers::module_imports::ModuleImports, TransformOptions};
|
||||||
pub type Ctx<'a> = Rc<TransformCtx<'a>>;
|
pub type Ctx<'a> = Rc<TransformCtx<'a>>;
|
||||||
|
|
||||||
pub struct TransformCtx<'a> {
|
pub struct TransformCtx<'a> {
|
||||||
|
errors: RefCell<Vec<Error>>,
|
||||||
|
|
||||||
|
pub trivias: &'a Trivias,
|
||||||
|
|
||||||
pub ast: AstBuilder<'a>,
|
pub ast: AstBuilder<'a>,
|
||||||
|
|
||||||
pub semantic: Semantic<'a>,
|
|
||||||
|
|
||||||
/// <https://babeljs.io/docs/options#filename>
|
/// <https://babeljs.io/docs/options#filename>
|
||||||
filename: String,
|
pub filename: String,
|
||||||
|
|
||||||
/// Source path in the form of `<CWD>/path/to/file/input.js`
|
/// Source path in the form of `<CWD>/path/to/file/input.js`
|
||||||
source_path: PathBuf,
|
pub source_path: PathBuf,
|
||||||
|
|
||||||
errors: RefCell<Vec<Error>>,
|
pub source_type: SourceType,
|
||||||
|
|
||||||
|
pub source_text: &'a str,
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
/// Manage import statement globally
|
/// Manage import statement globally
|
||||||
|
|
@ -37,7 +40,9 @@ impl<'a> TransformCtx<'a> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
allocator: &'a Allocator,
|
allocator: &'a Allocator,
|
||||||
source_path: &Path,
|
source_path: &Path,
|
||||||
semantic: Semantic<'a>,
|
source_type: SourceType,
|
||||||
|
source_text: &'a str,
|
||||||
|
trivias: &'a Trivias,
|
||||||
options: &TransformOptions,
|
options: &TransformOptions,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let filename = source_path
|
let filename = source_path
|
||||||
|
|
@ -49,11 +54,13 @@ impl<'a> TransformCtx<'a> {
|
||||||
.map_or_else(|_| source_path.to_path_buf(), |p| Path::new("<CWD>").join(p));
|
.map_or_else(|_| source_path.to_path_buf(), |p| Path::new("<CWD>").join(p));
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
errors: RefCell::new(vec![]),
|
||||||
ast: AstBuilder::new(allocator),
|
ast: AstBuilder::new(allocator),
|
||||||
semantic,
|
|
||||||
filename,
|
filename,
|
||||||
source_path,
|
source_path,
|
||||||
errors: RefCell::new(vec![]),
|
source_type,
|
||||||
|
source_text,
|
||||||
|
trivias,
|
||||||
module_imports: ModuleImports::new(allocator),
|
module_imports: ModuleImports::new(allocator),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -62,21 +69,9 @@ impl<'a> TransformCtx<'a> {
|
||||||
mem::take(&mut self.errors.borrow_mut())
|
mem::take(&mut self.errors.borrow_mut())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn filename(&self) -> &str {
|
|
||||||
&self.filename
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn source_path(&self) -> &Path {
|
|
||||||
&self.source_path
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add an Error
|
/// Add an Error
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub fn error<T: Into<Error>>(&self, error: T) {
|
pub fn error<T: Into<Error>>(&self, error: T) {
|
||||||
self.errors.borrow_mut().push(error.into());
|
self.errors.borrow_mut().push(error.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn source_type(&self) -> &SourceType {
|
|
||||||
self.semantic.source_type()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,11 @@ use oxc_allocator::{Allocator, Vec};
|
||||||
use oxc_ast::{
|
use oxc_ast::{
|
||||||
ast::*,
|
ast::*,
|
||||||
visit::{walk_mut, VisitMut},
|
visit::{walk_mut, VisitMut},
|
||||||
|
Trivias,
|
||||||
};
|
};
|
||||||
use oxc_diagnostics::Error;
|
use oxc_diagnostics::Error;
|
||||||
use oxc_semantic::Semantic;
|
use oxc_span::SourceType;
|
||||||
|
use oxc_syntax::scope::ScopeFlags;
|
||||||
|
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
compiler_assumptions::CompilerAssumptions, es2015::ES2015Options, options::TransformOptions,
|
compiler_assumptions::CompilerAssumptions, es2015::ES2015Options, options::TransformOptions,
|
||||||
|
|
@ -55,10 +57,19 @@ impl<'a> Transformer<'a> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
allocator: &'a Allocator,
|
allocator: &'a Allocator,
|
||||||
source_path: &Path,
|
source_path: &Path,
|
||||||
semantic: Semantic<'a>,
|
source_type: SourceType,
|
||||||
|
source_text: &'a str,
|
||||||
|
trivias: &'a Trivias,
|
||||||
options: TransformOptions,
|
options: TransformOptions,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let ctx = Rc::new(TransformCtx::new(allocator, source_path, semantic, &options));
|
let ctx = Rc::new(TransformCtx::new(
|
||||||
|
allocator,
|
||||||
|
source_path,
|
||||||
|
source_type,
|
||||||
|
source_text,
|
||||||
|
trivias,
|
||||||
|
&options,
|
||||||
|
));
|
||||||
Self {
|
Self {
|
||||||
ctx: Rc::clone(&ctx),
|
ctx: Rc::clone(&ctx),
|
||||||
x0_typescript: TypeScript::new(options.typescript, &ctx),
|
x0_typescript: TypeScript::new(options.typescript, &ctx),
|
||||||
|
|
@ -154,7 +165,7 @@ impl<'a> VisitMut<'a> for Transformer<'a> {
|
||||||
walk_mut::walk_formal_parameter_mut(self, param);
|
walk_mut::walk_formal_parameter_mut(self, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_function(&mut self, func: &mut Function<'a>, flags: Option<oxc_semantic::ScopeFlags>) {
|
fn visit_function(&mut self, func: &mut Function<'a>, flags: Option<ScopeFlags>) {
|
||||||
self.x0_typescript.transform_function(func, flags);
|
self.x0_typescript.transform_function(func, flags);
|
||||||
|
|
||||||
walk_mut::walk_function_mut(self, func, flags);
|
walk_mut::walk_function_mut(self, func, flags);
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ impl<'a> ReactDisplayName<'a> {
|
||||||
pub fn transform_export_default_declaration(&self, decl: &mut ExportDefaultDeclaration<'a>) {
|
pub fn transform_export_default_declaration(&self, decl: &mut ExportDefaultDeclaration<'a>) {
|
||||||
let Some(expr) = decl.declaration.as_expression_mut() else { return };
|
let Some(expr) = decl.declaration.as_expression_mut() else { return };
|
||||||
let Some(obj_expr) = Self::get_object_from_create_class(expr) else { return };
|
let Some(obj_expr) = Self::get_object_from_create_class(expr) else { return };
|
||||||
let name = self.ctx.ast.new_atom(self.ctx.filename());
|
let name = self.ctx.ast.new_atom(&self.ctx.filename);
|
||||||
self.add_display_name(obj_expr, name);
|
self.add_display_name(obj_expr, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ impl<'a> ReactJsx<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_script(&self) -> bool {
|
fn is_script(&self) -> bool {
|
||||||
self.ctx.semantic.source_type().is_script()
|
self.ctx.source_type.is_script()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ast(&self) -> &AstBuilder<'a> {
|
fn ast(&self) -> &AstBuilder<'a> {
|
||||||
|
|
|
||||||
|
|
@ -132,8 +132,7 @@ impl<'a> ReactJsxSource<'a> {
|
||||||
self.ctx.ast.binding_pattern(ident, None, false)
|
self.ctx.ast.binding_pattern(ident, None, false)
|
||||||
};
|
};
|
||||||
let decl = {
|
let decl = {
|
||||||
let string =
|
let string = self.ctx.ast.string_literal(SPAN, &self.ctx.source_path.to_string_lossy());
|
||||||
self.ctx.ast.string_literal(SPAN, &self.ctx.source_path().to_string_lossy());
|
|
||||||
let init = self.ctx.ast.literal_string_expression(string);
|
let init = self.ctx.ast.literal_string_expression(string);
|
||||||
let decl = self.ctx.ast.variable_declarator(SPAN, var_kind, id, Some(init), false);
|
let decl = self.ctx.ast.variable_declarator(SPAN, var_kind, id, Some(init), false);
|
||||||
self.ctx.ast.new_vec_single(decl)
|
self.ctx.ast.new_vec_single(decl)
|
||||||
|
|
|
||||||
|
|
@ -159,9 +159,8 @@ impl ReactOptions {
|
||||||
///
|
///
|
||||||
/// This behavior is aligned with babel.
|
/// This behavior is aligned with babel.
|
||||||
pub(crate) fn update_with_comments(&mut self, ctx: &Ctx) {
|
pub(crate) fn update_with_comments(&mut self, ctx: &Ctx) {
|
||||||
let semantic = &ctx.semantic;
|
for (_, span) in ctx.trivias.comments() {
|
||||||
for (_, span) in semantic.trivias().comments() {
|
let mut comment = span.source_text(ctx.source_text).trim_start();
|
||||||
let mut comment = span.source_text(semantic.source_text()).trim_start();
|
|
||||||
// strip leading jsdoc comment `*` and then whitespaces
|
// strip leading jsdoc comment `*` and then whitespaces
|
||||||
while let Some(cur_comment) = comment.strip_prefix('*') {
|
while let Some(cur_comment) = comment.strip_prefix('*') {
|
||||||
comment = cur_comment.trim_start();
|
comment = cur_comment.trim_start();
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use crate::TypeScriptOptions;
|
||||||
use oxc_allocator::Vec;
|
use oxc_allocator::Vec;
|
||||||
use oxc_ast::ast::*;
|
use oxc_ast::ast::*;
|
||||||
use oxc_span::{Atom, SPAN};
|
use oxc_span::{Atom, SPAN};
|
||||||
use oxc_syntax::operator::AssignmentOperator;
|
use oxc_syntax::{operator::AssignmentOperator, scope::ScopeFlags};
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
|
|
||||||
use super::collector::TypeScriptReferenceCollector;
|
use super::collector::TypeScriptReferenceCollector;
|
||||||
|
|
@ -217,11 +217,7 @@ impl<'a> TypeScriptAnnotations<'a> {
|
||||||
param.accessibility = None;
|
param.accessibility = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_function(
|
pub fn transform_function(&mut self, func: &mut Function<'a>, _flags: Option<ScopeFlags>) {
|
||||||
&mut self,
|
|
||||||
func: &mut Function<'a>,
|
|
||||||
_flags: Option<oxc_semantic::ScopeFlags>,
|
|
||||||
) {
|
|
||||||
func.this_param = None;
|
func.this_param = None;
|
||||||
func.type_parameters = None;
|
func.type_parameters = None;
|
||||||
func.return_type = None;
|
func.return_type = None;
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ use serde::Deserialize;
|
||||||
|
|
||||||
use oxc_allocator::Vec;
|
use oxc_allocator::Vec;
|
||||||
use oxc_ast::ast::*;
|
use oxc_ast::ast::*;
|
||||||
|
use oxc_syntax::scope::ScopeFlags;
|
||||||
|
|
||||||
use crate::context::Ctx;
|
use crate::context::Ctx;
|
||||||
|
|
||||||
|
|
@ -114,11 +115,7 @@ impl<'a> TypeScript<'a> {
|
||||||
self.annotations.transform_formal_parameter(param);
|
self.annotations.transform_formal_parameter(param);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_function(
|
pub fn transform_function(&mut self, func: &mut Function<'a>, flags: Option<ScopeFlags>) {
|
||||||
&mut self,
|
|
||||||
func: &mut Function<'a>,
|
|
||||||
flags: Option<oxc_semantic::ScopeFlags>,
|
|
||||||
) {
|
|
||||||
self.annotations.transform_function(func, flags);
|
self.annotations.transform_function(func, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ impl<'a> TypeScript<'a> {
|
||||||
self.transform_ts_type_name(&mut *type_name.to_ts_type_name_mut())
|
self.transform_ts_type_name(&mut *type_name.to_ts_type_name_mut())
|
||||||
}
|
}
|
||||||
TSModuleReference::ExternalModuleReference(reference) => {
|
TSModuleReference::ExternalModuleReference(reference) => {
|
||||||
if self.ctx.source_type().is_module() {
|
if self.ctx.source_type.is_module() {
|
||||||
self.ctx.error(ImportEqualsRequireUnsupported(decl_span));
|
self.ctx.error(ImportEqualsRequireUnsupported(decl_span));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,7 +80,7 @@ impl<'a> TypeScript<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
export_assignment: &mut TSExportAssignment<'a>,
|
export_assignment: &mut TSExportAssignment<'a>,
|
||||||
) {
|
) {
|
||||||
if self.ctx.source_type().is_module() {
|
if self.ctx.source_type.is_module() {
|
||||||
self.ctx.error(ExportAssignmentUnsupported(export_assignment.span));
|
self.ctx.error(ExportAssignmentUnsupported(export_assignment.span));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -187,9 +187,9 @@ impl Oxc {
|
||||||
self.save_diagnostics(semantic_ret.errors);
|
self.save_diagnostics(semantic_ret.errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let semantic = Rc::new(semantic_ret.semantic);
|
||||||
// Only lint if there are not syntax errors
|
// Only lint if there are not syntax errors
|
||||||
if run_options.lint() && self.diagnostics.borrow().is_empty() {
|
if run_options.lint() && self.diagnostics.borrow().is_empty() {
|
||||||
let semantic = Rc::new(semantic_ret.semantic);
|
|
||||||
let lint_ctx = LintContext::new(path.clone().into_boxed_path(), &semantic);
|
let lint_ctx = LintContext::new(path.clone().into_boxed_path(), &semantic);
|
||||||
let linter_ret = Linter::default().run(lint_ctx);
|
let linter_ret = Linter::default().run(lint_ctx);
|
||||||
let diagnostics = linter_ret.into_iter().map(|e| e.error).collect();
|
let diagnostics = linter_ret.into_iter().map(|e| e.error).collect();
|
||||||
|
|
@ -226,14 +226,16 @@ impl Oxc {
|
||||||
}
|
}
|
||||||
|
|
||||||
if run_options.transform() {
|
if run_options.transform() {
|
||||||
// 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_module_record(PathBuf::new(), program)
|
|
||||||
.build(program)
|
|
||||||
.semantic;
|
|
||||||
let options = TransformOptions::default();
|
let options = TransformOptions::default();
|
||||||
let result = Transformer::new(&allocator, &path, semantic, options).build(program);
|
let result = Transformer::new(
|
||||||
|
&allocator,
|
||||||
|
&path,
|
||||||
|
source_type,
|
||||||
|
source_text,
|
||||||
|
semantic.trivias(),
|
||||||
|
options,
|
||||||
|
)
|
||||||
|
.build(program);
|
||||||
if let Err(errs) = result {
|
if let Err(errs) = result {
|
||||||
self.save_diagnostics(errs);
|
self.save_diagnostics(errs);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,7 @@ use std::path::Path;
|
||||||
|
|
||||||
use oxc_allocator::Allocator;
|
use oxc_allocator::Allocator;
|
||||||
use oxc_benchmark::{criterion_group, criterion_main, BenchmarkId, Criterion};
|
use oxc_benchmark::{criterion_group, criterion_main, BenchmarkId, Criterion};
|
||||||
use oxc_parser::Parser;
|
use oxc_parser::{Parser, ParserReturn};
|
||||||
use oxc_semantic::SemanticBuilder;
|
|
||||||
use oxc_span::SourceType;
|
use oxc_span::SourceType;
|
||||||
use oxc_tasks_common::TestFiles;
|
use oxc_tasks_common::TestFiles;
|
||||||
use oxc_transformer::{TransformOptions, Transformer};
|
use oxc_transformer::{TransformOptions, Transformer};
|
||||||
|
|
@ -20,15 +19,16 @@ fn bench_transformer(criterion: &mut Criterion) {
|
||||||
// transforming an already transformed AST.
|
// transforming an already transformed AST.
|
||||||
b.iter_with_large_drop(|| {
|
b.iter_with_large_drop(|| {
|
||||||
let allocator = Allocator::default();
|
let allocator = Allocator::default();
|
||||||
let program = Parser::new(&allocator, source_text, source_type).parse().program;
|
let ParserReturn { trivias, program, .. } =
|
||||||
let semantic =
|
Parser::new(&allocator, source_text, source_type).parse();
|
||||||
SemanticBuilder::new(source_text, source_type).build(&program).semantic;
|
|
||||||
let program = allocator.alloc(program);
|
|
||||||
let transform_options = TransformOptions::default();
|
let transform_options = TransformOptions::default();
|
||||||
|
let program = allocator.alloc(program);
|
||||||
Transformer::new(
|
Transformer::new(
|
||||||
&allocator,
|
&allocator,
|
||||||
Path::new(&file.file_name),
|
Path::new(&file.file_name),
|
||||||
semantic,
|
source_type,
|
||||||
|
source_text,
|
||||||
|
&trivias,
|
||||||
transform_options,
|
transform_options,
|
||||||
)
|
)
|
||||||
.build(program)
|
.build(program)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use oxc_allocator::Allocator;
|
use oxc_allocator::Allocator;
|
||||||
use oxc_parser::Parser;
|
use oxc_parser::Parser;
|
||||||
use oxc_semantic::SemanticBuilder;
|
|
||||||
use oxc_span::SourceType;
|
use oxc_span::SourceType;
|
||||||
use oxc_transformer::{TransformOptions, Transformer};
|
use oxc_transformer::{TransformOptions, Transformer};
|
||||||
|
|
||||||
|
|
@ -18,18 +17,12 @@ use crate::{
|
||||||
/// TODO: add codegen to turn on idempotency test.
|
/// TODO: add codegen to turn on idempotency test.
|
||||||
fn get_result(source_text: &str, source_type: SourceType, source_path: &Path) -> TestResult {
|
fn get_result(source_text: &str, source_type: SourceType, source_path: &Path) -> TestResult {
|
||||||
let allocator = Allocator::default();
|
let allocator = Allocator::default();
|
||||||
|
let ret = Parser::new(&allocator, source_text, source_type).parse();
|
||||||
let parser_ret = Parser::new(&allocator, source_text, source_type).parse();
|
let mut program = ret.program;
|
||||||
|
|
||||||
let semantic_ret = SemanticBuilder::new(source_text, source_type)
|
|
||||||
.with_trivias(parser_ret.trivias)
|
|
||||||
.with_check_syntax_error(true)
|
|
||||||
.build(&parser_ret.program);
|
|
||||||
|
|
||||||
let mut program = parser_ret.program;
|
|
||||||
let options = TransformOptions::default();
|
let options = TransformOptions::default();
|
||||||
let _ = Transformer::new(&allocator, source_path, semantic_ret.semantic, options)
|
let _ =
|
||||||
.build(&mut program);
|
Transformer::new(&allocator, source_path, source_type, source_text, &ret.trivias, options)
|
||||||
|
.build(&mut program);
|
||||||
TestResult::Passed
|
TestResult::Passed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ test = false
|
||||||
oxc_span = { workspace = true }
|
oxc_span = { workspace = true }
|
||||||
oxc_allocator = { workspace = true }
|
oxc_allocator = { workspace = true }
|
||||||
oxc_parser = { workspace = true }
|
oxc_parser = { workspace = true }
|
||||||
oxc_semantic = { workspace = true }
|
|
||||||
oxc_codegen = { workspace = true }
|
oxc_codegen = { workspace = true }
|
||||||
oxc_transformer = { workspace = true }
|
oxc_transformer = { workspace = true }
|
||||||
oxc_tasks_common = { workspace = true }
|
oxc_tasks_common = { workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ use oxc_allocator::Allocator;
|
||||||
use oxc_codegen::{Codegen, CodegenOptions};
|
use oxc_codegen::{Codegen, CodegenOptions};
|
||||||
use oxc_diagnostics::{miette::miette, Error};
|
use oxc_diagnostics::{miette::miette, Error};
|
||||||
use oxc_parser::Parser;
|
use oxc_parser::Parser;
|
||||||
use oxc_semantic::SemanticBuilder;
|
|
||||||
use oxc_span::{SourceType, VALID_EXTENSIONS};
|
use oxc_span::{SourceType, VALID_EXTENSIONS};
|
||||||
use oxc_tasks_common::{normalize_path, print_diff_in_terminal, BabelOptions, TestOs};
|
use oxc_tasks_common::{normalize_path, print_diff_in_terminal, BabelOptions, TestOs};
|
||||||
use oxc_transformer::{
|
use oxc_transformer::{
|
||||||
|
|
@ -206,21 +205,20 @@ pub trait TestCase {
|
||||||
);
|
);
|
||||||
|
|
||||||
let ret = Parser::new(&allocator, &source_text, source_type).parse();
|
let ret = Parser::new(&allocator, &source_text, source_type).parse();
|
||||||
|
let mut program = ret.program;
|
||||||
let semantic = SemanticBuilder::new(&source_text, source_type)
|
let result = Transformer::new(
|
||||||
.with_trivias(ret.trivias)
|
&allocator,
|
||||||
.build_module_record(PathBuf::new(), &ret.program)
|
path,
|
||||||
.build(&ret.program)
|
source_type,
|
||||||
.semantic;
|
&source_text,
|
||||||
|
&ret.trivias,
|
||||||
let transformed_program = allocator.alloc(ret.program);
|
transform_options.clone(),
|
||||||
|
)
|
||||||
let result = Transformer::new(&allocator, path, semantic, transform_options.clone())
|
.build(&mut program);
|
||||||
.build(transformed_program);
|
|
||||||
|
|
||||||
result.map(|()| {
|
result.map(|()| {
|
||||||
Codegen::<false>::new("", &source_text, CodegenOptions::default())
|
Codegen::<false>::new("", &source_text, CodegenOptions::default())
|
||||||
.build(transformed_program)
|
.build(&program)
|
||||||
.source_text
|
.source_text
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -290,23 +288,20 @@ impl TestCase for ConformanceTestCase {
|
||||||
Ok(transform_options) => {
|
Ok(transform_options) => {
|
||||||
let ret = Parser::new(&allocator, &input, source_type).parse();
|
let ret = Parser::new(&allocator, &input, source_type).parse();
|
||||||
if ret.errors.is_empty() {
|
if ret.errors.is_empty() {
|
||||||
let semantic = SemanticBuilder::new(&input, source_type)
|
let mut program = ret.program;
|
||||||
.with_trivias(ret.trivias)
|
|
||||||
.build_module_record(PathBuf::new(), &ret.program)
|
|
||||||
.build(&ret.program)
|
|
||||||
.semantic;
|
|
||||||
let program = allocator.alloc(ret.program);
|
|
||||||
let transformer = Transformer::new(
|
let transformer = Transformer::new(
|
||||||
&allocator,
|
&allocator,
|
||||||
&self.path,
|
&self.path,
|
||||||
semantic,
|
source_type,
|
||||||
|
&input,
|
||||||
|
&ret.trivias,
|
||||||
transform_options.clone(),
|
transform_options.clone(),
|
||||||
);
|
);
|
||||||
let result = transformer.build(program);
|
let result = transformer.build(&mut program);
|
||||||
if result.is_ok() {
|
if result.is_ok() {
|
||||||
transformed_code =
|
transformed_code =
|
||||||
Codegen::<false>::new("", &input, codegen_options.clone())
|
Codegen::<false>::new("", &input, codegen_options.clone())
|
||||||
.build(program)
|
.build(&program)
|
||||||
.source_text;
|
.source_text;
|
||||||
} else {
|
} else {
|
||||||
let error = result
|
let error = result
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue