feat(eslint-plugin-react-internal): support ESLint 8.x (#22249)
Co-authored-by: Dan Abramov <dan.abramov@gmail.com>
Michaël De Boey committed
Sep 6, 2021 at 21:42 UTC
b394c38e880e1b3ee7ed03b26bc7c24f61827dbc
14 files changed
+226
-207
.eslintrc.js
+4
-1
@@ -183,7 +183,10 @@ module.exports = {
183
},
184
},
185
{
186
- files: ['packages/eslint-plugin-react-hooks/src/*.js'],
186
+ files: [
187
+ 'scripts/eslint-rules/*.js',
188
+ 'packages/eslint-plugin-react-hooks/src/*.js'
189
+ ],
190
plugins: ['eslint-plugin'],
191
rules: {
192
'eslint-plugin/prefer-object-rule': ERROR,
scripts/eslint-rules/__tests__/invariant-args-test.internal.js
+1
-1
@@ -10,7 +10,7 @@
10
'use strict';
11
12
const rule = require('../invariant-args');
13
-const RuleTester = require('eslint').RuleTester;
13
+const {RuleTester} = require('eslint');
14
const ruleTester = new RuleTester();
15
16
ruleTester.run('eslint-rules/invariant-args', rule, {
scripts/eslint-rules/__tests__/no-cross-fork-imports-test.internal.js
+1
-1
@@ -10,7 +10,7 @@
10
'use strict';
11
12
const rule = require('../no-cross-fork-imports');
13
-const RuleTester = require('eslint').RuleTester;
13
+const {RuleTester} = require('eslint');
14
const ruleTester = new RuleTester({
15
parserOptions: {
16
ecmaVersion: 8,
scripts/eslint-rules/__tests__/no-cross-fork-types-test.internal.js
+1
-1
@@ -10,7 +10,7 @@
10
'use strict';
11
12
const rule = require('../no-cross-fork-types');
13
-const RuleTester = require('eslint').RuleTester;
13
+const {RuleTester} = require('eslint');
14
const ruleTester = new RuleTester({
15
parserOptions: {
16
ecmaVersion: 8,
scripts/eslint-rules/__tests__/no-primitive-constructors-test.internal.js
+1
-1
@@ -10,7 +10,7 @@
10
'use strict';
11
12
const rule = require('../no-primitive-constructors');
13
-const RuleTester = require('eslint').RuleTester;
13
+const {RuleTester} = require('eslint');
14
const ruleTester = new RuleTester();
15
16
ruleTester.run('eslint-rules/no-primitive-constructors', rule, {
scripts/eslint-rules/__tests__/no-production-logging-test.internal.js
+1
-1
@@ -10,7 +10,7 @@
10
'use strict';
11
12
const rule = require('../no-production-logging');
13
-const RuleTester = require('eslint').RuleTester;
13
+const {RuleTester} = require('eslint');
14
const ruleTester = new RuleTester();
15
16
ruleTester.run('no-production-logging', rule, {
scripts/eslint-rules/__tests__/no-to-warn-dev-within-to-throw-test.internal.js
+1
-1
@@ -10,7 +10,7 @@
10
'use strict';
11
12
const rule = require('../no-to-warn-dev-within-to-throw');
13
-const RuleTester = require('eslint').RuleTester;
13
+const {RuleTester} = require('eslint');
14
const ruleTester = new RuleTester();
15
16
ruleTester.run('eslint-rules/no-to-warn-dev-within-to-throw', rule, {
scripts/eslint-rules/__tests__/warning-args-test.internal.js
+1
-1
@@ -10,7 +10,7 @@
10
'use strict';
11
12
const rule = require('../warning-args');
13
-const RuleTester = require('eslint').RuleTester;
13
+const {RuleTester} = require('eslint');
14
const ruleTester = new RuleTester();
15
16
ruleTester.run('eslint-rules/warning-args', rule, {
scripts/eslint-rules/invariant-args.js
+77
-74
@@ -24,83 +24,86 @@ Object.keys(existingErrorMap).forEach(key =>
24
* argument.
25
*/
26
27
-module.exports = function(context) {
28
- // we also allow literal strings and concatenated literal strings
29
- function getLiteralString(node) {
30
- if (node.type === 'Literal' && typeof node.value === 'string') {
31
- return node.value;
32
- } else if (node.type === 'BinaryExpression' && node.operator === '+') {
33
- const l = getLiteralString(node.left);
34
- const r = getLiteralString(node.right);
35
- if (l !== null && r !== null) {
36
- return l + r;
27
+module.exports = {
28
+ meta: {
29
+ schema: [],
30
+ },
31
+ create(context) {
32
+ // we also allow literal strings and concatenated literal strings
33
+ function getLiteralString(node) {
34
+ if (node.type === 'Literal' && typeof node.value === 'string') {
35
+ return node.value;
36
+ } else if (node.type === 'BinaryExpression' && node.operator === '+') {
37
+ const l = getLiteralString(node.left);
38
+ const r = getLiteralString(node.right);
39
+ if (l !== null && r !== null) {
40
+ return l + r;
41
+ }
42
}
43
+ return null;
44
}
39
- return null;
40
- }
45
42
- return {
43
- CallExpression: function(node) {
44
- // This could be a little smarter by checking context.getScope() to see
45
- // how warning/invariant was defined.
46
- const isInvariant =
47
- node.callee.type === 'Identifier' && node.callee.name === 'invariant';
48
- if (!isInvariant) {
49
- return;
50
- }
51
- if (node.arguments.length < 2) {
52
- context.report(node, '{{name}} takes at least two arguments', {
53
- name: node.callee.name,
54
- });
55
- return;
56
- }
57
- const format = getLiteralString(node.arguments[1]);
58
- if (format === null) {
59
- context.report(
60
- node,
61
- 'The second argument to {{name}} must be a string literal',
62
- {name: node.callee.name}
63
- );
64
- return;
65
- }
66
- if (format.length < 10 || /^[s\W]*$/.test(format)) {
67
- context.report(
68
- node,
69
- 'The {{name}} format should be able to uniquely identify this ' +
70
- '{{name}}. Please, use a more descriptive format than: {{format}}',
71
- {name: node.callee.name, format: format}
72
- );
73
- return;
74
- }
75
- // count the number of formatting substitutions, plus the first two args
76
- const expectedNArgs = (format.match(/%s/g) || []).length + 2;
77
- if (node.arguments.length !== expectedNArgs) {
78
- context.report(
79
- node,
80
- 'Expected {{expectedNArgs}} arguments in call to {{name}} based on ' +
81
- 'the number of "%s" substitutions, but got {{length}}',
82
- {
83
- expectedNArgs: expectedNArgs,
46
+ return {
47
+ CallExpression: function(node) {
48
+ // This could be a little smarter by checking context.getScope() to see
49
+ // how warning/invariant was defined.
50
+ const isInvariant =
51
+ node.callee.type === 'Identifier' && node.callee.name === 'invariant';
52
+ if (!isInvariant) {
53
+ return;
54
+ }
55
+ if (node.arguments.length < 2) {
56
+ context.report(node, '{{name}} takes at least two arguments', {
57
name: node.callee.name,
85
- length: node.arguments.length,
86
- }
87
- );
88
- }
58
+ });
59
+ return;
60
+ }
61
+ const format = getLiteralString(node.arguments[1]);
62
+ if (format === null) {
63
+ context.report(
64
+ node,
65
+ 'The second argument to {{name}} must be a string literal',
66
+ {name: node.callee.name}
67
+ );
68
+ return;
69
+ }
70
+ if (format.length < 10 || /^[s\W]*$/.test(format)) {
71
+ context.report(
72
+ node,
73
+ 'The {{name}} format should be able to uniquely identify this ' +
74
+ '{{name}}. Please, use a more descriptive format than: {{format}}',
75
+ {name: node.callee.name, format: format}
76
+ );
77
+ return;
78
+ }
79
+ // count the number of formatting substitutions, plus the first two args
80
+ const expectedNArgs = (format.match(/%s/g) || []).length + 2;
81
+ if (node.arguments.length !== expectedNArgs) {
82
+ context.report(
83
+ node,
84
+ 'Expected {{expectedNArgs}} arguments in call to {{name}} based on ' +
85
+ 'the number of "%s" substitutions, but got {{length}}',
86
+ {
87
+ expectedNArgs: expectedNArgs,
88
+ name: node.callee.name,
89
+ length: node.arguments.length,
90
+ }
91
+ );
92
+ }
93
90
- if (!messages.has(format)) {
91
- context.report(
92
- node,
93
- 'Error message does not have a corresponding production ' +
94
- 'error code.\n\n' +
95
- 'Run `yarn extract-errors` to add the message to error code ' +
96
- 'map, so it can be stripped from the production builds. ' +
97
- "Alternatively, if you're updating an existing error " +
98
- 'message, you can modify ' +
99
- '`scripts/error-codes/codes.json` directly.'
100
- );
101
- }
102
- },
103
- };
94
+ if (!messages.has(format)) {
95
+ context.report(
96
+ node,
97
+ 'Error message does not have a corresponding production ' +
98
+ 'error code.\n\n' +
99
+ 'Run `yarn extract-errors` to add the message to error code ' +
100
+ 'map, so it can be stripped from the production builds. ' +
101
+ "Alternatively, if you're updating an existing error " +
102
+ 'message, you can modify ' +
103
+ '`scripts/error-codes/codes.json` directly.'
104
+ );
105
+ }
106
+ },
107
+ };
108
+ },
109
};
105
-
106
-module.exports.schema = [];
scripts/eslint-rules/no-cross-fork-types.js
-1
@@ -46,7 +46,6 @@ function warnIfOldField(context, oldFields, identifier) {
46
module.exports = {
47
meta: {
48
type: 'problem',
49
- fixable: 'code',
49
},
50
create(context) {
51
const sourceFilename = context.getFilename();
scripts/eslint-rules/no-primitive-constructors.js
+40
-35
@@ -9,42 +9,47 @@
9
10
'use strict';
11
12
-module.exports = function(context) {
13
- function report(node, name, msg) {
14
- context.report(node, `Do not use the ${name} constructor. ${msg}`);
15
- }
12
+module.exports = {
13
+ meta: {
14
+ schema: [],
15
+ },
16
+ create(context) {
17
+ function report(node, name, msg) {
18
+ context.report(node, `Do not use the ${name} constructor. ${msg}`);
19
+ }
20
17
- function check(node) {
18
- const name = node.callee.name;
19
- switch (name) {
20
- case 'Boolean':
21
- report(
22
- node,
23
- name,
24
- 'To cast a value to a boolean, use double negation: !!value'
25
- );
26
- break;
27
- case 'String':
28
- report(
29
- node,
30
- name,
31
- 'To cast a value to a string, concat it with the empty string ' +
32
- "(unless it's a symbol, which has different semantics): " +
33
- "'' + value"
34
- );
35
- break;
36
- case 'Number':
37
- report(
38
- node,
39
- name,
40
- 'To cast a value to a number, use the plus operator: +value'
41
- );
42
- break;
21
+ function check(node) {
22
+ const name = node.callee.name;
23
+ switch (name) {
24
+ case 'Boolean':
25
+ report(
26
+ node,
27
+ name,
28
+ 'To cast a value to a boolean, use double negation: !!value'
29
+ );
30
+ break;
31
+ case 'String':
32
+ report(
33
+ node,
34
+ name,
35
+ 'To cast a value to a string, concat it with the empty string ' +
36
+ "(unless it's a symbol, which has different semantics): " +
37
+ "'' + value"
38
+ );
39
+ break;
40
+ case 'Number':
41
+ report(
42
+ node,
43
+ name,
44
+ 'To cast a value to a number, use the plus operator: +value'
45
+ );
46
+ break;
47
+ }
48
}
44
- }
49
46
- return {
47
- CallExpression: check,
48
- NewExpression: check,
49
- };
50
+ return {
51
+ CallExpression: check,
52
+ NewExpression: check,
53
+ };
54
+ },
55
};
scripts/eslint-rules/no-production-logging.js
+1
@@ -12,6 +12,7 @@
12
module.exports = {
13
meta: {
14
fixable: 'code',
15
+ schema: [],
16
},
17
create: function(context) {
18
function isInDEVBlock(node) {
scripts/eslint-rules/no-to-warn-dev-within-to-throw.js
+26
-21
@@ -9,28 +9,33 @@
9
10
'use strict';
11
12
-module.exports = function(context) {
13
- return {
14
- Identifier(node) {
15
- if (node.name === 'toWarnDev' || node.name === 'toErrorDev') {
16
- let current = node;
17
- while (current.parent) {
18
- if (current.type === 'CallExpression') {
19
- if (
20
- current &&
21
- current.callee &&
22
- current.callee.property &&
23
- current.callee.property.name === 'toThrow'
24
- ) {
25
- context.report(
26
- node,
27
- node.name + '() matcher should not be nested'
28
- );
12
+module.exports = {
13
+ meta: {
14
+ schema: [],
15
+ },
16
+ create(context) {
17
+ return {
18
+ Identifier(node) {
19
+ if (node.name === 'toWarnDev' || node.name === 'toErrorDev') {
20
+ let current = node;
21
+ while (current.parent) {
22
+ if (current.type === 'CallExpression') {
23
+ if (
24
+ current &&
25
+ current.callee &&
26
+ current.callee.property &&
27
+ current.callee.property.name === 'toThrow'
28
+ ) {
29
+ context.report(
30
+ node,
31
+ node.name + '() matcher should not be nested'
32
+ );
33
+ }
34
}
35
+ current = current.parent;
36
}
31
- current = current.parent;
37
}
33
- }
34
- },
35
- };
38
+ },
39
+ };
40
+ },
41
};
scripts/eslint-rules/warning-args.js
+71
-68
@@ -24,76 +24,79 @@ Object.keys(existingErrorMap).forEach(key =>
24
* argument.
25
*/
26
27
-module.exports = function(context) {
28
- // we also allow literal strings and concatenated literal strings
29
- function getLiteralString(node) {
30
- if (node.type === 'Literal' && typeof node.value === 'string') {
31
- return node.value;
32
- } else if (node.type === 'BinaryExpression' && node.operator === '+') {
33
- const l = getLiteralString(node.left);
34
- const r = getLiteralString(node.right);
35
- if (l !== null && r !== null) {
36
- return l + r;
27
+module.exports = {
28
+ meta: {
29
+ schema: [],
30
+ },
31
+ create(context) {
32
+ // we also allow literal strings and concatenated literal strings
33
+ function getLiteralString(node) {
34
+ if (node.type === 'Literal' && typeof node.value === 'string') {
35
+ return node.value;
36
+ } else if (node.type === 'BinaryExpression' && node.operator === '+') {
37
+ const l = getLiteralString(node.left);
38
+ const r = getLiteralString(node.right);
39
+ if (l !== null && r !== null) {
40
+ return l + r;
41
+ }
42
}
43
+ return null;
44
}
39
- return null;
40
- }
45
42
- return {
43
- CallExpression: function(node) {
44
- // This could be a little smarter by checking context.getScope() to see
45
- // how warning/invariant was defined.
46
- const isWarning =
47
- node.callee.type === 'MemberExpression' &&
48
- node.callee.object.type === 'Identifier' &&
49
- node.callee.object.name === 'console' &&
50
- node.callee.property.type === 'Identifier' &&
51
- (node.callee.property.name === 'error' ||
52
- node.callee.property.name === 'warn');
53
- if (!isWarning) {
54
- return;
55
- }
56
- const name = 'console.' + node.callee.property.name;
57
- if (node.arguments.length < 1) {
58
- context.report(node, '{{name}} takes at least one argument', {
59
- name,
60
- });
61
- return;
62
- }
63
- const format = getLiteralString(node.arguments[0]);
64
- if (format === null) {
65
- context.report(
66
- node,
67
- 'The first argument to {{name}} must be a string literal',
68
- {name}
69
- );
70
- return;
71
- }
72
- if (format.length < 10 || /^[s\W]*$/.test(format)) {
73
- context.report(
74
- node,
75
- 'The {{name}} format should be able to uniquely identify this ' +
76
- 'warning. Please, use a more descriptive format than: {{format}}',
77
- {name, format}
78
- );
79
- return;
80
- }
81
- // count the number of formatting substitutions, plus the first two args
82
- const expectedNArgs = (format.match(/%s/g) || []).length + 1;
83
- if (node.arguments.length !== expectedNArgs) {
84
- context.report(
85
- node,
86
- 'Expected {{expectedNArgs}} arguments in call to {{name}} based on ' +
87
- 'the number of "%s" substitutions, but got {{length}}',
88
- {
89
- expectedNArgs: expectedNArgs,
46
+ return {
47
+ CallExpression: function(node) {
48
+ // This could be a little smarter by checking context.getScope() to see
49
+ // how warning/invariant was defined.
50
+ const isWarning =
51
+ node.callee.type === 'MemberExpression' &&
52
+ node.callee.object.type === 'Identifier' &&
53
+ node.callee.object.name === 'console' &&
54
+ node.callee.property.type === 'Identifier' &&
55
+ (node.callee.property.name === 'error' ||
56
+ node.callee.property.name === 'warn');
57
+ if (!isWarning) {
58
+ return;
59
+ }
60
+ const name = 'console.' + node.callee.property.name;
61
+ if (node.arguments.length < 1) {
62
+ context.report(node, '{{name}} takes at least one argument', {
63
name,
91
- length: node.arguments.length,
92
- }
93
- );
94
- }
95
- },
96
- };
64
+ });
65
+ return;
66
+ }
67
+ const format = getLiteralString(node.arguments[0]);
68
+ if (format === null) {
69
+ context.report(
70
+ node,
71
+ 'The first argument to {{name}} must be a string literal',
72
+ {name}
73
+ );
74
+ return;
75
+ }
76
+ if (format.length < 10 || /^[s\W]*$/.test(format)) {
77
+ context.report(
78
+ node,
79
+ 'The {{name}} format should be able to uniquely identify this ' +
80
+ 'warning. Please, use a more descriptive format than: {{format}}',
81
+ {name, format}
82
+ );
83
+ return;
84
+ }
85
+ // count the number of formatting substitutions, plus the first two args
86
+ const expectedNArgs = (format.match(/%s/g) || []).length + 1;
87
+ if (node.arguments.length !== expectedNArgs) {
88
+ context.report(
89
+ node,
90
+ 'Expected {{expectedNArgs}} arguments in call to {{name}} based on ' +
91
+ 'the number of "%s" substitutions, but got {{length}}',
92
+ {
93
+ expectedNArgs: expectedNArgs,
94
+ name,
95
+ length: node.arguments.length,
96
+ }
97
+ );
98
+ }
99
+ },
100
+ };
101
+ },
102
};
98
-
99
-module.exports.schema = [];