-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Description
💻
- Would you like to work on a fix?
How are you using Babel?
Programmatic API (babel.transform
, babel.parse
)
Input code
Non-strict code allows let
as an identifier. To avoid ambiguity, the grammar prohibits let
as an identifier token in places where it would be confused with the let
contextual keyword. The generator is not aware of these restrictions, so it emits illegal or incorrect code for a valid AST.
for ((let)[x];;);
for ((let)[x] in {});
(let)[x];
for ((let) of []);
async () => {
for await ((let) of []);
};
Configuration file name
No response
Configuration
{}
Current and expected behavior
Expected behaviour: The input is emitted as-is, with extra parentheses to ensure that let
is treated as an identifier.
Actual behaviour: The generated code is illegal or incorrect:
for (let[x];;);
for (let[x] in {});
let[x];
for (let of []);
async () => {
for await (let of []);
};
Environment
- Babel v7.14.1
Possible solution
Generator's parentheses.ts
already has a helper function isFirstInStatement
that does the hard work of figuring out whether an AST node could emit the first token in a particular context. It just needs some extra flags to treat for-loop heads as a successful match, and optionally not treat ExpressionStatement as a match (if the identifier is not followed by [
).
Some contexts only prohibit let [
. We can detect this case by checking t.isMemberExpression(parent, { object: node, computed: true })
.
With these components, we can add a case to Identifier
that requests parentheses when let
would occur in an illegal context.
Additional context
No response