Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support source phase import syntax #15486

Closed
wants to merge 14 commits into from
4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -32,8 +32,8 @@
"dependencies": {
"@angular/compiler": "16.2.6",
"@babel/code-frame": "7.22.13",
"@babel/parser": "7.22.16",
"@babel/types": "7.22.19",
"@babel/parser": "7.23.0",
"@babel/types": "7.23.0",
"@glimmer/syntax": "0.84.3",
"@iarna/toml": "2.2.5",
"@prettier/is-es5-identifier-name": "0.2.0",
Expand Down
2 changes: 2 additions & 0 deletions src/language-js/parse/babel.js
Expand Up @@ -26,6 +26,7 @@ const parseOptions = {
allowUndeclaredExports: true,
errorRecovery: true,
createParenthesizedExpressions: true,
createImportExpressions: true,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@babel/parser requires this to parse import.source("x") syntax.

plugins: [
// When adding a plugin, please add a test in `tests/format/js/babel-plugins`,
// To remove plugins, remove it here and run `yarn test tests/format/js/babel-plugins` to verify
Expand All @@ -45,6 +46,7 @@ const parseOptions = {
"importReflection",
"explicitResourceManagement",
["importAttributes", { deprecatedAssertSyntax: true }],
"sourcePhaseImports",
],
tokens: true,
ranges: true,
Expand Down
9 changes: 8 additions & 1 deletion src/language-js/print/call-expression.js
Expand Up @@ -68,7 +68,7 @@ function printCallExpression(path, options, print) {

const contents = [
isNew ? "new " : "",
isDynamicImport ? "import" : print("callee"),
isDynamicImport ? printDynamicImportCallee(node) : print("callee"),
optional,
printFunctionTypeParameters(path, options, print),
printCallArguments(path, options, print),
Expand All @@ -83,6 +83,13 @@ function printCallExpression(path, options, print) {
return contents;
}

function printDynamicImportCallee(node) {
if (!node.phase) {
return "import";
}
return `import.${node.phase}`;
}

function isCommonsJsOrAmdCall(node, parentNode) {
if (node.callee.type !== "Identifier") {
return false;
Expand Down
1 change: 1 addition & 0 deletions src/language-js/print/module.js
Expand Up @@ -34,6 +34,7 @@ function printImportDeclaration(path, options, print) {
return [
"import",
node.module ? " module" : "",
node.phase ? ` ${node.phase}` : "",
printImportKind(node),
printModuleSpecifiers(path, options, print),
printModuleSource(path, options, print),
Expand Down
19 changes: 18 additions & 1 deletion src/language-js/utils/index.js
Expand Up @@ -1050,9 +1050,15 @@ function getCallArguments(node) {
if (node.type === "ImportExpression") {
args = [node.source];

// import attributes
if (node.attributes) {
args.push(node.attributes);
}

// deprecated import assertions
if (node.options) {
args.push(node.options);
}
}

callArgumentsCache.set(node, args);
Expand All @@ -1064,22 +1070,33 @@ function iterateCallArgumentsPath(path, iteratee) {
if (node.type === "ImportExpression") {
path.call((sourcePath) => iteratee(sourcePath, 0), "source");

// import attributes
if (node.attributes) {
path.call((sourcePath) => iteratee(sourcePath, 1), "attributes");
}

// deprecated import assertions
if (node.options) {
path.call((sourcePath) => iteratee(sourcePath, 1), "options");
}
} else {
path.each(iteratee, "arguments");
}
}

function getCallArgumentSelector(node, index) {
if (node.type === "ImportExpression") {
if (index === 0 || index === (node.attributes ? -2 : -1)) {
if (index === 0 || index === (node.attributes || node.options ? -2 : -1)) {
return "source";
}
// import attributes
if (node.attributes && (index === 1 || index === -1)) {
return "attributes";
}
// deprecated import assertions
if (node.options && (index === 1 || index === -1)) {
return "options";
}
throw new RangeError("Invalid argument index");
}
if (index < 0) {
Expand Down
40 changes: 40 additions & 0 deletions tests/format/js/babel-plugins/__snapshots__/jsfmt.spec.js.snap
Expand Up @@ -2461,6 +2461,46 @@ const re = /^(?i:[a-z])[a-z]$/;
================================================================================
`;

exports[`source-phase-imports.js [acorn] format 1`] = `
"Unexpected token (1:15)
> 1 | import source fooSource from "foo";
| ^
2 | import.source("x");
3 |"
`;

exports[`source-phase-imports.js [espree] format 1`] = `
"Unexpected token fooSource (1:15)
> 1 | import source fooSource from "foo";
| ^
2 | import.source("x");
3 |"
`;

exports[`source-phase-imports.js [meriyah] format 1`] = `
"Import source must be string (1:23)
> 1 | import source fooSource from "foo";
| ^
2 | import.source("x");
3 |"
`;

exports[`source-phase-imports.js format 1`] = `
====================================options=====================================
parsers: ["babel", "babel-ts", "babel-flow"]
printWidth: 80
| printWidth
=====================================input======================================
import source fooSource from "foo";
import.source("x");

=====================================output=====================================
import source fooSource from "foo";
import.source("x");

================================================================================
`;

exports[`throw-expressions.js [acorn] format 1`] = `
"Unexpected token (3:23)
1 | // https://babeljs.io/docs/en/babel-plugin-proposal-throw-expressions
Expand Down
3 changes: 3 additions & 0 deletions tests/format/js/babel-plugins/jsfmt.spec.js
Expand Up @@ -31,6 +31,7 @@ run_spec(import.meta, ["babel", "babel-ts", "babel-flow"], {
"import-reflection.js",
"explicit-resource-management.js",
"regexp-modifiers.js",
"source-phase-imports.js",
],
espree: [
"decimal.js",
Expand Down Expand Up @@ -60,6 +61,7 @@ run_spec(import.meta, ["babel", "babel-ts", "babel-flow"], {
"import-reflection.js",
"explicit-resource-management.js",
"regexp-modifiers.js",
"source-phase-imports.js",
],
meriyah: [
"decimal.js",
Expand Down Expand Up @@ -91,6 +93,7 @@ run_spec(import.meta, ["babel", "babel-ts", "babel-flow"], {
"import-reflection.js",
"explicit-resource-management.js",
"regexp-modifiers.js",
"source-phase-imports.js",
],
babel: ["flow.js", "typescript.js"],
__babel_estree: ["flow.js", "typescript.js"],
Expand Down
2 changes: 2 additions & 0 deletions tests/format/js/babel-plugins/source-phase-imports.js
@@ -0,0 +1,2 @@
import source fooSource from "foo";
import.source("x");