From 97b48764957426f39d7bc07cd0528b2ebc0c00d5 Mon Sep 17 00:00:00 2001 From: Elizabeth Craig Date: Thu, 28 Sep 2023 13:20:42 -0700 Subject: [PATCH 1/2] react-hooks/rules-of-hooks: detect issues in class properties --- .../ESLintRuleExhaustiveDeps-test.js | 3 +- .../__tests__/ESLintRulesOfHooks-test.js | 118 ++++++++++++++++-- .../eslint-plugin-react-hooks/package.json | 2 +- .../src/RulesOfHooks.js | 3 +- yarn.lock | 75 ++++++----- 5 files changed, 148 insertions(+), 53 deletions(-) diff --git a/packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js b/packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js index 2934c33e5d17b..055474ea321e0 100644 --- a/packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js +++ b/packages/eslint-plugin-react-hooks/__tests__/ESLintRuleExhaustiveDeps-test.js @@ -8300,6 +8300,7 @@ describe('rules-of-hooks/exhaustive-deps', () => { ecmaVersion: 6, sourceType: 'module', }; + const languageOptionsV9 = { ecmaVersion: 6, sourceType: 'module', @@ -8442,7 +8443,7 @@ describe('rules-of-hooks/exhaustive-deps', () => { parser: require('@typescript-eslint/parser-v5'), }, }).run( - 'eslint: v9, parser: @typescript-eslint/parser@^5.0.0-0', + 'eslint: v9, parser: @typescript-eslint/parser@^5.0.0', ReactHooksESLintRule, { valid: [ diff --git a/packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js b/packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js index 9152999f647c3..62a6bdff32aee 100644 --- a/packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js +++ b/packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js @@ -1561,19 +1561,117 @@ if (!process.env.CI) { } describe('rules-of-hooks/rules-of-hooks', () => { - new ESLintTesterV7({ - parser: require.resolve('babel-eslint'), + const parserOptionsV7 = { + ecmaFeatures: { + jsx: true, + }, + ecmaVersion: 6, + sourceType: 'module', + }; + + const languageOptionsV9 = { + ecmaVersion: 6, + sourceType: 'module', parserOptions: { - ecmaVersion: 6, - sourceType: 'module', + ecmaFeatures: { + jsx: true, + }, }, - }).run('eslint: v7', ReactHooksESLintRule, tests); + }; + + new ESLintTesterV7({ + parser: require.resolve('babel-eslint'), + parserOptions: parserOptionsV7, + }).run('eslint: v7, parser: babel-eslint', ReactHooksESLintRule, tests); new ESLintTesterV9({ languageOptions: { - parser: BabelEslintParser, - ecmaVersion: 6, - sourceType: 'module', - }, - }).run('eslint: v9', ReactHooksESLintRule, tests); + ...languageOptionsV9, + parser: require('@babel/eslint-parser'), + }, + }).run( + 'eslint: v9, parser: @babel/eslint-parser', + ReactHooksESLintRule, + tests + ); + + new ESLintTesterV7({ + parser: require.resolve('@typescript-eslint/parser-v2'), + parserOptions: parserOptionsV7, + }).run( + 'eslint: v7, parser: @typescript-eslint/parser@2.x', + ReactHooksESLintRule, + tests + ); + + new ESLintTesterV9({ + languageOptions: { + ...languageOptionsV9, + parser: require('@typescript-eslint/parser-v2'), + }, + }).run( + 'eslint: v9, parser: @typescript-eslint/parser@2.x', + ReactHooksESLintRule, + tests + ); + + new ESLintTesterV7({ + parser: require.resolve('@typescript-eslint/parser-v3'), + parserOptions: parserOptionsV7, + }).run( + 'eslint: v7, parser: @typescript-eslint/parser@3.x', + ReactHooksESLintRule, + tests + ); + + new ESLintTesterV9({ + languageOptions: { + ...languageOptionsV9, + parser: require('@typescript-eslint/parser-v3'), + }, + }).run( + 'eslint: v9, parser: @typescript-eslint/parser@3.x', + ReactHooksESLintRule, + tests + ); + + new ESLintTesterV7({ + parser: require.resolve('@typescript-eslint/parser-v4'), + parserOptions: parserOptionsV7, + }).run( + 'eslint: v7, parser: @typescript-eslint/parser@4.x', + ReactHooksESLintRule, + tests + ); + + new ESLintTesterV9({ + languageOptions: { + ...languageOptionsV9, + parser: require('@typescript-eslint/parser-v4'), + }, + }).run( + 'eslint: v9, parser: @typescript-eslint/parser@4.x', + ReactHooksESLintRule, + tests + ); + + new ESLintTesterV7({ + parser: require.resolve('@typescript-eslint/parser-v5'), + parserOptions: parserOptionsV7, + }).run( + 'eslint: v7, parser: @typescript-eslint/parser@^5.0.0-0', + ReactHooksESLintRule, + tests + ); + + new ESLintTesterV9({ + languageOptions: { + ...languageOptionsV9, + parser: require('@typescript-eslint/parser-v5'), + }, + }).run( + 'eslint: v9, parser: @typescript-eslint/parser@^5.0.0', + ReactHooksESLintRule, + tests + ); }); diff --git a/packages/eslint-plugin-react-hooks/package.json b/packages/eslint-plugin-react-hooks/package.json index 4a5bde9cb99ae..94cdf12ec765f 100644 --- a/packages/eslint-plugin-react-hooks/package.json +++ b/packages/eslint-plugin-react-hooks/package.json @@ -35,7 +35,7 @@ "@typescript-eslint/parser-v2": "npm:@typescript-eslint/parser@^2.26.0", "@typescript-eslint/parser-v3": "npm:@typescript-eslint/parser@^3.10.0", "@typescript-eslint/parser-v4": "npm:@typescript-eslint/parser@^4.1.0", - "@typescript-eslint/parser-v5": "npm:@typescript-eslint/parser@^5.0.0-0", + "@typescript-eslint/parser-v5": "npm:@typescript-eslint/parser@^5.62.0", "babel-eslint": "^10.0.3", "eslint-v7": "npm:eslint@^7.7.0", "eslint-v9": "npm:eslint@^9.0.0" diff --git a/packages/eslint-plugin-react-hooks/src/RulesOfHooks.js b/packages/eslint-plugin-react-hooks/src/RulesOfHooks.js index bb80a24fba690..fc340519e233e 100644 --- a/packages/eslint-plugin-react-hooks/src/RulesOfHooks.js +++ b/packages/eslint-plugin-react-hooks/src/RulesOfHooks.js @@ -549,7 +549,8 @@ export default { } else if ( codePathNode.parent && (codePathNode.parent.type === 'MethodDefinition' || - codePathNode.parent.type === 'ClassProperty') && + codePathNode.parent.type === 'ClassProperty' || + codePathNode.parent.type === 'PropertyDefinition') && codePathNode.parent.value === codePathNode ) { // Custom message for hooks inside a class diff --git a/yarn.lock b/yarn.lock index 5392bd0309256..48eca75afbba8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3536,15 +3536,15 @@ "@typescript-eslint/typescript-estree" "4.1.0" debug "^4.1.1" -"@typescript-eslint/parser-v5@npm:@typescript-eslint/parser@^5.0.0-0": - version "5.0.0-alpha.25" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.0.0-alpha.25.tgz#d966eb8b2cf97f0134a5589791017e0a720bb995" - integrity sha512-e0Q2fWVXle8l9pCCV2K/pQrn0Wyp8nV/Gp8AbEUqP6xLfgrOxejzcERP9y5x1rnwrp7pPXZhticsNLjqljhh6w== - dependencies: - "@typescript-eslint/scope-manager" "5.0.0-alpha.25+faf2d1d2" - "@typescript-eslint/types" "5.0.0-alpha.25+faf2d1d2" - "@typescript-eslint/typescript-estree" "5.0.0-alpha.25+faf2d1d2" - debug "^4.3.1" +"@typescript-eslint/parser-v5@npm:@typescript-eslint/parser@^5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.62.0.tgz#1b63d082d849a2fcae8a569248fbe2ee1b8a56c7" + integrity sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA== + dependencies: + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/typescript-estree" "5.62.0" + debug "^4.3.4" "@typescript-eslint/scope-manager@4.1.0": version "4.1.0" @@ -3554,13 +3554,13 @@ "@typescript-eslint/types" "4.1.0" "@typescript-eslint/visitor-keys" "4.1.0" -"@typescript-eslint/scope-manager@5.0.0-alpha.25+faf2d1d2": - version "5.0.0-alpha.25" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.0.0-alpha.25.tgz#eb90cb682f6a3a14ba9afc4bd7c1f66cf362e1b0" - integrity sha512-tZumo5HziFbOI+unwQ7Xgimn4FHltg20TCxVCU2tl7YyFhiQl1WxnmhU7/1MUNWXzK9RA88MRKvUON1lgK1FLw== +"@typescript-eslint/scope-manager@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c" + integrity sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w== dependencies: - "@typescript-eslint/types" "5.0.0-alpha.25+faf2d1d2" - "@typescript-eslint/visitor-keys" "5.0.0-alpha.25+faf2d1d2" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" "@typescript-eslint/scope-manager@6.21.0": version "6.21.0" @@ -3580,10 +3580,10 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.1.0.tgz#edbd3fec346f34e13ce7aa176b03b497a32c496a" integrity sha512-rkBqWsO7m01XckP9R2YHVN8mySOKKY2cophGM8K5uDK89ArCgahItQYdbg/3n8xMxzu2elss+an1TphlUpDuJw== -"@typescript-eslint/types@5.0.0-alpha.25+faf2d1d2": - version "5.0.0-alpha.25" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.0.0-alpha.25.tgz#2c5aaaee8d41d08fbb91193cc6df482374700b2e" - integrity sha512-M9PZ+m1vD+UaBt+9hJ1bXTA94s4fvY3fOQkwYxrtreqqdzaiNcW8F5GAO3dthzmS+6II+XAsWfCQzCoBvoiOrw== +"@typescript-eslint/types@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" + integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== "@typescript-eslint/types@6.21.0": version "6.21.0" @@ -3631,17 +3631,17 @@ semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/typescript-estree@5.0.0-alpha.25+faf2d1d2": - version "5.0.0-alpha.25" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.0.0-alpha.25.tgz#1e9ad3464c93fffb1b17d8cc3e2523ae6add930b" - integrity sha512-EIEX4TSWGIBBi9DMZd8FZoI52Ua6hkHj2T8ah83BEBVMS9wCJDZyryuw0PHTesA2ZB5yiQbtNQrrODLJxz1hAw== +"@typescript-eslint/typescript-estree@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" + integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== dependencies: - "@typescript-eslint/types" "5.0.0-alpha.25+faf2d1d2" - "@typescript-eslint/visitor-keys" "5.0.0-alpha.25+faf2d1d2" - debug "^4.3.1" - globby "^11.0.3" - is-glob "^4.0.1" - semver "^7.3.5" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" tsutils "^3.21.0" "@typescript-eslint/typescript-estree@6.21.0": @@ -3686,13 +3686,13 @@ "@typescript-eslint/types" "4.1.0" eslint-visitor-keys "^2.0.0" -"@typescript-eslint/visitor-keys@5.0.0-alpha.25+faf2d1d2": - version "5.0.0-alpha.25" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.0.0-alpha.25.tgz#0b4a909d4020094e638dee1ff72e12d24783c94b" - integrity sha512-vh5AIlr3wxkhFMreop5Y1Wi5Sc9oK03J8+SiyKMEEAqwWmk6e2ryHr1001oWRuK4e6d/CjVNa73omERCWcTXTg== +"@typescript-eslint/visitor-keys@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" + integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw== dependencies: - "@typescript-eslint/types" "5.0.0-alpha.25+faf2d1d2" - eslint-visitor-keys "^3.0.0" + "@typescript-eslint/types" "5.62.0" + eslint-visitor-keys "^3.3.0" "@typescript-eslint/visitor-keys@6.21.0": version "6.21.0" @@ -7522,11 +7522,6 @@ eslint-visitor-keys@^2.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== -eslint-visitor-keys@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.0.0.tgz#e32e99c6cdc2eb063f204eda5db67bfe58bb4186" - integrity sha512-mJOZa35trBTb3IyRmo8xmKBZlxf+N7OnUl4+ZhJHs/r+0770Wh/LEACE2pqMGMe27G/4y8P2bYGk4J70IC5k1Q== - eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: version "3.4.3" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" From 39d9aa1240adbd59b9d197a6303f803a57280ba0 Mon Sep 17 00:00:00 2001 From: Miguel Jimenez Esun Date: Fri, 20 Dec 2024 11:48:12 +0100 Subject: [PATCH 2/2] Fix unused dependency --- .../__tests__/ESLintRulesOfHooks-test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js b/packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js index 62a6bdff32aee..b8ec97678aa16 100644 --- a/packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js +++ b/packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js @@ -12,7 +12,6 @@ const ESLintTesterV7 = require('eslint-v7').RuleTester; const ESLintTesterV9 = require('eslint-v9').RuleTester; const ReactHooksESLintPlugin = require('eslint-plugin-react-hooks'); -const BabelEslintParser = require('@babel/eslint-parser'); const ReactHooksESLintRule = ReactHooksESLintPlugin.rules['rules-of-hooks']; /**