From 2575bba0ae30b1b0b4013539be3b0dc4eb8114eb Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Thu, 29 Sep 2022 15:51:09 -0700 Subject: [PATCH] [Fix] `no-arrow-function-lifecycle`: when converting from an arrow, remove the semi and wrapping parens Fixes #3337 --- CHANGELOG.md | 2 + lib/rules/no-arrow-function-lifecycle.js | 6 ++- .../lib/rules/no-arrow-function-lifecycle.js | 54 +++++++++++++++++++ 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a95f5bf67..7b9e559291 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,10 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange ### Fixed * [`no-unknown-property`]: add `dialog` attributes ([#3436][] @ljharb) +* [`no-arrow-function-lifecycle`]: when converting from an arrow, remove the semi and wrapping parens ([#3337][] @ljharb) [#3436]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3436 +[#3337]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3337 ## [7.31.8] - 2022.09.08 diff --git a/lib/rules/no-arrow-function-lifecycle.js b/lib/rules/no-arrow-function-lifecycle.js index 273eb1caa9..d9be92540f 100644 --- a/lib/rules/no-arrow-function-lifecycle.js +++ b/lib/rules/no-arrow-function-lifecycle.js @@ -94,13 +94,15 @@ module.exports = { } bodyRange = [ (previousComment.length > 0 ? previousComment[0] : body).range[0], - (nextComment.length > 0 ? nextComment[nextComment.length - 1] : body).range[1], + (nextComment.length > 0 ? nextComment[nextComment.length - 1] : body).range[1] + + (node.value.body.type === 'ObjectExpression' ? 1 : 0), // to account for a wrapped end paren ]; } const headRange = [ node.key.range[1], (previousComment.length > 0 ? previousComment[0] : body).range[0], ]; + const hasSemi = node.value.expression && sourceCode.getText(node).slice(node.value.range[1] - node.range[0]) === ';'; report( context, @@ -119,7 +121,7 @@ module.exports = { return [].concat( fixer.replaceTextRange(headRange, getText(node)), isBlockBody ? [] : fixer.replaceTextRange( - bodyRange, + [bodyRange[0], bodyRange[1] + (hasSemi ? 1 : 0)], `{ return ${previousComment.map((x) => sourceCode.getText(x)).join('')}${sourceCode.getText(body)}${nextComment.map((x) => sourceCode.getText(x)).join('')}; }` ) ); diff --git a/tests/lib/rules/no-arrow-function-lifecycle.js b/tests/lib/rules/no-arrow-function-lifecycle.js index a0b3ed1ad2..ac22256c2c 100644 --- a/tests/lib/rules/no-arrow-function-lifecycle.js +++ b/tests/lib/rules/no-arrow-function-lifecycle.js @@ -987,5 +987,59 @@ ruleTester.run('no-arrow-function-lifecycle', rule, { } `, }, + { + code: ` + export default class Root extends Component { + getInitialState = () => ({ + errorImporting: null, + errorParsing: null, + errorUploading: null, + file: null, + fromExtension: false, + importSuccess: false, + isImporting: false, + isParsing: false, + isUploading: false, + parsedResults: null, + showLongRunningMessage: false, + }); + } + `, + features: ['class fields'], + errors: [{ message: 'getInitialState is a React lifecycle method, and should not be an arrow function or in a class field. Use an instance method instead.' }], + output: semver.satisfies(eslintPkg.version, '> 3') ? ` + export default class Root extends Component { + getInitialState() { return { + errorImporting: null, + errorParsing: null, + errorUploading: null, + file: null, + fromExtension: false, + importSuccess: false, + isImporting: false, + isParsing: false, + isUploading: false, + parsedResults: null, + showLongRunningMessage: false, + }; } + } + ` : ` + export default class Root extends Component { + getInitialState = () => ({ + errorImporting: null, + errorParsing: null, + errorUploading: null, + file: null, + fromExtension: false, + importSuccess: false, + isImporting: false, + isParsing: false, + isUploading: false, + parsedResults: null, + showLongRunningMessage: false, + }); + } + `, + }, ]), });