From 6ecb30a5ae670a4045b674bcf9ef2042d50b7b7f Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Fri, 5 Feb 2021 07:04:54 +0800 Subject: [PATCH] Refactor `ChainElement` related parts (#10245) * Rename `isCallOrOptionalCallExpression` -> `isCallExpression` * Replace use of `OptionalCallExpression` * Fix * Add `isMemberExpression` * Check truly in `isCallExpression` and `isMemberExpression` * Replace `OptionalMemberExpression` * Remove unneeded check * Fix type check --- src/language-js/comments.js | 17 ++--- src/language-js/needs-parens.js | 13 ++-- src/language-js/print/binaryish.js | 13 ++-- src/language-js/print/call-arguments.js | 4 +- src/language-js/print/call-expression.js | 4 +- src/language-js/print/jsx.js | 7 +-- src/language-js/print/member-chain.js | 28 ++++----- src/language-js/print/member.js | 8 +-- src/language-js/print/template-literal.js | 4 +- src/language-js/print/ternary.js | 10 ++- src/language-js/printer-estree.js | 10 ++- src/language-js/utils.js | 75 +++++++++++------------ 12 files changed, 87 insertions(+), 106 deletions(-) diff --git a/src/language-js/comments.js b/src/language-js/comments.js index e4e0caa09..f0a0ae6c1 100644 --- a/src/language-js/comments.js +++ b/src/language-js/comments.js @@ -20,6 +20,8 @@ const { hasFlowShorthandAnnotationComment, hasFlowAnnotationComment, hasIgnoreComment, + isCallExpression, + isMemberExpression, } = require("./utils"); const { locStart, locEnd } = require("./loc"); @@ -315,9 +317,7 @@ function handleMemberExpressionComments({ followingNode, }) { if ( - enclosingNode && - (enclosingNode.type === "MemberExpression" || - enclosingNode.type === "OptionalMemberExpression") && + isMemberExpression(enclosingNode) && followingNode && followingNode.type === "Identifier" ) { @@ -521,8 +521,7 @@ function handleCommentInEmptyParens({ comment, enclosingNode, text }) { enclosingNode && ((isRealFunctionLikeNode(enclosingNode) && getFunctionParameters(enclosingNode).length === 0) || - ((enclosingNode.type === "CallExpression" || - enclosingNode.type === "OptionalCallExpression" || + ((isCallExpression(enclosingNode) || enclosingNode.type === "NewExpression") && enclosingNode.arguments.length === 0)) ) { @@ -644,9 +643,7 @@ function handleCallExpressionComments({ enclosingNode, }) { if ( - enclosingNode && - (enclosingNode.type === "CallExpression" || - enclosingNode.type === "OptionalCallExpression") && + isCallExpression(enclosingNode) && precedingNode && enclosingNode.callee === precedingNode && enclosingNode.arguments.length > 0 @@ -958,9 +955,7 @@ function willPrintOwnComments(path /*, options */) { ((node && (isJsxNode(node) || hasFlowShorthandAnnotationComment(node) || - (parent && - (parent.type === "CallExpression" || - parent.type === "OptionalCallExpression") && + (isCallExpression(parent) && (hasFlowAnnotationComment(node.leadingComments) || hasFlowAnnotationComment(node.trailingComments))))) || (parent && diff --git a/src/language-js/needs-parens.js b/src/language-js/needs-parens.js index 9ecb744b9..0dbd01a74 100644 --- a/src/language-js/needs-parens.js +++ b/src/language-js/needs-parens.js @@ -10,6 +10,8 @@ const { startsWithNoLookaheadToken, shouldFlatten, getPrecedence, + isCallExpression, + isMemberExpression, } = require("./utils"); function needsParens(path, options) { @@ -675,9 +677,7 @@ function needsParens(path, options) { (name === "callee" && (parent.type === "BindExpression" || parent.type === "NewExpression")) || - (name === "object" && - (parent.type === "MemberExpression" || - parent.type === "OptionalMemberExpression")) + (name === "object" && isMemberExpression(parent)) ); case "NGPipeExpression": if ( @@ -687,9 +687,7 @@ function needsParens(path, options) { // Preserve parens for compatibility with AngularJS expressions !(node.extra && node.extra.parenthesized)) || parent.type === "ArrayExpression" || - ((parent.type === "CallExpression" || - parent.type === "OptionalCallExpression") && - parent.arguments[name] === node) || + (isCallExpression(parent) && parent.arguments[name] === node) || (name === "right" && parent.type === "NGPipeExpression") || (name === "property" && parent.type === "MemberExpression") || parent.type === "AssignmentExpression" @@ -709,7 +707,6 @@ function needsParens(path, options) { parent.type !== "AssignmentExpression" && parent.type !== "AssignmentPattern" && parent.type !== "BinaryExpression" && - parent.type !== "CallExpression" && parent.type !== "NewExpression" && parent.type !== "ConditionalExpression" && parent.type !== "ExpressionStatement" && @@ -720,7 +717,7 @@ function needsParens(path, options) { parent.type !== "JSXFragment" && parent.type !== "LogicalExpression" && parent.type !== "ObjectProperty" && - parent.type !== "OptionalCallExpression" && + !isCallExpression(parent) && parent.type !== "Property" && parent.type !== "ReturnStatement" && parent.type !== "ThrowStatement" && diff --git a/src/language-js/print/binaryish.js b/src/language-js/print/binaryish.js index 11e332f42..fb911725c 100644 --- a/src/language-js/print/binaryish.js +++ b/src/language-js/print/binaryish.js @@ -22,6 +22,8 @@ const { shouldFlatten, hasComment, CommentCheckFlags, + isCallExpression, + isMemberExpression, } = require("../utils"); /** @typedef {import("../../document").Doc} Doc */ @@ -69,13 +71,9 @@ function printBinaryishExpression(path, options, print) { // c // ).call() if ( - ((parent.type === "CallExpression" || - parent.type === "OptionalCallExpression") && - parent.callee === n) || + (isCallExpression(parent) && parent.callee === n) || parent.type === "UnaryExpression" || - ((parent.type === "MemberExpression" || - parent.type === "OptionalMemberExpression") && - !parent.computed) + (isMemberExpression(parent) && !parent.computed) ) { return group([indent([softline, ...parts]), softline]); } @@ -98,8 +96,7 @@ function printBinaryishExpression(path, options, print) { (parent.type === "ConditionalExpression" && parentParent.type !== "ReturnStatement" && parentParent.type !== "ThrowStatement" && - parentParent.type !== "CallExpression" && - parentParent.type !== "OptionalCallExpression") || + !isCallExpression(parentParent)) || parent.type === "TemplateLiteral"; const shouldIndentIfInlining = diff --git a/src/language-js/print/call-arguments.js b/src/language-js/print/call-arguments.js index 8121ec3a4..ed385406a 100644 --- a/src/language-js/print/call-arguments.js +++ b/src/language-js/print/call-arguments.js @@ -14,6 +14,7 @@ const { getCallArguments, iterateCallArgumentsPath, isNextLineEmpty, + isCallExpression, } = require("../utils"); const { @@ -251,8 +252,7 @@ function couldGroupArg(arg) { arg.body.type === "ArrowFunctionExpression" || arg.body.type === "ObjectExpression" || arg.body.type === "ArrayExpression" || - arg.body.type === "CallExpression" || - arg.body.type === "OptionalCallExpression" || + isCallExpression(arg.body) || arg.body.type === "ConditionalExpression" || isJsxNode(arg.body))) ); diff --git a/src/language-js/print/call-expression.js b/src/language-js/print/call-expression.js index 2b5a0941e..6b33179fc 100644 --- a/src/language-js/print/call-expression.js +++ b/src/language-js/print/call-expression.js @@ -7,7 +7,7 @@ const pathNeedsParens = require("../needs-parens"); const { getCallArguments, hasFlowAnnotationComment, - isCallOrOptionalCallExpression, + isCallExpression, isMemberish, isTemplateOnItsOwnLine, isTestCall, @@ -95,7 +95,7 @@ function printCallExpression(path, options, print) { // We group here when the callee is itself a call expression. // See `isLongCurriedCallExpression` for more info. - if (isDynamicImport || isCallOrOptionalCallExpression(n.callee)) { + if (isDynamicImport || isCallExpression(n.callee)) { return group(contents); } diff --git a/src/language-js/print/jsx.js b/src/language-js/print/jsx.js index 366afb9e2..1c67dc84c 100644 --- a/src/language-js/print/jsx.js +++ b/src/language-js/print/jsx.js @@ -22,7 +22,7 @@ const { isJsxNode, rawText, isLiteral, - isCallOrOptionalCallExpression, + isCallExpression, isStringLiteral, isBinaryish, hasComment, @@ -451,7 +451,7 @@ function maybeWrapJsxElementInParens(path, elem, options) { const shouldBreak = path.match( undefined, (node) => node.type === "ArrowFunctionExpression", - isCallOrOptionalCallExpression, + isCallExpression, (node) => node.type === "JSXExpressionContainer" ); @@ -505,8 +505,7 @@ function printJsxExpressionContainer(path, options, print) { (n.expression.type === "ArrayExpression" || n.expression.type === "ObjectExpression" || n.expression.type === "ArrowFunctionExpression" || - n.expression.type === "CallExpression" || - n.expression.type === "OptionalCallExpression" || + isCallExpression(n.expression) || n.expression.type === "FunctionExpression" || n.expression.type === "TemplateLiteral" || n.expression.type === "TaggedTemplateExpression" || diff --git a/src/language-js/print/member-chain.js b/src/language-js/print/member-chain.js index b12c6c191..2564fa507 100644 --- a/src/language-js/print/member-chain.js +++ b/src/language-js/print/member-chain.js @@ -10,7 +10,8 @@ const { } = require("../../common/util"); const pathNeedsParens = require("../needs-parens"); const { - isCallOrOptionalCallExpression, + isCallExpression, + isMemberExpression, isFunctionOrArrowExpression, isLongCurriedCallExpression, isMemberish, @@ -85,8 +86,8 @@ function printMemberChain(path, options, print) { function rec(path) { const node = path.getValue(); if ( - isCallOrOptionalCallExpression(node) && - (isMemberish(node.callee) || isCallOrOptionalCallExpression(node.callee)) + isCallExpression(node) && + (isMemberish(node.callee) || isCallExpression(node.callee)) ) { printedNodes.unshift({ node, @@ -111,8 +112,7 @@ function printMemberChain(path, options, print) { printed: printComments( path, () => - node.type === "OptionalMemberExpression" || - node.type === "MemberExpression" + isMemberExpression(node) ? printMemberLookup(path, options, print) : printBindExpressionCallee(path, options, print), options @@ -179,9 +179,8 @@ function printMemberChain(path, options, print) { for (; i < printedNodes.length; ++i) { if ( printedNodes[i].node.type === "TSNonNullExpression" || - isCallOrOptionalCallExpression(printedNodes[i].node) || - ((printedNodes[i].node.type === "MemberExpression" || - printedNodes[i].node.type === "OptionalMemberExpression") && + isCallExpression(printedNodes[i].node) || + (isMemberExpression(printedNodes[i].node) && printedNodes[i].node.computed && isNumericLiteral(printedNodes[i].node.property)) ) { @@ -190,7 +189,7 @@ function printMemberChain(path, options, print) { break; } } - if (!isCallOrOptionalCallExpression(printedNodes[0].node)) { + if (!isCallExpression(printedNodes[0].node)) { for (; i + 1 < printedNodes.length; ++i) { if ( isMemberish(printedNodes[i].node) && @@ -228,7 +227,7 @@ function printMemberChain(path, options, print) { } if ( - isCallOrOptionalCallExpression(printedNodes[i].node) || + isCallExpression(printedNodes[i].node) || printedNodes[i].node.type === "ImportExpression" ) { hasSeenCallExpression = true; @@ -288,8 +287,7 @@ function printMemberChain(path, options, print) { const lastNode = getLast(groups[0]).node; return ( - (lastNode.type === "MemberExpression" || - lastNode.type === "OptionalMemberExpression") && + isMemberExpression(lastNode) && lastNode.property.type === "Identifier" && (isFactory(lastNode.property.name) || hasComputed) ); @@ -350,7 +348,7 @@ function printMemberChain(path, options, print) { // empty line after const lastNodeBeforeIndent = getLast(groups[shouldMerge ? 1 : 0]).node; const shouldHaveEmptyLineBeforeIndent = - !isCallOrOptionalCallExpression(lastNodeBeforeIndent) && + !isCallExpression(lastNodeBeforeIndent) && shouldInsertEmptyLineAfter(lastNodeBeforeIndent); const expanded = [ @@ -362,13 +360,13 @@ function printMemberChain(path, options, print) { const callExpressions = printedNodes .map(({ node }) => node) - .filter(isCallOrOptionalCallExpression); + .filter(isCallExpression); function lastGroupWillBreakAndOtherCallsHaveFunctionArguments() { const lastGroupNode = getLast(getLast(groups)).node; const lastGroupDoc = getLast(printedGroups); return ( - isCallOrOptionalCallExpression(lastGroupNode) && + isCallExpression(lastGroupNode) && willBreak(lastGroupDoc) && callExpressions .slice(0, -1) diff --git a/src/language-js/print/member.js b/src/language-js/print/member.js index 01cc8b1eb..16d8ba603 100644 --- a/src/language-js/print/member.js +++ b/src/language-js/print/member.js @@ -3,7 +3,7 @@ const { builders: { softline, group, indent }, } = require("../../document"); -const { isNumericLiteral } = require("../utils"); +const { isNumericLiteral, isMemberExpression } = require("../utils"); const { printOptionalToken } = require("./misc"); function printMemberExpression(path, options, print) { @@ -17,8 +17,7 @@ function printMemberExpression(path, options, print) { i++; } while ( firstNonMemberParent && - (firstNonMemberParent.type === "MemberExpression" || - firstNonMemberParent.type === "OptionalMemberExpression" || + (isMemberExpression(firstNonMemberParent) || firstNonMemberParent.type === "TSNonNullExpression") ); @@ -33,8 +32,7 @@ function printMemberExpression(path, options, print) { n.computed || (n.object.type === "Identifier" && n.property.type === "Identifier" && - parent.type !== "MemberExpression" && - parent.type !== "OptionalMemberExpression"); + !isMemberExpression(parent)); return [ path.call(print, "object"), diff --git a/src/language-js/print/template-literal.js b/src/language-js/print/template-literal.js index 23e5d5692..9e7833296 100644 --- a/src/language-js/print/template-literal.js +++ b/src/language-js/print/template-literal.js @@ -20,6 +20,7 @@ const { isJestEachTemplateLiteral, isSimpleTemplateLiteral, hasComment, + isMemberExpression, } = require("../utils"); function printTemplateLiteral(path, print, options) { @@ -85,8 +86,7 @@ function printTemplateLiteral(path, print, options) { // in the middle of a MemberExpression if ( hasComment(expression) || - expression.type === "MemberExpression" || - expression.type === "OptionalMemberExpression" || + isMemberExpression(expression) || expression.type === "ConditionalExpression" || expression.type === "SequenceExpression" || expression.type === "TSAsExpression" || diff --git a/src/language-js/print/ternary.js b/src/language-js/print/ternary.js index 976f7b9cf..61d47d691 100644 --- a/src/language-js/print/ternary.js +++ b/src/language-js/print/ternary.js @@ -2,7 +2,12 @@ const flat = require("lodash/flatten"); const { hasNewlineInRange } = require("../../common/util"); -const { isJsxNode, isBlockComment, getComments } = require("../utils"); +const { + isJsxNode, + isBlockComment, + getComments, + isMemberExpression, +} = require("../utils"); const { locStart, locEnd } = require("../loc"); const { builders: { @@ -304,8 +309,7 @@ function printTernary(path, options, print) { // ).call() const breakClosingParen = !jsxMode && - (parent.type === "MemberExpression" || - parent.type === "OptionalMemberExpression" || + (isMemberExpression(parent) || (parent.type === "NGPipeExpression" && parent.left === node)) && !parent.computed; diff --git a/src/language-js/printer-estree.js b/src/language-js/printer-estree.js index 2222cd9a4..f65f02ef4 100644 --- a/src/language-js/printer-estree.js +++ b/src/language-js/printer-estree.js @@ -41,6 +41,8 @@ const { rawText, shouldPrintComma, hasIgnoreComment, + isCallExpression, + isMemberExpression, } = require("./utils"); const { locStart, locEnd } = require("./loc"); @@ -367,12 +369,8 @@ function printPathNoParens(path, options, print, args) { } const parent = path.getParentNode(); if ( - ((parent.type === "CallExpression" || - parent.type === "OptionalCallExpression") && - parent.callee === n) || - ((parent.type === "MemberExpression" || - parent.type === "OptionalMemberExpression") && - parent.object === n) + (isCallExpression(parent) && parent.callee === n) || + (isMemberExpression(parent) && parent.object === n) ) { return group([indent([softline, ...parts]), softline]); } diff --git a/src/language-js/utils.js b/src/language-js/utils.js index e309db064..afbaa43b4 100644 --- a/src/language-js/utils.js +++ b/src/language-js/utils.js @@ -101,10 +101,8 @@ function hasNakedLeftSide(node) { node.type === "LogicalExpression" || node.type === "NGPipeExpression" || node.type === "ConditionalExpression" || - node.type === "CallExpression" || - node.type === "OptionalCallExpression" || - node.type === "MemberExpression" || - node.type === "OptionalMemberExpression" || + isCallExpression(node) || + isMemberExpression(node) || node.type === "SequenceExpression" || node.type === "TaggedTemplateExpression" || node.type === "BindExpression" || @@ -309,13 +307,12 @@ function isTemplateLiteral(node) { * Note: `inject` is used in AngularJS 1.x, `async` in Angular 2+ * example: https://docs.angularjs.org/guide/unit-testing#using-beforeall- * - * @param {Node} node + * @param {CallExpression} node * @returns {boolean} */ function isAngularTestWrapper(node) { return ( - (node.type === "CallExpression" || - node.type === "OptionalCallExpression") && + isCallExpression(node) && node.callee.type === "Identifier" && (node.callee.name === "async" || node.callee.name === "inject" || @@ -352,15 +349,14 @@ function isTheOnlyJsxElementInMarkdown(options, path) { * @returns {boolean} */ function isMemberExpressionChain(node) { - if ( - node.type !== "MemberExpression" && - node.type !== "OptionalMemberExpression" - ) { + if (!isMemberExpression(node)) { return false; } + // @ts-ignore if (node.object.type === "Identifier") { return true; } + // @ts-ignore return isMemberExpressionChain(node.object); } @@ -423,8 +419,7 @@ function isBinaryish(node) { */ function isMemberish(node) { return ( - node.type === "MemberExpression" || - node.type === "OptionalMemberExpression" || + isMemberExpression(node) || (node.type === "BindExpression" && Boolean(node.object)) ); } @@ -500,13 +495,12 @@ function isSimpleType(node) { const unitTestRe = /^(skip|[fx]?(it|describe|test))$/; /** - * @param {CallExpression} node + * @param {{callee: MemberExpression | OptionalMemberExpression}} node * @returns {boolean} */ function isSkipOrOnlyBlock(node) { return ( - (node.callee.type === "MemberExpression" || - node.callee.type === "OptionalMemberExpression") && + isMemberExpression(node.callee) && node.callee.object.type === "Identifier" && node.callee.property.type === "Identifier" && unitTestRe.test(node.callee.object.name) && @@ -564,12 +558,25 @@ function isTestCall(n, parent) { } /** - * @param {CallExpression | OptionalCallExpression} node + * @param {Node} node * @returns {boolean} */ -function isCallOrOptionalCallExpression(node) { +function isCallExpression(node) { return ( - node.type === "CallExpression" || node.type === "OptionalCallExpression" + node && + (node.type === "CallExpression" || node.type === "OptionalCallExpression") + ); +} + +/** + * @param {Node} node + * @returns {boolean} + */ +function isMemberExpression(node) { + return ( + node && + (node.type === "MemberExpression" || + node.type === "OptionalMemberExpression") ); } @@ -601,15 +608,9 @@ function isSimpleTemplateLiteral(node) { } // Allow `a.b.c`, `a.b[c]`, and `this.x.y` - if ( - expr.type === "MemberExpression" || - expr.type === "OptionalMemberExpression" - ) { + if (isMemberExpression(expr)) { let head = expr; - while ( - head.type === "MemberExpression" || - head.type === "OptionalMemberExpression" - ) { + while (isMemberExpression(head)) { if ( head.property.type !== "Identifier" && head.property.type !== "Literal" && @@ -847,7 +848,7 @@ function isFunctionCompositionArgs(args) { if (count > 1) { return true; } - } else if (isCallOrOptionalCallExpression(arg)) { + } else if (isCallExpression(arg)) { for (const childArg of arg.arguments) { if (isFunctionOrArrowExpression(childArg)) { return true; @@ -872,8 +873,8 @@ function isLongCurriedCallExpression(path) { const node = path.getValue(); const parent = path.getParentNode(); return ( - isCallOrOptionalCallExpression(node) && - isCallOrOptionalCallExpression(parent) && + isCallExpression(node) && + isCallExpression(parent) && parent.callee === node && node.arguments.length > parent.arguments.length && parent.arguments.length > 0 @@ -938,21 +939,14 @@ function isSimpleCallArgument(node, depth) { return isChildSimple(node.source); } - if ( - node.type === "CallExpression" || - node.type === "OptionalCallExpression" || - node.type === "NewExpression" - ) { + if (isCallExpression(node) || node.type === "NewExpression") { return ( isSimpleCallArgument(node.callee, depth) && node.arguments.every(isChildSimple) ); } - if ( - node.type === "MemberExpression" || - node.type === "OptionalMemberExpression" - ) { + if (isMemberExpression(node)) { return ( isSimpleCallArgument(node.object, depth) && isSimpleCallArgument(node.property, depth) @@ -1355,7 +1349,8 @@ module.exports = { isBlockComment, isLineComment, isPrettierIgnoreComment, - isCallOrOptionalCallExpression, + isCallExpression, + isMemberExpression, isExportDeclaration, isFlowAnnotationComment, isFunctionCompositionArgs,