Skip to content

Commit

Permalink
fix(es/minifier): Apply new SyntaxContext to inlined Arrow (#8301)
Browse files Browse the repository at this point in the history
**Related issue:**

 - Closes #8288
  • Loading branch information
Austaras authored Nov 18, 2023
1 parent ba9d2f5 commit c18a959
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 30 deletions.
51 changes: 24 additions & 27 deletions crates/swc_ecma_minifier/src/compress/optimize/iife.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand All @@ -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 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);
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()));

// [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);
}
}
}
Expand Down
26 changes: 23 additions & 3 deletions crates/swc_ecma_minifier/src/compress/optimize/inline.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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)
Expand All @@ -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);

Expand Down
30 changes: 30 additions & 0 deletions crates/swc_ecma_minifier/tests/full/issues/8288/input.js
Original file line number Diff line number Diff line change
@@ -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;
}
1 change: 1 addition & 0 deletions crates/swc_ecma_minifier/tests/full/issues/8288/output.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit c18a959

Please sign in to comment.