eslint 1.7.3 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/conf/eslint.json +2 -0
- package/lib/cli-engine.js +80 -13
- package/lib/cli.js +12 -10
- package/lib/eslint.js +14 -14
- package/lib/logging.js +25 -0
- package/lib/options.js +7 -2
- package/lib/rules/array-bracket-spacing.js +2 -2
- package/lib/rules/arrow-body-style.js +71 -0
- package/lib/rules/comma-spacing.js +72 -36
- package/lib/rules/eol-last.js +10 -4
- package/lib/rules/no-arrow-condition.js +88 -0
- package/lib/rules/no-multiple-empty-lines.js +39 -13
- package/lib/rules/no-plusplus.js +22 -1
- package/lib/rules/no-shadow.js +21 -3
- package/lib/rules/space-in-parens.js +145 -200
- package/lib/rules/valid-jsdoc.js +35 -18
- package/lib/testers/rule-tester.js +62 -7
- package/lib/util/source-code.js +6 -0
- package/package.json +1 -1
@@ -13,13 +13,15 @@
|
|
13
13
|
module.exports = function(context) {
|
14
14
|
|
15
15
|
// Use options.max or 2 as default
|
16
|
-
var
|
16
|
+
var max = 2,
|
17
|
+
maxEOF;
|
17
18
|
|
18
19
|
// store lines that appear empty but really aren't
|
19
20
|
var notEmpty = [];
|
20
21
|
|
21
22
|
if (context.options.length) {
|
22
|
-
|
23
|
+
max = context.options[0].max;
|
24
|
+
maxEOF = context.options[0].maxEOF;
|
23
25
|
}
|
24
26
|
|
25
27
|
//--------------------------------------------------------------------------
|
@@ -45,17 +47,28 @@ module.exports = function(context) {
|
|
45
47
|
location,
|
46
48
|
trimmedLines = lines.map(function(str) {
|
47
49
|
return str.trim();
|
48
|
-
})
|
50
|
+
}),
|
51
|
+
firstOfEndingBlankLines;
|
49
52
|
|
50
53
|
// add the notEmpty lines in there with a placeholder
|
51
54
|
notEmpty.forEach(function(x, i) {
|
52
55
|
trimmedLines[i] = x;
|
53
56
|
});
|
54
57
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
58
|
+
if (typeof maxEOF === "undefined") {
|
59
|
+
// swallow the final newline, as some editors add it
|
60
|
+
// automatically and we don't want it to cause an issue
|
61
|
+
if (trimmedLines[trimmedLines.length - 1] === "") {
|
62
|
+
trimmedLines = trimmedLines.slice(0, -1);
|
63
|
+
}
|
64
|
+
firstOfEndingBlankLines = trimmedLines.length;
|
65
|
+
} else {
|
66
|
+
// save the number of the first of the last blank lines
|
67
|
+
firstOfEndingBlankLines = trimmedLines.length;
|
68
|
+
while (trimmedLines[firstOfEndingBlankLines - 1] === ""
|
69
|
+
&& firstOfEndingBlankLines > 0) {
|
70
|
+
firstOfEndingBlankLines--;
|
71
|
+
}
|
59
72
|
}
|
60
73
|
|
61
74
|
// Aggregate and count blank lines
|
@@ -67,12 +80,22 @@ module.exports = function(context) {
|
|
67
80
|
if (lastLocation === currentLocation - 1) {
|
68
81
|
blankCounter++;
|
69
82
|
} else {
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
83
|
+
location = {
|
84
|
+
line: lastLocation + 1,
|
85
|
+
column: 1
|
86
|
+
};
|
87
|
+
if (lastLocation < firstOfEndingBlankLines) {
|
88
|
+
// within the file, not at the end
|
89
|
+
if (blankCounter >= max) {
|
90
|
+
context.report(node, location,
|
91
|
+
"Multiple blank lines not allowed.");
|
92
|
+
}
|
93
|
+
} else {
|
94
|
+
// inside the last blank lines
|
95
|
+
if (blankCounter >= maxEOF) {
|
96
|
+
context.report(node, location,
|
97
|
+
"Too many blank lines at the end of file.");
|
98
|
+
}
|
76
99
|
}
|
77
100
|
|
78
101
|
// Finally, reset the blank counter
|
@@ -90,6 +113,9 @@ module.exports.schema = [
|
|
90
113
|
"properties": {
|
91
114
|
"max": {
|
92
115
|
"type": "integer"
|
116
|
+
},
|
117
|
+
"maxEOF": {
|
118
|
+
"type": "integer"
|
93
119
|
}
|
94
120
|
},
|
95
121
|
"required": ["max"],
|
package/lib/rules/no-plusplus.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* @fileoverview Rule to flag use of unary increment and decrement operators.
|
3
3
|
* @author Ian Christian Myers
|
4
|
+
* @author Brody McKee (github.com/mrmckeb)
|
4
5
|
*/
|
5
6
|
|
6
7
|
"use strict";
|
@@ -11,9 +12,19 @@
|
|
11
12
|
|
12
13
|
module.exports = function(context) {
|
13
14
|
|
15
|
+
var config = context.options[0],
|
16
|
+
allowInForAfterthought = false;
|
17
|
+
|
18
|
+
if (typeof config === "object") {
|
19
|
+
allowInForAfterthought = config.allowForLoopAfterthoughts === true;
|
20
|
+
}
|
21
|
+
|
14
22
|
return {
|
15
23
|
|
16
24
|
"UpdateExpression": function(node) {
|
25
|
+
if (allowInForAfterthought && node.parent.type === "ForStatement") {
|
26
|
+
return;
|
27
|
+
}
|
17
28
|
context.report(node, "Unary operator '" + node.operator + "' used.");
|
18
29
|
}
|
19
30
|
|
@@ -21,4 +32,14 @@ module.exports = function(context) {
|
|
21
32
|
|
22
33
|
};
|
23
34
|
|
24
|
-
module.exports.schema = [
|
35
|
+
module.exports.schema = [
|
36
|
+
{
|
37
|
+
"type": "object",
|
38
|
+
"properties": {
|
39
|
+
"allowForLoopAfterthoughts": {
|
40
|
+
"type": "boolean"
|
41
|
+
}
|
42
|
+
},
|
43
|
+
"additionalProperties": false
|
44
|
+
}
|
45
|
+
];
|
package/lib/rules/no-shadow.js
CHANGED
@@ -14,9 +14,20 @@ module.exports = function(context) {
|
|
14
14
|
|
15
15
|
var options = {
|
16
16
|
builtinGlobals: Boolean(context.options[0] && context.options[0].builtinGlobals),
|
17
|
-
hoist: (context.options[0] && context.options[0].hoist) || "functions"
|
17
|
+
hoist: (context.options[0] && context.options[0].hoist) || "functions",
|
18
|
+
allow: (context.options[0] && context.options[0].allow) || []
|
18
19
|
};
|
19
20
|
|
21
|
+
/**
|
22
|
+
* Check if variable name is allowed.
|
23
|
+
*
|
24
|
+
* @param {ASTNode} variable The variable to check.
|
25
|
+
* @returns {boolean} Whether or not the variable name is allowed.
|
26
|
+
*/
|
27
|
+
function isAllowed(variable) {
|
28
|
+
return options.allow.indexOf(variable.name) !== -1;
|
29
|
+
}
|
30
|
+
|
20
31
|
/**
|
21
32
|
* Checks if a variable of the class name in the class scope of ClassDeclaration.
|
22
33
|
*
|
@@ -142,7 +153,8 @@ module.exports = function(context) {
|
|
142
153
|
// Skip "arguments".
|
143
154
|
variable.identifiers.length > 0 &&
|
144
155
|
// Skip variables of a class name in the class scope of ClassDeclaration.
|
145
|
-
!isDuplicatedClassNameVariable(variable)
|
156
|
+
!isDuplicatedClassNameVariable(variable) &&
|
157
|
+
!isAllowed(variable)
|
146
158
|
);
|
147
159
|
});
|
148
160
|
|
@@ -175,7 +187,13 @@ module.exports.schema = [
|
|
175
187
|
"type": "object",
|
176
188
|
"properties": {
|
177
189
|
"builtinGlobals": {"type": "boolean"},
|
178
|
-
"hoist": {"enum": ["all", "functions", "never"]}
|
190
|
+
"hoist": {"enum": ["all", "functions", "never"]},
|
191
|
+
"allow": {
|
192
|
+
"type": "array",
|
193
|
+
"items": {
|
194
|
+
"type": "string"
|
195
|
+
}
|
196
|
+
}
|
179
197
|
},
|
180
198
|
"additionalProperties": false
|
181
199
|
}
|
@@ -6,6 +6,8 @@
|
|
6
6
|
*/
|
7
7
|
"use strict";
|
8
8
|
|
9
|
+
var astUtils = require("../ast-utils");
|
10
|
+
|
9
11
|
//------------------------------------------------------------------------------
|
10
12
|
// Rule Definition
|
11
13
|
//------------------------------------------------------------------------------
|
@@ -14,258 +16,201 @@ module.exports = function(context) {
|
|
14
16
|
|
15
17
|
var MISSING_SPACE_MESSAGE = "There must be a space inside this paren.",
|
16
18
|
REJECTED_SPACE_MESSAGE = "There should be no spaces inside this paren.",
|
17
|
-
|
19
|
+
ALWAYS = context.options[0] === "always",
|
20
|
+
|
21
|
+
exceptionsArrayOptions = (context.options.length === 2) ? context.options[1].exceptions : [],
|
18
22
|
options = {},
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
options.
|
25
|
-
options.
|
26
|
-
options.parenException = exceptionsArray.indexOf("()") !== -1 || false;
|
27
|
-
options.empty = exceptionsArray.indexOf("empty") !== -1 || false;
|
23
|
+
exceptions;
|
24
|
+
|
25
|
+
if (exceptionsArrayOptions.length) {
|
26
|
+
options.braceException = exceptionsArrayOptions.indexOf("{}") !== -1;
|
27
|
+
options.bracketException = exceptionsArrayOptions.indexOf("[]") !== -1;
|
28
|
+
options.parenException = exceptionsArrayOptions.indexOf("()") !== -1;
|
29
|
+
options.empty = exceptionsArrayOptions.indexOf("empty") !== -1;
|
28
30
|
}
|
29
31
|
|
30
32
|
/**
|
31
|
-
*
|
32
|
-
* two regular expressions to check for missing and rejected spaces.
|
33
|
+
* Produces an object with the opener and closer exception values
|
33
34
|
* @param {Object} opts The exception options
|
34
|
-
* @returns {Object} `
|
35
|
+
* @returns {Object} `openers` and `closers` exception values
|
35
36
|
* @private
|
36
37
|
*/
|
37
|
-
function
|
38
|
-
var
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
rejectedSpaceCheck;
|
44
|
-
|
45
|
-
// Populate openers and closers
|
46
|
-
if (opts.braceException) {
|
47
|
-
missingSpaceOpeners.push("\\{");
|
48
|
-
missingSpaceClosers.push("\\}");
|
49
|
-
rejectedSpaceOpeners.push("\\{");
|
50
|
-
rejectedSpaceClosers.push("\\}");
|
51
|
-
}
|
52
|
-
if (opts.bracketException) {
|
53
|
-
missingSpaceOpeners.push("\\[");
|
54
|
-
missingSpaceClosers.push("\\]");
|
55
|
-
rejectedSpaceOpeners.push("\\[");
|
56
|
-
rejectedSpaceClosers.push("\\]");
|
57
|
-
}
|
58
|
-
if (opts.parenException) {
|
59
|
-
missingSpaceOpeners.push("\\(");
|
60
|
-
missingSpaceClosers.push("\\)");
|
61
|
-
rejectedSpaceOpeners.push("\\(");
|
62
|
-
rejectedSpaceClosers.push("\\)");
|
63
|
-
}
|
64
|
-
if (opts.empty) {
|
65
|
-
missingSpaceOpeners.push("\\)");
|
66
|
-
missingSpaceClosers.push("\\(");
|
67
|
-
rejectedSpaceOpeners.push("\\)");
|
68
|
-
rejectedSpaceClosers.push("\\(");
|
38
|
+
function getExceptions() {
|
39
|
+
var openers = [],
|
40
|
+
closers = [];
|
41
|
+
if (options.braceException) {
|
42
|
+
openers.push("{");
|
43
|
+
closers.push("}");
|
69
44
|
}
|
70
45
|
|
71
|
-
if (
|
72
|
-
|
73
|
-
|
74
|
-
missingSpaceCheck += "|";
|
75
|
-
}
|
46
|
+
if (options.bracketException) {
|
47
|
+
openers.push("[");
|
48
|
+
closers.push("]");
|
76
49
|
}
|
77
|
-
if (missingSpaceClosers.length) {
|
78
|
-
missingSpaceCheck += "(" + missingSpaceClosers.join("|") + ")\\)";
|
79
|
-
}
|
80
|
-
|
81
|
-
// compose the rejected regexp
|
82
|
-
rejectedSpaceCheck = "\\( +[^" + rejectedSpaceOpeners.join("") + "]";
|
83
|
-
rejectedSpaceCheck += "|[^" + rejectedSpaceClosers.join("") + "] +\\)";
|
84
50
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
// e.g. \( +[^ \n\r\{]|[^ \n\r\}] +\) --- where {} is an exception
|
89
|
-
rejectedSpace: rejectedSpaceCheck
|
90
|
-
};
|
91
|
-
}
|
92
|
-
|
93
|
-
/**
|
94
|
-
* Used with the `always` option to produce, given the exception options,
|
95
|
-
* two regular expressions to check for missing and rejected spaces.
|
96
|
-
* @param {Object} opts The exception options
|
97
|
-
* @returns {Object} `missingSpace` and `rejectedSpace` regular expressions
|
98
|
-
* @private
|
99
|
-
*/
|
100
|
-
function getAlwaysChecks(opts) {
|
101
|
-
var missingSpaceOpeners = ["\\s", "\\)"],
|
102
|
-
missingSpaceClosers = ["\\s", "\\("],
|
103
|
-
rejectedSpaceOpeners = [],
|
104
|
-
rejectedSpaceClosers = [],
|
105
|
-
missingSpaceCheck,
|
106
|
-
rejectedSpaceCheck;
|
107
|
-
|
108
|
-
// Populate openers and closers
|
109
|
-
if (opts.braceException) {
|
110
|
-
missingSpaceOpeners.push("\\{");
|
111
|
-
missingSpaceClosers.push("\\}");
|
112
|
-
rejectedSpaceOpeners.push(" \\{");
|
113
|
-
rejectedSpaceClosers.push("\\} ");
|
114
|
-
}
|
115
|
-
if (opts.bracketException) {
|
116
|
-
missingSpaceOpeners.push("\\[");
|
117
|
-
missingSpaceClosers.push("\\]");
|
118
|
-
rejectedSpaceOpeners.push(" \\[");
|
119
|
-
rejectedSpaceClosers.push("\\] ");
|
51
|
+
if (options.parenException) {
|
52
|
+
openers.push("(");
|
53
|
+
closers.push(")");
|
120
54
|
}
|
121
|
-
if (opts.parenException) {
|
122
|
-
missingSpaceOpeners.push("\\(");
|
123
|
-
missingSpaceClosers.push("\\)");
|
124
|
-
rejectedSpaceOpeners.push(" \\(");
|
125
|
-
rejectedSpaceClosers.push("\\) ");
|
126
|
-
}
|
127
|
-
if (opts.empty) {
|
128
|
-
rejectedSpaceOpeners.push(" \\)");
|
129
|
-
rejectedSpaceClosers.push("\\( ");
|
130
|
-
}
|
131
|
-
|
132
|
-
// compose the allowed regexp
|
133
|
-
missingSpaceCheck = "\\([^" + missingSpaceOpeners.join("") + "]";
|
134
|
-
missingSpaceCheck += "|[^" + missingSpaceClosers.join("") + "]\\)";
|
135
55
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
if (rejectedSpaceClosers.length) {
|
140
|
-
rejectedSpaceCheck += "|";
|
141
|
-
}
|
142
|
-
}
|
143
|
-
if (rejectedSpaceClosers.length) {
|
144
|
-
rejectedSpaceCheck += "(" + rejectedSpaceClosers.join("|") + ")\\)";
|
56
|
+
if (options.empty) {
|
57
|
+
openers.push(")");
|
58
|
+
closers.push("(");
|
145
59
|
}
|
146
60
|
|
147
61
|
return {
|
148
|
-
|
149
|
-
|
150
|
-
// e.g. \(( \{})|(\} )\) --- where {} is an excpetion
|
151
|
-
rejectedSpace: rejectedSpaceCheck || ".^"
|
62
|
+
openers: openers,
|
63
|
+
closers: closers
|
152
64
|
};
|
153
65
|
}
|
154
66
|
|
155
|
-
spaceChecks = (context.options[0] === "always") ? getAlwaysChecks(options) : getNeverChecks(options);
|
156
|
-
missingSpaceRegExp = new RegExp(spaceChecks.missingSpace, "mg");
|
157
|
-
rejectedSpaceRegExp = new RegExp(spaceChecks.rejectedSpace, "mg");
|
158
|
-
|
159
|
-
|
160
67
|
//--------------------------------------------------------------------------
|
161
68
|
// Helpers
|
162
69
|
//--------------------------------------------------------------------------
|
163
|
-
|
164
|
-
var skipRanges = [];
|
70
|
+
var sourceCode = context.getSourceCode();
|
165
71
|
|
166
72
|
/**
|
167
|
-
*
|
168
|
-
* @param {
|
169
|
-
* @returns {
|
170
|
-
* @private
|
73
|
+
* Determines if a token is one of the exceptions for the opener paren
|
74
|
+
* @param {Object} token The token to check
|
75
|
+
* @returns {boolean} True if the token is one of the exceptions for the opener paren
|
171
76
|
*/
|
172
|
-
function
|
173
|
-
|
77
|
+
function isOpenerException(token) {
|
78
|
+
return token.type === "Punctuator" && exceptions.openers.indexOf(token.value) >= 0;
|
174
79
|
}
|
175
80
|
|
176
81
|
/**
|
177
|
-
*
|
178
|
-
* @
|
179
|
-
* @
|
82
|
+
* Determines if a token is one of the exceptions for the closer paren
|
83
|
+
* @param {Object} token The token to check
|
84
|
+
* @returns {boolean} True if the token is one of the exceptions for the closer paren
|
180
85
|
*/
|
181
|
-
function
|
182
|
-
|
183
|
-
return a[0] - b[0];
|
184
|
-
});
|
86
|
+
function isCloserException(token) {
|
87
|
+
return token.type === "Punctuator" && exceptions.closers.indexOf(token.value) >= 0;
|
185
88
|
}
|
186
89
|
|
187
90
|
/**
|
188
|
-
*
|
189
|
-
* @param {
|
190
|
-
* @
|
191
|
-
* @
|
91
|
+
* Determines if an opener paren should have a missing space after it
|
92
|
+
* @param {Object} left The paren token
|
93
|
+
* @param {Object} right The token after it
|
94
|
+
* @returns {boolean} True if the paren should have a space
|
192
95
|
*/
|
193
|
-
function
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
return
|
96
|
+
function shouldOpenerHaveSpace(left, right) {
|
97
|
+
if (sourceCode.isSpaceBetweenTokens(left, right)) {
|
98
|
+
return false;
|
99
|
+
}
|
100
|
+
|
101
|
+
if (ALWAYS) {
|
102
|
+
if (right.type === "Punctuator" && right.value === ")") {
|
103
|
+
return false;
|
201
104
|
}
|
105
|
+
return !isOpenerException(right);
|
106
|
+
} else {
|
107
|
+
return isOpenerException(right);
|
202
108
|
}
|
203
|
-
return false;
|
204
109
|
}
|
205
110
|
|
111
|
+
/**
|
112
|
+
* Determines if an closer paren should have a missing space after it
|
113
|
+
* @param {Object} left The token before the paren
|
114
|
+
* @param {Object} right The paren token
|
115
|
+
* @returns {boolean} True if the paren should have a space
|
116
|
+
*/
|
117
|
+
function shouldCloserHaveSpace(left, right) {
|
118
|
+
if (left.type === "Punctuator" && left.value === "(") {
|
119
|
+
return false;
|
120
|
+
}
|
206
121
|
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
return {
|
122
|
+
if (sourceCode.isSpaceBetweenTokens(left, right)) {
|
123
|
+
return false;
|
124
|
+
}
|
212
125
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
source = context.getSource(),
|
220
|
-
pos = 0;
|
221
|
-
|
222
|
-
/**
|
223
|
-
* Check the match
|
224
|
-
* @param {object} match Object to match
|
225
|
-
* @param {string} message Message to report
|
226
|
-
* @returns {void}
|
227
|
-
* @private
|
228
|
-
*/
|
229
|
-
function checkMatch(match, message) {
|
230
|
-
if (source.charAt(match.index) !== "(") {
|
231
|
-
// Matched a closing paren pattern
|
232
|
-
match.index += 1;
|
233
|
-
}
|
126
|
+
if (ALWAYS) {
|
127
|
+
return !isCloserException(left);
|
128
|
+
} else {
|
129
|
+
return isCloserException(left);
|
130
|
+
}
|
131
|
+
}
|
234
132
|
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
133
|
+
/**
|
134
|
+
* Determines if an opener paren should not have an existing space after it
|
135
|
+
* @param {Object} left The paren token
|
136
|
+
* @param {Object} right The token after it
|
137
|
+
* @returns {boolean} True if the paren should reject the space
|
138
|
+
*/
|
139
|
+
function shouldOpenerRejectSpace(left, right) {
|
140
|
+
if (!astUtils.isTokenOnSameLine(left, right)) {
|
141
|
+
return false;
|
142
|
+
}
|
241
143
|
|
242
|
-
|
243
|
-
|
244
|
-
|
144
|
+
if (!sourceCode.isSpaceBetweenTokens(left, right)) {
|
145
|
+
return false;
|
146
|
+
}
|
245
147
|
|
246
|
-
|
148
|
+
if (ALWAYS) {
|
149
|
+
return isOpenerException(right);
|
150
|
+
} else {
|
151
|
+
return !isOpenerException(right);
|
152
|
+
}
|
153
|
+
}
|
247
154
|
|
248
|
-
|
249
|
-
|
250
|
-
|
155
|
+
/**
|
156
|
+
* Determines if an closer paren should not have an existing space after it
|
157
|
+
* @param {Object} left The token before the paren
|
158
|
+
* @param {Object} right The paren token
|
159
|
+
* @returns {boolean} True if the paren should reject the space
|
160
|
+
*/
|
161
|
+
function shouldCloserRejectSpace(left, right) {
|
162
|
+
if (left.type === "Punctuator" && left.value === "(") {
|
163
|
+
return false;
|
164
|
+
}
|
251
165
|
|
252
|
-
|
253
|
-
|
254
|
-
|
166
|
+
if (!astUtils.isTokenOnSameLine(left, right)) {
|
167
|
+
return false;
|
168
|
+
}
|
255
169
|
|
256
|
-
|
170
|
+
if (!sourceCode.isSpaceBetweenTokens(left, right)) {
|
171
|
+
return false;
|
172
|
+
}
|
257
173
|
|
174
|
+
if (ALWAYS) {
|
175
|
+
return isCloserException(left);
|
176
|
+
} else {
|
177
|
+
return !isCloserException(left);
|
178
|
+
}
|
179
|
+
}
|
258
180
|
|
259
|
-
|
181
|
+
//--------------------------------------------------------------------------
|
182
|
+
// Public
|
183
|
+
//--------------------------------------------------------------------------
|
260
184
|
|
261
|
-
|
185
|
+
return {
|
186
|
+
"Program": function checkParenSpaces(node) {
|
187
|
+
var tokens = node.tokens;
|
188
|
+
var prevToken, nextToken;
|
189
|
+
exceptions = getExceptions();
|
262
190
|
|
263
|
-
|
191
|
+
tokens.forEach(function(token, i) {
|
192
|
+
prevToken = tokens[i - 1];
|
193
|
+
nextToken = tokens[i + 1];
|
264
194
|
|
265
|
-
|
195
|
+
if (token.type !== "Punctuator") {
|
196
|
+
return;
|
197
|
+
}
|
266
198
|
|
267
|
-
|
199
|
+
if (token.value !== "(" && token.value !== ")") {
|
200
|
+
return;
|
201
|
+
}
|
268
202
|
|
203
|
+
if (token.value === "(" && shouldOpenerHaveSpace(token, nextToken)) {
|
204
|
+
context.report(node, token.loc.end, MISSING_SPACE_MESSAGE);
|
205
|
+
} else if (token.value === "(" && shouldOpenerRejectSpace(token, nextToken)) {
|
206
|
+
context.report(node, token.loc.end, REJECTED_SPACE_MESSAGE);
|
207
|
+
} else if (token.value === ")" && shouldCloserHaveSpace(prevToken, token)) {
|
208
|
+
context.report(node, token.loc.end, MISSING_SPACE_MESSAGE);
|
209
|
+
} else if (token.value === ")" && shouldCloserRejectSpace(prevToken, token)) {
|
210
|
+
context.report(node, token.loc.end, REJECTED_SPACE_MESSAGE);
|
211
|
+
}
|
212
|
+
});
|
213
|
+
}
|
269
214
|
};
|
270
215
|
|
271
216
|
};
|