line_push/node_modules/eslint-plugin-unicorn/rules/explicit-length-check.js
2022-07-21 03:28:35 +00:00

174 lines
3.3 KiB
JavaScript

'use strict';
const getDocumentationUrl = require('./utils/get-documentation-url');
const operatorTypes = {
gt: ['>'],
gte: ['>='],
ne: ['!==', '!=']
};
function reportError(context, node, message, fixDetails) {
context.report({
node,
message,
fix: fixDetails && (fixer => {
return fixer.replaceText(
node,
`${context.getSourceCode().getText(fixDetails.node)} ${fixDetails.operator} ${fixDetails.value}`
);
})
});
}
function checkZeroType(context, node) {
if (node.operator === '<' && node.right.value === 1) {
reportError(
context,
node,
'Zero `.length` should be compared with `=== 0`.',
{
node: node.left,
operator: '===',
value: 0
}
);
}
}
function checkNonZeroType(context, node, type) {
const {value} = node.right;
const {operator} = node;
switch (type) {
case 'greater-than':
if (
(operatorTypes.gte.includes(operator) && value === 1) ||
(operatorTypes.ne.includes(operator) && value === 0)
) {
reportError(
context,
node,
'Non-zero `.length` should be compared with `> 0`.',
{
node: node.left,
operator: '>',
value: 0
}
);
}
break;
case 'greater-than-or-equal':
if (
(operatorTypes.gt.includes(operator) && value === 0) ||
(operatorTypes.ne.includes(operator) && value === 0)
) {
reportError(
context,
node,
'Non-zero `.length` should be compared with `>= 1`.',
{
node: node.left,
operator: '>=',
value: 1
}
);
}
break;
case 'not-equal':
if (
(operatorTypes.gt.includes(operator) && value === 0) ||
(operatorTypes.gte.includes(operator) && value === 1)
) {
reportError(
context,
node,
'Non-zero `.length` should be compared with `!== 0`.',
{
node: node.left,
operator: '!==',
value: 0
}
);
}
break;
default:
break;
}
}
function checkBinaryExpression(context, node, options) {
if (
node.right.type === 'Literal' &&
node.left.type === 'MemberExpression' &&
node.left.property.type === 'Identifier' &&
node.left.property.name === 'length'
) {
checkZeroType(context, node);
checkNonZeroType(context, node, options['non-zero']);
}
}
function checkExpression(context, node) {
if (node.type === 'LogicalExpression') {
checkExpression(context, node.left);
checkExpression(context, node.right);
return;
}
if (node.type === 'UnaryExpression' && node.operator === '!') {
checkExpression(context, node.argument);
return;
}
if (node.type === 'BinaryExpression') {
checkBinaryExpression(context, node, context.options[0] || {});
return;
}
if (
node.type === 'MemberExpression' &&
node.property.type === 'Identifier' &&
node.property.name === 'length' &&
!node.computed
) {
reportError(context, node, '`length` property should be compared to a value.');
}
}
const create = context => {
return {
IfStatement: node => {
checkExpression(context, node.test);
},
ConditionalExpression: node => {
checkExpression(context, node.test);
}
};
};
const schema = [
{
type: 'object',
properties: {
'non-zero': {
enum: ['not-equal', 'greater-than', 'greater-than-or-equal']
}
}
}
];
module.exports = {
create,
meta: {
type: 'problem',
docs: {
url: getDocumentationUrl(__filename)
},
fixable: 'code',
schema
}
};