mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
refactor(codegen): clean up annotation_comment
This commit is contained in:
parent
9fbe094948
commit
d1c4be0020
4 changed files with 72 additions and 106 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 ");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,6 @@
|
|||
mod annotation_comment;
|
||||
mod context;
|
||||
mod gen;
|
||||
mod gen_comment;
|
||||
mod operator;
|
||||
mod sourcemap_builder;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue