fix(es/minifier): Don't create names which is same as an unresolved var (#4806)

This commit is contained in:
Donny/강동윤 2022-05-26 18:27:24 +09:00 committed by GitHub
parent 829a9c0dd3
commit 073b1469e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 13 deletions

View File

@ -16,12 +16,21 @@ pub(super) struct Analyzer {
}
impl Analyzer {
pub(super) fn into_rename_map(mut self, preserved: &FxHashSet<Id>) -> AHashMap<Id, JsWord> {
pub(super) fn into_rename_map(
mut self,
preserved: &FxHashSet<Id>,
unresolved: &FxHashSet<JsWord>,
) -> AHashMap<Id, JsWord> {
let mut map = Default::default();
self.scope.prepare_renaming();
let preserved_symbols = preserved.iter().cloned().map(|v| v.0).collect();
let mut preserved_symbols = preserved
.iter()
.cloned()
.map(|v| v.0)
.collect::<FxHashSet<_>>();
preserved_symbols.extend(unresolved.iter().cloned());
self.scope
.rename(&mut map, &Default::default(), preserved, &preserved_symbols);

View File

@ -1,26 +1,39 @@
use rustc_hash::FxHashSet;
use swc_atoms::JsWord;
use swc_common::SyntaxContext;
use swc_ecma_ast::*;
use swc_ecma_utils::find_pat_ids;
use swc_ecma_visit::{noop_visit_type, Visit, VisitWith};
use crate::option::MangleOptions;
pub(super) fn idents_to_preserve<N>(options: MangleOptions, n: &N) -> FxHashSet<Id>
/// Returns `(preserved, unresolved)`
pub(super) fn idents_to_preserve<N>(
options: MangleOptions,
unresolved_ctxt: SyntaxContext,
n: &N,
) -> (FxHashSet<Id>, FxHashSet<JsWord>)
where
N: VisitWith<Preserver>,
{
let mut v = Preserver {
options,
unresolved_ctxt,
preserved: Default::default(),
unresolved: Default::default(),
should_preserve: false,
in_top_level: false,
};
n.visit_with(&mut v);
v.preserved
(v.preserved, v.unresolved)
}
pub(super) struct Preserver {
options: MangleOptions,
unresolved_ctxt: SyntaxContext,
preserved: FxHashSet<Id>,
unresolved: FxHashSet<JsWord>,
should_preserve: bool,
in_top_level: bool,
}
@ -116,6 +129,12 @@ impl Visit for Preserver {
}
}
fn visit_ident(&mut self, n: &Ident) {
if self.unresolved_ctxt == n.span.ctxt {
self.unresolved.insert(n.sym.clone());
}
}
fn visit_module_items(&mut self, n: &[ModuleItem]) {
for n in n {
self.in_top_level = true;

View File

@ -1,6 +1,6 @@
use rustc_hash::FxHashSet;
use swc_atoms::JsWord;
use swc_common::collections::AHashMap;
use swc_common::{collections::AHashMap, SyntaxContext};
use swc_ecma_ast::*;
use swc_ecma_transforms_base::hygiene::rename;
use swc_ecma_visit::{noop_visit_mut_type, VisitMut, VisitMutWith, VisitWith};
@ -9,17 +9,22 @@ use tracing::info;
use super::{analyzer::Analyzer, preserver::idents_to_preserve};
use crate::{debug::dump, marks::Marks, option::MangleOptions, util::contains_eval};
pub(crate) fn name_mangler(options: MangleOptions, _marks: Marks) -> impl VisitMut {
pub(crate) fn name_mangler(options: MangleOptions, marks: Marks) -> impl VisitMut {
Mangler {
options,
unresolved_ctxt: SyntaxContext::empty().apply_mark(marks.unresolved_mark),
preserved: Default::default(),
unresolved: Default::default(),
}
}
struct Mangler {
options: MangleOptions,
unresolved_ctxt: SyntaxContext,
preserved: FxHashSet<Id>,
unresolved: FxHashSet<JsWord>,
}
impl Mangler {
@ -33,7 +38,7 @@ impl Mangler {
};
node.visit_with(&mut analyzer);
analyzer.into_rename_map(&self.preserved)
analyzer.into_rename_map(&self.preserved, &self.unresolved)
}
}
@ -75,7 +80,9 @@ impl VisitMut for Mangler {
unit!(visit_mut_private_method, PrivateMethod);
fn visit_mut_module(&mut self, m: &mut Module) {
self.preserved = idents_to_preserve(self.options.clone(), &*m);
let v = idents_to_preserve(self.options.clone(), self.unresolved_ctxt, &*m);
self.preserved = v.0;
self.unresolved = v.1;
if option_env!("DEBUG_MANGLER") == Some("1") {
info!("Before: {}", dump(&*m, true));
@ -95,7 +102,9 @@ impl VisitMut for Mangler {
}
fn visit_mut_script(&mut self, s: &mut Script) {
self.preserved = idents_to_preserve(self.options.clone(), &*s);
let v = idents_to_preserve(self.options.clone(), self.unresolved_ctxt, &*s);
self.preserved = v.0;
self.unresolved = v.1;
if contains_eval(s, true) {
s.visit_mut_children_with(self);

View File

@ -1,12 +1,12 @@
import*as a from"react";export default function b(){const[c,d]=a.useState({hits:[]}),[b,e]=a.useState("react");return a.useEffect(()=>{""!==b&&a();async function a(){const a=await fetch("https://hn.algolia.com/api/v1/search?query="+b),c=await a.json();d(c)}},[b]),<>
import*as b from"react";export default function c(){const[d,e]=b.useState({hits:[]}),[c,f]=b.useState("react");return b.useEffect(()=>{""!==c&&b();async function b(){const b=await fetch("https://hn.algolia.com/api/v1/search?query="+c),d=await b.json();e(d)}},[c]),<>
<input value={b}onChange={a=>e(a.target.value)}/>
<input value={c}onChange={b=>f(b.target.value)}/>
<ul >
{c.hits.map(a=><li key={a.objectID}>
{d.hits.map(b=><li key={b.objectID}>
<a href={a.url}>{a.title}</a>
<a href={b.url}>{b.title}</a>
</li>)}