Skip to content

Commit 45b91fd

Browse files
authored
Turbopack: improve loop breaks (#77964)
1 parent 30a7204 commit 45b91fd

File tree

17 files changed

+1996
-276
lines changed

17 files changed

+1996
-276
lines changed

turbopack/crates/turbopack-ecmascript/src/analyzer/graph.rs

Lines changed: 78 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1744,6 +1744,42 @@ impl VisitAstPath for Analyzer<'_> {
17441744
}
17451745
}
17461746

1747+
fn visit_for_in_stmt<'ast: 'r, 'r>(
1748+
&mut self,
1749+
n: &'ast ForInStmt,
1750+
ast_path: &mut swc_core::ecma::visit::AstNodePath<'r>,
1751+
) {
1752+
{
1753+
let mut ast_path =
1754+
ast_path.with_guard(AstParentNodeRef::ForInStmt(n, ForInStmtField::Right));
1755+
n.right.visit_with_ast_path(self, &mut ast_path);
1756+
}
1757+
1758+
{
1759+
let mut ast_path =
1760+
ast_path.with_guard(AstParentNodeRef::ForInStmt(n, ForInStmtField::Left));
1761+
self.with_pat_value(
1762+
// TODO this should really be
1763+
// `Some(JsValue::iteratedKeys(Box::new(self.eval_context.eval(&n.right))))`
1764+
Some(JsValue::unknown_empty(
1765+
false,
1766+
"for-in variable currently not analyzed",
1767+
)),
1768+
|this| {
1769+
n.left.visit_with_ast_path(this, &mut ast_path);
1770+
},
1771+
)
1772+
}
1773+
1774+
let mut ast_path =
1775+
ast_path.with_guard(AstParentNodeRef::ForInStmt(n, ForInStmtField::Body));
1776+
1777+
let prev_early_return_stack = take(&mut self.early_return_stack);
1778+
n.body.visit_with_ast_path(self, &mut ast_path);
1779+
self.end_early_return_block();
1780+
self.early_return_stack = prev_early_return_stack;
1781+
}
1782+
17471783
fn visit_for_of_stmt<'ast: 'r, 'r>(
17481784
&mut self,
17491785
n: &'ast ForOfStmt,
@@ -1752,21 +1788,58 @@ impl VisitAstPath for Analyzer<'_> {
17521788
{
17531789
let mut ast_path =
17541790
ast_path.with_guard(AstParentNodeRef::ForOfStmt(n, ForOfStmtField::Right));
1755-
self.visit_expr(&n.right, &mut ast_path);
1791+
n.right.visit_with_ast_path(self, &mut ast_path);
17561792
}
17571793

1758-
let array = self.eval_context.eval(&n.right);
1794+
let iterable = self.eval_context.eval(&n.right);
17591795

1760-
self.with_pat_value(Some(JsValue::iterated(Box::new(array))), |this| {
1796+
// TODO n.await is ignored (async interables)
1797+
self.with_pat_value(Some(JsValue::iterated(Box::new(iterable))), |this| {
17611798
let mut ast_path =
17621799
ast_path.with_guard(AstParentNodeRef::ForOfStmt(n, ForOfStmtField::Left));
1763-
this.visit_for_head(&n.left, &mut ast_path);
1800+
n.left.visit_with_ast_path(this, &mut ast_path);
17641801
});
17651802

17661803
let mut ast_path =
17671804
ast_path.with_guard(AstParentNodeRef::ForOfStmt(n, ForOfStmtField::Body));
17681805

1769-
self.visit_stmt(&n.body, &mut ast_path);
1806+
let prev_early_return_stack = take(&mut self.early_return_stack);
1807+
n.body.visit_with_ast_path(self, &mut ast_path);
1808+
self.end_early_return_block();
1809+
self.early_return_stack = prev_early_return_stack;
1810+
}
1811+
1812+
fn visit_for_stmt<'ast: 'r, 'r>(
1813+
&mut self,
1814+
n: &'ast ForStmt,
1815+
ast_path: &mut swc_core::ecma::visit::AstNodePath<'r>,
1816+
) {
1817+
let prev_early_return_stack = take(&mut self.early_return_stack);
1818+
n.visit_children_with_ast_path(self, ast_path);
1819+
self.end_early_return_block();
1820+
self.early_return_stack = prev_early_return_stack;
1821+
}
1822+
1823+
fn visit_while_stmt<'ast: 'r, 'r>(
1824+
&mut self,
1825+
n: &'ast WhileStmt,
1826+
ast_path: &mut swc_core::ecma::visit::AstNodePath<'r>,
1827+
) {
1828+
let prev_early_return_stack = take(&mut self.early_return_stack);
1829+
n.visit_children_with_ast_path(self, ast_path);
1830+
self.end_early_return_block();
1831+
self.early_return_stack = prev_early_return_stack;
1832+
}
1833+
1834+
fn visit_do_while_stmt<'ast: 'r, 'r>(
1835+
&mut self,
1836+
n: &'ast DoWhileStmt,
1837+
ast_path: &mut swc_core::ecma::visit::AstNodePath<'r>,
1838+
) {
1839+
let prev_early_return_stack = take(&mut self.early_return_stack);
1840+
n.visit_children_with_ast_path(self, ast_path);
1841+
self.end_early_return_block();
1842+
self.early_return_stack = prev_early_return_stack;
17701843
}
17711844

