From f5fc865953c9bb62ddb531cdce679dc33938f1f2 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Tue, 10 Jan 2023 11:11:39 +0800 Subject: [PATCH] Forbid `AstPath.getName()` (#14106) --- .../prefer-ast-path-getters.js | 43 +++++++++++++------ .../test.js | 14 ++++++ src/language-js/print/function.js | 5 +-- src/language-js/print/object.js | 7 ++- 4 files changed, 49 insertions(+), 20 deletions(-) diff --git a/scripts/tools/eslint-plugin-prettier-internal-rules/prefer-ast-path-getters.js b/scripts/tools/eslint-plugin-prettier-internal-rules/prefer-ast-path-getters.js index 232080a3e..22736b664 100644 --- a/scripts/tools/eslint-plugin-prettier-internal-rules/prefer-ast-path-getters.js +++ b/scripts/tools/eslint-plugin-prettier-internal-rules/prefer-ast-path-getters.js @@ -13,6 +13,7 @@ const selector = [ ].join(""); const messageId = "prefer-ast-path-getters"; +const messageIdSuggestion = "prefer-ast-path-getters/suggestion"; function getReplacement(callExpression) { const method = callExpression.callee.property.name; @@ -24,6 +25,8 @@ function getReplacement(callExpression) { return { getter: "node", description }; } break; + case "getName": + return { getters: ["key", "index"], description }; case "getParentNode": { // `path.getParentNode()` @@ -57,9 +60,10 @@ module.exports = { url: "https://github.com/prettier/prettier/blob/main/scripts/tools/eslint-plugin-prettier-internal-rules/prefer-ast-path-getters.js", }, fixable: "code", + hasSuggestions: true, messages: { - [messageId]: - "Prefer `AstPath#{{ getter }}` over `AstPath#{{ description }}`.", + [messageId]: "Prefer {{replacement}} over `AstPath#{{ description }}`.", + [messageIdSuggestion]: "Use `AstPath#{{getter}}`.", }, }, create(context) { @@ -70,22 +74,35 @@ module.exports = { return; } - context.report({ + const getters = replacement.getters ?? [replacement.getter]; + const problem = { node: callExpression.callee, messageId, data: { - getter: replacement.getter, + replacement: new Intl.ListFormat("en-US", { + type: "disjunction", + }).format(getters.map((getter) => `\`AstPath#${getter}\``)), description: replacement.description, }, - fix: (fixer) => - fixer.replaceTextRange( - [ - callExpression.callee.property.range[0], - callExpression.range[1], - ], - replacement.getter - ), - }); + }; + + const useGetter = (getter) => (fixer) => + fixer.replaceTextRange( + [callExpression.callee.property.range[0], callExpression.range[1]], + getter + ); + + if (replacement.getter) { + problem.fix = useGetter(replacement.getter); + } else { + problem.suggest = getters.map((getter) => ({ + messageId: messageIdSuggestion, + data: { getter }, + fix: useGetter(getter), + })); + } + + context.report(problem); }, }; }, diff --git a/scripts/tools/eslint-plugin-prettier-internal-rules/test.js b/scripts/tools/eslint-plugin-prettier-internal-rules/test.js index 719d798f1..b539ccc01 100644 --- a/scripts/tools/eslint-plugin-prettier-internal-rules/test.js +++ b/scripts/tools/eslint-plugin-prettier-internal-rules/test.js @@ -922,5 +922,19 @@ test("prefer-ast-path-getters", { }, ], }, + { + code: "path.getName()", + output: "path.getName()", + errors: [ + { + message: + "Prefer `AstPath#key` or `AstPath#index` over `AstPath#getName()`.", + suggestions: [ + { desc: "Use `AstPath#key`.", output: "path.key" }, + { desc: "Use `AstPath#index`.", output: "path.index" }, + ], + }, + ], + }, ], }); diff --git a/src/language-js/print/function.js b/src/language-js/print/function.js index 00ebab56b..1cb28446a 100644 --- a/src/language-js/print/function.js +++ b/src/language-js/print/function.js @@ -244,9 +244,8 @@ function printArrowChain( bodyDoc, tailNode ) { - const name = path.getName(); - const { parent } = path; - const isCallee = isCallLikeExpression(parent) && name === "callee"; + const { parent, key } = path; + const isCallee = isCallLikeExpression(parent) && key === "callee"; const isAssignmentRhs = Boolean(args?.assignmentLayout); const shouldPutBodyOnSeparateLine = tailNode.body.type !== "BlockStatement" && diff --git a/src/language-js/print/object.js b/src/language-js/print/object.js index 054d89c6c..beb4d06aa 100644 --- a/src/language-js/print/object.js +++ b/src/language-js/print/object.js @@ -68,14 +68,13 @@ function printObject(path, options, print) { propsAndLoc.sort((a, b) => a.loc - b.loc); } - const { parent } = path; + const { parent, key } = path; const isFlowInterfaceLikeBody = isTypeAnnotation && - parent && + key === "body" && (parent.type === "InterfaceDeclaration" || parent.type === "DeclareInterface" || - parent.type === "DeclareClass") && - path.getName() === "body"; + parent.type === "DeclareClass"); const shouldBreak = node.type === "TSInterfaceBody" || isEnumBody ||