fix(es/minifier): Remove fake_block while calculating next scope (#5869)

**Description:**

We now remove `fake_block` mark from `with_ctx`.

**Related issue:**
 - Closes https://github.com/swc-project/swc/issues/5865
This commit is contained in:
Donny/강동윤 2022-09-15 15:04:47 +09:00 committed by GitHub
parent ec8bb432b9
commit 991a34e0c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 456 additions and 22 deletions

View File

@ -0,0 +1,68 @@
{
"$schema": "https://json.schemastore.org/swcrc",
"jsc": {
"parser": {
"syntax": "ecmascript",
"jsx": false
},
"target": "es2019",
"transform": {
"react": {
"runtime": "automatic"
}
},
"minify": {
"compress": {
"arguments": false,
"arrows": true,
"booleans": true,
"booleans_as_integers": false,
"collapse_vars": true,
"comparisons": true,
"computed_props": true,
"conditionals": true,
"dead_code": true,
"directives": true,
"drop_console": false,
"drop_debugger": true,
"evaluate": true,
"expression": false,
"hoist_funs": false,
"hoist_props": true,
"hoist_vars": false,
"if_return": true,
"join_vars": true,
"keep_classnames": false,
"keep_fargs": true,
"keep_fnames": false,
"keep_infinity": false,
"loops": true,
"negate_iife": true,
"properties": true,
"reduce_funcs": false,
"reduce_vars": false,
"side_effects": true,
"switches": true,
"typeofs": true,
"unsafe": false,
"unsafe_arrows": false,
"unsafe_comps": false,
"unsafe_Function": false,
"unsafe_math": false,
"unsafe_symbols": false,
"unsafe_methods": false,
"unsafe_proto": false,
"unsafe_regexp": false,
"unsafe_undefined": false,
"unused": true,
"const_to_let": true,
"pristine_globals": true
}
}
},
"isModule": true,
"module": {
"type": "es6"
},
"minify": true
}

View File

@ -0,0 +1,6 @@
v = ((a) => (b) => {
const n = a.map((t) => {
if (t) return ((e) => e.foo)(t);
});
return n;
})(r);

View File

@ -0,0 +1 @@
var a;v=(a=r,b=>{let n=a.map(t=>{if(t)return t.foo});return n});

View File

@ -546,21 +546,7 @@ impl Span {
"Cannot check if a span contains a `ROOT` mark"
);
let mut ctxt = self.ctxt;
loop {
if ctxt == SyntaxContext::empty() {
return false;
}
let m = ctxt.remove_mark();
if m == mark {
return true;
}
if m == Mark::root() {
return false;
}
}
self.ctxt.has_mark(mark)
}
/// Dummy span, both position are extremely large numbers so they would be

View File