17721845
fn visit_simple_assign_target<'ast: 'r, 'r>(

turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/react-dom-production/graph-explained.snapshot

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3399,8 +3399,7 @@ c#1018 = (arguments[2] | d[a])
33993399
c#1019 = arguments[2]
34003400

34013401
c#102 = (???*0* | "cssFloat")
3402-
- *0* c
3403-
⚠️ pattern without value
3402+
- *0* for-in variable currently not analyzed
34043403

34053404
c#1023 = arguments[2]
34063405

@@ -3471,8 +3470,7 @@ c#203 = (arguments[2] | b["tag"])
34713470
c#207 = b["length"]
34723471

34733472
c#212 = ???*0*
3474-
- *0* c
3475-
⚠️ pattern without value
3473+
- *0* for-in variable currently not analyzed
34763474

34773475
c#236 = (arguments[2] | new td("onChange", "change", null, c, d))
34783476

@@ -3504,9 +3502,10 @@ c#269 = arguments[2]
35043502

35053503
c#270 = {}
35063504

3507-
c#271 = ???*0*
3505+
c#271 = (???*0* | ???*1*)
35083506
- *0* c
35093507
⚠️ pattern without value
3508+
- *1* for-in variable currently not analyzed
35103509

35113510
c#274 = arguments[2]
35123511

@@ -3573,8 +3572,7 @@ c#364 = (b | undefined)
35733572
c#370 = (a["data"] | undefined)
35743573

35753574
c#381 = ???*0*
3576-
- *0* c
3577-
⚠️ pattern without value
3575+
- *0* for-in variable currently not analyzed
35783576

35793577
c#385 = arguments[2]
35803578

@@ -4656,8 +4654,7 @@ e#320 = (c["nextSibling"] | undefined)
46564654
e#341 = {}
46574655

46584656
e#345 = ???*0*
4659-
- *0* e
4660-
⚠️ pattern without value
4657+
- *0* for-in variable currently not analyzed
46614658

46624659
e#354 = ???*0*
46634660
- *0* e
@@ -4963,9 +4960,10 @@ f#308 = (e["stateNode"] | undefined | Kb(a, c) | Kb(a, b))
49634960

49644961
f#311 = b["_reactName"]
49654962

4966-
f#341 = ???*0*
4963+
f#341 = (???*0* | ???*1*)
49674964
- *0* f
49684965
⚠️ pattern without value
4966+
- *1* for-in variable currently not analyzed
49694967

49704968
f#357 = ((???*0* + e) | ???*1*["toString"](32))
49714969
- *0* unsupported expression
@@ -5076,8 +5074,7 @@ f#647 = (
50765074
| !(0)
50775075
| c
50785076
)
5079-
- *0* f
5080-
⚠️ pattern without value
5077+
- *0* for-in variable currently not analyzed
50815078

50825079
f#673 = (d["focusNode"] | undefined)
50835080

@@ -5279,9 +5276,10 @@ g#609 = (
52795276

52805277
g#614 = arguments[6]
52815278

5282-
g#639 = ???*0*
5279+
g#639 = (???*0* | ???*1*)
52835280
- *0* g
52845281
⚠️ pattern without value
5282+
- *1* for-in variable currently not analyzed
52855283

52865284
g#647 = (
52875285
| ???*0*
@@ -5292,8 +5290,7 @@ g#647 = (
52925290
| Mh(a)
52935291
| f["alternate"]
52945292
)
5295-
- *0* g
5296-
⚠️ pattern without value
5293+
- *0* for-in variable currently not analyzed
52975294

52985295
g#673 = (0 | undefined | (g + q["nodeValue"]["length"]))
52995296

@@ -5859,8 +5856,7 @@ l#601 = (
58595856
)
58605857

58615858
l#639 = (???*0* | f | undefined)
5862-
- *0* l
5863-
⚠️ pattern without value
5859+
- *0* for-in variable currently not analyzed
58645860

58655861
l#673 = (0 | undefined | ???*0*)
58665862
- *0* updated with update expression

0 commit comments

Comments
 (0)