From 01ab399316b4485422f38bb7e7aaee4d63b40796 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Sun, 20 Nov 2022 22:10:03 -0800 Subject: [PATCH] [Refactor] add `getMessageData` util --- lib/rules/hook-use-state.js | 75 +++++++++++++++++++++---------------- lib/util/message.js | 8 ++++ lib/util/report.js | 5 +-- 3 files changed, 53 insertions(+), 35 deletions(-) create mode 100644 lib/util/message.js diff --git a/lib/rules/hook-use-state.js b/lib/rules/hook-use-state.js index a9d3b7961c..ba0785495c 100644 --- a/lib/rules/hook-use-state.js +++ b/lib/rules/hook-use-state.js @@ -8,6 +8,7 @@ const Components = require('../util/Components'); const docsUrl = require('../util/docsUrl'); const report = require('../util/report'); +const getMessageData = require('../util/message'); // ------------------------------------------------------------------------------ // Rule Definition @@ -20,6 +21,8 @@ function isNodeDestructuring(node) { const messages = { useStateErrorMessage: 'useState call is not destructured into value + setter pair', useStateErrorMessageOrAddOption: 'useState call is not destructured into value + setter pair (you can allow destructuring by enabling "allowDestructuredState" option)', + suggestPair: 'Destructure useState call into value + setter pair', + suggestMemo: 'Replace useState call with useMemo', }; module.exports = { @@ -67,7 +70,10 @@ module.exports = { context, messages.useStateErrorMessage, 'useStateErrorMessage', - { node } + { + node, + suggest: false, + } ); return; } @@ -104,21 +110,23 @@ module.exports = { if (!isSymmetricGetterSetterPair) { const suggestions = [ - { - desc: 'Destructure useState call into value + setter pair', - fix: (fixer) => { - if (expectedSetterVariableNames.length === 0) { - return; - } - - const fix = fixer.replaceTextRange( - node.parent.id.range, - `[${valueVariableName}, ${expectedSetterVariableNames[0]}]` - ); - - return fix; - }, - }, + Object.assign( + getMessageData('suggestPair', messages.suggestPair), + { + fix(fixer) { + if (expectedSetterVariableNames.length === 0) { + return; + } + + const fix = fixer.replaceTextRange( + node.parent.id.range, + `[${valueVariableName}, ${expectedSetterVariableNames[0]}]` + ); + + return fix; + }, + } + ), ]; const defaultReactImports = components.getDefaultReactImports(); @@ -150,22 +158,24 @@ module.exports = { useMemoCode = 'useMemo'; } - suggestions.unshift({ - desc: 'Replace useState call with useMemo', - fix: (fixer) => [ - // Add useMemo import, if necessary - useStateReactImportSpecifier - && (!useMemoReactImportSpecifier || defaultReactImportName) - && fixer.insertTextAfter(useStateReactImportSpecifier, ', useMemo'), - // Convert single-value destructure to simple assignment - fixer.replaceTextRange(node.parent.id.range, valueVariableName), - // Convert useState call to useMemo + arrow function + dependency array - fixer.replaceTextRange( - node.range, - `${useMemoCode}(() => ${context.getSourceCode().getText(node.arguments[0])}, [])` - ), - ].filter(Boolean), - }); + suggestions.unshift(Object.assign( + getMessageData('suggestMemo', messages.suggestMemo), + { + fix: (fixer) => [ + // Add useMemo import, if necessary + useStateReactImportSpecifier + && (!useMemoReactImportSpecifier || defaultReactImportName) + && fixer.insertTextAfter(useStateReactImportSpecifier, ', useMemo'), + // Convert single-value destructure to simple assignment + fixer.replaceTextRange(node.parent.id.range, valueVariableName), + // Convert useState call to useMemo + arrow function + dependency array + fixer.replaceTextRange( + node.range, + `${useMemoCode}(() => ${context.getSourceCode().getText(node.arguments[0])}, [])` + ), + ].filter(Boolean), + } + )); } if (isOnlyValueDestructuring) { @@ -175,6 +185,7 @@ module.exports = { 'useStateErrorMessageOrAddOption', { node: node.parent.id, + suggest: false, } ); return; diff --git a/lib/util/message.js b/lib/util/message.js new file mode 100644 index 0000000000..0c9962a4de --- /dev/null +++ b/lib/util/message.js @@ -0,0 +1,8 @@ +'use strict'; + +const semver = require('semver'); +const eslintPkg = require('eslint/package.json'); + +module.exports = function getMessageData(messageId, message) { + return messageId && semver.satisfies(eslintPkg.version, '>= 4.15') ? { messageId } : { message }; +}; diff --git a/lib/util/report.js b/lib/util/report.js index d96577c0d5..9c10a13501 100644 --- a/lib/util/report.js +++ b/lib/util/report.js @@ -1,12 +1,11 @@ 'use strict'; -const semver = require('semver'); -const eslintPkg = require('eslint/package.json'); +const getMessageData = require('./message'); module.exports = function report(context, message, messageId, data) { context.report( Object.assign( - messageId && semver.satisfies(eslintPkg.version, '>= 4.15') ? { messageId } : { message }, + getMessageData(messageId, message), data ) );