eslint 0.22.0 → 0.24.1
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/LICENSE +20 -20
- package/README.md +111 -95
- package/bin/eslint.js +41 -41
- package/conf/environments.js +87 -81
- package/conf/eslint.json +186 -179
- package/lib/api.js +13 -12
- package/lib/cli-engine.js +441 -451
- package/lib/cli.js +196 -196
- package/lib/config-initializer.js +145 -145
- package/lib/config-validator.js +110 -110
- package/lib/config.js +428 -416
- package/lib/eslint.js +1072 -1073
- package/lib/file-finder.js +167 -167
- package/lib/formatters/checkstyle.js +68 -68
- package/lib/formatters/compact.js +53 -53
- package/lib/formatters/jslint-xml.js +40 -40
- package/lib/formatters/junit.js +63 -63
- package/lib/formatters/stylish.js +90 -90
- package/lib/formatters/tap.js +86 -86
- package/lib/ignored-paths.js +137 -137
- package/lib/load-rules.js +39 -39
- package/lib/options.js +132 -126
- package/lib/rule-context.js +107 -107
- package/lib/rules/accessor-pairs.js +65 -65
- package/lib/rules/array-bracket-spacing.js +180 -0
- package/lib/rules/block-scoped-var.js +339 -320
- package/lib/rules/brace-style.js +228 -228
- package/lib/rules/camelcase.js +111 -111
- package/lib/rules/comma-dangle.js +67 -64
- package/lib/rules/comma-spacing.js +191 -191
- package/lib/rules/comma-style.js +195 -195
- package/lib/rules/complexity.js +94 -94
- package/lib/rules/computed-property-spacing.js +144 -0
- package/lib/rules/consistent-return.js +75 -75
- package/lib/rules/consistent-this.js +119 -119
- package/lib/rules/constructor-super.js +108 -0
- package/lib/rules/curly.js +109 -109
- package/lib/rules/default-case.js +66 -66
- package/lib/rules/dot-location.js +63 -63
- package/lib/rules/dot-notation.js +119 -119
- package/lib/rules/eol-last.js +38 -38
- package/lib/rules/eqeqeq.js +96 -96
- package/lib/rules/func-names.js +45 -45
- package/lib/rules/func-style.js +49 -49
- package/lib/rules/generator-star-spacing.js +104 -87
- package/lib/rules/generator-star.js +76 -76
- package/lib/rules/global-strict.js +49 -49
- package/lib/rules/guard-for-in.js +32 -32
- package/lib/rules/handle-callback-err.js +81 -124
- package/lib/rules/indent.js +486 -486
- package/lib/rules/key-spacing.js +325 -325
- package/lib/rules/linebreak-style.js +44 -44
- package/lib/rules/lines-around-comment.js +228 -160
- package/lib/rules/max-depth.js +89 -89
- package/lib/rules/max-len.js +76 -76
- package/lib/rules/max-nested-callbacks.js +73 -73
- package/lib/rules/max-params.js +45 -45
- package/lib/rules/max-statements.js +61 -61
- package/lib/rules/new-cap.js +224 -224
- package/lib/rules/new-parens.js +29 -29
- package/lib/rules/newline-after-var.js +127 -127
- package/lib/rules/no-alert.js +153 -153
- package/lib/rules/no-array-constructor.js +31 -31
- package/lib/rules/no-bitwise.js +57 -57
- package/lib/rules/no-caller.js +29 -29
- package/lib/rules/no-catch-shadow.js +52 -52
- package/lib/rules/no-comma-dangle.js +45 -45
- package/lib/rules/no-cond-assign.js +123 -123
- package/lib/rules/no-console.js +27 -27
- package/lib/rules/no-constant-condition.js +73 -73
- package/lib/rules/no-continue.js +23 -23
- package/lib/rules/no-control-regex.js +58 -58
- package/lib/rules/no-debugger.js +22 -22
- package/lib/rules/no-delete-var.js +25 -25
- package/lib/rules/no-div-regex.js +27 -27
- package/lib/rules/no-dupe-args.js +89 -85
- package/lib/rules/no-dupe-keys.js +43 -43
- package/lib/rules/no-duplicate-case.js +67 -67
- package/lib/rules/no-else-return.js +125 -125
- package/lib/rules/no-empty-character-class.js +43 -43
- package/lib/rules/no-empty-class.js +45 -45
- package/lib/rules/no-empty-label.js +27 -27
- package/lib/rules/no-empty.js +49 -49
- package/lib/rules/no-eq-null.js +29 -29
- package/lib/rules/no-eval.js +26 -26
- package/lib/rules/no-ex-assign.js +42 -42
- package/lib/rules/no-extend-native.js +103 -103
- package/lib/rules/no-extra-bind.js +81 -81
- package/lib/rules/no-extra-boolean-cast.js +71 -71
- package/lib/rules/no-extra-parens.js +368 -355
- package/lib/rules/no-extra-semi.js +70 -23
- package/lib/rules/no-extra-strict.js +86 -86
- package/lib/rules/no-fallthrough.js +97 -97
- package/lib/rules/no-floating-decimal.js +30 -30
- package/lib/rules/no-func-assign.js +83 -83
- package/lib/rules/no-implied-eval.js +76 -76
- package/lib/rules/no-inline-comments.js +49 -49
- package/lib/rules/no-inner-declarations.js +78 -78
- package/lib/rules/no-invalid-regexp.js +53 -53
- package/lib/rules/no-irregular-whitespace.js +135 -135
- package/lib/rules/no-iterator.js +28 -28
- package/lib/rules/no-label-var.js +64 -64
- package/lib/rules/no-labels.js +44 -44
- package/lib/rules/no-lone-blocks.js +106 -27
- package/lib/rules/no-lonely-if.js +30 -30
- package/lib/rules/no-loop-func.js +58 -58
- package/lib/rules/no-mixed-requires.js +165 -165
- package/lib/rules/no-mixed-spaces-and-tabs.js +74 -74
- package/lib/rules/no-multi-spaces.js +119 -119
- package/lib/rules/no-multi-str.js +43 -43
- package/lib/rules/no-multiple-empty-lines.js +98 -98
- package/lib/rules/no-native-reassign.js +62 -62
- package/lib/rules/no-negated-in-lhs.js +25 -25
- package/lib/rules/no-nested-ternary.js +24 -24
- package/lib/rules/no-new-func.js +25 -25
- package/lib/rules/no-new-object.js +25 -25
- package/lib/rules/no-new-require.js +25 -25
- package/lib/rules/no-new-wrappers.js +26 -26
- package/lib/rules/no-new.js +27 -27
- package/lib/rules/no-obj-calls.js +28 -28
- package/lib/rules/no-octal-escape.js +39 -39
- package/lib/rules/no-octal.js +25 -25
- package/lib/rules/no-param-reassign.js +87 -87
- package/lib/rules/no-path-concat.js +39 -39
- package/lib/rules/no-plusplus.js +24 -24
- package/lib/rules/no-process-env.js +30 -30
- package/lib/rules/no-process-exit.js +33 -33
- package/lib/rules/no-proto.js +28 -28
- package/lib/rules/no-redeclare.js +68 -68
- package/lib/rules/no-regex-spaces.js +35 -35
- package/lib/rules/no-reserved-keys.js +56 -56
- package/lib/rules/no-restricted-modules.js +85 -85
- package/lib/rules/no-return-assign.js +53 -24
- package/lib/rules/no-script-url.js +34 -34
- package/lib/rules/no-self-compare.js +29 -29
- package/lib/rules/no-sequences.js +94 -94
- package/lib/rules/no-shadow-restricted-names.js +51 -51
- package/lib/rules/no-shadow.js +181 -136
- package/lib/rules/no-space-before-semi.js +98 -98
- package/lib/rules/no-spaced-func.js +37 -37
- package/lib/rules/no-sparse-arrays.js +33 -33
- package/lib/rules/no-sync.js +30 -30
- package/lib/rules/no-ternary.js +24 -24
- package/lib/rules/no-this-before-super.js +144 -0
- package/lib/rules/no-throw-literal.js +33 -33
- package/lib/rules/no-trailing-spaces.js +74 -63
- package/lib/rules/no-undef-init.js +28 -28
- package/lib/rules/no-undef.js +92 -92
- package/lib/rules/no-undefined.js +27 -27
- package/lib/rules/no-underscore-dangle.js +73 -73
- package/lib/rules/no-unexpected-multiline.js +58 -0
- package/lib/rules/no-unneeded-ternary.js +48 -48
- package/lib/rules/no-unreachable.js +98 -98
- package/lib/rules/no-unused-expressions.js +76 -76
- package/lib/rules/no-unused-vars.js +252 -250
- package/lib/rules/no-use-before-define.js +105 -105
- package/lib/rules/no-var.js +26 -26
- package/lib/rules/no-void.js +28 -28
- package/lib/rules/no-warning-comments.js +102 -102
- package/lib/rules/no-with.js +22 -22
- package/lib/rules/no-wrap-func.js +65 -65
- package/lib/rules/object-curly-spacing.js +231 -206
- package/lib/rules/object-shorthand.js +74 -73
- package/lib/rules/one-var.js +311 -304
- package/lib/rules/operator-assignment.js +118 -118
- package/lib/rules/operator-linebreak.js +114 -114
- package/lib/rules/padded-blocks.js +98 -98
- package/lib/rules/prefer-const.js +91 -0
- package/lib/rules/quote-props.js +72 -72
- package/lib/rules/quotes.js +92 -92
- package/lib/rules/radix.js +41 -41
- package/lib/rules/semi-spacing.js +167 -167
- package/lib/rules/semi.js +136 -136
- package/lib/rules/sort-vars.js +49 -49
- package/lib/rules/space-after-function-name.js +49 -49
- package/lib/rules/space-after-keywords.js +82 -82
- package/lib/rules/space-before-blocks.js +91 -91
- package/lib/rules/space-before-function-paren.js +139 -139
- package/lib/rules/space-before-function-parentheses.js +139 -139
- package/lib/rules/space-in-brackets.js +305 -305
- package/lib/rules/space-in-parens.js +281 -281
- package/lib/rules/space-infix-ops.js +106 -106
- package/lib/rules/space-return-throw-case.js +38 -38
- package/lib/rules/space-unary-ops.js +124 -133
- package/lib/rules/spaced-comment.js +143 -0
- package/lib/rules/spaced-line-comment.js +89 -89
- package/lib/rules/strict.js +242 -242
- package/lib/rules/use-isnan.js +26 -26
- package/lib/rules/valid-jsdoc.js +215 -215
- package/lib/rules/valid-typeof.js +42 -42
- package/lib/rules/vars-on-top.js +115 -115
- package/lib/rules/wrap-iife.js +48 -48
- package/lib/rules/wrap-regex.js +38 -38
- package/lib/rules/yoda.js +242 -225
- package/lib/rules.js +88 -88
- package/lib/timing.js +109 -109
- package/lib/token-store.js +201 -201
- package/lib/util/traverse.js +105 -105
- package/lib/util.js +125 -85
- package/package.json +6 -6
- package/CHANGELOG.md +0 -1638
package/lib/rules/one-var.js
CHANGED
@@ -1,304 +1,311 @@
|
|
1
|
-
/**
|
2
|
-
* @fileoverview A rule to control the use of single variable declarations.
|
3
|
-
* @author Ian Christian Myers
|
4
|
-
* @copyright 2015 Ian VanSchooten. All rights reserved.
|
5
|
-
* @copyright 2015 Joey Baker. All rights reserved.
|
6
|
-
* @copyright 2015 Danny Fritz. All rights reserved.
|
7
|
-
* @copyright 2013 Ian Christian Myers. All rights reserved.
|
8
|
-
*/
|
9
|
-
|
10
|
-
"use strict";
|
11
|
-
|
12
|
-
//------------------------------------------------------------------------------
|
13
|
-
// Rule Definition
|
14
|
-
//------------------------------------------------------------------------------
|
15
|
-
|
16
|
-
module.exports = function(context) {
|
17
|
-
|
18
|
-
var MODE_ALWAYS = "always",
|
19
|
-
MODE_NEVER = "never";
|
20
|
-
|
21
|
-
var mode = context.options[0];
|
22
|
-
|
23
|
-
var options = {
|
24
|
-
};
|
25
|
-
|
26
|
-
if (typeof mode === "string") { // simple options configuration with just a string
|
27
|
-
options.var = { uninitialized: mode, initialized: mode};
|
28
|
-
options.let = { uninitialized: mode, initialized: mode};
|
29
|
-
options.const = { uninitialized: mode, initialized: mode};
|
30
|
-
} else if (typeof mode === "object") { // options configuration is an object
|
31
|
-
if (mode.hasOwnProperty("var") && typeof mode.var === "string") {
|
32
|
-
options.var = { uninitialized: mode.var, initialized: mode.var};
|
33
|
-
}
|
34
|
-
if (mode.hasOwnProperty("let") && typeof mode.let === "string") {
|
35
|
-
options.let = { uninitialized: mode.let, initialized: mode.let};
|
36
|
-
}
|
37
|
-
if (mode.hasOwnProperty("const") && typeof mode.const === "string") {
|
38
|
-
options.const = { uninitialized: mode.const, initialized: mode.const};
|
39
|
-
}
|
40
|
-
if (mode.hasOwnProperty("uninitialized")) {
|
41
|
-
if (!options.var) {
|
42
|
-
options.var = {};
|
43
|
-
}
|
44
|
-
if (!options.let) {
|
45
|
-
options.let = {};
|
46
|
-
}
|
47
|
-
if (!options.const) {
|
48
|
-
options.const = {};
|
49
|
-
}
|
50
|
-
options.var.uninitialized = mode.uninitialized;
|
51
|
-
options.let.uninitialized = mode.uninitialized;
|
52
|
-
options.const.uninitialized = mode.uninitialized;
|
53
|
-
}
|
54
|
-
if (mode.hasOwnProperty("initialized")) {
|
55
|
-
if (!options.var) {
|
56
|
-
options.var = {};
|
57
|
-
}
|
58
|
-
if (!options.let) {
|
59
|
-
options.let = {};
|
60
|
-
}
|
61
|
-
if (!options.const) {
|
62
|
-
options.const = {};
|
63
|
-
}
|
64
|
-
options.var.initialized = mode.initialized;
|
65
|
-
options.let.initialized = mode.initialized;
|
66
|
-
options.const.initialized = mode.initialized;
|
67
|
-
}
|
68
|
-
}
|
69
|
-
|
70
|
-
//--------------------------------------------------------------------------
|
71
|
-
// Helpers
|
72
|
-
//--------------------------------------------------------------------------
|
73
|
-
|
74
|
-
var functionStack = [];
|
75
|
-
var blockStack = [];
|
76
|
-
|
77
|
-
/**
|
78
|
-
* Increments the blockStack counter.
|
79
|
-
* @returns {void}
|
80
|
-
* @private
|
81
|
-
*/
|
82
|
-
function startBlock() {
|
83
|
-
blockStack.push({
|
84
|
-
let: {initialized: false, uninitialized: false},
|
85
|
-
const: {initialized: false, uninitialized: false}
|
86
|
-
});
|
87
|
-
}
|
88
|
-
|
89
|
-
/**
|
90
|
-
* Increments the functionStack counter.
|
91
|
-
* @returns {void}
|
92
|
-
* @private
|
93
|
-
*/
|
94
|
-
function startFunction() {
|
95
|
-
functionStack.push({initialized: false, uninitialized: false});
|
96
|
-
startBlock();
|
97
|
-
}
|
98
|
-
|
99
|
-
/**
|
100
|
-
* Decrements the blockStack counter.
|
101
|
-
* @returns {void}
|
102
|
-
* @private
|
103
|
-
*/
|
104
|
-
function endBlock() {
|
105
|
-
blockStack.pop();
|
106
|
-
}
|
107
|
-
|
108
|
-
/**
|
109
|
-
* Decrements the functionStack counter.
|
110
|
-
* @returns {void}
|
111
|
-
* @private
|
112
|
-
*/
|
113
|
-
function endFunction() {
|
114
|
-
functionStack.pop();
|
115
|
-
endBlock();
|
116
|
-
}
|
117
|
-
|
118
|
-
/**
|
119
|
-
* Records whether initialized or uninitialized variables are defined in current scope.
|
120
|
-
* @param {string} statementType node.kind, one of: "var", "let", or "const"
|
121
|
-
* @param {ASTNode[]} declarations List of declarations
|
122
|
-
* @param {Object} currentScope The scope being investigated
|
123
|
-
* @returns {void}
|
124
|
-
* @private
|
125
|
-
*/
|
126
|
-
function recordTypes(statementType, declarations, currentScope) {
|
127
|
-
for (var i = 0; i < declarations.length; i++) {
|
128
|
-
if (declarations[i].init === null) {
|
129
|
-
if (options[statementType] && options[statementType].uninitialized === MODE_ALWAYS) {
|
130
|
-
currentScope.uninitialized = true;
|
131
|
-
}
|
132
|
-
} else {
|
133
|
-
if (options[statementType] && options[statementType].initialized === MODE_ALWAYS) {
|
134
|
-
currentScope.initialized = true;
|
135
|
-
}
|
136
|
-
}
|
137
|
-
}
|
138
|
-
}
|
139
|
-
|
140
|
-
/**
|
141
|
-
*
|
142
|
-
* @param
|
143
|
-
* @returns {Object}
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
*
|
160
|
-
* @
|
161
|
-
* @
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
"
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
]
|
1
|
+
/**
|
2
|
+
* @fileoverview A rule to control the use of single variable declarations.
|
3
|
+
* @author Ian Christian Myers
|
4
|
+
* @copyright 2015 Ian VanSchooten. All rights reserved.
|
5
|
+
* @copyright 2015 Joey Baker. All rights reserved.
|
6
|
+
* @copyright 2015 Danny Fritz. All rights reserved.
|
7
|
+
* @copyright 2013 Ian Christian Myers. All rights reserved.
|
8
|
+
*/
|
9
|
+
|
10
|
+
"use strict";
|
11
|
+
|
12
|
+
//------------------------------------------------------------------------------
|
13
|
+
// Rule Definition
|
14
|
+
//------------------------------------------------------------------------------
|
15
|
+
|
16
|
+
module.exports = function(context) {
|
17
|
+
|
18
|
+
var MODE_ALWAYS = "always",
|
19
|
+
MODE_NEVER = "never";
|
20
|
+
|
21
|
+
var mode = context.options[0];
|
22
|
+
|
23
|
+
var options = {
|
24
|
+
};
|
25
|
+
|
26
|
+
if (typeof mode === "string") { // simple options configuration with just a string
|
27
|
+
options.var = { uninitialized: mode, initialized: mode};
|
28
|
+
options.let = { uninitialized: mode, initialized: mode};
|
29
|
+
options.const = { uninitialized: mode, initialized: mode};
|
30
|
+
} else if (typeof mode === "object") { // options configuration is an object
|
31
|
+
if (mode.hasOwnProperty("var") && typeof mode.var === "string") {
|
32
|
+
options.var = { uninitialized: mode.var, initialized: mode.var};
|
33
|
+
}
|
34
|
+
if (mode.hasOwnProperty("let") && typeof mode.let === "string") {
|
35
|
+
options.let = { uninitialized: mode.let, initialized: mode.let};
|
36
|
+
}
|
37
|
+
if (mode.hasOwnProperty("const") && typeof mode.const === "string") {
|
38
|
+
options.const = { uninitialized: mode.const, initialized: mode.const};
|
39
|
+
}
|
40
|
+
if (mode.hasOwnProperty("uninitialized")) {
|
41
|
+
if (!options.var) {
|
42
|
+
options.var = {};
|
43
|
+
}
|
44
|
+
if (!options.let) {
|
45
|
+
options.let = {};
|
46
|
+
}
|
47
|
+
if (!options.const) {
|
48
|
+
options.const = {};
|
49
|
+
}
|
50
|
+
options.var.uninitialized = mode.uninitialized;
|
51
|
+
options.let.uninitialized = mode.uninitialized;
|
52
|
+
options.const.uninitialized = mode.uninitialized;
|
53
|
+
}
|
54
|
+
if (mode.hasOwnProperty("initialized")) {
|
55
|
+
if (!options.var) {
|
56
|
+
options.var = {};
|
57
|
+
}
|
58
|
+
if (!options.let) {
|
59
|
+
options.let = {};
|
60
|
+
}
|
61
|
+
if (!options.const) {
|
62
|
+
options.const = {};
|
63
|
+
}
|
64
|
+
options.var.initialized = mode.initialized;
|
65
|
+
options.let.initialized = mode.initialized;
|
66
|
+
options.const.initialized = mode.initialized;
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
//--------------------------------------------------------------------------
|
71
|
+
// Helpers
|
72
|
+
//--------------------------------------------------------------------------
|
73
|
+
|
74
|
+
var functionStack = [];
|
75
|
+
var blockStack = [];
|
76
|
+
|
77
|
+
/**
|
78
|
+
* Increments the blockStack counter.
|
79
|
+
* @returns {void}
|
80
|
+
* @private
|
81
|
+
*/
|
82
|
+
function startBlock() {
|
83
|
+
blockStack.push({
|
84
|
+
let: {initialized: false, uninitialized: false},
|
85
|
+
const: {initialized: false, uninitialized: false}
|
86
|
+
});
|
87
|
+
}
|
88
|
+
|
89
|
+
/**
|
90
|
+
* Increments the functionStack counter.
|
91
|
+
* @returns {void}
|
92
|
+
* @private
|
93
|
+
*/
|
94
|
+
function startFunction() {
|
95
|
+
functionStack.push({initialized: false, uninitialized: false});
|
96
|
+
startBlock();
|
97
|
+
}
|
98
|
+
|
99
|
+
/**
|
100
|
+
* Decrements the blockStack counter.
|
101
|
+
* @returns {void}
|
102
|
+
* @private
|
103
|
+
*/
|
104
|
+
function endBlock() {
|
105
|
+
blockStack.pop();
|
106
|
+
}
|
107
|
+
|
108
|
+
/**
|
109
|
+
* Decrements the functionStack counter.
|
110
|
+
* @returns {void}
|
111
|
+
* @private
|
112
|
+
*/
|
113
|
+
function endFunction() {
|
114
|
+
functionStack.pop();
|
115
|
+
endBlock();
|
116
|
+
}
|
117
|
+
|
118
|
+
/**
|
119
|
+
* Records whether initialized or uninitialized variables are defined in current scope.
|
120
|
+
* @param {string} statementType node.kind, one of: "var", "let", or "const"
|
121
|
+
* @param {ASTNode[]} declarations List of declarations
|
122
|
+
* @param {Object} currentScope The scope being investigated
|
123
|
+
* @returns {void}
|
124
|
+
* @private
|
125
|
+
*/
|
126
|
+
function recordTypes(statementType, declarations, currentScope) {
|
127
|
+
for (var i = 0; i < declarations.length; i++) {
|
128
|
+
if (declarations[i].init === null) {
|
129
|
+
if (options[statementType] && options[statementType].uninitialized === MODE_ALWAYS) {
|
130
|
+
currentScope.uninitialized = true;
|
131
|
+
}
|
132
|
+
} else {
|
133
|
+
if (options[statementType] && options[statementType].initialized === MODE_ALWAYS) {
|
134
|
+
currentScope.initialized = true;
|
135
|
+
}
|
136
|
+
}
|
137
|
+
}
|
138
|
+
}
|
139
|
+
|
140
|
+
/**
|
141
|
+
* Determines the current scope (function or block)
|
142
|
+
* @param {string} statementType node.kind, one of: "var", "let", or "const"
|
143
|
+
* @returns {Object} The scope associated with statementType
|
144
|
+
*/
|
145
|
+
function getCurrentScope(statementType) {
|
146
|
+
var currentScope;
|
147
|
+
if (statementType === "var") {
|
148
|
+
currentScope = functionStack[functionStack.length - 1];
|
149
|
+
} else if (statementType === "let") {
|
150
|
+
currentScope = blockStack[blockStack.length - 1].let;
|
151
|
+
} else if (statementType === "const") {
|
152
|
+
currentScope = blockStack[blockStack.length - 1].const;
|
153
|
+
}
|
154
|
+
return currentScope;
|
155
|
+
}
|
156
|
+
|
157
|
+
/**
|
158
|
+
* Counts the number of initialized and uninitialized declarations in a list of declarations
|
159
|
+
* @param {ASTNode[]} declarations List of declarations
|
160
|
+
* @returns {Object} Counts of 'uninitialized' and 'initialized' declarations
|
161
|
+
* @private
|
162
|
+
*/
|
163
|
+
function countDeclarations(declarations) {
|
164
|
+
var counts = { uninitialized: 0, initialized: 0 };
|
165
|
+
for (var i = 0; i < declarations.length; i++) {
|
166
|
+
if (declarations[i].init === null) {
|
167
|
+
counts.uninitialized++;
|
168
|
+
} else {
|
169
|
+
counts.initialized++;
|
170
|
+
}
|
171
|
+
}
|
172
|
+
return counts;
|
173
|
+
}
|
174
|
+
|
175
|
+
/**
|
176
|
+
* Determines if there is more than one var statement in the current scope.
|
177
|
+
* @param {string} statementType node.kind, one of: "var", "let", or "const"
|
178
|
+
* @param {ASTNode[]} declarations List of declarations
|
179
|
+
* @returns {boolean} Returns true if it is the first var declaration, false if not.
|
180
|
+
* @private
|
181
|
+
*/
|
182
|
+
function hasOnlyOneStatement(statementType, declarations) {
|
183
|
+
|
184
|
+
var declarationCounts = countDeclarations(declarations);
|
185
|
+
var currentOptions = options[statementType] || {};
|
186
|
+
var currentScope = getCurrentScope(statementType);
|
187
|
+
|
188
|
+
if (currentOptions.uninitialized === MODE_ALWAYS && currentOptions.initialized === MODE_ALWAYS) {
|
189
|
+
if (currentScope.uninitialized || currentScope.initialized) {
|
190
|
+
return false;
|
191
|
+
}
|
192
|
+
}
|
193
|
+
|
194
|
+
if (declarationCounts.uninitialized > 0) {
|
195
|
+
if (currentOptions.uninitialized === MODE_ALWAYS && currentScope.uninitialized) {
|
196
|
+
return false;
|
197
|
+
}
|
198
|
+
}
|
199
|
+
if (declarationCounts.initialized > 0) {
|
200
|
+
if (currentOptions.initialized === MODE_ALWAYS && currentScope.initialized) {
|
201
|
+
return false;
|
202
|
+
}
|
203
|
+
}
|
204
|
+
recordTypes(statementType, declarations, currentScope);
|
205
|
+
return true;
|
206
|
+
}
|
207
|
+
|
208
|
+
|
209
|
+
//--------------------------------------------------------------------------
|
210
|
+
// Public API
|
211
|
+
//--------------------------------------------------------------------------
|
212
|
+
|
213
|
+
return {
|
214
|
+
"Program": startFunction,
|
215
|
+
"FunctionDeclaration": startFunction,
|
216
|
+
"FunctionExpression": startFunction,
|
217
|
+
"ArrowFunctionExpression": startFunction,
|
218
|
+
"BlockStatement": startBlock,
|
219
|
+
"ForStatement": startBlock,
|
220
|
+
"SwitchStatement": startBlock,
|
221
|
+
|
222
|
+
"VariableDeclaration": function(node) {
|
223
|
+
var parent = node.parent,
|
224
|
+
type, declarations, declarationCounts;
|
225
|
+
|
226
|
+
type = node.kind;
|
227
|
+
if (!options[type]) {
|
228
|
+
return;
|
229
|
+
}
|
230
|
+
|
231
|
+
declarations = node.declarations;
|
232
|
+
declarationCounts = countDeclarations(declarations);
|
233
|
+
|
234
|
+
// always
|
235
|
+
if (!hasOnlyOneStatement(type, declarations)) {
|
236
|
+
if (options[type].initialized === MODE_ALWAYS && options[type].uninitialized === MODE_ALWAYS) {
|
237
|
+
context.report(node, "Combine this with the previous '" + type + "' statement.");
|
238
|
+
} else {
|
239
|
+
if (options[type].initialized === MODE_ALWAYS) {
|
240
|
+
context.report(node, "Combine this with the previous '" + type + "' statement with initialized variables.");
|
241
|
+
}
|
242
|
+
if (options[type].uninitialized === MODE_ALWAYS) {
|
243
|
+
context.report(node, "Combine this with the previous '" + type + "' statement with uninitialized variables.");
|
244
|
+
}
|
245
|
+
}
|
246
|
+
}
|
247
|
+
// never
|
248
|
+
if (parent.type !== "ForStatement" || parent.init !== node) {
|
249
|
+
var totalDeclarations = declarationCounts.uninitialized + declarationCounts.initialized;
|
250
|
+
if (totalDeclarations > 1) {
|
251
|
+
// both initialized and uninitialized
|
252
|
+
if (options[type].initialized === MODE_NEVER && options[type].uninitialized === MODE_NEVER) {
|
253
|
+
context.report(node, "Split '" + type + "' declarations into multiple statements.");
|
254
|
+
// initialized
|
255
|
+
} else if (options[type].initialized === MODE_NEVER && declarationCounts.initialized > 0) {
|
256
|
+
context.report(node, "Split initialized '" + type + "' declarations into multiple statements.");
|
257
|
+
// uninitialized
|
258
|
+
} else if (options[type].uninitialized === MODE_NEVER && declarationCounts.uninitialized > 0) {
|
259
|
+
context.report(node, "Split uninitialized '" + type + "' declarations into multiple statements.");
|
260
|
+
}
|
261
|
+
}
|
262
|
+
}
|
263
|
+
},
|
264
|
+
|
265
|
+
"ForStatement:exit": endBlock,
|
266
|
+
"SwitchStatement:exit": endBlock,
|
267
|
+
"BlockStatement:exit": endBlock,
|
268
|
+
"Program:exit": endFunction,
|
269
|
+
"FunctionDeclaration:exit": endFunction,
|
270
|
+
"FunctionExpression:exit": endFunction,
|
271
|
+
"ArrowFunctionExpression:exit": endFunction
|
272
|
+
};
|
273
|
+
|
274
|
+
};
|
275
|
+
|
276
|
+
module.exports.schema = [
|
277
|
+
{
|
278
|
+
"oneOf": [
|
279
|
+
{
|
280
|
+
"enum": ["always", "never"]
|
281
|
+
},
|
282
|
+
{
|
283
|
+
"type": "object",
|
284
|
+
"properties": {
|
285
|
+
"var": {
|
286
|
+
"enum": ["always", "never"]
|
287
|
+
},
|
288
|
+
"let": {
|
289
|
+
"enum": ["always", "never"]
|
290
|
+
},
|
291
|
+
"const": {
|
292
|
+
"enum": ["always", "never"]
|
293
|
+
}
|
294
|
+
},
|
295
|
+
"additionalProperties": false
|
296
|
+
},
|
297
|
+
{
|
298
|
+
"type": "object",
|
299
|
+
"properties": {
|
300
|
+
"initialized": {
|
301
|
+
"enum": ["always", "never"]
|
302
|
+
},
|
303
|
+
"uninitialized": {
|
304
|
+
"enum": ["always", "never"]
|
305
|
+
}
|
306
|
+
},
|
307
|
+
"additionalProperties": false
|
308
|
+
}
|
309
|
+
]
|
310
|
+
}
|
311
|
+
];
|