UNPKG

2.43 kBJavaScriptView Raw
1/**
2 * @fileoverview Rule to flag unnecessary double negation in Boolean contexts
3 * @author Brandon Mills
4 */
5
6"use strict";
7
8//------------------------------------------------------------------------------
9// Rule Definition
10//------------------------------------------------------------------------------
11
12module.exports = function(context) {
13
14 // Node types which have a test which will coerce values to booleans.
15 var BOOLEAN_NODE_TYPES = [
16 "IfStatement",
17 "DoWhileStatement",
18 "WhileStatement",
19 "ConditionalExpression",
20 "ForStatement"
21 ];
22
23 /**
24 * Check if a node is in a context where its value would be coerced to a boolean at runtime.
25 *
26 * @param {Object} node The node
27 * @param {Object} parent Its parent
28 * @returns {Boolean} If it is in a boolean context
29 */
30 function isInBooleanContext(node, parent) {
31 return (
32 (BOOLEAN_NODE_TYPES.indexOf(parent.type) !== -1 &&
33 node === parent.test) ||
34 // !<bool>
35 (parent.type === "UnaryExpression" &&
36 parent.operator === "!")
37 );
38 }
39
40
41 return {
42 "UnaryExpression": function(node) {
43 var ancestors = context.getAncestors(),
44 parent = ancestors.pop(),
45 grandparent = ancestors.pop();
46
47 // Exit early if it's guaranteed not to match
48 if (node.operator !== "!" ||
49 parent.type !== "UnaryExpression" ||
50 parent.operator !== "!") {
51 return;
52 }
53
54 if (isInBooleanContext(parent, grandparent) ||
55 // Boolean(<bool>) and new Boolean(<bool>)
56 ((grandparent.type === "CallExpression" || grandparent.type === "NewExpression") &&
57 grandparent.callee.type === "Identifier" &&
58 grandparent.callee.name === "Boolean")
59 ) {
60 context.report(node, "Redundant double negation.");
61 }
62 },
63 "CallExpression": function(node) {
64 var parent = node.parent;
65
66 if (node.callee.type !== "Identifier" || node.callee.name !== "Boolean") {
67 return;
68 }
69
70 if (isInBooleanContext(node, parent)) {
71 context.report(node, "Redundant Boolean call.");
72 }
73 }
74 };
75
76};
77
78module.exports.schema = [];