81 lines
2.3 KiB
JavaScript
81 lines
2.3 KiB
JavaScript
'use strict';
|
|
const {fixSpaceAroundKeyword} = require('./fix/index.js');
|
|
|
|
const MESSAGE_ID = 'prefer-math-min-max';
|
|
const messages = {
|
|
[MESSAGE_ID]: 'Prefer `Math.{{method}}()` to simplify ternary expressions.',
|
|
};
|
|
|
|
/** @param {import('eslint').Rule.RuleContext} context */
|
|
const create = context => ({
|
|
/** @param {import('estree').ConditionalExpression} conditionalExpression */
|
|
ConditionalExpression(conditionalExpression) {
|
|
const {test, consequent, alternate} = conditionalExpression;
|
|
|
|
if (test.type !== 'BinaryExpression') {
|
|
return;
|
|
}
|
|
|
|
const {operator, left, right} = test;
|
|
const [leftText, rightText, alternateText, consequentText] = [left, right, alternate, consequent].map(node => context.sourceCode.getText(node));
|
|
|
|
const isGreaterOrEqual = operator === '>' || operator === '>=';
|
|
const isLessOrEqual = operator === '<' || operator === '<=';
|
|
|
|
let method;
|
|
|
|
// Prefer `Math.min()`
|
|
if (
|
|
// `height > 50 ? 50 : height`
|
|
(isGreaterOrEqual && leftText === alternateText && rightText === consequentText)
|
|
// `height < 50 ? height : 50`
|
|
|| (isLessOrEqual && leftText === consequentText && rightText === alternateText)
|
|
) {
|
|
method = 'min';
|
|
} else if (
|
|
// `height > 50 ? height : 50`
|
|
(isGreaterOrEqual && leftText === consequentText && rightText === alternateText)
|
|
// `height < 50 ? 50 : height`
|
|
|| (isLessOrEqual && leftText === alternateText && rightText === consequentText)
|
|
) {
|
|
method = 'max';
|
|
}
|
|
|
|
if (!method) {
|
|
return;
|
|
}
|
|
|
|
return {
|
|
node: conditionalExpression,
|
|
messageId: MESSAGE_ID,
|
|
data: {method},
|
|
/** @param {import('eslint').Rule.RuleFixer} fixer */
|
|
* fix(fixer) {
|
|
const {sourceCode} = context;
|
|
|
|
yield * fixSpaceAroundKeyword(fixer, conditionalExpression, sourceCode);
|
|
|
|
const argumentsText = [left, right]
|
|
.map(node => node.type === 'SequenceExpression' ? `(${sourceCode.getText(node)})` : sourceCode.getText(node))
|
|
.join(', ');
|
|
|
|
yield fixer.replaceText(conditionalExpression, `Math.${method}(${argumentsText})`);
|
|
},
|
|
};
|
|
},
|
|
});
|
|
|
|
/** @type {import('eslint').Rule.RuleModule} */
|
|
module.exports = {
|
|
create,
|
|
meta: {
|
|
type: 'problem',
|
|
docs: {
|
|
description: 'Prefer `Math.min()` and `Math.max()` over ternaries for simple comparisons.',
|
|
recommended: true,
|
|
},
|
|
fixable: 'code',
|
|
messages,
|
|
},
|
|
};
|