UNPKG

2.13 kBJavaScriptView Raw
1const {docsUrl} = require('../utilities');
2
3const MESSAGES = {
4 always: 'You must include parentheses around a binary assignment expression.',
5 never:
6 'You must not include parentheses around a binary assignment expression.',
7};
8
9const BOOLEAN_OPERATORS = ['==', '===', '!=', '!==', '>', '>=', '<', '<='];
10
11module.exports = {
12 meta: {
13 docs: {
14 description:
15 'Enforce (or disallow) assignments of binary, boolean-producing expressions to be wrapped in parentheses.',
16 category: 'Best Practices',
17 recommended: false,
18 uri: docsUrl('binary-assignment-parens'),
19 },
20
21 schema: [
22 {
23 enum: ['always', 'never'],
24 },
25 ],
26 },
27
28 create(context) {
29 const config = context.options[0] || 'always';
30 const shouldHaveParens = config === 'always';
31
32 function hasParens(node) {
33 const beforeToken = context.getTokenBefore(node);
34 const hasBeforeParen =
35 beforeToken &&
36 beforeToken.type === 'Punctuator' &&
37 beforeToken.value === '(';
38 const afterToken = context.getTokenAfter(node);
39 const hasAfterParen =
40 afterToken &&
41 afterToken.type === 'Punctuator' &&
42 afterToken.value === ')';
43
44 return hasBeforeParen && hasAfterParen;
45 }
46
47 function evaluateBinaryExpression(node) {
48 if (BOOLEAN_OPERATORS.indexOf(node.operator) < 0) {
49 return;
50 }
51
52 if (shouldHaveParens !== hasParens(node)) {
53 context.report(node, MESSAGES[config]);
54 }
55 }
56
57 function evaluateLogicalExpression(node) {
58 [node.left, node.right].forEach(evaluateAssignmentExpression);
59 }
60
61 function evaluateAssignmentExpression(node) {
62 if (!node) {
63 return;
64 }
65
66 if (node.type === 'BinaryExpression') {
67 evaluateBinaryExpression(node);
68 }
69 if (node.type === 'LogicalExpression') {
70 evaluateLogicalExpression(node);
71 }
72 }
73
74 return {
75 VariableDeclarator(node) {
76 evaluateAssignmentExpression(node.init);
77 },
78
79 AssignmentExpression(node) {
80 evaluateAssignmentExpression(node.right);
81 },
82 };
83 },
84};