diff --git a/crates/swc/tests/fixture/issues-3xxx/3417/1/output/index.ts b/crates/swc/tests/fixture/issues-3xxx/3417/1/output/index.ts index df72eade9233..b27cc21be002 100644 --- a/crates/swc/tests/fixture/issues-3xxx/3417/1/output/index.ts +++ b/crates/swc/tests/fixture/issues-3xxx/3417/1/output/index.ts @@ -6,28 +6,28 @@ 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; } } } @@ -35,7 +35,7 @@ export function selectRooms(building) { 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; @@ -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; diff --git a/crates/swc_ecma_compat_es2015/src/block_scoping/mod.rs b/crates/swc_ecma_compat_es2015/src/block_scoping/mod.rs index bac1fc2218d6..0307eea8562f 100644 --- a/crates/swc_ecma_compat_es2015/src/block_scoping/mod.rs +++ b/crates/swc_ecma_compat_es2015/src/block_scoping/mod.rs @@ -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; @@ -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; } @@ -128,16 +129,6 @@ impl BlockScoping { fn handle_capture_of_vars(&mut self, body: &mut Box) { 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, @@ -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) {} -} diff --git a/crates/swc_ecma_transforms_compat/tests/for-of/issue-8010/1/exec.js b/crates/swc_ecma_transforms_compat/tests/for-of/issue-8010/1/exec.js new file mode 100644 index 000000000000..d1f04b1384e8 --- /dev/null +++ b/crates/swc_ecma_transforms_compat/tests/for-of/issue-8010/1/exec.js @@ -0,0 +1,5 @@ +for (const x of [0, 1, 2]) { + for (let i = 0; i < 1; i++) { + setTimeout(() => console.log(x)); + } +}