From 3f52ebeb48a2496f467ea817545fb81b375ba000 Mon Sep 17 00:00:00 2001 From: Boshen Date: Sun, 6 Oct 2024 09:39:48 +0800 Subject: [PATCH] refactor(napi/transform): remove context --- napi/transform/src/context.rs | 124 --------------------- napi/transform/src/errors.rs | 40 +++++++ napi/transform/src/isolated_declaration.rs | 52 ++++----- napi/transform/src/lib.rs | 2 +- napi/transform/src/transformer.rs | 40 +------ 5 files changed, 72 insertions(+), 186 deletions(-) delete mode 100644 napi/transform/src/context.rs create mode 100644 napi/transform/src/errors.rs diff --git a/napi/transform/src/context.rs b/napi/transform/src/context.rs deleted file mode 100644 index 22b045e16b5ff6..00000000000000 --- a/napi/transform/src/context.rs +++ /dev/null @@ -1,124 +0,0 @@ -use std::{ - cell::{Ref, RefCell}, - sync::Arc, -}; - -use oxc::{ - allocator::Allocator, - ast::{ast::Program, Trivias}, - codegen::Codegen, - diagnostics::{Error, NamedSource, OxcDiagnostic}, - parser::{Parser, ParserReturn}, - span::SourceType, -}; - -#[must_use] -pub(crate) struct TransformContext<'a> { - pub allocator: &'a Allocator, - program: RefCell>, - pub trivias: Trivias, - - /// Generate source maps? - source_map: bool, - - /// Path to the file being transformed. - filename: &'a str, - - /// Source text of the file being transformed. - source_text: &'a str, - source_type: SourceType, - - /// Errors that occurred during transformation. - errors: RefCell>, -} - -impl<'a> TransformContext<'a> { - pub fn new( - allocator: &'a Allocator, - filename: &'a str, - source_text: &'a str, - source_type: SourceType, - source_map: Option, - ) -> Self { - let ParserReturn { errors, program, trivias, .. } = - Parser::new(allocator, source_text, source_type).parse(); - let source_map = source_map.unwrap_or_default(); - Self { - allocator, - program: RefCell::new(program), - trivias, - - source_map, - - filename, - source_text, - source_type, - errors: RefCell::new(errors), - } - } - - #[inline] - pub fn file_name(&self) -> &'a str { - self.filename - } - - #[inline] - pub fn source_text(&self) -> &'a str { - self.source_text - } - - #[inline] - pub fn program(&self) -> Ref<'_, Program<'a>> { - self.program.borrow() - } - - pub fn codegen(&self) -> Codegen<'a> { - let codegen = Codegen::new(); - if self.source_map { - codegen.enable_source_map(self.file_name(), self.source_text()) - } else { - codegen - } - } - - pub fn add_diagnostics(&self, diagnostics: Vec) { - if diagnostics.is_empty() { - return; - } - self.errors.borrow_mut().extend(diagnostics); - } - - pub fn take_and_render_reports(&self) -> Vec { - let diagnostics = std::mem::take(&mut *self.errors.borrow_mut()); - // TODO: make pretty-printed errors configurable - self.wrap_diagnostics(diagnostics).map(|error| format!("{error:?}")).collect() - } - - fn wrap_diagnostics>( - &self, - diagnostics: D, - ) -> impl Iterator { - let source = { - let lang = match (self.source_type.is_javascript(), self.source_type.is_jsx()) { - (true, false) => "JavaScript", - (true, true) => "JSX", - (false, true) => "TypeScript React", - (false, false) => { - if self.source_type.is_typescript_definition() { - "TypeScript Declaration" - } else { - "TypeScript" - } - } - }; - - let ns = NamedSource::new(self.file_name(), self.source_text().to_string()) - .with_language(lang); - Arc::new(ns) - }; - - diagnostics - .into_iter() - .map(move |diagnostic| Error::from(diagnostic).with_source_code(Arc::clone(&source))) - } -} diff --git a/napi/transform/src/errors.rs b/napi/transform/src/errors.rs new file mode 100644 index 00000000000000..339184c4392979 --- /dev/null +++ b/napi/transform/src/errors.rs @@ -0,0 +1,40 @@ +use std::sync::Arc; + +use oxc::{ + diagnostics::{Error, NamedSource, OxcDiagnostic}, + span::SourceType, +}; + +pub fn wrap_diagnostics( + filename: &str, + source_type: SourceType, + source_text: &str, + errors: Vec, +) -> Vec { + if errors.is_empty() { + return vec![]; + } + let source = { + let lang = match (source_type.is_javascript(), source_type.is_jsx()) { + (true, false) => "JavaScript", + (true, true) => "JSX", + (false, true) => "TypeScript React", + (false, false) => { + if source_type.is_typescript_definition() { + "TypeScript Declaration" + } else { + "TypeScript" + } + } + }; + + let ns = NamedSource::new(filename, source_text.to_string()).with_language(lang); + Arc::new(ns) + }; + + errors + .into_iter() + .map(move |diagnostic| Error::from(diagnostic).with_source_code(Arc::clone(&source))) + .map(|error| format!("{error:?}")) + .collect() +} diff --git a/napi/transform/src/isolated_declaration.rs b/napi/transform/src/isolated_declaration.rs index 957309339dbfb4..beb6e72622f8f8 100644 --- a/napi/transform/src/isolated_declaration.rs +++ b/napi/transform/src/isolated_declaration.rs @@ -1,13 +1,18 @@ use napi_derive::napi; + use oxc::{ allocator::Allocator, - codegen::{CodegenReturn, CommentOptions}, + codegen::{CodeGenerator, CommentOptions}, isolated_declarations::IsolatedDeclarations, - napi::isolated_declarations::{IsolatedDeclarationsOptions, IsolatedDeclarationsResult}, + napi::{ + isolated_declarations::{IsolatedDeclarationsOptions, IsolatedDeclarationsResult}, + source_map::SourceMap, + }, + parser::Parser, span::SourceType, }; -use crate::context::TransformContext; +use crate::errors::wrap_diagnostics; /// TypeScript Isolated Declarations for Standalone DTS Emit #[allow(clippy::needless_pass_by_value)] @@ -20,36 +25,33 @@ pub fn isolated_declaration( let source_type = SourceType::from_path(&filename).unwrap_or_default().with_typescript(true); let allocator = Allocator::default(); let options = options.unwrap_or_default(); - let ctx = - TransformContext::new(&allocator, &filename, &source_text, source_type, options.sourcemap); - let transformed_ret = build_declarations(&ctx, options); - IsolatedDeclarationsResult { - code: transformed_ret.source_text, - map: options.sourcemap.and_then(|_| transformed_ret.source_map.map(Into::into)), - errors: ctx.take_and_render_reports(), - } -} + let ret = Parser::new(&allocator, &source_text, source_type).parse(); -pub(crate) fn build_declarations( - ctx: &TransformContext<'_>, - options: IsolatedDeclarationsOptions, -) -> CodegenReturn { let transformed_ret = IsolatedDeclarations::new( - ctx.allocator, - ctx.source_text(), - &ctx.trivias, + &allocator, + &source_text, + &ret.trivias, oxc::isolated_declarations::IsolatedDeclarationsOptions { strip_internal: options.strip_internal.unwrap_or(false), }, ) - .build(&ctx.program()); - ctx.add_diagnostics(transformed_ret.errors); - ctx.codegen() + .build(&ret.program); + + let codegen_ret = CodeGenerator::new() .enable_comment( - ctx.source_text(), - ctx.trivias.clone(), + &source_text, + ret.trivias.clone(), CommentOptions { preserve_annotate_comments: false }, ) - .build(&transformed_ret.program) + .build(&transformed_ret.program); + + let errors = ret.errors.into_iter().chain(transformed_ret.errors).collect(); + let errors = wrap_diagnostics(&filename, source_type, &source_text, errors); + + IsolatedDeclarationsResult { + code: codegen_ret.source_text, + map: codegen_ret.source_map.map(SourceMap::from), + errors, + } } diff --git a/napi/transform/src/lib.rs b/napi/transform/src/lib.rs index bcab5391a0575d..ad8e001a33cb34 100644 --- a/napi/transform/src/lib.rs +++ b/napi/transform/src/lib.rs @@ -1,4 +1,4 @@ -mod context; +mod errors; pub use oxc::napi::{isolated_declarations, transform}; diff --git a/napi/transform/src/transformer.rs b/napi/transform/src/transformer.rs index 544511c2e53382..2fe315d5d6be4f 100644 --- a/napi/transform/src/transformer.rs +++ b/napi/transform/src/transformer.rs @@ -1,11 +1,11 @@ -use std::{path::Path, sync::Arc}; +use std::path::Path; use napi::Either; use napi_derive::napi; use oxc::{ codegen::CodegenReturn, - diagnostics::{Error, NamedSource, OxcDiagnostic}, + diagnostics::OxcDiagnostic, napi::{ source_map::SourceMap, transform::{TransformOptions, TransformResult}, @@ -15,6 +15,8 @@ use oxc::{ CompilerInterface, }; +use crate::errors::wrap_diagnostics; + #[derive(Default)] struct Compiler { transform_options: oxc::transformer::TransformOptions, @@ -168,37 +170,3 @@ pub fn transform( errors: wrap_diagnostics(&filename, source_type, &source_text, compiler.errors), } } - -fn wrap_diagnostics( - filename: &str, - source_type: SourceType, - source_text: &str, - errors: Vec, -) -> Vec { - if errors.is_empty() { - return vec![]; - } - let source = { - let lang = match (source_type.is_javascript(), source_type.is_jsx()) { - (true, false) => "JavaScript", - (true, true) => "JSX", - (false, true) => "TypeScript React", - (false, false) => { - if source_type.is_typescript_definition() { - "TypeScript Declaration" - } else { - "TypeScript" - } - } - }; - - let ns = NamedSource::new(filename, source_text.to_string()).with_language(lang); - Arc::new(ns) - }; - - errors - .into_iter() - .map(move |diagnostic| Error::from(diagnostic).with_source_code(Arc::clone(&source))) - .map(|error| format!("{error:?}")) - .collect() -}