Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(es/compat): Consider only the variables used in the closure #9151

Merged
merged 5 commits into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 18 additions & 19 deletions crates/swc/tests/fixture/issues-3xxx/3417/1/output/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,36 @@ export function selectRooms(building) {
}
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
try {
var _loop = function() {
for(var _iterator = levels[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
var level = _step.value;
var levelId = level.id;
var levelRooms = roomsOnLevel(levelId, rooms, roomsByLevel);
var sortedRooms = [];
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
try {
for(var _iterator = levelRooms[Symbol.iterator](), _step1; !(_iteratorNormalCompletion = (_step1 = _iterator.next()).done); _iteratorNormalCompletion = true){
for(var _iterator1 = levelRooms[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
var room = _step1.value;
sortedRooms.push(room);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
_didIteratorError1 = true;
_iteratorError1 = err;
} finally{
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
_iterator1.return();
}
} finally{
if (_didIteratorError) {
throw _iteratorError;
if (_didIteratorError1) {
throw _iteratorError1;
}
}
}
sortedRooms.sort(function(a, b) {
return a + b;
});
var visitedRooms = {};
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
var _iteratorNormalCompletion2 = true, _didIteratorError2 = false, _iteratorError2 = undefined;
try {
var _loop = function() {
var room = _step2.value;
Expand Down Expand Up @@ -79,23 +79,22 @@ export function selectRooms(building) {
FLOOR_MAPPING[levelId]
];
};
for(var _iterator1 = sortedRooms[Symbol.iterator](), _step2; !(_iteratorNormalCompletion1 = (_step2 = _iterator1.next()).done); _iteratorNormalCompletion1 = true)_loop();
for(var _iterator2 = sortedRooms[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true)_loop();
} catch (err) {
_didIteratorError1 = true;
_iteratorError1 = err;
_didIteratorError2 = true;
_iteratorError2 = err;
} finally{
try {
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
_iterator1.return();
if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
_iterator2.return();
}
} finally{
if (_didIteratorError1) {
throw _iteratorError1;
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
};
for(var _iterator = levels[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true)_loop();
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
Expand Down
69 changes: 9 additions & 60 deletions crates/swc_ecma_compat_es2015/src/block_scoping/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ use swc_ecma_utils::{
ExprFactory, StmtLike,
};
use swc_ecma_visit::{
as_folder, noop_visit_mut_type, noop_visit_type, visit_mut_obj_and_computed, Fold, Visit,
VisitMut, VisitMutWith, VisitWith,
as_folder, noop_visit_mut_type, visit_mut_obj_and_computed, Fold, VisitMut, VisitMutWith,
};
use swc_trace_macro::swc_trace;

Expand Down Expand Up @@ -100,17 +99,19 @@ impl BlockScoping {
}

fn mark_as_used(&mut self, i: Id) {
for (idx, scope) in self.scope.iter_mut().rev().enumerate() {
// Only consider the variable used in a non-ScopeKind::Loop, which means it is
// captured in a closure
for scope in self
.scope
.iter_mut()
.rev()
.skip_while(|scope| matches!(scope, ScopeKind::Loop { .. }))
{
if let ScopeKind::Loop {
lexical_var, used, ..
} = scope
{
//
if lexical_var.contains(&i) {
if idx == 0 {
return;
}

used.push(i);
return;
}
Expand All @@ -128,16 +129,6 @@ impl BlockScoping {
fn handle_capture_of_vars(&mut self, body: &mut Box<Stmt>) {
let body_stmt = &mut **body;

{
let mut v = FunctionFinder { found: false };
body_stmt.visit_with(&mut v);
if !v.found {
self.scope.pop();
return;
}
}

//
if let Some(ScopeKind::Loop {
args,
used,
Expand Down Expand Up @@ -935,45 +926,3 @@ impl VisitMut for MutationHandler<'_> {
n.arg = Some(Box::new(self.make_reassignment(val)))
}
}

#[derive(Debug)]
struct FunctionFinder {
found: bool,
}

impl Visit for FunctionFinder {
noop_visit_type!();

fn visit_arrow_expr(&mut self, _: &ArrowExpr) {
self.found = true;
}

/// Do not recurse into nested loop.
///
/// https://github.com/swc-project/swc/issues/2622
fn visit_do_while_stmt(&mut self, _: &DoWhileStmt) {}

/// Do not recurse into nested loop.
///
/// https://github.com/swc-project/swc/issues/2622
fn visit_for_in_stmt(&mut self, _: &ForInStmt) {}

/// Do not recurse into nested loop.
///
/// https://github.com/swc-project/swc/issues/2622
fn visit_for_of_stmt(&mut self, _: &ForOfStmt) {}

/// Do not recurse into nested loop.
///
/// https://github.com/swc-project/swc/issues/2622
fn visit_for_stmt(&mut self, _: &ForStmt) {}

fn visit_function(&mut self, _: &Function) {
self.found = true
}

/// Do not recurse into nested loop.
///
/// https://github.com/swc-project/swc/issues/2622
fn visit_while_stmt(&mut self, _: &WhileStmt) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
for (const x of [0, 1, 2]) {
for (let i = 0; i < 1; i++) {
setTimeout(() => console.log(x));
}
}
Loading