mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
feat(oxc_codegen): generate annotation comments before CallExpression and NewExpression (#4119)
1. test case copy from `vue/core`, here are all usages of `#__PURE__` in `vue/core` https://gist.github.com/IWANABETHATGUY/c7911ecd98467a2969b2a994a34d32bc#file-pure_annotation_in_vue_repo-sh 2. Also took a look in other codebase, https://github.com/search?q=%23__PURE__&type=code, most of the usage of `#__PURE__` attached as leading comment before `CallExpression` and `NewExpression`
This commit is contained in:
parent
44c7fe39ee
commit
365d9ba252
4 changed files with 72 additions and 19 deletions
|
|
@ -12,6 +12,7 @@ use oxc_syntax::{
|
|||
|
||||
use crate::{
|
||||
annotation_comment::{gen_comment, get_leading_annotate_comment},
|
||||
gen_comment::GenComment,
|
||||
Codegen, Context, Operator,
|
||||
};
|
||||
|
||||
|
|
@ -32,11 +33,6 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// 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<'a, const MINIFY: bool, T> GenExpr<MINIFY> for Box<'a, T>
|
||||
where
|
||||
T: GenExpr<MINIFY>,
|
||||
|
|
@ -1075,18 +1071,6 @@ impl<'a, const MINIFY: bool> GenExpr<MINIFY> for TSAsExpression<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
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<'a, const MINIFY: bool> GenExpr<MINIFY> for ParenthesizedExpression<'a> {
|
||||
fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, precedence: Precedence, ctx: Context) {
|
||||
p.print_str(b"(");
|
||||
|
|
@ -1436,6 +1420,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.wrap(wrap, |p| {
|
||||
p.add_source_mapping(self.span.start);
|
||||
self.callee.gen_expr(p, self.precedence(), ctx);
|
||||
|
|
@ -2065,6 +2050,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.wrap(precedence > self.precedence(), |p| {
|
||||
p.add_source_mapping(self.span.start);
|
||||
p.print_str(b"new ");
|
||||
|
|
|
|||
33
crates/oxc_codegen/src/gen_comment.rs
Normal file
33
crates/oxc_codegen/src/gen_comment.rs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
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,6 +6,7 @@
|
|||
mod annotation_comment;
|
||||
mod context;
|
||||
mod gen;
|
||||
mod gen_comment;
|
||||
mod operator;
|
||||
mod sourcemap_builder;
|
||||
|
||||
|
|
@ -520,9 +521,9 @@ pub(crate) type MoveCommentMap = FxHashMap<u32, (u32, Comment)>;
|
|||
|
||||
// Comment related
|
||||
impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
|
||||
/// This method to avoid rustc borrow checker issue.
|
||||
/// Avoid issue related to rustc borrow checker .
|
||||
/// 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.
|
||||
/// as immutable first, and call the [Self::print_str] which is a mutable borrow.
|
||||
fn print_range_of_source_code(&mut self, range: Range<usize>) {
|
||||
self.code.extend_from_slice(self.source_text[range].as_bytes());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -372,6 +372,39 @@ let l2 = () => {}, l3 = () => {};
|
|||
const c2 = /* #__NO_SIDE_EFFECTS__ */ () => {}, c3 = () => {};
|
||||
",
|
||||
);
|
||||
|
||||
test_comment_helper(
|
||||
r"
|
||||
isFunction(options)
|
||||
? // #8326: extend call and options.name access are considered side-effects
|
||||
// by Rollup, so we have to wrap it in a pure-annotated IIFE.
|
||||
/*#__PURE__*/ (() =>
|
||||
extend({ name: options.name }, extraOptions, { setup: options }))()
|
||||
: options
|
||||
",
|
||||
r"isFunction(options) ? /*#__PURE__*/ (() => extend({name: options.name}, extraOptions, {setup: options}))() : options;
|
||||
",
|
||||
);
|
||||
|
||||
test_comment_helper(
|
||||
r"
|
||||
const obj = {
|
||||
props: /*#__PURE__*/ extend({}, TransitionPropsValidators, {
|
||||
tag: String,
|
||||
moveClass: String,
|
||||
}),
|
||||
};
|
||||
const p = /*#__PURE__*/ Promise.resolve();
|
||||
",
|
||||
"const obj = {props: /*#__PURE__*/ extend({}, TransitionPropsValidators, {\n\ttag: String,\n\tmoveClass: String\n})};\nconst p = /*#__PURE__*/ Promise.resolve();\n",
|
||||
);
|
||||
|
||||
test_comment_helper(
|
||||
r"
|
||||
const staticCacheMap = /*#__PURE__*/ new WeakMap()
|
||||
",
|
||||
"const staticCacheMap = /*#__PURE__*/ new WeakMap();\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
Loading…
Reference in a new issue