-
-
Notifications
You must be signed in to change notification settings - Fork 385
/
Copy pathprefer-math-min-max.js
80 lines (67 loc) · 2.27 KB
/
prefer-math-min-max.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
'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,
},
};