@samitouri / QOS-React-2 / commits / b394c38e88

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 = [];