Allow Babel parse in "script" mode (#20041)

This commit is contained in:
fisker Cheung authored and GitHub committed 2026-09-12 11:47:48 +08:00
1 parent 99a784fa23
commit 968c1a62c8
17 files changed
+418 -207

No files matched your search

+17
View File
@@ -93,6 +93,23 @@ function shouldAddParenthesesToIdentifier(path) {
}
}
if (node.name === "await") {
const statement = path.findAncestor(
(node) => node.type === "ExpressionStatement",
);
if (statement) {
const { expression } = statement;
if (
startsWithNoLookaheadToken(
expression,
(leftmostNode) => leftmostNode === node,
)
) {
return true;
}
}
}
// `(type) satisfies never;` and similar cases
if (
key === "expression" &&
+8 -6
View File
@@ -7,8 +7,8 @@ import createBabelParseError from "./utilities/create-babel-parse-error.js";
import createParser from "./utilities/create-parser.js";
import {
getSourceType,
SOURCE_TYPE_COMBINATIONS,
SOURCE_TYPE_COMMONJS,
SOURCE_TYPE_MODULE,
} from "./utilities/source-types.js";
import wrapExpression from "./utilities/wrap-expression.js";
@@ -22,7 +22,6 @@ const createBabelParser = (options) => createParser(createParse(options));
/** @type {ParserOptions} */
const parseOptions = {
sourceType: SOURCE_TYPE_MODULE,
allowImportExportEverywhere: true,
allowReturnOutsideFunction: true,
allowNewTargetOutsideFunction: true,
@@ -132,8 +131,11 @@ function createParse({ isExpression = false, optionsCombinations }) {
let combinations = optionsCombinations;
const sourceType = options.__babelSourceType ?? getSourceType(filepath);
if (sourceType && sourceType !== SOURCE_TYPE_MODULE) {
combinations = combinations.map((options) => ({
combinations = (
sourceType ? [sourceType] : SOURCE_TYPE_COMBINATIONS
).flatMap((sourceType) =>
combinations.map((options) => ({
...options,
sourceType,
// `sourceType: "commonjs"` does not allow these two properties
@@ -143,8 +145,8 @@ function createParse({ isExpression = false, optionsCombinations }) {
allowNewTargetOutsideFunction: undefined,
}
: undefined),
}));
}
})),
);
const shouldEnableV8intrinsicPlugin = /%[A-Z]/.test(text);
if (text.includes("|>")) {
@@ -43,7 +43,7 @@ export class C1 {
p = await(0);
}
await(0);
(await)(0);
async function foo() {
function bar(x = await(2)) {}
@@ -55,7 +55,7 @@ export class C2 {
}
function foo(promise) {
await(promise);
(await)(promise);
}
function a() {
@@ -63,18 +63,18 @@ function a() {
}
() => {
await(x);
(await)(x);
};
function foo() {
await(foo);
(await)(foo);
}
export class C {
p = await(0);
}
await(0);
(await)(0);
================================================================================
`;
@@ -1,58 +0,0 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`html-like-comments.js format[babel] 1`] = `
"Unexpected token (2:1)
1 | alert(
> 2 | <!-- comment
| ^
3 | 'hello world'
4 | )
5 |
Cause: Unexpected token (2:0)"
`;
exports[`html-like-comments.js format[babel-ts] 1`] = `
"Unexpected token (2:1)
1 | alert(
> 2 | <!-- comment
| ^
3 | 'hello world'
4 | )
5 |
Cause: Unexpected token (2:0)"
`;
exports[`html-like-comments.js format[flow] 1`] = `
"Unexpected token \`!\`, expected the token \`>\` (2:2)
1 | alert(
> 2 | <!-- comment
| ^
3 | 'hello world'
4 | )
5 |
Cause: Unexpected token \`!\`, expected the token \`>\` (2:1)"
`;
exports[`html-like-comments.js format[hermes] 1`] = `
"'identifier' expected as JSX element name (2:2)
1 | alert(
> 2 | <!-- comment
| ^
3 | 'hello world'
4 | )
5 |
Cause: 'identifier' expected as JSX element name (2:1)
<!-- comment
^"
`;
exports[`html-like-comments.js format[typescript] 1`] = `
"Expression expected. (2:1)
1 | alert(
> 2 | <!-- comment
| ^
3 | 'hello world'
4 | )
5 |
Cause: Expression expected."
`;
@@ -1,14 +0,0 @@
runFormatTest(import.meta, [
"babel",
// "acorn",
// "espree",
// "meriyah",
"typescript",
"babel-ts",
// "oxc",
// "oxc-ts",
// "yuku",
// "yuku-ts",
"flow",
"hermes",
]);
@@ -118,7 +118,7 @@ await (0);
=====================================output=====================================
function foo(promise) {
await(promise);
(await)(promise);
}
function a() {
@@ -126,11 +126,11 @@ function a() {
}
() => {
await(x);
(await)(x);
};
function foo2() {
await(foo);
(await)(foo);
}
export class C {
@@ -16,33 +16,6 @@ alert(1);
================================================================================
`;
exports[`comment.js format[__babel_estree] 1`] = `
"Unexpected token (1:1)
> 1 | <!--
| ^
2 | alert(1)
3 | -->
Cause: Unexpected token (1:0)"
`;
exports[`comment.js format[babel] 1`] = `
"Unexpected token (1:1)
> 1 | <!--
| ^
2 | alert(1)
3 | -->
Cause: Unexpected token (1:0)"
`;
exports[`comment.js format[babel-ts] 1`] = `
"Unexpected token (1:1)
> 1 | <!--
| ^
2 | alert(1)
3 | -->
Cause: Unexpected token (1:0)"
`;
exports[`comment.js format[flow] 1`] = `
"Unexpected token \`!\`, expected the token \`>\` (1:2)
> 1 | <!--
@@ -71,3 +44,57 @@ exports[`comment.js format[typescript] 1`] = `
3 | -->
Cause: Expression expected."
`;
exports[`html-like-comments.js format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
printWidth: 80 (default) |
=====================================input======================================
alert(
<!-- comment
'hello world'
)
=====================================output=====================================
alert(
<!-- comment
"hello world",
);
================================================================================
`;
exports[`html-like-comments.js format[flow] 1`] = `
"Unexpected token \`!\`, expected the token \`>\` (2:2)
1 | alert(
> 2 | <!-- comment
| ^
3 | 'hello world'
4 | )
5 |
Cause: Unexpected token \`!\`, expected the token \`>\` (2:1)"
`;
exports[`html-like-comments.js format[hermes] 1`] = `
"'identifier' expected as JSX element name (2:2)
1 | alert(
> 2 | <!-- comment
| ^
3 | 'hello world'
4 | )
5 |
Cause: 'identifier' expected as JSX element name (2:1)
<!-- comment
^"
`;
exports[`html-like-comments.js format[typescript] 1`] = `
"Expression expected. (2:1)
1 | alert(
> 2 | <!-- comment
| ^
3 | 'hello world'
4 | )
5 |
Cause: Expression expected."
`;
@@ -1,10 +1,7 @@
runFormatTest(import.meta, ["babel", "flow", "typescript"], {
errors: {
babel: true,
flow: true,
typescript: true,
"babel-ts": true,
hermes: true,
__babel_estree: true,
},
});
@@ -0,0 +1,235 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`snippet: #0 - {"semi":false} format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
semi: false
printWidth: 80 (default) |
=====================================input======================================
await(1)
=====================================output=====================================
;(await)(1)
================================================================================
`;
exports[`snippet: #1 - {"semi":false} format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
semi: false
printWidth: 80 (default) |
=====================================input======================================
(await)(1)
=====================================output=====================================
;(await)(1)
================================================================================
`;
exports[`snippet: #2 - {"semi":false} format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
semi: false
printWidth: 80 (default) |
=====================================input======================================
await(1,2)
=====================================output=====================================
;(await)(1, 2)
================================================================================
`;
exports[`snippet: #3 - {"semi":false} format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
semi: false
printWidth: 80 (default) |
=====================================input======================================
(await)(1,2)
=====================================output=====================================
;(await)(1, 2)
================================================================================
`;
exports[`snippet: #4 - {"semi":false} format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
semi: false
printWidth: 80 (default) |
=====================================input======================================
await()
=====================================output=====================================
;(await)()
================================================================================
`;
exports[`snippet: #5 - {"semi":false} format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
semi: false
printWidth: 80 (default) |
=====================================input======================================
(await)()
=====================================output=====================================
;(await)()
================================================================================
`;
exports[`snippet: #6 - {"semi":false} format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
semi: false
printWidth: 80 (default) |
=====================================input======================================
await?.(1)
=====================================output=====================================
;(await)?.(1)
================================================================================
`;
exports[`snippet: #7 - {"semi":false} format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
semi: false
printWidth: 80 (default) |
=====================================input======================================
(await)?.()
=====================================output=====================================
;(await)?.()
================================================================================
`;
exports[`snippet: #8 - {"semi":false} format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
semi: false
printWidth: 80 (default) |
=====================================input======================================
await + 1
=====================================output=====================================
;(await) + 1
================================================================================
`;
exports[`snippet: #9 - {"semi":false} format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
semi: false
printWidth: 80 (default) |
=====================================input======================================
(await) + 1
=====================================output=====================================
;(await) + 1
================================================================================
`;
exports[`snippet: #10 - {"semi":false} format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
semi: false
printWidth: 80 (default) |
=====================================input======================================
await - 1
=====================================output=====================================
;(await) - 1
================================================================================
`;
exports[`snippet: #11 - {"semi":false} format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
semi: false
printWidth: 80 (default) |
=====================================input======================================
(await) - 1
=====================================output=====================================
;(await) - 1
================================================================================
`;
exports[`snippet: #12 - {"semi":false} format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
semi: false
printWidth: 80 (default) |
=====================================input======================================
await[0]
=====================================output=====================================
;(await)[0]
================================================================================
`;
exports[`snippet: #13 - {"semi":false} format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
semi: false
printWidth: 80 (default) |
=====================================input======================================
(await)[0]
=====================================output=====================================
;(await)[0]
================================================================================
`;
exports[`snippet: #14 - {"semi":false} format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
semi: false
printWidth: 80 (default) |
=====================================input======================================
await.all [0]
=====================================output=====================================
;(await).all[0]
================================================================================
`;
exports[`snippet: #15 - {"semi":false} format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
semi: false
printWidth: 80 (default) |
=====================================input======================================
(await).all [0]
=====================================output=====================================
;(await).all[0]
================================================================================
`;
exports[`snippet: #16 - {"semi":false} format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
semi: false
printWidth: 80 (default) |
=====================================input======================================
await?.x
=====================================output=====================================
;(await)?.x
================================================================================
`;
exports[`snippet: #17 - {"semi":false} format 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
semi: false
printWidth: 80 (default) |
=====================================input======================================
(await)?.x
=====================================output=====================================
;(await)?.x
================================================================================
`;
@@ -0,0 +1,37 @@
const testCases = [
"await(1)",
"(await)(1)",
"await(1,2)",
"(await)(1,2)",
"await()",
"(await)()",
"await?.(1)",
"(await)?.()",
"await + 1",
"(await) + 1",
"await - 1",
"(await) - 1",
"await[0]",
"(await)[0]",
"await.all [0]",
"(await).all [0]",
"await?.x",
"(await)?.x",
].map((code) => ({ code, filepath: "test.cjs" }));
runFormatTest(
{
importMeta: import.meta,
snippets: testCases,
},
["babel", "flow", "typescript"],
{ semi: false },
);
@@ -36,7 +36,7 @@ parsers: ["babel", "typescript"]
await(1);
=====================================output=====================================
await(1);
(await)(1);
================================================================================
`;
@@ -24,27 +24,6 @@ parsers: ["babel", "typescript", "flow"]
================================================================================
`;
exports[`snippet: 0006-e58e.jsx format[__babel_estree] 1`] = `
"Unexpected token (1:1)
> 1 | <!--a
| ^
Cause: Unexpected token (1:0)"
`;
exports[`snippet: 0006-e58e.jsx format[babel] 1`] = `
"Unexpected token (1:1)
> 1 | <!--a
| ^
Cause: Unexpected token (1:0)"
`;
exports[`snippet: 0006-e58e.jsx format[babel-ts] 1`] = `
"Unexpected token (1:1)
> 1 | <!--a
| ^
Cause: Unexpected token (1:0)"
`;
exports[`snippet: 0006-e58e.jsx format[flow] 1`] = `
"Unexpected token \`!\`, expected the token \`>\` (1:2)
> 1 | <!--a
@@ -14,9 +14,6 @@ runFormatTest(
["babel", "typescript", "flow"],
{
errors: {
babel: htmlComments,
"babel-ts": htmlComments,
__babel_estree: htmlComments,
typescript: htmlComments,
flow: [
...htmlComments,
@@ -13,6 +13,12 @@ exports[`snippet: #0 format[oxc-ts] 1`] = `
| ^"
`;
exports[`snippet: #0 format[oxc-ts] 2`] = `
"Cannot assign to this expression (1:1)
> 1 | a()++
| ^^^"
`;
exports[`snippet: #0 format[typescript] 1`] = `
"Invalid left-hand side expression in unary operation (1:1)
> 1 | 1 ++
@@ -20,12 +26,25 @@ exports[`snippet: #0 format[typescript] 1`] = `
Cause: Invalid left-hand side expression in unary operation"
`;
exports[`snippet: #0 format[typescript] 2`] = `
"Invalid left-hand side expression in unary operation (1:1)
> 1 | a()++
| ^^^
Cause: Invalid left-hand side expression in unary operation"
`;
exports[`snippet: #0 format[yuku-ts] 1`] = `
"Invalid operand for increment/decrement operator (1:1)
> 1 | 1 ++
| ^"
`;
exports[`snippet: #0 format[yuku-ts] 2`] = `
"Invalid operand for increment/decrement operator (1:1)
> 1 | a()++
| ^^^"
`;
exports[`snippet: #1 format[babel-ts] 1`] = `
"Invalid left-hand side in postfix operation. (1:2)
> 1 | (1)++
@@ -39,6 +58,12 @@ exports[`snippet: #1 format[oxc-ts] 1`] = `
| ^"
`;
exports[`snippet: #1 format[oxc-ts] 2`] = `
"Cannot assign to this expression (1:2)
> 1 | (a())++
| ^^^"
`;
exports[`snippet: #1 format[typescript] 1`] = `
"Invalid left-hand side expression in unary operation (1:1)
> 1 | (1)++
@@ -46,12 +71,25 @@ exports[`snippet: #1 format[typescript] 1`] = `
Cause: Invalid left-hand side expression in unary operation"
`;
exports[`snippet: #1 format[typescript] 2`] = `
"Invalid left-hand side expression in unary operation (1:1)
> 1 | (a())++
| ^^^^^
Cause: Invalid left-hand side expression in unary operation"
`;
exports[`snippet: #1 format[yuku-ts] 1`] = `
"Invalid operand for increment/decrement operator (1:1)
> 1 | (1)++
| ^^^"
`;
exports[`snippet: #1 format[yuku-ts] 2`] = `
"Invalid operand for increment/decrement operator (1:1)
> 1 | (a())++
| ^^^^^"
`;
exports[`snippet: #2 format[babel-ts] 1`] = `
"Invalid left-hand side in postfix operation. (1:2)
> 1 | (1)--
@@ -339,131 +377,79 @@ exports[`snippet: #12 format[yuku-ts] 1`] = `
`;
exports[`snippet: #13 format[babel-ts] 1`] = `
"Invalid left-hand side in postfix operation. (1:1)
> 1 | a()++
| ^
Cause: Invalid left-hand side in postfix operation. (1:0)"
`;
exports[`snippet: #13 format[oxc-ts] 1`] = `
"Cannot assign to this expression (1:1)
> 1 | a()++
| ^^^"
`;
exports[`snippet: #13 format[typescript] 1`] = `
"Invalid left-hand side expression in unary operation (1:1)
> 1 | a()++
| ^^^
Cause: Invalid left-hand side expression in unary operation"
`;
exports[`snippet: #13 format[yuku-ts] 1`] = `
"Invalid operand for increment/decrement operator (1:1)
> 1 | a()++
| ^^^"
`;
exports[`snippet: #14 format[babel-ts] 1`] = `
"Invalid optional chaining in the left-hand side of postfix operation. (1:1)
> 1 | x?.y++
| ^
Cause: Invalid optional chaining in the left-hand side of postfix operation. (1:0)"
`;
exports[`snippet: #14 format[oxc-ts] 1`] = `
exports[`snippet: #13 format[oxc-ts] 1`] = `
"Cannot assign to this expression (1:1)
> 1 | x?.y++
| ^^^^"
`;
exports[`snippet: #14 format[typescript] 1`] = `
exports[`snippet: #13 format[typescript] 1`] = `
"Invalid left-hand side expression in unary operation (1:1)
> 1 | x?.y++
| ^^^^
Cause: Invalid left-hand side expression in unary operation"
`;
exports[`snippet: #14 format[yuku-ts] 1`] = `
exports[`snippet: #13 format[yuku-ts] 1`] = `
"Invalid operand for increment/decrement operator (1:1)
> 1 | x?.y++
| ^^^^"
`;
exports[`snippet: #15 format[babel-ts] 1`] = `
exports[`snippet: #14 format[babel-ts] 1`] = `
"Invalid optional chaining in the left-hand side of postfix operation. (1:1)
> 1 | x?.y.z++
| ^
Cause: Invalid optional chaining in the left-hand side of postfix operation. (1:0)"
`;
exports[`snippet: #15 format[oxc-ts] 1`] = `
exports[`snippet: #14 format[oxc-ts] 1`] = `
"Cannot assign to this expression (1:1)
> 1 | x?.y.z++
| ^^^^^^"
`;
exports[`snippet: #15 format[typescript] 1`] = `
exports[`snippet: #14 format[typescript] 1`] = `
"Invalid left-hand side expression in unary operation (1:1)
> 1 | x?.y.z++
| ^^^^^^
Cause: Invalid left-hand side expression in unary operation"
`;
exports[`snippet: #15 format[yuku-ts] 1`] = `
exports[`snippet: #14 format[yuku-ts] 1`] = `
"Invalid operand for increment/decrement operator (1:1)
> 1 | x?.y.z++
| ^^^^^^"
`;
exports[`snippet: #16 format[babel-ts] 1`] = `
exports[`snippet: #15 format[babel-ts] 1`] = `
"Invalid optional chaining in the left-hand side of postfix operation. (1:1)
> 1 | x?.y().z++
| ^
Cause: Invalid optional chaining in the left-hand side of postfix operation. (1:0)"
`;
exports[`snippet: #16 format[oxc-ts] 1`] = `
exports[`snippet: #15 format[oxc-ts] 1`] = `
"Cannot assign to this expression (1:1)
> 1 | x?.y().z++
| ^^^^^^^^"
`;
exports[`snippet: #16 format[typescript] 1`] = `
exports[`snippet: #15 format[typescript] 1`] = `
"Invalid left-hand side expression in unary operation (1:1)
> 1 | x?.y().z++
| ^^^^^^^^
Cause: Invalid left-hand side expression in unary operation"
`;
exports[`snippet: #16 format[yuku-ts] 1`] = `
exports[`snippet: #15 format[yuku-ts] 1`] = `
"Invalid operand for increment/decrement operator (1:1)
> 1 | x?.y().z++
| ^^^^^^^^"
`;
exports[`snippet: #17 format[babel-ts] 1`] = `
"Invalid left-hand side in postfix operation. (1:2)
> 1 | (a())++
| ^
Cause: Invalid left-hand side in postfix operation. (1:1)"
`;
exports[`snippet: #17 format[oxc-ts] 1`] = `
"Cannot assign to this expression (1:2)
> 1 | (a())++
| ^^^"
`;
exports[`snippet: #17 format[typescript] 1`] = `
"Invalid left-hand side expression in unary operation (1:1)
> 1 | (a())++
| ^^^^^
Cause: Invalid left-hand side expression in unary operation"
`;
exports[`snippet: #17 format[yuku-ts] 1`] = `
"Invalid operand for increment/decrement operator (1:1)
> 1 | (a())++
| ^^^^^"
`;
@@ -22,12 +22,18 @@ runFormatTest(
"++(x + x)",
"--(x + x)",
"a()++",
"x?.y++",
"x?.y.z++",
"x?.y().z++",
"(a())++",
],
},
["typescript", "babel-ts", "oxc-ts", "yuku-ts"],
);
runFormatTest(
{
importMeta: import.meta,
snippets: ["a()++", "(a())++"],
},
["typescript", "oxc-ts", "yuku-ts"],
);
@@ -8,7 +8,7 @@ parsers: ["typescript"]
await(1);
=====================================output=====================================
await(1);
(await)(1);
================================================================================
`;