From 13c88511da5cd4cba2df40d66b62ea05c4464314 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Wed, 11 Nov 2020 10:02:47 +0800 Subject: [PATCH] Refactor: Add `getCallArguments` and `iterateCallArgumentsPath` (#9608) --- src/language-js/print/call-arguments.js | 26 ++++++++-------------- src/language-js/printer-estree.js | 16 +++++++------- src/language-js/utils.js | 29 +++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 25 deletions(-) diff --git a/src/language-js/print/call-arguments.js b/src/language-js/print/call-arguments.js index e36d2d694..0561f1b8b 100644 --- a/src/language-js/print/call-arguments.js +++ b/src/language-js/print/call-arguments.js @@ -15,6 +15,8 @@ const { isJSXNode, isLongCurriedCallExpression, shouldPrintComma, + getCallArguments, + iterateCallArgumentsPath, } = require("../utils"); const { locEnd } = require("../loc"); @@ -36,8 +38,8 @@ const { function printCallArguments(path, options, print) { const node = path.getValue(); const isDynamicImport = node.type === "ImportExpression"; - const args = isDynamicImport ? [node.source] : node.arguments; + const args = getCallArguments(node); if (args.length === 0) { return concat([ "(", @@ -94,7 +96,8 @@ function printCallArguments(path, options, print) { let shouldBreakForArrowFunction = false; let hasEmptyLineFollowingFirstArg = false; const lastArgIndex = args.length - 1; - const printArgument = (argPath, index) => { + const printedArguments = []; + iterateCallArgumentsPath(path, (argPath, index) => { const arg = argPath.getNode(); const parts = [print(argPath)]; @@ -116,11 +119,8 @@ function printCallArguments(path, options, print) { argPath ); - return concat(parts); - }; - const printedArguments = isDynamicImport - ? [path.call((path) => printArgument(path, 0), "source")] - : path.map(printArgument, "arguments"); + printedArguments.push(concat(parts)); + }); const maybeTrailingComma = // Dynamic imports cannot have trailing commas @@ -161,8 +161,7 @@ function printCallArguments(path, options, print) { // We want to print the last argument with a special flag let printedExpanded = []; - let i = 0; - const printArgument = (argPath) => { + iterateCallArgumentsPath(path, (argPath, i) => { if (shouldGroupFirst && i === 0) { printedExpanded = [ concat([ @@ -178,14 +177,7 @@ function printCallArguments(path, options, print) { .slice(0, -1) .concat(argPath.call((p) => print(p, { expandLastArg: true }))); } - i++; - }; - - if (isDynamicImport) { - path.call(printArgument, "source"); - } else { - path.each(printArgument, "arguments"); - } + }); const somePrintedArgumentsWillBreak = printedArguments.some(willBreak); diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index add0da277..b98856f8a 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -53,6 +53,8 @@ const { classChildNeedsASIProtection, classPropMayCauseASIProblems, getFunctionParameters, + getCallArguments, + iterateCallArgumentsPath, getLeftSidePathName, getParentExportDeclaration, getTypeScriptMappedTypeModifier, @@ -966,7 +968,7 @@ function printPathNoParens(path, options, print, args) { const isDynamicImport = n.type === "ImportExpression"; const optional = printOptionalToken(path); - const args = isDynamicImport ? [n.source] : n.arguments; + const args = getCallArguments(n); if ( // We want to keep CommonJS- and AMD-style require calls, and AMD-style // define calls, as a unit. @@ -982,18 +984,16 @@ function printPathNoParens(path, options, print, args) { // e.g. `it('long name', () => {` (!isNew && isTestCall(n, path.getParentNode())) ) { + const printed = []; + iterateCallArgumentsPath(path, (argPath) => { + printed.push(print(argPath)); + }); return concat([ isNew ? "new " : "", path.call(print, "callee"), optional, printFunctionTypeParameters(path, options, print), - concat([ - "(", - isDynamicImport - ? path.call(print, "source") - : join(", ", path.map(print, "arguments")), - ")", - ]), + concat(["(", join(", ", printed), ")"]), ]); } diff --git a/src/language-js/utils.js b/src/language-js/utils.js index d5564efba..412c5d09e 100644 --- a/src/language-js/utils.js +++ b/src/language-js/utils.js @@ -1446,6 +1446,33 @@ function iterateFunctionParametersPath(path, iteratee) { } } +const callArgumentsCache = new WeakMap(); +function getCallArguments(node) { + if (callArgumentsCache.has(node)) { + return callArgumentsCache.get(node); + } + const args = + node.type === "ImportExpression" + ? // No parser except `babel` supports `import("./foo.json", { assert: { type: "json" } })` yet, + // And `babel` parser it as `CallExpression` + // We need add the second argument here + [node.source] + : node.arguments; + + callArgumentsCache.set(node, args); + return args; +} + +function iterateCallArgumentsPath(path, iteratee) { + const node = path.getValue(); + // See comment in `getCallArguments` + if (node.type === "ImportExpression") { + path.call((sourcePath) => iteratee(sourcePath, 0), "source"); + } else { + path.each(iteratee, "arguments"); + } +} + function isPrettierIgnoreComment(comment) { return comment.value.trim() === "prettier-ignore"; } @@ -1472,6 +1499,8 @@ module.exports = { classPropMayCauseASIProblems, getFunctionParameters, iterateFunctionParametersPath, + getCallArguments, + iterateCallArgumentsPath, hasRestParameter, getLeftSidePathName, getParentExportDeclaration,