@ -325,6 +325,33 @@ impl SyntaxContext {
SyntaxContext(0)
}
/// Returns `true` if `self` is marked with `mark`.
///
/// Panics if `mark` is not a valid mark.
pub fn has_mark(self, mark: Mark) -> bool {
debug_assert_ne!(
mark,
Mark::root(),
"Cannot check if a span contains a `ROOT` mark"
);
let mut ctxt = self;
loop {
if ctxt == SyntaxContext::empty() {
return false;
}
let m = ctxt.remove_mark();
if m == mark {
return true;
}
if m == Mark::root() {
return false;
}
}
}
#[inline]
pub fn as_u32(self) -> u32 {
self.0

View File

@ -2924,7 +2924,9 @@ impl Take for SynthesizedStmts {
impl Drop for SynthesizedStmts {
fn drop(&mut self) {
if !self.0.is_empty() {
if !std::thread::panicking() {
panic!("We should not drop synthesized stmts");
}
}
}
}

View File

@ -34,12 +34,20 @@ where
}
/// RAII guard to change context temporarically
pub(super) fn with_ctx(&mut self, ctx: Ctx) -> WithCtx<'_, 'b, M> {
pub(super) fn with_ctx(&mut self, mut ctx: Ctx) -> WithCtx<'_, 'b, M> {
let mut scope_ctxt = ctx.scope;
if self.ctx.scope != scope_ctxt {
if scope_ctxt.clone().remove_mark() == self.marks.fake_block {
scope_ctxt.remove_mark();
}
ctx.scope = scope_ctxt;
#[cfg(debug_assertions)]
{
let scope_ctxt = ctx.scope;
if self.ctx.scope != scope_ctxt {
self.data.scopes.get(&scope_ctxt).expect("scope not found");
self.data.scopes.get(&scope_ctxt).unwrap_or_else(|| {
panic!("scope not found: {:?}; {:#?}", scope_ctxt, self.data.scopes)
});
}
}

View File

@ -0,0 +1,272 @@
TestSnapshot {
vars: [
(
(
Atom('a' type=static),
#2,
),
VarUsageInfo {
inline_prevented: false,
ref_count: 1,
cond_init: false,
declared: true,
declared_count: 1,
declared_as_fn_param: true,
declared_as_fn_expr: false,
assign_count: 0,
mutation_by_call_count: 0,
usage_count: 1,
reassigned_with_assignment: false,
reassigned_with_var_decl: false,
mutated: false,
has_property_access: true,
has_property_mutation: false,
accessed_props: {},
exported: false,
used_above_decl: false,
is_fn_local: false,
used_by_nested_fn: true,
executed_multiple_time: false,
used_in_cond: false,
var_kind: None,
var_initialized: false,
declared_as_catch_param: false,
no_side_effect_for_member_access: false,
used_as_callee: false,
used_as_arg: false,
pure_fn: false,
infects: [],
},
),
(
(
Atom('b' type=static),
#3,
),
VarUsageInfo {
inline_prevented: false,
ref_count: 0,
cond_init: false,
declared: true,
declared_count: 1,
declared_as_fn_param: true,
declared_as_fn_expr: false,
assign_count: 0,
mutation_by_call_count: 0,
usage_count: 0,
reassigned_with_assignment: false,
reassigned_with_var_decl: false,
mutated: false,
has_property_access: false,
has_property_mutation: false,
accessed_props: {},
exported: false,
used_above_decl: false,
is_fn_local: true,
used_by_nested_fn: true,
executed_multiple_time: false,
used_in_cond: false,
var_kind: None,
var_initialized: false,
declared_as_catch_param: false,
no_side_effect_for_member_access: false,
used_as_callee: false,
used_as_arg: false,
pure_fn: false,
infects: [],
},
),
(
(
Atom('e' type=inline),
#5,
),
VarUsageInfo {
inline_prevented: false,
ref_count: 1,
cond_init: false,
declared: true,
declared_count: 1,
declared_as_fn_param: true,
declared_as_fn_expr: false,
assign_count: 0,
mutation_by_call_count: 0,
usage_count: 1,
reassigned_with_assignment: false,
reassigned_with_var_decl: false,
mutated: false,
has_property_access: true,
has_property_mutation: false,
accessed_props: {},
exported: false,
used_above_decl: false,
is_fn_local: true,
used_by_nested_fn: true,
executed_multiple_time: false,
used_in_cond: true,
var_kind: None,
var_initialized: false,
declared_as_catch_param: false,
no_side_effect_for_member_access: false,
used_as_callee: false,
used_as_arg: false,
pure_fn: false,
infects: [],
},
),
(
(
Atom('n' type=inline),
#3,
),
VarUsageInfo {
inline_prevented: false,
ref_count: 1,
cond_init: false,
declared: true,
declared_count: 1,
declared_as_fn_param: false,
declared_as_fn_expr: false,
assign_count: 0,
mutation_by_call_count: 0,
usage_count: 1,
reassigned_with_assignment: false,
reassigned_with_var_decl: false,
mutated: false,
has_property_access: false,
has_property_mutation: false,
accessed_props: {},
exported: false,
used_above_decl: false,
is_fn_local: true,
used_by_nested_fn: true,
executed_multiple_time: false,
used_in_cond: false,
var_kind: Some(
"const",
),
var_initialized: true,
declared_as_catch_param: false,
no_side_effect_for_member_access: false,
used_as_callee: false,
used_as_arg: false,
pure_fn: false,
infects: [],
},
),
(
(
Atom('r' type=inline),
#1,
),
VarUsageInfo {
inline_prevented: false,
ref_count: 1,
cond_init: false,
declared: false,
declared_count: 0,
declared_as_fn_param: false,
declared_as_fn_expr: false,
assign_count: 0,
mutation_by_call_count: 1,
usage_count: 1,
reassigned_with_assignment: false,
reassigned_with_var_decl: false,
mutated: true,
has_property_access: false,
has_property_mutation: false,
accessed_props: {},
exported: false,
used_above_decl: true,
is_fn_local: true,
used_by_nested_fn: false,
executed_multiple_time: false,
used_in_cond: false,
var_kind: None,
var_initialized: false,
declared_as_catch_param: false,
no_side_effect_for_member_access: false,
used_as_callee: false,
used_as_arg: true,
pure_fn: false,
infects: [],
},
),
(
(
Atom('t' type=inline),
#4,
),
VarUsageInfo {
inline_prevented: false,
ref_count: 2,
cond_init: false,
declared: true,
declared_count: 1,
declared_as_fn_param: true,
declared_as_fn_expr: false,
assign_count: 0,
mutation_by_call_count: 2,
usage_count: 2,
reassigned_with_assignment: false,
reassigned_with_var_decl: false,
mutated: true,
has_property_access: false,
has_property_mutation: false,
accessed_props: {},
exported: false,
used_above_decl: false,
is_fn_local: true,
used_by_nested_fn: true,
executed_multiple_time: false,
used_in_cond: true,
var_kind: None,
var_initialized: false,
declared_as_catch_param: false,
no_side_effect_for_member_access: false,
used_as_callee: false,
used_as_arg: true,
pure_fn: false,
infects: [],
},
),
(
(
Atom('v' type=inline),
#1,
),
VarUsageInfo {
inline_prevented: false,
ref_count: 1,
cond_init: false,
declared: false,
declared_count: 0,
declared_as_fn_param: false,
declared_as_fn_expr: false,
assign_count: 0,
mutation_by_call_count: 0,
usage_count: 0,
reassigned_with_assignment: false,
reassigned_with_var_decl: false,
mutated: true,
has_property_access: false,
has_property_mutation: false,
accessed_props: {},
exported: false,
used_above_decl: true,
is_fn_local: true,
used_by_nested_fn: false,
executed_multiple_time: false,
used_in_cond: false,
var_kind: None,
var_initialized: true,
declared_as_catch_param: false,
no_side_effect_for_member_access: false,
used_as_callee: false,
used_as_arg: false,
pure_fn: false,
infects: [],
},
),
],
}

View File

@ -0,0 +1,46 @@
{
"arguments": false,
"arrows": true,
"booleans": true,
"booleans_as_integers": false,
"collapse_vars": true,
"comparisons": true,
"computed_props": true,
"conditionals": true,
"dead_code": true,
"directives": true,
"drop_console": false,
"drop_debugger": true,
"evaluate": true,
"expression": false,
"hoist_funs": false,
"hoist_props": true,
"hoist_vars": false,
"if_return": true,
"join_vars": true,
"keep_classnames": false,
"keep_fargs": true,
"keep_fnames": false,
"keep_infinity": false,
"loops": true,
"negate_iife": true,
"properties": true,
"reduce_funcs": false,
"reduce_vars": false,
"side_effects": true,
"switches": true,
"typeofs": true,
"unsafe": false,
"unsafe_arrows": false,
"unsafe_comps": false,
"unsafe_Function": false,
"unsafe_math": false,
"unsafe_symbols": false,
"unsafe_methods": false,
"unsafe_proto": false,
"unsafe_regexp": false,
"unsafe_undefined": false,
"unused": true,
"const_to_let": true,
"pristine_globals": true
}

View File

@ -0,0 +1,6 @@
v = ((a) => (b) => {
const n = a.map((t) => {
if (t) return ((e) => e.foo)(t);
});
return n;
})(r);

View File

@ -0,0 +1,6 @@
v = ((a)=>(b)=>{
const n = a.map((t)=>{
if (t) return ((e)=>e.foo)(t);
});
return n;
})(r);

View File

@ -0,0 +1,6 @@
v = ((n)=>(o)=>{
const t = n.map((n)=>{
if (n) return ((n)=>n.foo)(n);
});
return t;
})(r);