| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 | 
							- /**
 
-  * @fileoverview Rule to flag unnecessary double negation in Boolean contexts
 
-  * @author Brandon Mills
 
-  */
 
- "use strict";
 
- //------------------------------------------------------------------------------
 
- // Requirements
 
- //------------------------------------------------------------------------------
 
- const astUtils = require("./utils/ast-utils");
 
- //------------------------------------------------------------------------------
 
- // Rule Definition
 
- //------------------------------------------------------------------------------
 
- module.exports = {
 
-     meta: {
 
-         type: "suggestion",
 
-         docs: {
 
-             description: "disallow unnecessary boolean casts",
 
-             category: "Possible Errors",
 
-             recommended: true,
 
-             url: "https://eslint.org/docs/rules/no-extra-boolean-cast"
 
-         },
 
-         schema: [],
 
-         fixable: "code",
 
-         messages: {
 
-             unexpectedCall: "Redundant Boolean call.",
 
-             unexpectedNegation: "Redundant double negation."
 
-         }
 
-     },
 
-     create(context) {
 
-         const sourceCode = context.getSourceCode();
 
-         // Node types which have a test which will coerce values to booleans.
 
-         const BOOLEAN_NODE_TYPES = [
 
-             "IfStatement",
 
-             "DoWhileStatement",
 
-             "WhileStatement",
 
-             "ConditionalExpression",
 
-             "ForStatement"
 
-         ];
 
-         /**
 
-          * Check if a node is in a context where its value would be coerced to a boolean at runtime.
 
-          * @param {ASTNode} node The node
 
-          * @param {ASTNode} parent Its parent
 
-          * @returns {boolean} If it is in a boolean context
 
-          */
 
-         function isInBooleanContext(node, parent) {
 
-             return (
 
-                 (BOOLEAN_NODE_TYPES.indexOf(parent.type) !== -1 &&
 
-                     node === parent.test) ||
 
-                 // !<bool>
 
-                 (parent.type === "UnaryExpression" &&
 
-                     parent.operator === "!")
 
-             );
 
-         }
 
-         /**
 
-          * Check if a node has comments inside.
 
-          * @param {ASTNode} node The node to check.
 
-          * @returns {boolean} `true` if it has comments inside.
 
-          */
 
-         function hasCommentsInside(node) {
 
-             return Boolean(sourceCode.getCommentsInside(node).length);
 
-         }
 
-         return {
 
-             UnaryExpression(node) {
 
-                 const ancestors = context.getAncestors(),
 
-                     parent = ancestors.pop(),
 
-                     grandparent = ancestors.pop();
 
-                 // Exit early if it's guaranteed not to match
 
-                 if (node.operator !== "!" ||
 
-                         parent.type !== "UnaryExpression" ||
 
-                         parent.operator !== "!") {
 
-                     return;
 
-                 }
 
-                 if (isInBooleanContext(parent, grandparent) ||
 
-                     // Boolean(<bool>) and new Boolean(<bool>)
 
-                     ((grandparent.type === "CallExpression" || grandparent.type === "NewExpression") &&
 
-                         grandparent.callee.type === "Identifier" &&
 
-                         grandparent.callee.name === "Boolean")
 
-                 ) {
 
-                     context.report({
 
-                         node: parent,
 
-                         messageId: "unexpectedNegation",
 
-                         fix: fixer => {
 
-                             if (hasCommentsInside(parent)) {
 
-                                 return null;
 
-                             }
 
-                             let prefix = "";
 
-                             const tokenBefore = sourceCode.getTokenBefore(parent);
 
-                             const firstReplacementToken = sourceCode.getFirstToken(node.argument);
 
-                             if (tokenBefore && tokenBefore.range[1] === parent.range[0] &&
 
-                                     !astUtils.canTokensBeAdjacent(tokenBefore, firstReplacementToken)) {
 
-                                 prefix = " ";
 
-                             }
 
-                             return fixer.replaceText(parent, prefix + sourceCode.getText(node.argument));
 
-                         }
 
-                     });
 
-                 }
 
-             },
 
-             CallExpression(node) {
 
-                 const parent = node.parent;
 
-                 if (node.callee.type !== "Identifier" || node.callee.name !== "Boolean") {
 
-                     return;
 
-                 }
 
-                 if (isInBooleanContext(node, parent)) {
 
-                     context.report({
 
-                         node,
 
-                         messageId: "unexpectedCall",
 
-                         fix: fixer => {
 
-                             if (!node.arguments.length) {
 
-                                 if (parent.type === "UnaryExpression" && parent.operator === "!") {
 
-                                     // !Boolean() -> true
 
-                                     if (hasCommentsInside(parent)) {
 
-                                         return null;
 
-                                     }
 
-                                     const replacement = "true";
 
-                                     let prefix = "";
 
-                                     const tokenBefore = sourceCode.getTokenBefore(parent);
 
-                                     if (tokenBefore && tokenBefore.range[1] === parent.range[0] &&
 
-                                             !astUtils.canTokensBeAdjacent(tokenBefore, replacement)) {
 
-                                         prefix = " ";
 
-                                     }
 
-                                     return fixer.replaceText(parent, prefix + replacement);
 
-                                 }
 
-                                 // Boolean() -> false
 
-                                 if (hasCommentsInside(node)) {
 
-                                     return null;
 
-                                 }
 
-                                 return fixer.replaceText(node, "false");
 
-                             }
 
-                             if (node.arguments.length > 1 || node.arguments[0].type === "SpreadElement" ||
 
-                                     hasCommentsInside(node)) {
 
-                                 return null;
 
-                             }
 
-                             const argument = node.arguments[0];
 
-                             if (astUtils.getPrecedence(argument) < astUtils.getPrecedence(node.parent)) {
 
-                                 return fixer.replaceText(node, `(${sourceCode.getText(argument)})`);
 
-                             }
 
-                             return fixer.replaceText(node, sourceCode.getText(argument));
 
-                         }
 
-                     });
 
-                 }
 
-             }
 
-         };
 
-     }
 
- };
 
 
  |