mirror of
https://github.com/swc-project/swc.git
synced 2024-10-05 04:39:06 +03:00
fix(es/minifier): Apply new SyntaxContext
to inlined Arrow
(#8301)
**Related issue:** - Closes #8288
This commit is contained in:
parent
ba9d2f56cc
commit
c18a959e3a
@ -509,12 +509,11 @@ impl Optimizer<'_> {
|
||||
//
|
||||
// For arrow expressions this is required because we copy simple arrow
|
||||
// expressions.
|
||||
let mut remap = HashMap::default();
|
||||
let new_ctxt = SyntaxContext::empty().apply_mark(Mark::fresh(Mark::root()));
|
||||
|
||||
for p in param_ids.iter() {
|
||||
remap.insert(p.to_id(), new_ctxt);
|
||||
}
|
||||
let new_ctxt = SyntaxContext::empty().apply_mark(Mark::new());
|
||||
let remap = param_ids
|
||||
.iter()
|
||||
.map(|p| (p.to_id(), new_ctxt))
|
||||
.collect::<FxHashMap<_, _>>();
|
||||
|
||||
{
|
||||
let vars = param_ids
|
||||
@ -843,7 +842,7 @@ impl Optimizer<'_> {
|
||||
|
||||
// We remap variables.
|
||||
let mut remap = HashMap::default();
|
||||
let new_ctxt = SyntaxContext::empty().apply_mark(Mark::fresh(Mark::root()));
|
||||
let new_ctxt = SyntaxContext::empty().apply_mark(Mark::new());
|
||||
|
||||
let params = orig_params
|
||||
.iter()
|
||||
@ -857,27 +856,25 @@ impl Optimizer<'_> {
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
{
|
||||
for stmt in &body.stmts {
|
||||
if let Stmt::Decl(Decl::Var(var)) = stmt {
|
||||
for decl in &var.decls {
|
||||
let ids: Vec<Id> = find_pat_ids(&decl.name);
|
||||
for stmt in &body.stmts {
|
||||
if let Stmt::Decl(Decl::Var(var)) = stmt {
|
||||
for decl in &var.decls {
|
||||
let ids: Vec<Id> = find_pat_ids(&decl.name);
|
||||
|
||||
for id in ids {
|
||||
let ctx = remap
|
||||
.entry(id.clone())
|
||||
.or_insert_with(|| SyntaxContext::empty().apply_mark(Mark::new()));
|
||||
for id in ids {
|
||||
let ctx = remap
|
||||
.entry(id.clone())
|
||||
.or_insert_with(|| SyntaxContext::empty().apply_mark(Mark::new()));
|
||||
|
||||
// [is_skippable_for_seq] would check fn scope
|
||||
if let Some(usage) = self.data.vars.get(&id) {
|
||||
let mut usage = usage.clone();
|
||||
// as we turn var declaration into assignment
|
||||
// we need to maintain correct var usage
|
||||
if decl.init.is_some() {
|
||||
usage.ref_count += 1;
|
||||
}
|
||||
self.data.vars.insert((id.0, *ctx), usage);
|
||||
// [is_skippable_for_seq] would check fn scope
|
||||
if let Some(usage) = self.data.vars.get(&id) {
|
||||
let mut usage = usage.clone();
|
||||
// as we turn var declaration into assignment
|
||||
// we need to maintain correct var usage
|
||||
if decl.init.is_some() {
|
||||
usage.ref_count += 1;
|
||||
}
|
||||
self.data.vars.insert((id.0, *ctx), usage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
use swc_common::{util::take::Take, EqIgnoreSpan, Spanned};
|
||||
use rustc_hash::FxHashMap;
|
||||
use swc_common::{collections::AHashSet, util::take::Take, EqIgnoreSpan, Mark, Spanned};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_transforms_optimization::simplify::expr_simplifier;
|
||||
use swc_ecma_usage_analyzer::alias::{collect_infects_from, AliasConfig};
|
||||
use swc_ecma_utils::{class_has_side_effect, find_pat_ids, ExprExt};
|
||||
use swc_ecma_utils::{class_has_side_effect, collect_decls, find_pat_ids, ExprExt, Remapper};
|
||||
use swc_ecma_visit::VisitMutWith;
|
||||
|
||||
use super::Optimizer;
|
||||
@ -808,7 +809,7 @@ impl Optimizer<'_> {
|
||||
}
|
||||
Expr::Ident(i) => {
|
||||
let id = i.to_id();
|
||||
if let Some(value) = self
|
||||
if let Some(mut value) = self
|
||||
.vars
|
||||
.lits
|
||||
.get(&id)
|
||||
@ -827,6 +828,25 @@ impl Optimizer<'_> {
|
||||
return;
|
||||
}
|
||||
|
||||
// currently renamer relies on the fact no distinct var has same ctxt, we need
|
||||
// to remap all new bindings.
|
||||
let bindings: AHashSet<Id> = collect_decls(&*value);
|
||||
let new_mark = Mark::new();
|
||||
let mut cache = FxHashMap::default();
|
||||
let remap: FxHashMap<_, _> = bindings
|
||||
.into_iter()
|
||||
.map(|id| {
|
||||
let value = cache
|
||||
.entry(id.1)
|
||||
.or_insert_with(|| id.1.apply_mark(new_mark));
|
||||
|
||||
(id, *value)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut remapper = Remapper::new(&remap);
|
||||
value.visit_mut_with(&mut remapper);
|
||||
|
||||
self.changed = true;
|
||||
report_change!("inline: Replacing a variable `{}` with cheap expression", i);
|
||||
|
||||
|
30
crates/swc_ecma_minifier/tests/full/issues/8288/input.js
Normal file
30
crates/swc_ecma_minifier/tests/full/issues/8288/input.js
Normal file
@ -0,0 +1,30 @@
|
||||
function memoizeWithArgs(fnWithArgs, options) {
|
||||
const fn = proxyMemoize((args) => fnWithArgs(...args), options);
|
||||
return (...args) => fn(args);
|
||||
}
|
||||
|
||||
function makeSelector(selector, selectorTransformer) {
|
||||
return (state) => selectorTransformer(selector(state));
|
||||
}
|
||||
|
||||
export function createSelectorHook(selector) {
|
||||
const useSelectorHook = (selectorTransformer, deps) => {
|
||||
const memoSelector = useMemo(
|
||||
() =>
|
||||
selectorTransformer && deps
|
||||
? makeSelector(
|
||||
selector,
|
||||
memoizeWithArgs(selectorTransformer)
|
||||
)
|
||||
: undefined,
|
||||
deps
|
||||
);
|
||||
const finalSelector = memoSelector
|
||||
? memoSelector
|
||||
: selectorTransformer
|
||||
? makeSelector(selector, selectorTransformer)
|
||||
: selector;
|
||||
return useSelector(finalSelector);
|
||||
};
|
||||
return useSelectorHook;
|
||||
}
|
@ -0,0 +1 @@
|
||||
export function createSelectorHook(e){return(o,r)=>{const t=useMemo(()=>{var t;return o&&r?(t=function(e,o){const r=proxyMemoize(o=>e(...o),void 0);return(...e)=>r(e)}(o),o=>t(e(o))):void 0},r)||(o?r=>o(e(r)):e);return useSelector(t)}}
|
Loading…
Reference in New Issue
Block a user