93 lines
2.1 KiB
JavaScript
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};
|