Skip to content

Commit d0571ea

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 bb57fa7 commit d0571ea

File tree

11 files changed

+3125
-11
lines changed

11 files changed

+3125
-11
lines changed

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

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

37-
const tests = {
37+
const allTests = {
3838
valid: [
3939
{
40+
only: true,
4041
code: normalizeIndent`
4142
// Valid because components can use hooks.
4243
function ComponentWithHook() {
4344
useHook();
4445
}
4546
`,
4647
},
48+
{
49+
only: true,
50+
syntax: 'flow',
51+
code: normalizeIndent`
52+
// Component syntax
53+
component Button() {
54+
useHook();
55+
return <div>Button!</div>;
56+
}
57+
`,
58+
},
59+
{
60+
only: true,
61+
syntax: 'flow',
62+
code: normalizeIndent`
63+
// Component syntax
64+
hook useSampleHook() {
65+
useHook();
66+
}
67+
`,
68+
},
4769
{
4870
code: normalizeIndent`
4971
// Valid because components can use hooks.
@@ -1287,8 +1309,8 @@ const tests = {
12871309
};
12881310

12891311
if (__EXPERIMENTAL__) {
1290-
tests.valid = [
1291-
...tests.valid,
1312+
allTests.valid = [
1313+
...allTests.valid,
12921314
{
12931315
code: normalizeIndent`
12941316
// Valid because functions created with useEffectEvent can be called in a useEffect.
@@ -1385,8 +1407,8 @@ if (__EXPERIMENTAL__) {
13851407
`,
13861408
},
13871409
];
1388-
tests.invalid = [
1389-
...tests.invalid,
1410+
allTests.invalid = [
1411+
...allTests.invalid,
13901412
{
13911413
code: normalizeIndent`
13921414
function MyComponent({ theme }) {
@@ -1536,7 +1558,7 @@ function asyncComponentHookError(fn) {
15361558
if (!process.env.CI) {
15371559
let only = [];
15381560
let skipped = [];
1539-
[...tests.valid, ...tests.invalid].forEach(t => {
1561+
[...allTests.valid, ...allTests.invalid].forEach(t => {
15401562
if (t.skip) {
15411563
delete t.skip;
15421564
skipped.push(t);
@@ -1555,10 +1577,23 @@ if (!process.env.CI) {
15551577
}
15561578
return true;
15571579
};
1558-
tests.valid = tests.valid.filter(predicate);
1559-
tests.invalid = tests.invalid.filter(predicate);
1580+
allTests.valid = allTests.valid.filter(predicate);
1581+
allTests.invalid = allTests.invalid.filter(predicate);
15601582
}
15611583

1584+
function filteredTests(predicate) {
1585+
return {
1586+
valid: allTests.valid.filter(predicate),
1587+
invalid: allTests.invalid.filter(predicate),
1588+
};
1589+
}
1590+
1591+
const flowTests = filteredTests(t => t.syntax == null || t.syntax === 'flow');
1592+
const tests = filteredTests(t => t.syntax !== 'flow');
1593+
1594+
allTests.valid.forEach(t => delete t.syntax);
1595+
allTests.invalid.forEach(t => delete t.syntax);
1596+
15621597
describe('rules-of-hooks/rules-of-hooks', () => {
15631598
const parserOptionsV7 = {
15641599
ecmaFeatures: {
@@ -1594,6 +1629,17 @@ describe('rules-of-hooks/rules-of-hooks', () => {
15941629
tests
15951630
);
15961631

1632+
new ESLintTesterV9({
1633+
languageOptions: {
1634+
...languageOptionsV9,
1635+
parser: require('hermes-eslint'),
1636+
parserOptions: {
1637+
sourceType: 'module',
1638+
enableExperimentalComponentSyntax: true,
1639+
},
1640+
},
1641+
}).run('eslint: v9, parser: hermes-eslint', ReactHooksESLintRule, flowTests);
1642+
15971643
new ESLintTesterV7({
15981644
parser: require.resolve('@typescript-eslint/parser-v2'),
15991645
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)