securityos/node_modules/eslint-plugin-unicorn/rules/utils/boolean.js

93 lines
2.1 KiB
JavaScript

'use strict';
const isLogicalExpression = require('./is-logical-expression.js');
const isLogicNot = node => node?.type === 'UnaryExpression' && node.operator === '!';
const isLogicNotArgument = node => isLogicNot(node.parent) && node.parent.argument === node;
const isBooleanCallArgument = node => isBooleanCall(node.parent) && node.parent.arguments[0] === node;
const isBooleanCall = node =>
node?.type === 'CallExpression'
&& node.callee.type === 'Identifier'
&& node.callee.name === 'Boolean'
&& node.arguments.length === 1;
const isVueBooleanAttributeValue = node =>
node?.type === 'VExpressionContainer'
&& node.parent.type === 'VAttribute'
&& node.parent.directive
&& node.parent.value === node
&& node.parent.key.type === 'VDirectiveKey'
&& node.parent.key.name.type === 'VIdentifier'
&& (
node.parent.key.name.rawName === 'if'
|| node.parent.key.name.rawName === 'else-if'
|| node.parent.key.name.rawName === 'show'
);
/**
Check if the value of node is a `boolean`.
@param {Node} node
@returns {boolean}
*/
function isBooleanNode(node) {
if (
isLogicNot(node)
|| isLogicNotArgument(node)
|| isBooleanCall(node)
|| isBooleanCallArgument(node)
) {
return true;
}
const {parent} = node;
if (isVueBooleanAttributeValue(parent)) {
return true;
}
if (
(
parent.type === 'IfStatement'
|| parent.type === 'ConditionalExpression'
|| parent.type === 'WhileStatement'
|| parent.type === 'DoWhileStatement'
|| parent.type === 'ForStatement'
)
&& parent.test === node
) {
return true;
}
if (isLogicalExpression(parent)) {
return isBooleanNode(parent);
}
return false;
}
/**
Get the boolean type-casting ancestor.
@typedef {{ node: Node, isNegative: boolean }} Result
@param {Node} node
@returns {Result}
*/
function getBooleanAncestor(node) {
let isNegative = false;
// eslint-disable-next-line no-constant-condition
while (true) {
if (isLogicNotArgument(node)) {
isNegative = !isNegative;
node = node.parent;
} else if (isBooleanCallArgument(node)) {
node = node.parent;
} else {
break;
}
}
return {node, isNegative};
}
module.exports = {isBooleanNode, getBooleanAncestor};