mirror of
https://github.com/zebrajr/react.git
synced 2026-01-15 12:15:22 +00:00
feat(eslint-plugin-react-internal): support ESLint 8.x (#22249)
Co-authored-by: Dan Abramov <dan.abramov@gmail.com>
This commit is contained in:
@@ -183,7 +183,10 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['packages/eslint-plugin-react-hooks/src/*.js'],
|
||||
files: [
|
||||
'scripts/eslint-rules/*.js',
|
||||
'packages/eslint-plugin-react-hooks/src/*.js'
|
||||
],
|
||||
plugins: ['eslint-plugin'],
|
||||
rules: {
|
||||
'eslint-plugin/prefer-object-rule': ERROR,
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
'use strict';
|
||||
|
||||
const rule = require('../invariant-args');
|
||||
const RuleTester = require('eslint').RuleTester;
|
||||
const {RuleTester} = require('eslint');
|
||||
const ruleTester = new RuleTester();
|
||||
|
||||
ruleTester.run('eslint-rules/invariant-args', rule, {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
'use strict';
|
||||
|
||||
const rule = require('../no-cross-fork-imports');
|
||||
const RuleTester = require('eslint').RuleTester;
|
||||
const {RuleTester} = require('eslint');
|
||||
const ruleTester = new RuleTester({
|
||||
parserOptions: {
|
||||
ecmaVersion: 8,
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
'use strict';
|
||||
|
||||
const rule = require('../no-cross-fork-types');
|
||||
const RuleTester = require('eslint').RuleTester;
|
||||
const {RuleTester} = require('eslint');
|
||||
const ruleTester = new RuleTester({
|
||||
parserOptions: {
|
||||
ecmaVersion: 8,
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
'use strict';
|
||||
|
||||
const rule = require('../no-primitive-constructors');
|
||||
const RuleTester = require('eslint').RuleTester;
|
||||
const {RuleTester} = require('eslint');
|
||||
const ruleTester = new RuleTester();
|
||||
|
||||
ruleTester.run('eslint-rules/no-primitive-constructors', rule, {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
'use strict';
|
||||
|
||||
const rule = require('../no-production-logging');
|
||||
const RuleTester = require('eslint').RuleTester;
|
||||
const {RuleTester} = require('eslint');
|
||||
const ruleTester = new RuleTester();
|
||||
|
||||
ruleTester.run('no-production-logging', rule, {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
'use strict';
|
||||
|
||||
const rule = require('../no-to-warn-dev-within-to-throw');
|
||||
const RuleTester = require('eslint').RuleTester;
|
||||
const {RuleTester} = require('eslint');
|
||||
const ruleTester = new RuleTester();
|
||||
|
||||
ruleTester.run('eslint-rules/no-to-warn-dev-within-to-throw', rule, {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
'use strict';
|
||||
|
||||
const rule = require('../warning-args');
|
||||
const RuleTester = require('eslint').RuleTester;
|
||||
const {RuleTester} = require('eslint');
|
||||
const ruleTester = new RuleTester();
|
||||
|
||||
ruleTester.run('eslint-rules/warning-args', rule, {
|
||||
|
||||
@@ -24,83 +24,86 @@ Object.keys(existingErrorMap).forEach(key =>
|
||||
* argument.
|
||||
*/
|
||||
|
||||
module.exports = function(context) {
|
||||
// we also allow literal strings and concatenated literal strings
|
||||
function getLiteralString(node) {
|
||||
if (node.type === 'Literal' && typeof node.value === 'string') {
|
||||
return node.value;
|
||||
} else if (node.type === 'BinaryExpression' && node.operator === '+') {
|
||||
const l = getLiteralString(node.left);
|
||||
const r = getLiteralString(node.right);
|
||||
if (l !== null && r !== null) {
|
||||
return l + r;
|
||||
module.exports = {
|
||||
meta: {
|
||||
schema: [],
|
||||
},
|
||||
create(context) {
|
||||
// we also allow literal strings and concatenated literal strings
|
||||
function getLiteralString(node) {
|
||||
if (node.type === 'Literal' && typeof node.value === 'string') {
|
||||
return node.value;
|
||||
} else if (node.type === 'BinaryExpression' && node.operator === '+') {
|
||||
const l = getLiteralString(node.left);
|
||||
const r = getLiteralString(node.right);
|
||||
if (l !== null && r !== null) {
|
||||
return l + r;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
CallExpression: function(node) {
|
||||
// This could be a little smarter by checking context.getScope() to see
|
||||
// how warning/invariant was defined.
|
||||
const isInvariant =
|
||||
node.callee.type === 'Identifier' && node.callee.name === 'invariant';
|
||||
if (!isInvariant) {
|
||||
return;
|
||||
}
|
||||
if (node.arguments.length < 2) {
|
||||
context.report(node, '{{name}} takes at least two arguments', {
|
||||
name: node.callee.name,
|
||||
});
|
||||
return;
|
||||
}
|
||||
const format = getLiteralString(node.arguments[1]);
|
||||
if (format === null) {
|
||||
context.report(
|
||||
node,
|
||||
'The second argument to {{name}} must be a string literal',
|
||||
{name: node.callee.name}
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (format.length < 10 || /^[s\W]*$/.test(format)) {
|
||||
context.report(
|
||||
node,
|
||||
'The {{name}} format should be able to uniquely identify this ' +
|
||||
'{{name}}. Please, use a more descriptive format than: {{format}}',
|
||||
{name: node.callee.name, format: format}
|
||||
);
|
||||
return;
|
||||
}
|
||||
// count the number of formatting substitutions, plus the first two args
|
||||
const expectedNArgs = (format.match(/%s/g) || []).length + 2;
|
||||
if (node.arguments.length !== expectedNArgs) {
|
||||
context.report(
|
||||
node,
|
||||
'Expected {{expectedNArgs}} arguments in call to {{name}} based on ' +
|
||||
'the number of "%s" substitutions, but got {{length}}',
|
||||
{
|
||||
expectedNArgs: expectedNArgs,
|
||||
return {
|
||||
CallExpression: function(node) {
|
||||
// This could be a little smarter by checking context.getScope() to see
|
||||
// how warning/invariant was defined.
|
||||
const isInvariant =
|
||||
node.callee.type === 'Identifier' && node.callee.name === 'invariant';
|
||||
if (!isInvariant) {
|
||||
return;
|
||||
}
|
||||
if (node.arguments.length < 2) {
|
||||
context.report(node, '{{name}} takes at least two arguments', {
|
||||
name: node.callee.name,
|
||||
length: node.arguments.length,
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
const format = getLiteralString(node.arguments[1]);
|
||||
if (format === null) {
|
||||
context.report(
|
||||
node,
|
||||
'The second argument to {{name}} must be a string literal',
|
||||
{name: node.callee.name}
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (format.length < 10 || /^[s\W]*$/.test(format)) {
|
||||
context.report(
|
||||
node,
|
||||
'The {{name}} format should be able to uniquely identify this ' +
|
||||
'{{name}}. Please, use a more descriptive format than: {{format}}',
|
||||
{name: node.callee.name, format: format}
|
||||
);
|
||||
return;
|
||||
}
|
||||
// count the number of formatting substitutions, plus the first two args
|
||||
const expectedNArgs = (format.match(/%s/g) || []).length + 2;
|
||||
if (node.arguments.length !== expectedNArgs) {
|
||||
context.report(
|
||||
node,
|
||||
'Expected {{expectedNArgs}} arguments in call to {{name}} based on ' +
|
||||
'the number of "%s" substitutions, but got {{length}}',
|
||||
{
|
||||
expectedNArgs: expectedNArgs,
|
||||
name: node.callee.name,
|
||||
length: node.arguments.length,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (!messages.has(format)) {
|
||||
context.report(
|
||||
node,
|
||||
'Error message does not have a corresponding production ' +
|
||||
'error code.\n\n' +
|
||||
'Run `yarn extract-errors` to add the message to error code ' +
|
||||
'map, so it can be stripped from the production builds. ' +
|
||||
"Alternatively, if you're updating an existing error " +
|
||||
'message, you can modify ' +
|
||||
'`scripts/error-codes/codes.json` directly.'
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
if (!messages.has(format)) {
|
||||
context.report(
|
||||
node,
|
||||
'Error message does not have a corresponding production ' +
|
||||
'error code.\n\n' +
|
||||
'Run `yarn extract-errors` to add the message to error code ' +
|
||||
'map, so it can be stripped from the production builds. ' +
|
||||
"Alternatively, if you're updating an existing error " +
|
||||
'message, you can modify ' +
|
||||
'`scripts/error-codes/codes.json` directly.'
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
module.exports.schema = [];
|
||||
|
||||
@@ -46,7 +46,6 @@ function warnIfOldField(context, oldFields, identifier) {
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
fixable: 'code',
|
||||
},
|
||||
create(context) {
|
||||
const sourceFilename = context.getFilename();
|
||||
|
||||
@@ -9,42 +9,47 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = function(context) {
|
||||
function report(node, name, msg) {
|
||||
context.report(node, `Do not use the ${name} constructor. ${msg}`);
|
||||
}
|
||||
|
||||
function check(node) {
|
||||
const name = node.callee.name;
|
||||
switch (name) {
|
||||
case 'Boolean':
|
||||
report(
|
||||
node,
|
||||
name,
|
||||
'To cast a value to a boolean, use double negation: !!value'
|
||||
);
|
||||
break;
|
||||
case 'String':
|
||||
report(
|
||||
node,
|
||||
name,
|
||||
'To cast a value to a string, concat it with the empty string ' +
|
||||
"(unless it's a symbol, which has different semantics): " +
|
||||
"'' + value"
|
||||
);
|
||||
break;
|
||||
case 'Number':
|
||||
report(
|
||||
node,
|
||||
name,
|
||||
'To cast a value to a number, use the plus operator: +value'
|
||||
);
|
||||
break;
|
||||
module.exports = {
|
||||
meta: {
|
||||
schema: [],
|
||||
},
|
||||
create(context) {
|
||||
function report(node, name, msg) {
|
||||
context.report(node, `Do not use the ${name} constructor. ${msg}`);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
CallExpression: check,
|
||||
NewExpression: check,
|
||||
};
|
||||
function check(node) {
|
||||
const name = node.callee.name;
|
||||
switch (name) {
|
||||
case 'Boolean':
|
||||
report(
|
||||
node,
|
||||
name,
|
||||
'To cast a value to a boolean, use double negation: !!value'
|
||||
);
|
||||
break;
|
||||
case 'String':
|
||||
report(
|
||||
node,
|
||||
name,
|
||||
'To cast a value to a string, concat it with the empty string ' +
|
||||
"(unless it's a symbol, which has different semantics): " +
|
||||
"'' + value"
|
||||
);
|
||||
break;
|
||||
case 'Number':
|
||||
report(
|
||||
node,
|
||||
name,
|
||||
'To cast a value to a number, use the plus operator: +value'
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
CallExpression: check,
|
||||
NewExpression: check,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
module.exports = {
|
||||
meta: {
|
||||
fixable: 'code',
|
||||
schema: [],
|
||||
},
|
||||
create: function(context) {
|
||||
function isInDEVBlock(node) {
|
||||
|
||||
@@ -9,28 +9,33 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = function(context) {
|
||||
return {
|
||||
Identifier(node) {
|
||||
if (node.name === 'toWarnDev' || node.name === 'toErrorDev') {
|
||||
let current = node;
|
||||
while (current.parent) {
|
||||
if (current.type === 'CallExpression') {
|
||||
if (
|
||||
current &&
|
||||
current.callee &&
|
||||
current.callee.property &&
|
||||
current.callee.property.name === 'toThrow'
|
||||
) {
|
||||
context.report(
|
||||
node,
|
||||
node.name + '() matcher should not be nested'
|
||||
);
|
||||
module.exports = {
|
||||
meta: {
|
||||
schema: [],
|
||||
},
|
||||
create(context) {
|
||||
return {
|
||||
Identifier(node) {
|
||||
if (node.name === 'toWarnDev' || node.name === 'toErrorDev') {
|
||||
let current = node;
|
||||
while (current.parent) {
|
||||
if (current.type === 'CallExpression') {
|
||||
if (
|
||||
current &&
|
||||
current.callee &&
|
||||
current.callee.property &&
|
||||
current.callee.property.name === 'toThrow'
|
||||
) {
|
||||
context.report(
|
||||
node,
|
||||
node.name + '() matcher should not be nested'
|
||||
);
|
||||
}
|
||||
}
|
||||
current = current.parent;
|
||||
}
|
||||
current = current.parent;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
@@ -24,76 +24,79 @@ Object.keys(existingErrorMap).forEach(key =>
|
||||
* argument.
|
||||
*/
|
||||
|
||||
module.exports = function(context) {
|
||||
// we also allow literal strings and concatenated literal strings
|
||||
function getLiteralString(node) {
|
||||
if (node.type === 'Literal' && typeof node.value === 'string') {
|
||||
return node.value;
|
||||
} else if (node.type === 'BinaryExpression' && node.operator === '+') {
|
||||
const l = getLiteralString(node.left);
|
||||
const r = getLiteralString(node.right);
|
||||
if (l !== null && r !== null) {
|
||||
return l + r;
|
||||
module.exports = {
|
||||
meta: {
|
||||
schema: [],
|
||||
},
|
||||
create(context) {
|
||||
// we also allow literal strings and concatenated literal strings
|
||||
function getLiteralString(node) {
|
||||
if (node.type === 'Literal' && typeof node.value === 'string') {
|
||||
return node.value;
|
||||
} else if (node.type === 'BinaryExpression' && node.operator === '+') {
|
||||
const l = getLiteralString(node.left);
|
||||
const r = getLiteralString(node.right);
|
||||
if (l !== null && r !== null) {
|
||||
return l + r;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
CallExpression: function(node) {
|
||||
// This could be a little smarter by checking context.getScope() to see
|
||||
// how warning/invariant was defined.
|
||||
const isWarning =
|
||||
node.callee.type === 'MemberExpression' &&
|
||||
node.callee.object.type === 'Identifier' &&
|
||||
node.callee.object.name === 'console' &&
|
||||
node.callee.property.type === 'Identifier' &&
|
||||
(node.callee.property.name === 'error' ||
|
||||
node.callee.property.name === 'warn');
|
||||
if (!isWarning) {
|
||||
return;
|
||||
}
|
||||
const name = 'console.' + node.callee.property.name;
|
||||
if (node.arguments.length < 1) {
|
||||
context.report(node, '{{name}} takes at least one argument', {
|
||||
name,
|
||||
});
|
||||
return;
|
||||
}
|
||||
const format = getLiteralString(node.arguments[0]);
|
||||
if (format === null) {
|
||||
context.report(
|
||||
node,
|
||||
'The first argument to {{name}} must be a string literal',
|
||||
{name}
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (format.length < 10 || /^[s\W]*$/.test(format)) {
|
||||
context.report(
|
||||
node,
|
||||
'The {{name}} format should be able to uniquely identify this ' +
|
||||
'warning. Please, use a more descriptive format than: {{format}}',
|
||||
{name, format}
|
||||
);
|
||||
return;
|
||||
}
|
||||
// count the number of formatting substitutions, plus the first two args
|
||||
const expectedNArgs = (format.match(/%s/g) || []).length + 1;
|
||||
if (node.arguments.length !== expectedNArgs) {
|
||||
context.report(
|
||||
node,
|
||||
'Expected {{expectedNArgs}} arguments in call to {{name}} based on ' +
|
||||
'the number of "%s" substitutions, but got {{length}}',
|
||||
{
|
||||
expectedNArgs: expectedNArgs,
|
||||
return {
|
||||
CallExpression: function(node) {
|
||||
// This could be a little smarter by checking context.getScope() to see
|
||||
// how warning/invariant was defined.
|
||||
const isWarning =
|
||||
node.callee.type === 'MemberExpression' &&
|
||||
node.callee.object.type === 'Identifier' &&
|
||||
node.callee.object.name === 'console' &&
|
||||
node.callee.property.type === 'Identifier' &&
|
||||
(node.callee.property.name === 'error' ||
|
||||
node.callee.property.name === 'warn');
|
||||
if (!isWarning) {
|
||||
return;
|
||||
}
|
||||
const name = 'console.' + node.callee.property.name;
|
||||
if (node.arguments.length < 1) {
|
||||
context.report(node, '{{name}} takes at least one argument', {
|
||||
name,
|
||||
length: node.arguments.length,
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
return;
|
||||
}
|
||||
const format = getLiteralString(node.arguments[0]);
|
||||
if (format === null) {
|
||||
context.report(
|
||||
node,
|
||||
'The first argument to {{name}} must be a string literal',
|
||||
{name}
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (format.length < 10 || /^[s\W]*$/.test(format)) {
|
||||
context.report(
|
||||
node,
|
||||
'The {{name}} format should be able to uniquely identify this ' +
|
||||
'warning. Please, use a more descriptive format than: {{format}}',
|
||||
{name, format}
|
||||
);
|
||||
return;
|
||||
}
|
||||
// count the number of formatting substitutions, plus the first two args
|
||||
const expectedNArgs = (format.match(/%s/g) || []).length + 1;
|
||||
if (node.arguments.length !== expectedNArgs) {
|
||||
context.report(
|
||||
node,
|
||||
'Expected {{expectedNArgs}} arguments in call to {{name}} based on ' +
|
||||
'the number of "%s" substitutions, but got {{length}}',
|
||||
{
|
||||
expectedNArgs: expectedNArgs,
|
||||
name,
|
||||
length: node.arguments.length,
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
module.exports.schema = [];
|
||||
|
||||
Reference in New Issue
Block a user