mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
refactor(isolated-declarations): decouple codegen (#3715)
This commit is contained in:
parent
87c3282deb
commit
815260ed2f
6 changed files with 37 additions and 42 deletions
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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() }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue