Skip to content

Commit a63158d

Browse files
committed
[eslint-plugin-react-hooks] updates for component syntax
Adds support for Flow's component and hook syntax. [docs](https://flow.org/en/docs/react/component-syntax/)
1 parent f739642 commit a63158d

File tree

11 files changed

+3130
-11
lines changed

11 files changed

+3130
-11
lines changed

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

Lines changed: 59 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+
// Component syntax
61+
hook useSampleHook() {
62+
useHook();
63+
}
64+
`,
65+
},
4766
{
4867
code: normalizeIndent`
4968
// Valid because components can use hooks.
@@ -1287,8 +1306,8 @@ const tests = {
12871306
};
12881307

12891308
if (__EXPERIMENTAL__) {
1290-
tests.valid = [
1291-
...tests.valid,
1309+
allTests.valid = [
1310+
...allTests.valid,
12921311
{
12931312
code: normalizeIndent`
12941313
// Valid because functions created with useEffectEvent can be called in a useEffect.
@@ -1385,8 +1404,8 @@ if (__EXPERIMENTAL__) {
13851404
`,
13861405
},
13871406
];
1388-
tests.invalid = [
1389-
...tests.invalid,
1407+
allTests.invalid = [
1408+
...allTests.invalid,
13901409
{
13911410
code: normalizeIndent`
13921411
function MyComponent({ theme }) {
@@ -1536,7 +1555,7 @@ function asyncComponentHookError(fn) {
15361555
if (!process.env.CI) {
15371556
let only = [];
15381557
let skipped = [];
1539-
[...tests.valid, ...tests.invalid].forEach(t => {
1558+
[...allTests.valid, ...allTests.invalid].forEach(t => {
15401559
if (t.skip) {
15411560
delete t.skip;
15421561
skipped.push(t);
@@ -1555,10 +1574,23 @@ if (!process.env.CI) {
15551574
}
15561575
return true;
15571576
};
1558-
tests.valid = tests.valid.filter(predicate);
1559-
tests.invalid = tests.invalid.filter(predicate);
1577+
allTests.valid = allTests.valid.filter(predicate);
1578+
allTests.invalid = allTests.invalid.filter(predicate);
1579+
}
1580+
1581+
function filteredTests(predicate) {
1582+
return {
1583+
valid: allTests.valid.filter(predicate),
1584+
invalid: allTests.invalid.filter(predicate),
1585+
};
15601586
}
15611587

1588+
const flowTests = filteredTests(t => t.syntax == null || t.syntax === 'flow');
1589+
const tests = filteredTests(t => t.syntax !== 'flow');
1590+
1591+
allTests.valid.forEach(t => delete t.syntax);
1592+
allTests.invalid.forEach(t => delete t.syntax);
1593+
15621594
describe('rules-of-hooks/rules-of-hooks', () => {
15631595
const parserOptionsV7 = {
15641596
ecmaFeatures: {
@@ -1594,6 +1626,25 @@ describe('rules-of-hooks/rules-of-hooks', () => {
15941626
tests
15951627
);
15961628

1629+
new ESLintTesterV7({
1630+
parser: require.resolve('hermes-eslint'),
1631+
parserOptions: {
1632+
sourceType: 'module',
1633+
enableExperimentalComponentSyntax: true,
1634+
},
1635+
}).run('eslint: v7, parser: hermes-eslint', ReactHooksESLintRule, flowTests);
1636+
1637+
new ESLintTesterV9({
1638+
languageOptions: {
1639+
...languageOptionsV9,
1640+
parser: require('hermes-eslint'),
1641+
parserOptions: {
1642+
sourceType: 'module',
1643+
enableExperimentalComponentSyntax: true,
1644+
},
1645+
},
1646+
}).run('eslint: v9, parser: hermes-eslint', ReactHooksESLintRule, flowTests);
1647+
15971648
new ESLintTesterV7({
15981649
parser: require.resolve('@typescript-eslint/parser-v2'),
15991650
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)