mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
fix(transformer/es2018/for-await): hoist for-await generated bindings (#22355)
`for await` lowering emits several temporary bindings as `var`, but the transformer was registering those generated symbols in the current block scope instead of the nearest hoist scope.
For example, this input:
```js
async function* f(iter) {
{
for await (const value of iter) {
value;
}
}
}
```
is lowered into code shaped like this:
```js
async function* f(iter) {
{
var _iteratorAbruptCompletion = false;
var _didIteratorError = false;
var _iteratorError;
try {
for (
var _iterator = _asyncIterator(iter), _step;
// ^^^^^^^^^ ^^^^^
// These are `var` declarations, so semantically they belong to
// the function/hoist scope, not the inner block scope.
_iteratorAbruptCompletion = !(_step = await _iterator.next()).done;
_iteratorAbruptCompletion = false
) {
const value = _step.value;
value;
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
}
}
}
```
Before this PR, the AST transform generated the right JavaScript, but its semantic metadata recorded `_iterator`, `_step`, `_didIteratorError`, `_iteratorError`, and `_iteratorAbruptCompletion` in the current block scope:
That made the transformed semantic data disagree with semantic data rebuilt from the emitted AST.
This commit is contained in:
1 parent
ba2a1d39c6
commit
67ab1c9288
3 files changed
+8
-74
No files matched your search
@@ -102,8 +102,11 @@ impl<'a> AsyncGeneratorFunctions<'a> {
|
||||
span: Span,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) -> ArenaVec<'a, Statement<'a>> {
|
||||
let step_key =
|
||||
ctx.generate_uid("step", ctx.current_scope_id(), SymbolFlags::FunctionScopedVariable);
|
||||
let step_key = ctx.generate_uid(
|
||||
"step",
|
||||
ctx.current_hoist_scope_id(),
|
||||
SymbolFlags::FunctionScopedVariable,
|
||||
);
|
||||
// step.value
|
||||
let step_value = Expression::from(ctx.ast.member_expression_static(
|
||||
SPAN,
|
||||
@@ -205,7 +208,7 @@ impl<'a> AsyncGeneratorFunctions<'a> {
|
||||
span: Span,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) -> ArenaVec<'a, Statement<'a>> {
|
||||
let var_scope_id = ctx.current_scope_id();
|
||||
let var_scope_id = ctx.current_hoist_scope_id();
|
||||
|
||||
let iterator_had_error_key =
|
||||
ctx.generate_uid("didIteratorError", var_scope_id, SymbolFlags::FunctionScopedVariable);
|
||||
|
||||
@@ -2,7 +2,7 @@ commit: 6402dbbf
|
||||
|
||||
semantic_babel Summary:
|
||||
AST Parsed : 2236/2236 (100.00%)
|
||||
Positive Passed: 2030/2236 (90.79%)
|
||||
Positive Passed: 2031/2236 (90.83%)
|
||||
semantic Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/comments/decorators/decorators-after-export/input.js
|
||||
Symbol span mismatch for "C":
|
||||
after transform: SymbolId(0): Span { start: 65, end: 66 }
|
||||
@@ -87,29 +87,6 @@ Symbol scope ID mismatch for "_await":
|
||||
after transform: SymbolId(3): ScopeId(2)
|
||||
rebuilt : SymbolId(2): ScopeId(0)
|
||||
|
||||
semantic Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2026/async-explicit-resource-management/valid-await-using-comments/input.js
|
||||
Bindings mismatch:
|
||||
after transform: ScopeId(1): ["_usingCtx", "_usingCtx3", "_usingCtx4"]
|
||||
rebuilt : ScopeId(3): ["_didIteratorError", "_iterator", "_iteratorAbruptCompletion", "_iteratorError", "_step", "_usingCtx", "_usingCtx3", "_usingCtx4"]
|
||||
Bindings mismatch:
|
||||
after transform: ScopeId(7): ["_didIteratorError", "_iterator", "_iteratorAbruptCompletion", "_iteratorError", "_step"]
|
||||
rebuilt : ScopeId(16): []
|
||||
Symbol scope ID mismatch for "_iteratorAbruptCompletion":
|
||||
after transform: SymbolId(14): ScopeId(7)
|
||||
rebuilt : SymbolId(13): ScopeId(3)
|
||||
Symbol scope ID mismatch for "_didIteratorError":
|
||||
after transform: SymbolId(13): ScopeId(7)
|
||||
rebuilt : SymbolId(14): ScopeId(3)
|
||||
Symbol scope ID mismatch for "_iteratorError":
|
||||
after transform: SymbolId(15): ScopeId(7)
|
||||
rebuilt : SymbolId(15): ScopeId(3)
|
||||
Symbol scope ID mismatch for "_iterator":
|
||||
after transform: SymbolId(16): ScopeId(7)
|
||||
rebuilt : SymbolId(16): ScopeId(3)
|
||||
Symbol scope ID mismatch for "_step":
|
||||
after transform: SymbolId(11): ScopeId(7)
|
||||
rebuilt : SymbolId(17): ScopeId(3)
|
||||
|
||||
semantic Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2026/async-explicit-resource-management/valid-for-using-binding-of-of/input.js
|
||||
Symbol reference IDs mismatch for "of":
|
||||
after transform: SymbolId(1): [ReferenceId(0)]
|
||||
|
||||
@@ -2,53 +2,7 @@ commit: d0c1b455
|
||||
|
||||
semantic_test262 Summary:
|
||||
AST Parsed : 47095/47095 (100.00%)
|
||||
Positive Passed: 45450/47095 (96.51%)
|
||||
semantic Error: tasks/coverage/test262/test/built-ins/AsyncFromSyncIteratorPrototype/next/for-await-iterator-next-rejected-promise-close.js
|
||||
Bindings mismatch:
|
||||
after transform: ScopeId(4): []
|
||||
rebuilt : ScopeId(4): ["_didIteratorError", "_iterator", "_iteratorAbruptCompletion", "_iteratorError", "_step"]
|
||||
Bindings mismatch:
|
||||
after transform: ScopeId(5): ["_didIteratorError", "_iterator", "_iteratorAbruptCompletion", "_iteratorError", "_step"]
|
||||
rebuilt : ScopeId(5): []
|
||||
Symbol scope ID mismatch for "_iteratorAbruptCompletion":
|
||||
after transform: SymbolId(8): ScopeId(5)
|
||||
rebuilt : SymbolId(5): ScopeId(4)
|
||||
Symbol scope ID mismatch for "_didIteratorError":
|
||||
after transform: SymbolId(7): ScopeId(5)
|
||||
rebuilt : SymbolId(6): ScopeId(4)
|
||||
Symbol scope ID mismatch for "_iteratorError":
|
||||
after transform: SymbolId(9): ScopeId(5)
|
||||
rebuilt : SymbolId(7): ScopeId(4)
|
||||
Symbol scope ID mismatch for "_iterator":
|
||||
after transform: SymbolId(10): ScopeId(5)
|
||||
rebuilt : SymbolId(8): ScopeId(4)
|
||||
Symbol scope ID mismatch for "_step":
|
||||
after transform: SymbolId(5): ScopeId(5)
|
||||
rebuilt : SymbolId(9): ScopeId(4)
|
||||
|
||||
semantic Error: tasks/coverage/test262/test/built-ins/AsyncFromSyncIteratorPrototype/next/for-await-next-rejected-promise-close.js
|
||||
Bindings mismatch:
|
||||
after transform: ScopeId(4): []
|
||||
rebuilt : ScopeId(4): ["_didIteratorError", "_iterator", "_iteratorAbruptCompletion", "_iteratorError", "_step"]
|
||||
Bindings mismatch:
|
||||
after transform: ScopeId(5): ["_didIteratorError", "_iterator", "_iteratorAbruptCompletion", "_iteratorError", "_step"]
|
||||
rebuilt : ScopeId(5): []
|
||||
Symbol scope ID mismatch for "_iteratorAbruptCompletion":
|
||||
after transform: SymbolId(8): ScopeId(5)
|
||||
rebuilt : SymbolId(5): ScopeId(4)
|
||||
Symbol scope ID mismatch for "_didIteratorError":
|
||||
after transform: SymbolId(7): ScopeId(5)
|
||||
rebuilt : SymbolId(6): ScopeId(4)
|
||||
Symbol scope ID mismatch for "_iteratorError":
|
||||
after transform: SymbolId(9): ScopeId(5)
|
||||
rebuilt : SymbolId(7): ScopeId(4)
|
||||
Symbol scope ID mismatch for "_iterator":
|
||||
after transform: SymbolId(10): ScopeId(5)
|
||||
rebuilt : SymbolId(8): ScopeId(4)
|
||||
Symbol scope ID mismatch for "_step":
|
||||
after transform: SymbolId(5): ScopeId(5)
|
||||
rebuilt : SymbolId(9): ScopeId(4)
|
||||
|
||||
Positive Passed: 45452/47095 (96.51%)
|
||||
semantic Error: tasks/coverage/test262/test/language/arguments-object/cls-decl-async-private-gen-meth-args-trailing-comma-multiple.js
|
||||
Scope flags mismatch:
|
||||
after transform: ScopeId(2): ScopeFlags(StrictMode | Function)
|
||||
|
||||
Reference in new issue
Block a user