Skip to content

Commit

Permalink
Enable import attributes parsing by default (#16850)
Browse files Browse the repository at this point in the history
* Enable import attributes parsing by default

* Remove plugin from tests

* Update fixtures

* Fix failures

* `make build`

* Fix TS errors

* Fix

* Update .d.ts

* Move in core

* [babel 8] Remove syntax plugins from preset-env

* Update fixtures

* Fix ESM build of Babel 7 and standalone

* Update flow allowlist

* Update parser fixtures for Babel 8

* Update generator tests

* Update parser test

* Update standalone

* Do not run import attribtues plugin test in Babel 8

* Make tests pass in babel 8

* Fix Babel 8 build

* [babel 8] Stop printing legacy "with" attributes

* fix prettier integration test

* Fix Babel 8 compat in syntax-import-attributes

* Try fix

* Do not error for the removed `importAttributes` plugin

* Skip a test in babel7/8 compat e2e

* Throw an error when using removed option from the parser

* Fixes after rebase

* Raise `ImportCallArity` also when `createImportExpressions`

* Fix linting
  • Loading branch information
nicolo-ribaudo authored Oct 24, 2024
1 parent c369676 commit 64fa466
Show file tree
Hide file tree
Showing 309 changed files with 1,271 additions and 624 deletions.
3 changes: 3 additions & 0 deletions Gulpfile.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,7 @@ function buildRollup(packages, buildStandalone) {
bool(process.env.BABEL_8_BREAKING)
? [
// These require()s are all in babel-preset-env/src/polyfills/babel-7-plugins.cjs
// and packages/babel-preset-env/src/babel-7-available-plugins.cjs.
// They are gated by a !process.env.BABEL_8_BREAKING check, but
// @rollup/plugin-commonjs extracts them to import statements outside of the
// check and thus they end up in the final bundle.
Expand All @@ -418,6 +419,8 @@ function buildRollup(packages, buildStandalone) {
"./babel-polyfill.cjs",
"./regenerator.cjs",
"@babel/compat-data/corejs2-built-ins",
"@babel/plugin-syntax-import-assertions",
"@babel/plugin-syntax-import-attributes",
]
: [],
dynamicRequireTargets: [
Expand Down
38 changes: 24 additions & 14 deletions eslint/babel-eslint-parser/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,31 @@ const BABEL_OPTIONS = {
),
};
const PROPS_TO_REMOVE = [
"importKind",
"exportKind",
"variance",
"typeArguments",
"filename",
"identifierName",
{ key: "importKind", type: null },
{ key: "exportKind", type: null },
{ key: "variance", type: null },
{ key: "typeArguments", type: null },
{ key: "filename", type: null },
{ key: "identifierName", type: null },
// espree doesn't support these yet
{ key: "attributes", type: "ImportDeclaration" },
{ key: "attributes", type: "ExportNamedDeclaration" },
{ key: "attributes", type: "ExportAllDeclaration" },
{ key: "attributes", type: "ImportExpression" },
{ key: "options", type: "ImportExpression" },
];

function deeplyRemoveProperties(obj, props) {
for (const [k, v] of Object.entries(obj)) {
if (
props.some(
({ key, type }) => key === k && (type == null || type === obj.type),
)
) {
delete obj[k];
continue;
}

if (typeof v === "object") {
if (Array.isArray(v)) {
for (const el of v) {
Expand All @@ -51,16 +66,9 @@ function deeplyRemoveProperties(obj, props) {
}
}

if (props.includes(k)) {
delete obj[k];
} else if (v != null) {
if (v != null) {
deeplyRemoveProperties(v, props);
}
continue;
}

if (props.includes(k)) {
delete obj[k];
}
}
}
Expand Down Expand Up @@ -101,6 +109,7 @@ describe("Babel and Espree", () => {
}).ast;

deeplyRemoveProperties(babelAST, PROPS_TO_REMOVE);
deeplyRemoveProperties(espreeAST, ["offset"]);
expect(babelAST).toEqual(espreeAST);
} else {
// ESLint 8
Expand All @@ -117,6 +126,7 @@ describe("Babel and Espree", () => {
}).ast;

deeplyRemoveProperties(babelAST, PROPS_TO_REMOVE);
deeplyRemoveProperties(espreeAST, ["offset"]);
expect(babelAST).toEqual(espreeAST);
}
}
Expand Down
12 changes: 6 additions & 6 deletions packages/babel-core/src/parser/util/missing-plugin-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,6 @@ const pluginNameMap: Record<
url: "https://github.com/babel/babel/tree/main/packages/babel-preset-react",
},
},
importAttributes: {
syntax: {
name: "@babel/plugin-syntax-import-attributes",
url: "https://github.com/babel/babel/tree/main/packages/babel-plugin-syntax-import-attributes",
},
},
pipelineOperator: {
syntax: {
name: "@babel/plugin-syntax-pipeline-operator",
Expand Down Expand Up @@ -204,6 +198,12 @@ if (!process.env.BABEL_8_BREAKING) {
url: "https://github.com/babel/babel/tree/main/packages/babel-plugin-syntax-import-assertions",
},
},
importAttributes: {
syntax: {
name: "@babel/plugin-syntax-import-attributes",
url: "https://github.com/babel/babel/tree/main/packages/babel-plugin-syntax-import-attributes",
},
},
importMeta: {
syntax: {
name: "@babel/plugin-syntax-import-meta",
Expand Down
9 changes: 6 additions & 3 deletions packages/babel-generator/src/generators/modules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export function _printAttributes(
const { attributes, assertions } = node;

if (
!process.env.BABEL_8_BREAKING &&
attributes &&
!importAttributesKeyword &&
// In the production build only show the warning once.
Expand All @@ -101,7 +102,11 @@ Please specify the "importAttributesKeyword" generator option, whose value can b
this.word(useAssertKeyword ? "assert" : "with");
this.space();

if (!useAssertKeyword && importAttributesKeyword !== "with") {
if (
!process.env.BABEL_8_BREAKING &&
!useAssertKeyword &&
importAttributesKeyword !== "with"
) {
// with-legacy
this.printList(attributes || assertions);
return;
Expand Down Expand Up @@ -132,11 +137,9 @@ export function ExportAllDeclaration(
this.space();
this.word("from");
this.space();
// @ts-expect-error Fixme: attributes is not defined in DeclareExportAllDeclaration
if (node.attributes?.length || node.assertions?.length) {
this.print(node.source, true);
this.space();
// @ts-expect-error Fixme: attributes is not defined in DeclareExportAllDeclaration
this._printAttributes(node, false);
} else {
this.print(node.source);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"plugins": [["importAttributes", { "deprecatedAssertSyntax": true }]],
"plugins": ["deprecatedImportAssert"],
"importAttributesKeyword": "assert"
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
{
"BABEL_8_BREAKING": true,
"plugins": [["importAttributes", { "deprecatedAssertSyntax": true }]],
"warns": "You are using import attributes, without specifying the desired output syntax.",
"expectedReParseError": true
"plugins": ["deprecatedImportAssert"]
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
import "a" with type: "json";
import "a" with { type: "json" };
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"plugins": [["importAttributes", { "deprecatedAssertSyntax": true }]],
"BABEL_8_BREAKING": false,
"plugins": ["deprecatedImportAssert"],
"importAttributesKeyword": "with-legacy",
"expectedReParseError": true
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"plugins": [["importAttributes", { "deprecatedAssertSyntax": true }]],
"plugins": ["deprecatedImportAssert"],
"importAttributesKeyword": "with"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import "a" with { type: "json" };
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"BABEL_8_BREAKING": false,
"_": "The warning is only shown once in the release build, tested by the assertions-with-to-default fixture",
"noWarnInPublishBuild": true,
"plugins": ["importAttributes"],
"warns": "You are using import attributes, without specifying the desired output syntax.",
"expectedReParseError": true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import "a" with type: "json";
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
{
"_": "The warning is only shown once in the release build, tested by the assertions-with-to-default fixture",
"noWarnInPublishBuild": true,
"plugins": ["importAttributes"],
"warns": "You are using import attributes, without specifying the desired output syntax.",
"expectedReParseError": true
"BABEL_8_BREAKING": true,
"plugins": ["importAttributes"]
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
import "a" with type: "json";
import "a" with { type: "json" };
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"BABEL_8_BREAKING": false,
"plugins": ["importAttributes"],
"importAttributesKeyword": "with-legacy",
"expectedReParseError": true
Expand Down
2 changes: 1 addition & 1 deletion packages/babel-generator/test/preserve-format.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const FAILURES = [
"importAttributesKeyword/attributes-assert-to-with/input.js",
"importAttributesKeyword/attributes-assert-to-with-legacy/input.js",
"importAttributesKeyword/attributes-with-to-assert/input.js",
"importAttributesKeyword/attributes-with-to-default/input.js",
"importAttributesKeyword/attributes-with-to-default-babel-7/input.js",
"importAttributesKeyword/attributes-with-to-with-legacy/input.js",
"importAttributesKeyword/legacy-module-attributes-to-assert/input.js",
"importAttributesKeyword/legacy-module-attributes-to-with/input.js",
Expand Down
9 changes: 2 additions & 7 deletions packages/babel-parser/src/parse-error/standard-errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,15 +117,10 @@ export default {
"Illegal 'use strict' directive in function with non-simple parameter list.",
IllegalReturn: "'return' outside of function.",
ImportAttributesUseAssert:
"The `assert` keyword in import attributes is deprecated and it has been replaced by the `with` keyword. You can enable the `deprecatedAssertSyntax: true` option in the import attributes plugin to suppress this error.",
"The `assert` keyword in import attributes is deprecated and it has been replaced by the `with` keyword. You can enable the `deprecatedImportAssert` parser plugin to suppress this error.",
ImportBindingIsString: ({ importName }: { importName: string }) =>
`A string literal cannot be used as an imported binding.\n- Did you mean \`import { "${importName}" as foo }\`?`,
ImportCallArgumentTrailingComma:
"Trailing comma is disallowed inside import(...) arguments.",
ImportCallArity: ({ maxArgumentCount }: { maxArgumentCount: 1 | 2 }) =>
`\`import()\` requires exactly ${
maxArgumentCount === 1 ? "one argument" : "one or two arguments"
}.`,
ImportCallArity: `\`import()\` requires exactly one or two arguments.`,
ImportCallNotNewExpression: "Cannot use new with import(...).",
ImportCallSpreadArgument: "`...` is not allowed in `import()`.",
ImportJSONBindingNotDefault:
Expand Down
74 changes: 16 additions & 58 deletions packages/babel-parser/src/parser/expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -881,9 +881,7 @@ export default abstract class ExpressionParser extends LValParser {
} else {
node.arguments = this.parseCallExpressionArguments(
tt.parenR,
base.type === "Import",
base.type !== "Super",
// @ts-expect-error todo(flow->ts)
node,
refExpressionErrors,
);
Expand Down Expand Up @@ -960,27 +958,8 @@ export default abstract class ExpressionParser extends LValParser {
optional: boolean,
): T {
if (node.callee.type === "Import") {
if (node.arguments.length === 2) {
if (
process.env.BABEL_8_BREAKING ||
!(
this.hasPlugin("moduleAttributes") ||
this.hasPlugin("importAssertions")
)
) {
this.expectPlugin("importAttributes");
}
}
if (node.arguments.length === 0 || node.arguments.length > 2) {
this.raise(Errors.ImportCallArity, node, {
maxArgumentCount:
this.hasPlugin("importAttributes") ||
(!process.env.BABEL_8_BREAKING &&
(this.hasPlugin("importAssertions") ||
this.hasPlugin("moduleAttributes")))
? 2
: 1,
});
this.raise(Errors.ImportCallArity, node);
} else {
for (const arg of node.arguments) {
if (arg.type === "SpreadElement") {
Expand All @@ -998,11 +977,10 @@ export default abstract class ExpressionParser extends LValParser {
parseCallExpressionArguments(
this: Parser,
close: TokenType,
dynamicImport?: boolean,
allowPlaceholder?: boolean,
nodeForExtra?: N.Node | null,
nodeForExtra?: Undone<N.Node> | null,
refExpressionErrors?: ExpressionErrors | null,
): Array<N.Expression | undefined | null> {
): Array<N.Expression> {
const elts: N.Expression[] = [];
let first = true;
const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody;
Expand All @@ -1014,18 +992,6 @@ export default abstract class ExpressionParser extends LValParser {
} else {
this.expect(tt.comma);
if (this.match(close)) {
if (
dynamicImport &&
!this.hasPlugin("importAttributes") &&
(process.env.BABEL_8_BREAKING ||
(!this.hasPlugin("importAssertions") &&
!this.hasPlugin("moduleAttributes")))
) {
this.raise(
Errors.ImportCallArgumentTrailingComma,
this.state.lastTokStartLoc,
);
}
if (nodeForExtra) {
this.addTrailingCommaExtraToNode(nodeForExtra);
}
Expand Down Expand Up @@ -2067,10 +2033,7 @@ export default abstract class ExpressionParser extends LValParser {
} else {
this.expect(tt.comma);
if (this.match(close)) {
this.addTrailingCommaExtraToNode(
// @ts-expect-error todo(flow->ts) improve node types
node,
);
this.addTrailingCommaExtraToNode(node);
break;
}
}
Expand Down Expand Up @@ -2115,7 +2078,7 @@ export default abstract class ExpressionParser extends LValParser {
return this.finishNode(node, type);
}

addTrailingCommaExtraToNode(node: N.Node): void {
addTrailingCommaExtraToNode(node: Undone<N.Node>): void {
this.addExtra(node, "trailingComma", this.state.lastTokStartLoc.index);
this.addExtra(node, "trailingCommaLoc", this.state.lastTokStartLoc, false);
}
Expand Down Expand Up @@ -2982,25 +2945,20 @@ export default abstract class ExpressionParser extends LValParser {
): N.ImportExpression {
this.next(); // eat tt.parenL
node.source = this.parseMaybeAssignAllowIn();
if (
this.hasPlugin("importAttributes") ||
(!process.env.BABEL_8_BREAKING && this.hasPlugin("importAssertions"))
) {
node.options = null;
}
node.options = null;
if (this.eat(tt.comma)) {
if (
process.env.BABEL_8_BREAKING ||
!(
this.hasPlugin("moduleAttributes") ||
this.hasPlugin("importAssertions")
)
) {
this.expectPlugin("importAttributes");
}
if (!this.match(tt.parenR)) {
node.options = this.parseMaybeAssignAllowIn();
this.eat(tt.comma);

if (this.eat(tt.comma) && !this.match(tt.parenR)) {
// keep consuming arguments, to then throw ImportCallArity
// instead of "expected )"
do {
this.parseMaybeAssignAllowIn();
} while (this.eat(tt.comma) && !this.match(tt.parenR));

this.raise(Errors.ImportCallArity, node);
}
}
}
this.expect(tt.parenR);
Expand Down
Loading

0 comments on commit 64fa466

Please sign in to comment.