refactor(codegen): clean up annotation_comment

This commit is contained in:
Boshen 2024-07-14 15:55:50 +08:00
parent 9fbe094948
commit d1c4be0020
No known key found for this signature in database
GPG key ID: 67715A371E534061
4 changed files with 72 additions and 106 deletions

View file

@ -9,72 +9,76 @@ static MATCHER: Lazy<DoubleArrayAhoCorasick<usize>> = Lazy::new(|| {
DoubleArrayAhoCorasick::new(patterns).unwrap()
});
pub fn get_leading_annotate_comment<const MINIFY: bool>(
node_start: u32,
codegen: &mut Codegen<{ MINIFY }>,
) -> Option<Comment> {
let maybe_leading_comment = codegen.try_get_leading_comment(node_start);
let comment = maybe_leading_comment?;
let real_end = match comment.kind {
CommentKind::SingleLine => comment.span.end,
CommentKind::MultiLine => comment.span.end + 2,
};
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()) {
let comment_content = &source_code[comment.span.start as usize..comment.span.end as usize];
if MATCHER.find_iter(&comment_content).next().is_some() {
return Some(*comment);
impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
pub(crate) fn get_leading_annotate_comment(&mut self, node_start: u32) -> Option<Comment> {
let maybe_leading_comment = self.try_get_leading_comment(node_start);
let comment = maybe_leading_comment?;
let real_end = match comment.kind {
CommentKind::SingleLine => comment.span.end,
CommentKind::MultiLine => comment.span.end + 2,
};
let source_code = self.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()) {
let comment_content =
&source_code[comment.span.start as usize..comment.span.end as usize];
if MATCHER.find_iter(&comment_content).next().is_some() {
return Some(*comment);
}
None
} else {
None
}
None
} else {
None
}
}
pub fn print_comment<const MINIFY: bool>(comment: Comment, p: &mut Codegen<{ MINIFY }>) {
// ```js
// /*#__PURE__*/
// Object.getOwnPropertyNames(Symbol)
// // ios10.x Object.getOwnPropertyNames(Symbol) can enumerate 'arguments' and 'caller'
// // but accessing them on Symbol leads to TypeError because Symbol is a strict mode
// // function
// .filter(key => key !== 'arguments' && key !== 'caller')
// .map(key => (Symbol)[key])
// .filter(isSymbol),
// ```
// in this example, `Object.getOwnPropertyNames(Symbol)` and `Object.getOwnPropertyNames(Symbol).filter()`, `Object.getOwnPropertyNames(Symbol).filter().map()`
// share the same leading comment. since they both are call expr and has same span start, we need to avoid print the same comment multiple times.
if p.latest_consumed_comment_end >= comment.span.end {
return;
}
p.latest_consumed_comment_end = comment.span.end;
match comment.kind {
CommentKind::SingleLine => {
p.print_str("//");
p.print_range_of_source_code(comment.span.start as usize..comment.span.end as usize);
p.print_soft_newline();
p.print_indent();
pub(crate) fn print_comment(&mut self, comment: Comment) {
// ```js
// /*#__PURE__*/
// Object.getOwnPropertyNames(Symbol)
// // ios10.x Object.getOwnPropertyNames(Symbol) can enumerate 'arguments' and 'caller'
// // but accessing them on Symbol leads to TypeError because Symbol is a strict mode
// // function
// .filter(key => key !== 'arguments' && key !== 'caller')
// .map(key => (Symbol)[key])
// .filter(isSymbol),
// ```
// in this example, `Object.getOwnPropertyNames(Symbol)` and `Object.getOwnPropertyNames(Symbol).filter()`, `Object.getOwnPropertyNames(Symbol).filter().map()`
// share the same leading comment. since they both are call expr and has same span start, we need to avoid print the same comment multiple times.
if self.latest_consumed_comment_end >= comment.span.end {
return;
}
CommentKind::MultiLine => {
p.print_str("/*");
p.print_range_of_source_code(comment.span.start as usize..comment.span.end as usize);
p.print_str("*/");
p.print_soft_space();
self.latest_consumed_comment_end = comment.span.end;
match comment.kind {
CommentKind::SingleLine => {
self.print_str("//");
self.print_range_of_source_code(
comment.span.start as usize..comment.span.end as usize,
);
self.print_soft_newline();
self.print_indent();
}
CommentKind::MultiLine => {
self.print_str("/*");
self.print_range_of_source_code(
comment.span.start as usize..comment.span.end as usize,
);
self.print_str("*/");
self.print_soft_space();
}
}
}
}
pub fn gen_comment<const MINIFY: bool>(node_start: u32, codegen: &mut Codegen<{ MINIFY }>) {
if !codegen.comment_options.preserve_annotate_comments {
return;
}
if let Some(comment) = codegen.try_take_moved_comment(node_start) {
print_comment::<MINIFY>(comment, codegen);
}
let maybe_leading_annotate_comment = get_leading_annotate_comment(node_start, codegen);
if let Some(comment) = maybe_leading_annotate_comment {
print_comment::<MINIFY>(comment, codegen);
pub(crate) fn gen_comment(&mut self, node_start: u32) {
if !self.comment_options.preserve_annotate_comments {
return;
}
if let Some(comment) = self.try_take_moved_comment(node_start) {
self.print_comment(comment);
}
let maybe_leading_annotate_comment = self.get_leading_annotate_comment(node_start);
if let Some(comment) = maybe_leading_annotate_comment {
self.print_comment(comment);
}
}
}

View file

@ -10,11 +10,7 @@ use oxc_syntax::{
precedence::{GetPrecedence, Precedence},
};
use crate::{
annotation_comment::{gen_comment, get_leading_annotate_comment},
gen_comment::GenComment,
Codegen, Context, Operator,
};
use crate::{Codegen, Context, Operator};
pub trait Gen<const MINIFY: bool> {
fn gen(&self, _p: &mut Codegen<{ MINIFY }>, _ctx: Context) {}
@ -586,7 +582,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for VariableDeclaration<'a> {
if let Some(declarator) = self.declarations.first() {
if let Some(ref init) = declarator.init {
if let Some(leading_annotate_comment) =
get_leading_annotate_comment(self.span.start, p)
p.get_leading_annotate_comment(self.span.start)
{
p.move_comment(init.span().start, leading_annotate_comment);
}
@ -620,7 +616,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for VariableDeclarator<'a> {
impl<'a, const MINIFY: bool> Gen<MINIFY> for Function<'a> {
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
p.add_source_mapping(self.span.start);
self.gen_comment(p, ctx);
p.gen_comment(self.span.start);
let n = p.code_len();
let wrap = self.is_expression() && (p.start_of_stmt == n || p.start_of_default_export == n);
p.wrap(wrap, |p| {
@ -850,7 +846,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ExportNamedDeclaration<'a> {
if p.comment_options.preserve_annotate_comments {
match &self.declaration {
Some(Declaration::FunctionDeclaration(_)) => {
gen_comment(self.span.start, p);
p.gen_comment(self.span.start);
}
Some(Declaration::VariableDeclaration(var_decl))
if matches!(var_decl.kind, VariableDeclarationKind::Const) =>
@ -858,7 +854,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ExportNamedDeclaration<'a> {
if let Some(declarator) = var_decl.declarations.first() {
if let Some(ref init) = declarator.init {
if let Some(leading_annotate_comment) =
get_leading_annotate_comment(self.span.start, p)
p.get_leading_annotate_comment(self.span.start)
{
p.move_comment(init.span().start, leading_annotate_comment);
}
@ -1425,7 +1421,7 @@ impl<'a, const MINIFY: bool> GenExpr<MINIFY> for CallExpression<'a> {
fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, precedence: Precedence, ctx: Context) {
let wrap = precedence > self.precedence() || ctx.has_forbid_call();
let ctx = ctx.and_forbid_call(false);
self.gen_comment(p, ctx);
p.gen_comment(self.span.start);
p.wrap(wrap, |p| {
p.add_source_mapping(self.span.start);
self.callee.gen_expr(p, self.precedence(), ctx);
@ -1596,7 +1592,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for PropertyKey<'a> {
impl<'a, const MINIFY: bool> GenExpr<MINIFY> for ArrowFunctionExpression<'a> {
fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, precedence: Precedence, ctx: Context) {
p.wrap(precedence > Precedence::Assign, |p| {
self.gen_comment(p, ctx);
p.gen_comment(self.span.start);
if self.r#async {
p.add_source_mapping(self.span.start);
p.print_str("async");
@ -2055,7 +2051,7 @@ impl<'a, const MINIFY: bool> GenExpr<MINIFY> for ChainExpression<'a> {
impl<'a, const MINIFY: bool> GenExpr<MINIFY> for NewExpression<'a> {
fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, precedence: Precedence, ctx: Context) {
self.gen_comment(p, ctx);
p.gen_comment(self.span.start);
p.wrap(precedence > self.precedence(), |p| {
p.add_source_mapping(self.span.start);
p.print_str("new ");

View file

@ -1,33 +0,0 @@
use oxc_ast::ast::{ArrowFunctionExpression, CallExpression, Function, NewExpression};
use crate::annotation_comment::gen_comment;
use crate::{Codegen, Context};
/// the [GenComment] trait only generate annotate comments like `/* @__PURE__ */` and `/* @__NO_SIDE_EFFECTS__ */`.
pub trait GenComment<const MINIFY: bool> {
fn gen_comment(&self, _p: &mut Codegen<{ MINIFY }>, _ctx: Context) {}
}
impl<const MINIFY: bool> GenComment<MINIFY> for ArrowFunctionExpression<'_> {
fn gen_comment(&self, codegen: &mut Codegen<{ MINIFY }>, _ctx: Context) {
gen_comment(self.span.start, codegen);
}
}
impl<const MINIFY: bool> GenComment<MINIFY> for Function<'_> {
fn gen_comment(&self, codegen: &mut Codegen<{ MINIFY }>, _ctx: Context) {
gen_comment(self.span.start, codegen);
}
}
impl<const MINIFY: bool> GenComment<MINIFY> for CallExpression<'_> {
fn gen_comment(&self, codegen: &mut Codegen<{ MINIFY }>, _ctx: Context) {
gen_comment(self.span.start, codegen);
}
}
impl<const MINIFY: bool> GenComment<MINIFY> for NewExpression<'_> {
fn gen_comment(&self, codegen: &mut Codegen<{ MINIFY }>, _ctx: Context) {
gen_comment(self.span.start, codegen);
}
}

View file

@ -6,7 +6,6 @@
mod annotation_comment;
mod context;
mod gen;
mod gen_comment;
mod operator;
mod sourcemap_builder;