Skip to content

feat(eslint-plugin-react-internal): support ESLint 8.x #22249

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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, {
Expand Down
151 changes: 77 additions & 74 deletions scripts/eslint-rules/invariant-args.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [];
1 change: 0 additions & 1 deletion scripts/eslint-rules/no-cross-fork-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ function warnIfOldField(context, oldFields, identifier) {
module.exports = {
meta: {
type: 'problem',
fixable: 'code',
},
create(context) {
const sourceFilename = context.getFilename();
Expand Down
75 changes: 40 additions & 35 deletions scripts/eslint-rules/no-primitive-constructors.js
Original file line number Diff line number Diff line change
Expand Up @@ -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}`);
}
module.exports = {
meta: {
schema: [],
},
create(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;
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,
};
return {
CallExpression: check,
NewExpression: check,
};
},
};
1 change: 1 addition & 0 deletions scripts/eslint-rules/no-production-logging.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
module.exports = {
meta: {
fixable: 'code',
schema: [],
},
create: function(context) {
function isInDEVBlock(node) {
Expand Down
47 changes: 26 additions & 21 deletions scripts/eslint-rules/no-to-warn-dev-within-to-throw.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
},
};
},
};
},
};
Loading