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