refactor(isolated-declarations): decouple codegen (#3715)

This commit is contained in:
Boshen 2024-06-17 11:45:29 +00:00
parent 87c3282deb
commit 815260ed2f
6 changed files with 37 additions and 42 deletions

View file

@ -19,7 +19,7 @@ pub fn get_leading_annotate_comment<const MINIFY: bool>(
CommentKind::SingleLine => comment.end,
CommentKind::MultiLine => comment.end + 2,
};
let source_code = codegen.source_code;
let source_code = codegen.source_text;
let content_between = &source_code[real_end as usize..node_start as usize];
// Used for VariableDeclaration (Rollup only respects "const" and only for the first one)
if content_between.chars().all(|ch| ch.is_ascii_whitespace()) {

View file

@ -72,7 +72,7 @@ impl<'a, const MINIFY: bool> From<Codegen<'a, MINIFY>> for Cow<'a, str> {
pub struct Codegen<'a, const MINIFY: bool> {
options: CodegenOptions,
source_code: &'a str,
source_text: &'a str,
trivias: Trivias,
@ -116,24 +116,24 @@ pub enum Separator {
impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
pub fn new(
source_name: &str,
source_code: &'a str,
source_text: &'a str,
trivias: Trivias,
options: CodegenOptions,
) -> Self {
// Initialize the output code buffer to reduce memory reallocation.
// Minification will reduce by at least half of the original size.
let source_len = source_code.len();
let source_len = source_text.len();
let capacity = if MINIFY { source_len / 2 } else { source_len };
let sourcemap_builder = options.enable_source_map.then(|| {
let mut sourcemap_builder = SourcemapBuilder::default();
sourcemap_builder.with_name_and_source(source_name, source_code);
sourcemap_builder.with_name_and_source(source_name, source_text);
sourcemap_builder
});
Self {
options,
source_code,
source_text,
trivias,
// mangler: None,
code: Vec::with_capacity(capacity),
@ -192,7 +192,7 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
/// Since if you want to print a range of source code, you need to borrow the source code
/// immutable first, and call the [Self::print_str] which is a mutable borrow.
pub fn print_range_of_source_code(&mut self, range: Range<usize>) {
self.code.extend_from_slice(self.source_code[range].as_bytes());
self.code.extend_from_slice(self.source_text[range].as_bytes());
}
/// In some scenario, we want to move the comment that should be codegened to another position.

View file

@ -20,7 +20,6 @@ workspace = true
doctest = false
[dependencies]
oxc_codegen = { workspace = true }
oxc_ast = { workspace = true }
oxc_span = { workspace = true }
oxc_allocator = { workspace = true }
@ -30,7 +29,5 @@ oxc_syntax = { workspace = true, features = ["to_js_string"] }
rustc-hash = { workspace = true }
[dev-dependencies]
oxc_parser = { workspace = true }
[features]
default = []
oxc_parser = { workspace = true }
oxc_codegen = { workspace = true }

View file

@ -2,6 +2,8 @@
use std::{env, path::Path};
use oxc_allocator::Allocator;
use oxc_ast::Trivias;
use oxc_codegen::{Codegen, CodegenOptions};
use oxc_isolated_declarations::TransformerDts;
use oxc_parser::Parser;
use oxc_span::SourceType;
@ -31,11 +33,14 @@ fn main() {
println!("Original:\n");
println!("{source_text}\n");
let program = ret.program;
let ret = TransformerDts::new(&allocator, path, &source_text, ret.trivias).build(&program);
let ret = TransformerDts::new(&allocator).build(&ret.program);
let printed =
Codegen::<false>::new("", &source_text, Trivias::default(), CodegenOptions::default())
.build(&ret.program)
.source_text;
println!("Transformed dts:\n");
println!("{}\n", ret.source_text);
println!("Dts Emit:\n");
println!("{printed}\n");
if !ret.errors.is_empty() {
println!("Transformed dts failed:\n");

View file

@ -17,20 +17,18 @@ mod return_type;
mod scope;
mod types;
use std::{collections::VecDeque, path::Path, rc::Rc};
use std::{collections::VecDeque, rc::Rc};
use context::{Ctx, TransformDtsCtx};
use oxc_allocator::Allocator;
use oxc_ast::Trivias;
#[allow(clippy::wildcard_imports)]
use oxc_ast::{ast::*, Visit};
use oxc_codegen::{Codegen, CodegenOptions};
use oxc_diagnostics::OxcDiagnostic;
use oxc_span::{SourceType, SPAN};
use scope::ScopeTree;
pub struct TransformerDtsReturn {
pub source_text: String,
pub struct TransformerDtsReturn<'a> {
pub program: Program<'a>,
pub errors: Vec<OxcDiagnostic>,
}
@ -40,13 +38,7 @@ pub struct TransformerDts<'a> {
}
impl<'a> TransformerDts<'a> {
#[allow(clippy::needless_pass_by_value)]
pub fn new(
allocator: &'a Allocator,
_source_path: &Path,
_source_text: &'a str,
_trivias: Trivias,
) -> Self {
pub fn new(allocator: &'a Allocator) -> Self {
let ctx = Rc::new(TransformDtsCtx::new(allocator));
Self { ctx, scope: ScopeTree::new(allocator) }
}
@ -54,17 +46,12 @@ impl<'a> TransformerDts<'a> {
/// # Errors
///
/// Returns `Vec<Error>` if any errors were collected during the transformation.
pub fn build(mut self, program: &Program<'a>) -> TransformerDtsReturn {
pub fn build(mut self, program: &Program<'a>) -> TransformerDtsReturn<'a> {
let source_type = SourceType::default().with_module(true).with_typescript_definition(true);
let directives = self.ctx.ast.new_vec();
let stmts = self.transform_program(program);
let program = self.ctx.ast.program(SPAN, source_type, directives, None, stmts);
let source_text =
Codegen::<false>::new("", "", Trivias::default(), CodegenOptions::default())
.build(&program)
.source_text;
TransformerDtsReturn { source_text, errors: self.ctx.take_errors() }
TransformerDtsReturn { program, errors: self.ctx.take_errors() }
}
}

View file

@ -3,7 +3,10 @@
use std::path::{Path, PathBuf};
use oxc_allocator::Allocator;
use oxc_isolated_declarations::{TransformerDts, TransformerDtsReturn};
use oxc_ast::Trivias;
use oxc_codegen::{Codegen, CodegenOptions};
use oxc_diagnostics::OxcDiagnostic;
use oxc_isolated_declarations::TransformerDts;
use oxc_parser::Parser;
use oxc_span::SourceType;
@ -137,13 +140,12 @@ impl TypeScriptTranspileCase {
}
for unit in &self.units {
let ret = transpile(&self.path, &unit.content);
let (source_text, errors) = transpile(&self.path, &unit.content);
let baseline = Baseline {
name: change_extension(&unit.name),
original: unit.content.clone(),
oxc_printed: ret.source_text,
diagnostic: ret
.errors
oxc_printed: source_text,
diagnostic: errors
.into_iter()
.map(|e| e.message.clone())
.collect::<Vec<_>>()
@ -160,9 +162,13 @@ fn change_extension(name: &str) -> String {
Path::new(name).with_extension("").with_extension("d.ts").to_str().unwrap().to_string()
}
fn transpile(path: &Path, source_text: &str) -> TransformerDtsReturn {
fn transpile(path: &Path, source_text: &str) -> (String, Vec<OxcDiagnostic>) {
let allocator = Allocator::default();
let source_type = SourceType::from_path(path).unwrap();
let ret = Parser::new(&allocator, source_text, source_type).parse();
TransformerDts::new(&allocator, path, source_text, ret.trivias).build(&ret.program)
let ret = TransformerDts::new(&allocator).build(&ret.program);
let printed = Codegen::<false>::new("", "", Trivias::default(), CodegenOptions::default())
.build(&ret.program)
.source_text;
(printed, ret.errors)
}