fix(es/minifier): Force rename synthesized identifiers (#9473)

**Related issue:**

 - Closes https://github.com/swc-project/swc/issues/9468
This commit is contained in:
Donny/강동윤 2024-08-21 14:01:16 +09:00 committed by GitHub
parent 3ee8980dbe
commit c72b5f8b32
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 46 additions and 20 deletions

View File

@ -0,0 +1,6 @@
---
swc_ecma_minifier: patch
swc_core: patch
---
fix(es/minifier): Force rename synthesized identifiers

View File

@ -2,11 +2,11 @@ use radix_fmt::Radix;
use swc_common::{util::take::Take, Spanned, SyntaxContext};
use swc_ecma_ast::*;
use swc_ecma_utils::{number::ToJsString, ExprExt, IsEmpty, Value};
#[cfg(feature = "debug")]
use {crate::debug::dump, tracing::debug};
use super::Pure;
use crate::compress::util::{eval_as_number, is_pure_undefined_or_null};
#[cfg(feature = "debug")]
use crate::debug::dump;
impl Pure<'_> {
pub(super) fn eval_array_method_call(&mut self, e: &mut Expr) {
@ -659,21 +659,15 @@ impl Pure<'_> {
_ => return,
};
#[cfg(feature = "debug")]
debug!(
"before: optimize_member_expr: {}",
dump(&*member_expr, false)
);
if let Some(replacement) =
self.optimize_member_expr(&mut member_expr.obj, &member_expr.prop)
{
*e = replacement;
self.changed = true;
report_change!("member_expr: Optimized member expression");
#[cfg(feature = "debug")]
debug!("after: optimize_member_expr: {}", dump(&*e, false));
report_change!(
"member_expr: Optimized member expression as {}",
dump(&*e, false)
);
}
}

View File

@ -232,7 +232,7 @@ pub fn optimize(
let _timer = timer!("mangle names");
// TODO: base54.reset();
let preserved = idents_to_preserve(mangle.clone(), &n);
let preserved = idents_to_preserve(mangle.clone(), marks, &n);
let chars = CharFreq::compute(
&n,

View File

@ -1,26 +1,36 @@
use rustc_hash::FxHashSet;
use swc_ecma_ast::*;
use swc_ecma_usage_analyzer::marks::Marks;
use swc_ecma_utils::find_pat_ids;
use swc_ecma_visit::{noop_visit_type, Visit, VisitWith};
use crate::option::MangleOptions;
/// Returns `(preserved, unresolved)`
pub(crate) fn idents_to_preserve<N>(options: MangleOptions, n: &N) -> FxHashSet<Id>
pub(crate) fn idents_to_preserve<N>(options: MangleOptions, marks: Marks, n: &N) -> FxHashSet<Id>
where
N: VisitWith<Preserver>,
N: for<'a> VisitWith<Preserver<'a>>,
{
let mut v = Preserver {
options,
options: &options,
preserved: Default::default(),
should_preserve: false,
in_top_level: false,
};
n.visit_with(&mut v);
let top_level_mark = marks.top_level_ctxt.outer();
// Force rename synthesized names
// See https://github.com/swc-project/swc/issues/9468
v.preserved.retain(|id| {
options.reserved.contains(&id.0) || id.1.outer().is_descendant_of(top_level_mark)
});
v.preserved
}
pub(crate) struct Preserver {
options: MangleOptions,
pub(crate) struct Preserver<'a> {
options: &'a MangleOptions,
preserved: FxHashSet<Id>,
@ -28,13 +38,13 @@ pub(crate) struct Preserver {
in_top_level: bool,
}
impl Preserver {
impl<'a> Preserver<'a> {
fn is_reserved(&self, ident: &Ident) -> bool {
self.options.reserved.contains(&ident.sym)
}
}
impl Visit for Preserver {
impl<'a> Visit for Preserver<'a> {
noop_visit_type!();
fn visit_block_stmt(&mut self, n: &BlockStmt) {

View File

@ -0,0 +1,10 @@
function func1(arg1, arg2) {
return getX(arg1) + arg2
}
function getX(x) {
const v = document.getElementById('eid').getAttribute(x)
return v
}
console.log(func1(7, getX('data-x')))
console.log(func1(7, getX('data-y')))

View File

@ -0,0 +1 @@
{}

View File

@ -0,0 +1,5 @@
var t, e;
function getX(t) {
return document.getElementById('eid').getAttribute(t);
}
console.log((t = getX('data-x'), getX(7) + t)), console.log((e = getX('data-y'), getX(7) + e));