forked from foxglove/eslint-plugin
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathstrict-equality.js
81 lines (72 loc) · 2.38 KB
/
strict-equality.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
81
// https://github.com/eslint/eslint/blob/dd58cd4afa6ced9016c091fc99a702c97a3e44f0/lib/rules/utils/ast-utils.js#L155
function isNullLiteral(node) {
return (
node.type === "Literal" &&
// eslint-disable-next-line @lichtblick/strict-equality
node.value === null &&
!node.regex &&
!node.bigint
);
}
// - Prefer double equals when comparing with undefined
// - Prefer undefined over null
// - Prefer triple equals everywhere else
module.exports = {
meta: {
type: "suggestion",
fixable: "code",
schema: [],
messages: {
unexpected: "Prefer '{{expectedOperator}}' over '{{actualOperator}}'.",
unexpectedStrict: `Prefer 'x {{expectedOp}} {{literal}}' to catch both null and undefined`,
},
},
create(context) {
const sourceCode = context.getSourceCode();
function isUndefinedLiteral(node) {
return node.type === "Identifier" && node.name === "undefined";
}
return {
BinaryExpression: (node) => {
function preferDoubleEqual(node, loc, literal) {
let expectedOp = node.operator.substring(0, 2);
context.report({
node,
loc,
messageId: "unexpectedStrict",
data: { expectedOp, literal },
});
}
const operatorToken = sourceCode.getFirstTokenBetween(
node.left,
node.right,
(token) => token.value === node.operator
);
// If either side is undefined, prefer double equals
if (isUndefinedLiteral(node.left) || isUndefinedLiteral(node.right)) {
if (node.operator === "===" || node.operator === "!==") {
preferDoubleEqual(node, operatorToken.loc, "undefined");
}
}
// If either side is null, prefer double equals
else if (isNullLiteral(node.left) || isNullLiteral(node.right)) {
if (node.operator === "===" || node.operator === "!==") {
preferDoubleEqual(node, operatorToken.loc, "null");
}
}
// Otherwise, prefer triple equals
else if (node.operator === "==" || node.operator === "!=") {
context.report({
node,
loc: operatorToken.loc,
messageId: "unexpected",
data: {
expectedOperator: node.operator + "=",
actualOperator: node.operator,
},
});
}
},
};
},
};