]>
Commit | Line | Data |
---|---|---|
eb39fafa DC |
1 | /** |
2 | * @fileoverview Rule to flag bitwise identifiers | |
3 | * @author Nicholas C. Zakas | |
4 | */ | |
5 | ||
6 | "use strict"; | |
7 | ||
8 | /* | |
9 | * | |
10 | * Set of bitwise operators. | |
11 | * | |
12 | */ | |
13 | const BITWISE_OPERATORS = [ | |
14 | "^", "|", "&", "<<", ">>", ">>>", | |
15 | "^=", "|=", "&=", "<<=", ">>=", ">>>=", | |
16 | "~" | |
17 | ]; | |
18 | ||
19 | //------------------------------------------------------------------------------ | |
20 | // Rule Definition | |
21 | //------------------------------------------------------------------------------ | |
22 | ||
23 | module.exports = { | |
24 | meta: { | |
25 | type: "suggestion", | |
26 | ||
27 | docs: { | |
28 | description: "disallow bitwise operators", | |
29 | category: "Stylistic Issues", | |
30 | recommended: false, | |
31 | url: "https://eslint.org/docs/rules/no-bitwise" | |
32 | }, | |
33 | ||
34 | schema: [ | |
35 | { | |
36 | type: "object", | |
37 | properties: { | |
38 | allow: { | |
39 | type: "array", | |
40 | items: { | |
41 | enum: BITWISE_OPERATORS | |
42 | }, | |
43 | uniqueItems: true | |
44 | }, | |
45 | int32Hint: { | |
46 | type: "boolean", | |
47 | default: false | |
48 | } | |
49 | }, | |
50 | additionalProperties: false | |
51 | } | |
52 | ], | |
53 | ||
54 | messages: { | |
55 | unexpected: "Unexpected use of '{{operator}}'." | |
56 | } | |
57 | }, | |
58 | ||
59 | create(context) { | |
60 | const options = context.options[0] || {}; | |
61 | const allowed = options.allow || []; | |
62 | const int32Hint = options.int32Hint === true; | |
63 | ||
64 | /** | |
65 | * Reports an unexpected use of a bitwise operator. | |
66 | * @param {ASTNode} node Node which contains the bitwise operator. | |
67 | * @returns {void} | |
68 | */ | |
69 | function report(node) { | |
70 | context.report({ node, messageId: "unexpected", data: { operator: node.operator } }); | |
71 | } | |
72 | ||
73 | /** | |
74 | * Checks if the given node has a bitwise operator. | |
75 | * @param {ASTNode} node The node to check. | |
76 | * @returns {boolean} Whether or not the node has a bitwise operator. | |
77 | */ | |
78 | function hasBitwiseOperator(node) { | |
79 | return BITWISE_OPERATORS.indexOf(node.operator) !== -1; | |
80 | } | |
81 | ||
82 | /** | |
83 | * Checks if exceptions were provided, e.g. `{ allow: ['~', '|'] }`. | |
84 | * @param {ASTNode} node The node to check. | |
85 | * @returns {boolean} Whether or not the node has a bitwise operator. | |
86 | */ | |
87 | function allowedOperator(node) { | |
88 | return allowed.indexOf(node.operator) !== -1; | |
89 | } | |
90 | ||
91 | /** | |
92 | * Checks if the given bitwise operator is used for integer typecasting, i.e. "|0" | |
93 | * @param {ASTNode} node The node to check. | |
94 | * @returns {boolean} whether the node is used in integer typecasting. | |
95 | */ | |
96 | function isInt32Hint(node) { | |
97 | return int32Hint && node.operator === "|" && node.right && | |
98 | node.right.type === "Literal" && node.right.value === 0; | |
99 | } | |
100 | ||
101 | /** | |
102 | * Report if the given node contains a bitwise operator. | |
103 | * @param {ASTNode} node The node to check. | |
104 | * @returns {void} | |
105 | */ | |
106 | function checkNodeForBitwiseOperator(node) { | |
107 | if (hasBitwiseOperator(node) && !allowedOperator(node) && !isInt32Hint(node)) { | |
108 | report(node); | |
109 | } | |
110 | } | |
111 | ||
112 | return { | |
113 | AssignmentExpression: checkNodeForBitwiseOperator, | |
114 | BinaryExpression: checkNodeForBitwiseOperator, | |
115 | UnaryExpression: checkNodeForBitwiseOperator | |
116 | }; | |
117 | ||
118 | } | |
119 | }; |