UNPKG

2.69 kBJavaScriptView Raw
1/**
2 * @fileoverview Require spaces around infix operators
3 * @author Michael Ficarra
4 */
5"use strict";
6
7//------------------------------------------------------------------------------
8// Rule Definition
9//------------------------------------------------------------------------------
10
11module.exports = function(context) {
12
13 var OPERATORS = [
14 "*", "/", "%", "+", "-", "<<", ">>", ">>>", "<", "<=", ">", ">=", "in",
15 "instanceof", "==", "!=", "===", "!==", "&", "^", "|", "&&", "||", "=",
16 "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=", "&=", "^=", "|=",
17 "?", ":", ","
18 ];
19
20 function isSpaced(left, right) {
21 var op, tokens = context.getTokens({range: [left.range[1], right.range[0]]}, 1, 1);
22 for(var i = 1, l = tokens.length - 1; i < l; ++i) {
23 op = tokens[i];
24 if(
25 op.type === "Punctuator" &&
26 OPERATORS.indexOf(op.value) >= 0 &&
27 (tokens[i - 1].range[1] >= op.range[0] || op.range[1] >= tokens[i + 1].range[0])
28 ) {
29 return false;
30 }
31 }
32 return true;
33 }
34
35 function isRightSpaced(left, right) {
36 var op, tokens = context.getTokens({range: [left.range[1], right.range[0]]}, 1, 1);
37 for(var i = 1, l = tokens.length - 1; i < l; ++i) {
38 op = tokens[i];
39 if(
40 op.type === "Punctuator" &&
41 OPERATORS.indexOf(op.value) >= 0 &&
42 op.range[1] >= tokens[i + 1].range[0]
43 ) {
44 return false;
45 }
46 }
47 return true;
48 }
49
50 function report(node) {
51 context.report(node, "Infix operators must be spaced.");
52 }
53
54 function checkBinary(node) {
55 if(!isSpaced(node.left, node.right)) { report(node); }
56 }
57
58 function checkSequence(node) {
59 for(var i = 0, l = node.expressions.length - 1; i < l; ++i) {
60 if(!isRightSpaced(node.expressions[i], node.expressions[i + 1])) {
61 report(node);
62 break;
63 }
64 }
65 }
66
67 function checkConditional(node) {
68 if(!isSpaced(node.test, node.consequent) || !isSpaced(node.consequent, node.alternate)) {
69 report(node);
70 }
71 }
72
73 function checkVar(node) {
74 if(node.init && !isSpaced(node.id, node.init)) {
75 report(node);
76 }
77 }
78
79 return {
80 "AssignmentExpression": checkBinary,
81 "BinaryExpression": checkBinary,
82 "LogicalExpression": checkBinary,
83 "ConditionalExpression": checkConditional,
84 "SequenceExpression": checkSequence,
85 "VariableDeclarator": checkVar
86 };
87
88};