mirror of
https://github.com/nodejs/node.git
synced 2025-08-15 13:48:44 +02:00
tools: prepare custom rules for ESLint v9
Refs: https://eslint.org/docs/latest/use/migrate-to-9.0.0 PR-URL: https://github.com/nodejs/node/pull/52889 Reviewed-By: Moshe Atlow <moshe@atlow.co.il> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Yagiz Nizipli <yagiz.nizipli@sentry.io>
This commit is contained in:
parent
2b657ccfb3
commit
3c1069bb06
10 changed files with 142 additions and 118 deletions
|
@ -56,7 +56,7 @@ module.exports = {
|
|||
schema: [],
|
||||
},
|
||||
create(context) {
|
||||
const sourceCode = context.getSourceCode();
|
||||
const sourceCode = context.sourceCode;
|
||||
|
||||
return {
|
||||
ArrayPattern(node) {
|
||||
|
|
|
@ -25,41 +25,43 @@ function isTopLevel(node) {
|
|||
return false;
|
||||
}
|
||||
|
||||
module.exports = (context) => {
|
||||
if (context.parserOptions.sourceType === 'module') {
|
||||
return {};
|
||||
}
|
||||
|
||||
function getRequiredModuleNameFromCall(node) {
|
||||
// Node has arguments and first argument is string
|
||||
if (node.arguments.length && isString(node.arguments[0])) {
|
||||
return node.arguments[0].value.trim();
|
||||
module.exports = {
|
||||
create(context) {
|
||||
if (context.parserOptions.sourceType === 'module') {
|
||||
return {};
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const required = new Set();
|
||||
|
||||
const rules = {
|
||||
CallExpression: (node) => {
|
||||
if (isRequireCall(node) && isTopLevel(node)) {
|
||||
const moduleName = getRequiredModuleNameFromCall(node);
|
||||
if (moduleName === undefined) {
|
||||
return;
|
||||
}
|
||||
if (required.has(moduleName)) {
|
||||
context.report(
|
||||
node,
|
||||
'\'{{moduleName}}\' require is duplicated.',
|
||||
{ moduleName },
|
||||
);
|
||||
} else {
|
||||
required.add(moduleName);
|
||||
}
|
||||
function getRequiredModuleNameFromCall(node) {
|
||||
// Node has arguments and first argument is string
|
||||
if (node.arguments.length && isString(node.arguments[0])) {
|
||||
return node.arguments[0].value.trim();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
return rules;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const required = new Set();
|
||||
|
||||
const rules = {
|
||||
CallExpression: (node) => {
|
||||
if (isRequireCall(node) && isTopLevel(node)) {
|
||||
const moduleName = getRequiredModuleNameFromCall(node);
|
||||
if (moduleName === undefined) {
|
||||
return;
|
||||
}
|
||||
if (required.has(moduleName)) {
|
||||
context.report(
|
||||
node,
|
||||
'\'{{moduleName}}\' require is duplicated.',
|
||||
{ moduleName },
|
||||
);
|
||||
} else {
|
||||
required.add(moduleName);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
return rules;
|
||||
},
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
module.exports = {
|
||||
create(context) {
|
||||
const sourceCode = context.getSourceCode();
|
||||
const sourceCode = context.sourceCode;
|
||||
const regexpStack = [];
|
||||
let regexpBuffer = [];
|
||||
let inRegExp = false;
|
||||
|
|
|
@ -24,32 +24,34 @@ const suggestions = {
|
|||
'—': '-',
|
||||
};
|
||||
|
||||
module.exports = (context) => {
|
||||
module.exports = {
|
||||
create(context) {
|
||||
|
||||
const reportIfError = (node, sourceCode) => {
|
||||
const reportIfError = (node, sourceCode) => {
|
||||
|
||||
const matches = sourceCode.text.match(nonAsciiRegexPattern);
|
||||
const matches = sourceCode.text.match(nonAsciiRegexPattern);
|
||||
|
||||
if (!matches) return;
|
||||
if (!matches) return;
|
||||
|
||||
const offendingCharacter = matches[0];
|
||||
const offendingCharacterPosition = matches.index;
|
||||
const suggestion = suggestions[offendingCharacter];
|
||||
const offendingCharacter = matches[0];
|
||||
const offendingCharacterPosition = matches.index;
|
||||
const suggestion = suggestions[offendingCharacter];
|
||||
|
||||
let message = `Non-ASCII character '${offendingCharacter}' detected.`;
|
||||
let message = `Non-ASCII character '${offendingCharacter}' detected.`;
|
||||
|
||||
message = suggestion ?
|
||||
`${message} Consider replacing with: ${suggestion}` :
|
||||
message;
|
||||
message = suggestion ?
|
||||
`${message} Consider replacing with: ${suggestion}` :
|
||||
message;
|
||||
|
||||
context.report({
|
||||
node,
|
||||
message,
|
||||
loc: sourceCode.getLocFromIndex(offendingCharacterPosition),
|
||||
});
|
||||
};
|
||||
context.report({
|
||||
node,
|
||||
message,
|
||||
loc: sourceCode.getLocFromIndex(offendingCharacterPosition),
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
Program: (node) => reportIfError(node, context.getSourceCode()),
|
||||
};
|
||||
return {
|
||||
Program: (node) => reportIfError(node, context.sourceCode),
|
||||
};
|
||||
},
|
||||
};
|
||||
|
|
|
@ -12,7 +12,7 @@ module.exports = {
|
|||
fixable: 'code',
|
||||
},
|
||||
create(context) {
|
||||
const sourceCode = context.getSourceCode();
|
||||
const sourceCode = context.sourceCode;
|
||||
let assertImported = false;
|
||||
|
||||
function hasSameTokens(nodeA, nodeB) {
|
||||
|
|
|
@ -31,7 +31,7 @@ module.exports = {
|
|||
node,
|
||||
message: parseError(assertMethod, arg.operator),
|
||||
fix: (fixer) => {
|
||||
const sourceCode = context.getSourceCode();
|
||||
const sourceCode = context.sourceCode;
|
||||
const left = sourceCode.getText(arg.left);
|
||||
const right = sourceCode.getText(arg.right);
|
||||
return fixer.replaceText(
|
||||
|
|
|
@ -3,64 +3,66 @@
|
|||
const mustCall = 'CallExpression[callee.object.name="common"]' +
|
||||
'[callee.property.name="mustCall"]';
|
||||
|
||||
module.exports = (context) => {
|
||||
function isAssertIfError(node) {
|
||||
return node.type === 'MemberExpression' &&
|
||||
node.object.type === 'Identifier' &&
|
||||
node.object.name === 'assert' &&
|
||||
node.property.type === 'Identifier' &&
|
||||
node.property.name === 'ifError';
|
||||
}
|
||||
|
||||
function isCallToIfError(node, errName) {
|
||||
return node.type === 'CallExpression' &&
|
||||
isAssertIfError(node.callee) &&
|
||||
node.arguments.length > 0 &&
|
||||
node.arguments[0].type === 'Identifier' &&
|
||||
node.arguments[0].name === errName;
|
||||
}
|
||||
|
||||
function bodyStartsWithCallToIfError(body, errName) {
|
||||
while (body.type === 'BlockStatement' && body.body.length > 0)
|
||||
body = body.body[0];
|
||||
|
||||
let expr;
|
||||
switch (body.type) {
|
||||
case 'ReturnStatement':
|
||||
expr = body.argument;
|
||||
break;
|
||||
case 'ExpressionStatement':
|
||||
expr = body.expression;
|
||||
break;
|
||||
default:
|
||||
expr = body;
|
||||
module.exports = {
|
||||
create(context) {
|
||||
function isAssertIfError(node) {
|
||||
return node.type === 'MemberExpression' &&
|
||||
node.object.type === 'Identifier' &&
|
||||
node.object.name === 'assert' &&
|
||||
node.property.type === 'Identifier' &&
|
||||
node.property.name === 'ifError';
|
||||
}
|
||||
|
||||
return isCallToIfError(expr, errName);
|
||||
}
|
||||
function isCallToIfError(node, errName) {
|
||||
return node.type === 'CallExpression' &&
|
||||
isAssertIfError(node.callee) &&
|
||||
node.arguments.length > 0 &&
|
||||
node.arguments[0].type === 'Identifier' &&
|
||||
node.arguments[0].name === errName;
|
||||
}
|
||||
|
||||
return {
|
||||
[`${mustCall}:exit`]: (mustCall) => {
|
||||
if (mustCall.arguments.length > 0) {
|
||||
const callback = mustCall.arguments[0];
|
||||
if (isAssertIfError(callback)) {
|
||||
context.report(mustCall, 'Please use common.mustSucceed instead of ' +
|
||||
'common.mustCall(assert.ifError).');
|
||||
}
|
||||
function bodyStartsWithCallToIfError(body, errName) {
|
||||
while (body.type === 'BlockStatement' && body.body.length > 0)
|
||||
body = body.body[0];
|
||||
|
||||
if (callback.type === 'ArrowFunctionExpression' ||
|
||||
callback.type === 'FunctionExpression') {
|
||||
if (callback.params.length > 0 &&
|
||||
callback.params[0].type === 'Identifier') {
|
||||
const errName = callback.params[0].name;
|
||||
if (bodyStartsWithCallToIfError(callback.body, errName)) {
|
||||
context.report(mustCall, 'Please use common.mustSucceed instead' +
|
||||
' of common.mustCall with' +
|
||||
' assert.ifError.');
|
||||
let expr;
|
||||
switch (body.type) {
|
||||
case 'ReturnStatement':
|
||||
expr = body.argument;
|
||||
break;
|
||||
case 'ExpressionStatement':
|
||||
expr = body.expression;
|
||||
break;
|
||||
default:
|
||||
expr = body;
|
||||
}
|
||||
|
||||
return isCallToIfError(expr, errName);
|
||||
}
|
||||
|
||||
return {
|
||||
[`${mustCall}:exit`]: (mustCall) => {
|
||||
if (mustCall.arguments.length > 0) {
|
||||
const callback = mustCall.arguments[0];
|
||||
if (isAssertIfError(callback)) {
|
||||
context.report(mustCall, 'Please use common.mustSucceed instead of ' +
|
||||
'common.mustCall(assert.ifError).');
|
||||
}
|
||||
|
||||
if (callback.type === 'ArrowFunctionExpression' ||
|
||||
callback.type === 'FunctionExpression') {
|
||||
if (callback.params.length > 0 &&
|
||||
callback.params[0].type === 'Identifier') {
|
||||
const errName = callback.params[0].name;
|
||||
if (bodyStartsWithCallToIfError(callback.body, errName)) {
|
||||
context.report(mustCall, 'Please use common.mustSucceed instead' +
|
||||
' of common.mustCall with' +
|
||||
' assert.ifError.');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
|
|
@ -75,9 +75,27 @@ module.exports = {
|
|||
messages: {
|
||||
error: 'Use `const { {{name}} } = primordials;` instead of the global.',
|
||||
},
|
||||
schema: {
|
||||
type: 'array',
|
||||
items: [
|
||||
{
|
||||
type: 'object',
|
||||
required: ['name'],
|
||||
properties: {
|
||||
name: { type: 'string' },
|
||||
ignore: {
|
||||
type: 'array',
|
||||
items: { type: 'string' },
|
||||
},
|
||||
into: { type: 'string' },
|
||||
},
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
create(context) {
|
||||
const globalScope = context.getSourceCode().scopeManager.globalScope;
|
||||
const globalScope = context.sourceCode.scopeManager.globalScope;
|
||||
|
||||
const nameMap = new Map();
|
||||
const renameMap = new Map();
|
||||
|
@ -110,7 +128,7 @@ module.exports = {
|
|||
}
|
||||
const name = node.name;
|
||||
const parent = getDestructuringAssignmentParent(
|
||||
context.getScope(),
|
||||
context.sourceCode.getScope(node),
|
||||
node,
|
||||
);
|
||||
const parentName = parent?.name;
|
||||
|
@ -155,7 +173,7 @@ module.exports = {
|
|||
}
|
||||
|
||||
const variables =
|
||||
context.getSourceCode().scopeManager.getDeclaredVariables(node);
|
||||
context.sourceCode.scopeManager.getDeclaredVariables(node);
|
||||
if (variables.length === 0) {
|
||||
context.report({
|
||||
node,
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
'use strict';
|
||||
|
||||
// Cribbed from `eslint-module-utils/declaredScope`
|
||||
function declaredScope(context, name) {
|
||||
const references = context.getScope().references;
|
||||
function declaredScope(context, node, name) {
|
||||
const references = context.sourceCode.getScope(node).references;
|
||||
const reference = references.find((x) => x.identifier.name === name);
|
||||
if (!reference) return undefined;
|
||||
return reference.resolved.scope.type;
|
||||
|
@ -33,12 +33,12 @@ module.exports = {
|
|||
[callee.type="MemberExpression"][callee.object.name="Object"][callee.property.name="create"]\
|
||||
)'(node) {
|
||||
if (node.callee.type === 'MemberExpression') {
|
||||
const scope = declaredScope(context, node.callee.object);
|
||||
const scope = declaredScope(context, node, node.callee.object);
|
||||
if (scope && scope !== 'module' && scope !== 'global') {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const value = context.getSourceCode().getText(node.arguments[0]);
|
||||
const value = context.sourceCode.getText(node.arguments[0]);
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'error',
|
||||
|
|
|
@ -46,7 +46,7 @@ module.exports = {
|
|||
message: 'Every object must have __proto__: null',
|
||||
fix: function(fixer) {
|
||||
// Generate the fix suggestion to add __proto__: null
|
||||
const sourceCode = context.getSourceCode();
|
||||
const sourceCode = context.sourceCode;
|
||||
const firstProperty = properties[0];
|
||||
const firstPropertyToken = sourceCode.getFirstToken(firstProperty);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue