/** * @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, }; }, };