From ee27b92465ce1f81452c4c8e422e9ab8e07ebb8c Mon Sep 17 00:00:00 2001 From: Boshen <1430279+Boshen@users.noreply.github.com> Date: Fri, 1 Nov 2024 16:56:56 +0000 Subject: [PATCH] feat(codegen): print eof legal comments (#7058) part of https://github.com/oxc-project/oxc/issues/7050 --- crates/oxc_codegen/src/comment.rs | 22 +++++++++- crates/oxc_codegen/src/lib.rs | 7 ++-- crates/oxc_codegen/src/options.rs | 10 +++++ .../tests/integration/legal_comments.rs | 10 ++++- .../snapshots/legal_eof_comments.snap | 42 +++++++++++++++++++ 5 files changed, 85 insertions(+), 6 deletions(-) create mode 100644 crates/oxc_codegen/tests/integration/snapshots/legal_eof_comments.snap diff --git a/crates/oxc_codegen/src/comment.rs b/crates/oxc_codegen/src/comment.rs index 6e8a861169bd3..8179f31c64840 100644 --- a/crates/oxc_codegen/src/comment.rs +++ b/crates/oxc_codegen/src/comment.rs @@ -50,8 +50,14 @@ impl<'a> Codegen<'a> { } fn is_legal_comment(&self, comment: &Comment) -> bool { - (self.options.comments || self.options.legal_comments.is_inline()) - && comment.is_legal(self.source_text) + if self.options.comments { + if self.options.legal_comments.is_inline() || self.options.legal_comments.is_none() { + return comment.is_legal(self.source_text); + } + } else if self.options.legal_comments.is_inline() { + return comment.is_legal(self.source_text); + } + false } /// Weather to keep leading comments. @@ -142,6 +148,18 @@ impl<'a> Codegen<'a> { } } + pub(crate) fn try_print_eof_legal_comments(&mut self, comments: &[Comment]) { + if !self.options.legal_comments.is_eof() { + return; + } + for c in comments { + if c.is_legal(self.source_text) { + self.print_comment(c); + self.print_hard_newline(); + } + } + } + fn print_comments(&mut self, start: u32, comments: &[Comment], unused_comments: Vec) { if comments.first().is_some_and(|c| c.preceded_by_newline) { // Skip printing newline if this comment is already on a newline. diff --git a/crates/oxc_codegen/src/lib.rs b/crates/oxc_codegen/src/lib.rs index 089f628948238..320123de33b91 100644 --- a/crates/oxc_codegen/src/lib.rs +++ b/crates/oxc_codegen/src/lib.rs @@ -183,8 +183,9 @@ impl<'a> Codegen<'a> { self } - /// Print a [`Program`] into a string of source code. A source map will be - /// generated if [`CodegenOptions::source_map_path`] is set. + /// Print a [`Program`] into a string of source code. + /// + /// A source map will be generated if [`CodegenOptions::source_map_path`] is set. #[must_use] pub fn build(mut self, program: &Program<'a>) -> CodegenReturn { self.quote = if self.options.single_quote { b'\'' } else { b'"' }; @@ -196,8 +197,8 @@ impl<'a> Codegen<'a> { if let Some(path) = &self.options.source_map_path { self.sourcemap_builder = Some(SourcemapBuilder::new(path, program.source_text)); } - program.print(&mut self, Context::default()); + self.try_print_eof_legal_comments(&program.comments); let code = self.code.into_string(); let map = self.sourcemap_builder.map(SourcemapBuilder::into_sourcemap); CodegenReturn { code, map } diff --git a/crates/oxc_codegen/src/options.rs b/crates/oxc_codegen/src/options.rs index 0807a8e6f1063..64b6ee73f8866 100644 --- a/crates/oxc_codegen/src/options.rs +++ b/crates/oxc_codegen/src/options.rs @@ -19,10 +19,20 @@ pub enum LegalComment { } impl LegalComment { + /// Is None. + pub fn is_none(self) -> bool { + self == Self::None + } + /// Is inline mode. pub fn is_inline(self) -> bool { self == Self::Inline } + + /// Is EOF mode. + pub fn is_eof(self) -> bool { + self == Self::Eof + } } /// Codegen Options. diff --git a/crates/oxc_codegen/tests/integration/legal_comments.rs b/crates/oxc_codegen/tests/integration/legal_comments.rs index 0700fd6b6abaf..e1abc8897f004 100644 --- a/crates/oxc_codegen/tests/integration/legal_comments.rs +++ b/crates/oxc_codegen/tests/integration/legal_comments.rs @@ -1,4 +1,6 @@ -use crate::snapshot; +use oxc_codegen::{CodegenOptions, LegalComment}; + +use crate::{snapshot, snapshot_options}; fn cases() -> Vec<&'static str> { vec![ @@ -13,3 +15,9 @@ fn cases() -> Vec<&'static str> { fn legal_inline_comment() { snapshot("legal_inline_comments", &cases()); } + +#[test] +fn legal_eof_comment() { + let options = CodegenOptions { legal_comments: LegalComment::Eof, ..Default::default() }; + snapshot_options("legal_eof_comments", &cases(), &options); +} diff --git a/crates/oxc_codegen/tests/integration/snapshots/legal_eof_comments.snap b/crates/oxc_codegen/tests/integration/snapshots/legal_eof_comments.snap new file mode 100644 index 0000000000000..a4c429fe61146 --- /dev/null +++ b/crates/oxc_codegen/tests/integration/snapshots/legal_eof_comments.snap @@ -0,0 +1,42 @@ +--- +source: crates/oxc_codegen/tests/integration/main.rs +--- +########## 0 +/* @license */ +/* @license */ +foo;bar; +---------- +foo; +bar; +/* @license */ +/* @license */ + +########## 1 +/* @license */ +/* @preserve */ +foo;bar; +---------- +foo; +bar; +/* @license */ +/* @preserve */ + +########## 2 +/* @license */ +//! KEEP +foo;bar; +---------- +foo; +bar; +/* @license */ +//! KEEP + +########## 3 +/* @license */ +/*! KEEP */ +foo;bar; +---------- +foo; +bar; +/* @license */ +/*! KEEP */