2025-04-19 23:12:19 -04:00

146 lines
3.2 KiB
JavaScript

/**
* @fileoverview Rule to flag bitwise identifiers
* @author Nicholas C. Zakas
*/
'use strict';
/*
*
* Set of bitwise operators.
*
*/
const BITWISE_OPERATORS = [
'^',
'|',
'&',
'<<',
'>>',
'>>>',
'^=',
'|=',
'&=',
'<<=',
'>>=',
'>>>=',
'~',
];
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
/** @type {import('../types').Rule.RuleModule} */
module.exports = {
meta: {
type: 'suggestion',
defaultOptions: [
{
allow: [],
int32Hint: false,
},
],
docs: {
description: 'Disallow bitwise operators',
recommended: false,
url: 'https://eslint.org/docs/latest/rules/no-bitwise',
},
schema: [
{
type: 'object',
properties: {
allow: {
type: 'array',
items: {
enum: BITWISE_OPERATORS,
},
uniqueItems: true,
},
int32Hint: {
type: 'boolean',
},
},
additionalProperties: false,
},
],
messages: {
unexpected: "Unexpected use of '{{operator}}'.",
},
},
create(context) {
const [{ allow: allowed, int32Hint }] = context.options;
/**
* Reports an unexpected use of a bitwise operator.
* @param {ASTNode} node Node which contains the bitwise operator.
* @returns {void}
*/
function report(node) {
context.report({
node,
messageId: 'unexpected',
data: { operator: node.operator },
});
}
/**
* Checks if the given node has a bitwise operator.
* @param {ASTNode} node The node to check.
* @returns {boolean} Whether or not the node has a bitwise operator.
*/
function hasBitwiseOperator(node) {
return BITWISE_OPERATORS.includes(node.operator);
}
/**
* Checks if exceptions were provided, e.g. `{ allow: ['~', '|'] }`.
* @param {ASTNode} node The node to check.
* @returns {boolean} Whether or not the node has a bitwise operator.
*/
function allowedOperator(node) {
return allowed.includes(node.operator);
}
/**
* Checks if the given bitwise operator is used for integer typecasting, i.e. "|0"
* @param {ASTNode} node The node to check.
* @returns {boolean} whether the node is used in integer typecasting.
*/
function isInt32Hint(node) {
return (
int32Hint &&
node.operator === '|' &&
node.right &&
node.right.type === 'Literal' &&
node.right.value === 0
);
}
/**
* Report if the given node contains a bitwise operator.
* @param {ASTNode} node The node to check.
* @returns {void}
*/
function checkNodeForBitwiseOperator(node) {
if (
hasBitwiseOperator(node) &&
!allowedOperator(node) &&
!isInt32Hint(node)
) {
report(node);
}
}
return {
AssignmentExpression: checkNodeForBitwiseOperator,
BinaryExpression: checkNodeForBitwiseOperator,
UnaryExpression: checkNodeForBitwiseOperator,
};
},
};