Skip to content

Commit ce9ae3c

Browse files
kassensyungsters
authored andcommitted
[eslint-plugin-react-hooks] updates for component syntax (#33089)
Adds support for Flow's component and hook syntax. [docs](https://flow.org/en/docs/react/component-syntax/)
1 parent 43ede7b commit ce9ae3c

File tree

11 files changed

+3152
-11
lines changed

11 files changed

+3152
-11
lines changed

packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js

Lines changed: 81 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ function normalizeIndent(strings) {
3434
// }
3535
// ***************************************************
3636

37-
const tests = {
37+
const allTests = {
3838
valid: [
3939
{
4040
code: normalizeIndent`
@@ -44,6 +44,25 @@ const tests = {
4444
}
4545
`,
4646
},
47+
{
48+
syntax: 'flow',
49+
code: normalizeIndent`
50+
// Component syntax
51+
component Button() {
52+
useHook();
53+
return <div>Button!</div>;
54+
}
55+
`,
56+
},
57+
{
58+
syntax: 'flow',
59+
code: normalizeIndent`
60+
// Hook syntax
61+
hook useSampleHook() {
62+
useHook();
63+
}
64+
`,
65+
},
4766
{
4867
code: normalizeIndent`
4968
// Valid because components can use hooks.
@@ -563,6 +582,28 @@ const tests = {
563582
},
564583
],
565584
invalid: [
585+
{
586+
syntax: 'flow',
587+
code: normalizeIndent`
588+
component Button(cond: boolean) {
589+
if (cond) {
590+
useConditionalHook();
591+
}
592+
}
593+
`,
594+
errors: [conditionalError('useConditionalHook')],
595+
},
596+
{
597+
syntax: 'flow',
598+
code: normalizeIndent`
599+
hook useTest(cond: boolean) {
600+
if (cond) {
601+
useConditionalHook();
602+
}
603+
}
604+
`,
605+
errors: [conditionalError('useConditionalHook')],
606+
},
566607
{
567608
code: normalizeIndent`
568609
// Invalid because it's dangerous and might not warn otherwise.
@@ -1287,8 +1328,8 @@ const tests = {
12871328
};
12881329

12891330
if (__EXPERIMENTAL__) {
1290-
tests.valid = [
1291-
...tests.valid,
1331+
allTests.valid = [
1332+
...allTests.valid,
12921333
{
12931334
code: normalizeIndent`
12941335
// Valid because functions created with useEffectEvent can be called in a useEffect.
@@ -1385,8 +1426,8 @@ if (__EXPERIMENTAL__) {
13851426
`,
13861427
},
13871428
];
1388-
tests.invalid = [
1389-
...tests.invalid,
1429+
allTests.invalid = [
1430+
...allTests.invalid,
13901431
{
13911432
code: normalizeIndent`
13921433
function MyComponent({ theme }) {
@@ -1536,7 +1577,7 @@ function asyncComponentHookError(fn) {
15361577
if (!process.env.CI) {
15371578
let only = [];
15381579
let skipped = [];
1539-
[...tests.valid, ...tests.invalid].forEach(t => {
1580+
[...allTests.valid, ...allTests.invalid].forEach(t => {
15401581
if (t.skip) {
15411582
delete t.skip;
15421583
skipped.push(t);
@@ -1555,10 +1596,23 @@ if (!process.env.CI) {
15551596
}
15561597
return true;
15571598
};
1558-
tests.valid = tests.valid.filter(predicate);
1559-
tests.invalid = tests.invalid.filter(predicate);
1599+
allTests.valid = allTests.valid.filter(predicate);
1600+
allTests.invalid = allTests.invalid.filter(predicate);
1601+
}
1602+
1603+
function filteredTests(predicate) {
1604+
return {
1605+
valid: allTests.valid.filter(predicate),
1606+
invalid: allTests.invalid.filter(predicate),
1607+
};
15601608
}
15611609

1610+
const flowTests = filteredTests(t => t.syntax == null || t.syntax === 'flow');
1611+
const tests = filteredTests(t => t.syntax !== 'flow');
1612+
1613+
allTests.valid.forEach(t => delete t.syntax);
1614+
allTests.invalid.forEach(t => delete t.syntax);
1615+
15621616
describe('rules-of-hooks/rules-of-hooks', () => {
15631617
const parserOptionsV7 = {
15641618
ecmaFeatures: {
@@ -1594,6 +1648,25 @@ describe('rules-of-hooks/rules-of-hooks', () => {
15941648
tests
15951649
);
15961650

1651+
new ESLintTesterV7({
1652+
parser: require.resolve('hermes-eslint'),
1653+
parserOptions: {
1654+
sourceType: 'module',
1655+
enableExperimentalComponentSyntax: true,
1656+
},
1657+
}).run('eslint: v7, parser: hermes-eslint', ReactHooksESLintRule, flowTests);
1658+
1659+
new ESLintTesterV9({
1660+
languageOptions: {
1661+
...languageOptionsV9,
1662+
parser: require('hermes-eslint'),
1663+
parserOptions: {
1664+
sourceType: 'module',
1665+
enableExperimentalComponentSyntax: true,
1666+
},
1667+
},
1668+
}).run('eslint: v9, parser: hermes-eslint', ReactHooksESLintRule, flowTests);
1669+
15971670
new ESLintTesterV7({
15981671
parser: require.resolve('@typescript-eslint/parser-v2'),
15991672
parserOptions: parserOptionsV7,
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright OpenJS Foundation and other contributors, <www.openjsf.org>
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is
8+
furnished to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in
11+
all copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
THE SOFTWARE.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Code Path Analyzer
2+
3+
This code is a forked version of ESLints Code Path Analyzer which includes
4+
support for Component Syntax.
5+
6+
Forked from: https://github.com/eslint/eslint/tree/main/lib/linter/code-path-analysis
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
'use strict';
2+
3+
function assert(cond) {
4+
if (!cond) {
5+
throw new Error('Assertion violated.');
6+
}
7+
}
8+
9+
module.exports = assert;

0 commit comments

Comments
 (0)