line_push/node_modules/eslint-plugin-unicorn/rules/prefer-number-properties.js
2022-07-17 13:16:16 +08:00

115 lines
2.4 KiB
JavaScript

'use strict';
const getDocumentationUrl = require('./utils/get-documentation-url');
const isShadowed = require('./utils/is-shadowed');
const renameIdentifier = require('./utils/rename-identifier');
const METHOD_ERROR_MESSAGE_ID = 'method-error';
const METHOD_SUGGESTION_MESSAGE_ID = 'method-suggestion';
const PROPERTY_ERROR_MESSAGE_ID = 'property-error';
const methods = {
// Safe
parseInt: true,
parseFloat: true,
// Unsafe
isNaN: false,
isFinite: false
};
const methodsSelector = [
'CallExpression',
'>',
'Identifier.callee',
`:matches(${Object.keys(methods).map(name => `[name="${name}"]`).join(', ')})`
].join('');
const propertiesSelector = [
'Identifier',
'[name="NaN"]',
`:not(${
[
'MemberExpression[computed=false] > Identifier.property',
'FunctionDeclaration > Identifier.id',
'ClassDeclaration > Identifier.id',
'MethodDefinition > Identifier.key',
'VariableDeclarator > Identifier.id',
'Property[shorthand=false] > Identifier.key',
'TSDeclareFunction > Identifier.id',
'TSEnumMember > Identifier.id',
'TSPropertySignature > Identifier.key'
].join(', ')
})`
].join('');
const create = context => {
const sourceCode = context.getSourceCode();
return {
[methodsSelector]: node => {
if (isShadowed(context.getScope(), node)) {
return;
}
const {name} = node;
const isSafe = methods[name];
const problem = {
node,
messageId: METHOD_ERROR_MESSAGE_ID,
data: {
name
}
};
const fix = fixer => renameIdentifier(node, `Number.${name}`, fixer, sourceCode);
if (isSafe) {
problem.fix = fix;
} else {
problem.suggest = [
{
messageId: METHOD_SUGGESTION_MESSAGE_ID,
data: {
name
},
fix
}
];
}
context.report(problem);
},
[propertiesSelector]: node => {
if (isShadowed(context.getScope(), node)) {
return;
}
const {name} = node;
context.report({
node,
messageId: PROPERTY_ERROR_MESSAGE_ID,
data: {
name
},
fix: fixer => renameIdentifier(node, `Number.${name}`, fixer, sourceCode)
});
}
};
};
module.exports = {
create,
meta: {
type: 'suggestion',
docs: {
url: getDocumentationUrl(__filename)
},
fixable: 'code',
messages: {
[METHOD_ERROR_MESSAGE_ID]: 'Prefer `Number.{{name}}()` over `{{name}}()`.',
[METHOD_SUGGESTION_MESSAGE_ID]: 'Replace `{{name}}()` with `Number.{{name}}()`.',
[PROPERTY_ERROR_MESSAGE_ID]: 'Prefer `Number.{{name}}` over `{{name}}`.'
}
}
};