eslint 3.15.0 → 3.16.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.
Files changed (97) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/conf/{eslint.json → eslint-recommended.js} +85 -71
  3. package/lib/ast-utils.js +185 -19
  4. package/lib/code-path-analysis/code-path-state.js +2 -2
  5. package/lib/config/autoconfig.js +3 -3
  6. package/lib/config/config-file.js +14 -7
  7. package/lib/config/config-initializer.js +1 -1
  8. package/lib/config.js +3 -2
  9. package/lib/eslint.js +4 -4
  10. package/lib/rules/arrow-body-style.js +7 -4
  11. package/lib/rules/arrow-spacing.js +7 -6
  12. package/lib/rules/block-spacing.js +2 -2
  13. package/lib/rules/brace-style.js +2 -6
  14. package/lib/rules/capitalized-comments.js +6 -6
  15. package/lib/rules/comma-spacing.js +3 -3
  16. package/lib/rules/consistent-return.js +1 -1
  17. package/lib/rules/constructor-super.js +3 -3
  18. package/lib/rules/curly.js +11 -7
  19. package/lib/rules/default-case.js +3 -3
  20. package/lib/rules/eqeqeq.js +15 -6
  21. package/lib/rules/func-call-spacing.js +10 -13
  22. package/lib/rules/generator-star-spacing.js +18 -19
  23. package/lib/rules/id-blacklist.js +2 -2
  24. package/lib/rules/id-length.js +3 -3
  25. package/lib/rules/id-match.js +2 -2
  26. package/lib/rules/indent.js +7 -6
  27. package/lib/rules/key-spacing.js +12 -16
  28. package/lib/rules/keyword-spacing.js +2 -13
  29. package/lib/rules/line-comment-position.js +1 -1
  30. package/lib/rules/linebreak-style.js +7 -1
  31. package/lib/rules/lines-around-comment.js +4 -4
  32. package/lib/rules/lines-around-directive.js +3 -3
  33. package/lib/rules/max-lines.js +2 -2
  34. package/lib/rules/max-statements-per-line.js +7 -6
  35. package/lib/rules/newline-after-var.js +7 -2
  36. package/lib/rules/newline-per-chained-call.js +3 -1
  37. package/lib/rules/no-cond-assign.js +3 -3
  38. package/lib/rules/no-extend-native.js +3 -3
  39. package/lib/rules/no-extra-bind.js +3 -4
  40. package/lib/rules/no-extra-boolean-cast.js +8 -0
  41. package/lib/rules/no-extra-parens.js +1 -2
  42. package/lib/rules/no-inner-declarations.js +4 -4
  43. package/lib/rules/no-irregular-whitespace.js +7 -1
  44. package/lib/rules/no-lone-blocks.js +10 -10
  45. package/lib/rules/no-mixed-operators.js +1 -7
  46. package/lib/rules/no-multi-spaces.js +4 -1
  47. package/lib/rules/no-multi-str.js +7 -3
  48. package/lib/rules/no-return-assign.js +7 -14
  49. package/lib/rules/no-sequences.js +7 -6
  50. package/lib/rules/no-trailing-spaces.js +8 -2
  51. package/lib/rules/no-undefined.js +45 -6
  52. package/lib/rules/no-unexpected-multiline.js +9 -8
  53. package/lib/rules/no-unneeded-ternary.js +5 -1
  54. package/lib/rules/no-unused-labels.js +17 -2
  55. package/lib/rules/no-unused-vars.js +2 -16
  56. package/lib/rules/no-useless-computed-key.js +8 -3
  57. package/lib/rules/no-useless-concat.js +10 -7
  58. package/lib/rules/no-useless-escape.js +1 -1
  59. package/lib/rules/no-useless-return.js +1 -7
  60. package/lib/rules/no-var.js +1 -3
  61. package/lib/rules/no-whitespace-before-property.js +5 -16
  62. package/lib/rules/object-curly-newline.js +2 -2
  63. package/lib/rules/object-curly-spacing.js +7 -25
  64. package/lib/rules/object-property-newline.js +3 -3
  65. package/lib/rules/object-shorthand.js +2 -2
  66. package/lib/rules/operator-assignment.js +1 -1
  67. package/lib/rules/operator-linebreak.js +8 -10
  68. package/lib/rules/padded-blocks.js +4 -4
  69. package/lib/rules/prefer-spread.js +1 -1
  70. package/lib/rules/prefer-template.js +1 -1
  71. package/lib/rules/quotes.js +10 -6
  72. package/lib/rules/semi-spacing.js +4 -0
  73. package/lib/rules/space-before-function-paren.js +8 -5
  74. package/lib/rules/spaced-comment.js +2 -2
  75. package/lib/rules/strict.js +2 -2
  76. package/lib/rules/unicode-bom.js +1 -1
  77. package/lib/rules/wrap-iife.js +5 -5
  78. package/lib/rules/yoda.js +2 -7
  79. package/lib/testers/rule-tester.js +13 -6
  80. package/lib/token-store/backward-token-comment-cursor.js +57 -0
  81. package/lib/token-store/backward-token-cursor.js +56 -0
  82. package/lib/token-store/cursor.js +76 -0
  83. package/lib/token-store/cursors.js +92 -0
  84. package/lib/token-store/decorative-cursor.js +39 -0
  85. package/lib/token-store/filter-cursor.js +43 -0
  86. package/lib/token-store/forward-token-comment-cursor.js +57 -0
  87. package/lib/token-store/forward-token-cursor.js +61 -0
  88. package/lib/token-store/index.js +604 -0
  89. package/lib/token-store/limit-cursor.js +40 -0
  90. package/lib/token-store/padded-token-cursor.js +38 -0
  91. package/lib/token-store/skip-cursor.js +42 -0
  92. package/lib/token-store/utils.js +100 -0
  93. package/lib/util/source-code-fixer.js +35 -39
  94. package/lib/util/source-code.js +31 -15
  95. package/messages/extend-config-missing.txt +3 -0
  96. package/package.json +2 -2
  97. package/lib/token-store.js +0 -203
package/CHANGELOG.md CHANGED
@@ -1,3 +1,35 @@
1
+ v3.16.0 - February 20, 2017
2
+
3
+ * d89d0b4 Update: fix quotes false negative for string literals as template tags (#8107) (Teddy Katz)
4
+ * 21be366 Chore: Ensuring eslint:recommended rules are sorted. (#8106) (Kevin Partington)
5
+ * 360dbe4 Update: Improve error message when extend config missing (fixes #6115) (#8100) (alberto)
6
+ * f62a724 Chore: use updated token iterator methods (#8103) (Kai Cataldo)
7
+ * daf6f26 Fix: check output in RuleTester when errors is a number (fixes #7640) (#8097) (alberto)
8
+ * cfb65c5 Update: make no-lone-blocks report blocks in switch cases (fixes #8047) (#8062) (Teddy Katz)
9
+ * 290fb1f Update: Add includeComments to getTokenByRangeStart (fixes #8068) (#8069) (Kai Cataldo)
10
+ * ff066dc Chore: Incorrect source code test text (#8096) (Jack Ford)
11
+ * 14d146d Docs: Clarify --ext only works with directories (fixes #7939) (#8095) (alberto)
12
+ * 013a454 Docs: Add TSC meeting quorum requirement (#8086) (Kevin Partington)
13
+ * 7516303 Fix: `sourceCode.getTokenAfter` shouldn't skip tokens after comments (#8055) (Toru Nagashima)
14
+ * c53e034 Fix: unicode-bom fixer insert BOM in appropriate location (fixes #8083) (#8084) (pantosha)
15
+ * 55ac302 Chore: fix the timing to define rules for tests (#8082) (Toru Nagashima)
16
+ * c7e64f3 Upgrade: mock-fs (#8070) (Toru Nagashima)
17
+ * acc3301 Update: handle uncommon linebreaks consistently in rules (fixes #7949) (#8049) (Teddy Katz)
18
+ * 591b74a Chore: enable operator-linebreak on ESLint codebase (#8064) (Teddy Katz)
19
+ * 6445d2a Docs: Add documentation for /* exported */ (fixes #7998) (#8065) (Lee Yi Min)
20
+ * fcc38db Chore: simplify and improve performance for autofix (#8035) (Toru Nagashima)
21
+ * b04fde7 Chore: improve performance of SourceCode constructor (#8054) (Teddy Katz)
22
+ * 90fd555 Update: improve null detection in eqeqeq for ES6 regexes (fixes #8020) (#8042) (Teddy Katz)
23
+ * 16248e2 Fix: no-extra-boolean-cast incorrect Boolean() autofixing (fixes #7977) (#8037) (Jonathan Wilsson)
24
+ * 834f45d Update: rewrite TokenStore (fixes #7810) (#7936) (Toru Nagashima)
25
+ * 329dcdc Chore: unify checks for statement list parents (#8048) (Teddy Katz)
26
+ * c596690 Docs: Clarify generator-star-spacing config example (fixes #8027) (#8034) (Hòa Trần)
27
+ * a11d4a6 Docs: fix a typo in shareable configs documentation (#8036) (Dan Homola)
28
+ * 1e3d4c6 Update: add fixer for no-unused-labels (#7841) (Teddy Katz)
29
+ * f47fb98 Update: ensure semi-spacing checks import/export declarations (#8033) (Teddy Katz)
30
+ * e228d56 Update: no-undefined handles properties/classes/modules (fixes #7964) (#7966) (Kevin Partington)
31
+ * 7bc92d9 Chore: fix invalid test cases (#8030) (Toru Nagashima)
32
+
1
33
  v3.15.0 - February 3, 2017
2
34
 
3
35
  * f2a3580 Fix: `no-extra-parens` incorrect precedence (fixes #7978) (#7999) (alberto)
@@ -1,7 +1,81 @@
1
- {
2
- "parser": "espree",
3
- "ecmaFeatures": {},
4
- "rules": {
1
+ /**
2
+ * @fileoverview Configuration applied when a user configuration extends from
3
+ * eslint:recommended.
4
+ * @author Nicholas C. Zakas
5
+ */
6
+
7
+ "use strict";
8
+
9
+ /* eslint sort-keys: ["error", "asc"], quote-props: ["error", "consistent"] */
10
+ /* eslint-disable sort-keys */
11
+
12
+ module.exports = {
13
+ parser: "espree",
14
+ ecmaFeatures: {},
15
+
16
+ rules: {
17
+
18
+ /* eslint-enable sort-keys */
19
+ "accessor-pairs": "off",
20
+ "array-bracket-spacing": "off",
21
+ "array-callback-return": "off",
22
+ "arrow-body-style": "off",
23
+ "arrow-parens": "off",
24
+ "arrow-spacing": "off",
25
+ "block-scoped-var": "off",
26
+ "block-spacing": "off",
27
+ "brace-style": "off",
28
+ "callback-return": "off",
29
+ "camelcase": "off",
30
+ "capitalized-comments": "off",
31
+ "class-methods-use-this": "off",
32
+ "comma-dangle": "off",
33
+ "comma-spacing": "off",
34
+ "comma-style": "off",
35
+ "complexity": "off",
36
+ "computed-property-spacing": "off",
37
+ "consistent-return": "off",
38
+ "consistent-this": "off",
39
+ "constructor-super": "error",
40
+ "curly": "off",
41
+ "default-case": "off",
42
+ "dot-location": "off",
43
+ "dot-notation": "off",
44
+ "eol-last": "off",
45
+ "eqeqeq": "off",
46
+ "func-call-spacing": "off",
47
+ "func-name-matching": "off",
48
+ "func-names": "off",
49
+ "func-style": "off",
50
+ "generator-star-spacing": "off",
51
+ "global-require": "off",
52
+ "guard-for-in": "off",
53
+ "handle-callback-err": "off",
54
+ "id-blacklist": "off",
55
+ "id-length": "off",
56
+ "id-match": "off",
57
+ "indent": "off",
58
+ "init-declarations": "off",
59
+ "jsx-quotes": "off",
60
+ "key-spacing": "off",
61
+ "keyword-spacing": "off",
62
+ "line-comment-position": "off",
63
+ "linebreak-style": "off",
64
+ "lines-around-comment": "off",
65
+ "lines-around-directive": "off",
66
+ "max-depth": "off",
67
+ "max-len": "off",
68
+ "max-lines": "off",
69
+ "max-nested-callbacks": "off",
70
+ "max-params": "off",
71
+ "max-statements": "off",
72
+ "max-statements-per-line": "off",
73
+ "multiline-ternary": "off",
74
+ "new-cap": "off",
75
+ "new-parens": "off",
76
+ "newline-after-var": "off",
77
+ "newline-before-return": "off",
78
+ "newline-per-chained-call": "off",
5
79
  "no-alert": "off",
6
80
  "no-array-constructor": "off",
7
81
  "no-await-in-loop": "off",
@@ -100,20 +174,20 @@
100
174
  "no-sequences": "off",
101
175
  "no-shadow": "off",
102
176
  "no-shadow-restricted-names": "off",
103
- "no-whitespace-before-property": "off",
104
177
  "no-spaced-func": "off",
105
178
  "no-sparse-arrays": "error",
106
179
  "no-sync": "off",
107
180
  "no-tabs": "off",
181
+ "no-template-curly-in-string": "off",
108
182
  "no-ternary": "off",
109
- "no-trailing-spaces": "off",
110
183
  "no-this-before-super": "error",
111
184
  "no-throw-literal": "off",
185
+ "no-trailing-spaces": "off",
112
186
  "no-undef": "error",
113
187
  "no-undef-init": "off",
114
188
  "no-undefined": "off",
115
- "no-unexpected-multiline": "error",
116
189
  "no-underscore-dangle": "off",
190
+ "no-unexpected-multiline": "error",
117
191
  "no-unmodified-loop-condition": "off",
118
192
  "no-unneeded-ternary": "off",
119
193
  "no-unreachable": "error",
@@ -130,70 +204,11 @@
130
204
  "no-useless-escape": "off",
131
205
  "no-useless-rename": "off",
132
206
  "no-useless-return": "off",
133
- "no-void": "off",
134
207
  "no-var": "off",
208
+ "no-void": "off",
135
209
  "no-warning-comments": "off",
210
+ "no-whitespace-before-property": "off",
136
211
  "no-with": "off",
137
- "array-bracket-spacing": "off",
138
- "array-callback-return": "off",
139
- "arrow-body-style": "off",
140
- "arrow-parens": "off",
141
- "arrow-spacing": "off",
142
- "accessor-pairs": "off",
143
- "block-scoped-var": "off",
144
- "block-spacing": "off",
145
- "brace-style": "off",
146
- "callback-return": "off",
147
- "camelcase": "off",
148
- "capitalized-comments": "off",
149
- "class-methods-use-this": "off",
150
- "comma-dangle": "off",
151
- "comma-spacing": "off",
152
- "comma-style": "off",
153
- "complexity": "off",
154
- "computed-property-spacing": "off",
155
- "consistent-return": "off",
156
- "consistent-this": "off",
157
- "constructor-super": "error",
158
- "curly": "off",
159
- "default-case": "off",
160
- "dot-location": "off",
161
- "dot-notation": "off",
162
- "eol-last": "off",
163
- "eqeqeq": "off",
164
- "func-call-spacing": "off",
165
- "func-names": "off",
166
- "func-name-matching": "off",
167
- "func-style": "off",
168
- "generator-star-spacing": "off",
169
- "global-require": "off",
170
- "guard-for-in": "off",
171
- "handle-callback-err": "off",
172
- "id-blacklist": "off",
173
- "id-length": "off",
174
- "id-match": "off",
175
- "indent": "off",
176
- "init-declarations": "off",
177
- "jsx-quotes": "off",
178
- "key-spacing": "off",
179
- "keyword-spacing": "off",
180
- "linebreak-style": "off",
181
- "line-comment-position": "off",
182
- "lines-around-comment": "off",
183
- "lines-around-directive": "off",
184
- "max-depth": "off",
185
- "max-len": "off",
186
- "max-lines": "off",
187
- "max-nested-callbacks": "off",
188
- "max-params": "off",
189
- "max-statements": "off",
190
- "max-statements-per-line": "off",
191
- "multiline-ternary": "off",
192
- "new-cap": "off",
193
- "new-parens": "off",
194
- "newline-after-var": "off",
195
- "newline-before-return": "off",
196
- "newline-per-chained-call": "off",
197
212
  "object-curly-newline": "off",
198
213
  "object-curly-spacing": ["off", "never"],
199
214
  "object-property-newline": "off",
@@ -221,8 +236,8 @@
221
236
  "rest-spread-spacing": "off",
222
237
  "semi": "off",
223
238
  "semi-spacing": "off",
224
- "sort-keys": "off",
225
239
  "sort-imports": "off",
240
+ "sort-keys": "off",
226
241
  "sort-vars": "off",
227
242
  "space-before-blocks": "off",
228
243
  "space-before-function-paren": "off",
@@ -241,8 +256,7 @@
241
256
  "vars-on-top": "off",
242
257
  "wrap-iife": "off",
243
258
  "wrap-regex": "off",
244
- "no-template-curly-in-string": "off",
245
259
  "yield-star-spacing": "off",
246
260
  "yoda": "off"
247
261
  }
248
- }
262
+ };
package/lib/ast-utils.js CHANGED
@@ -24,6 +24,12 @@ const bindOrCallOrApplyPattern = /^(?:bind|call|apply)$/;
24
24
  const breakableTypePattern = /^(?:(?:Do)?While|For(?:In|Of)?|Switch)Statement$/;
25
25
  const thisTagPattern = /^[\s*]*@this/m;
26
26
 
27
+ const LINEBREAKS = new Set(["\r\n", "\r", "\n", "\u2028", "\u2029"]);
28
+ const LINEBREAK_MATCHER = /\r\n|[\r\n\u2028\u2029]/;
29
+
30
+ // A set of node types that can contain a list of statements
31
+ const STATEMENT_LIST_PARENTS = new Set(["Program", "BlockStatement", "SwitchCase"]);
32
+
27
33
  /**
28
34
  * Checks reference if is non initializer and writable.
29
35
  * @param {Reference} reference - A reference to check.
@@ -142,7 +148,7 @@ function isInLoop(node) {
142
148
  */
143
149
  function isNullOrUndefined(node) {
144
150
  return (
145
- (node.type === "Literal" && node.value === null) ||
151
+ module.exports.isNullLiteral(node) ||
146
152
  (node.type === "Identifier" && node.name === "undefined") ||
147
153
  (node.type === "UnaryExpression" && node.operator === "void")
148
154
  );
@@ -210,6 +216,15 @@ function isMethodWhichHasThisArg(node) {
210
216
  return false;
211
217
  }
212
218
 
219
+ /**
220
+ * Creates the negate function of the given function.
221
+ * @param {Function} f - The function to negate.
222
+ * @returns {Function} Negated function.
223
+ */
224
+ function negate(f) {
225
+ return token => !f(token);
226
+ }
227
+
213
228
  /**
214
229
  * Checks whether or not a node has a `@this` tag in its comments.
215
230
  * @param {ASTNode} node - A node to check.
@@ -247,20 +262,123 @@ function isParenthesised(sourceCode, node) {
247
262
  }
248
263
 
249
264
  /**
250
- * Gets the `=>` token of the given arrow function node.
265
+ * Checks if the given token is an arrow token or not.
251
266
  *
252
- * @param {ASTNode} node - The arrow function node to get.
253
- * @param {SourceCode} sourceCode - The source code object to get tokens.
254
- * @returns {Token} `=>` token.
267
+ * @param {Token} token - The token to check.
268
+ * @returns {boolean} `true` if the token is an arrow token.
255
269
  */
256
- function getArrowToken(node, sourceCode) {
257
- let token = sourceCode.getTokenBefore(node.body);
270
+ function isArrowToken(token) {
271
+ return token.value === "=>" && token.type === "Punctuator";
272
+ }
258
273
 
259
- while (token.value !== "=>") {
260
- token = sourceCode.getTokenBefore(token);
261
- }
274
+ /**
275
+ * Checks if the given token is a comma token or not.
276
+ *
277
+ * @param {Token} token - The token to check.
278
+ * @returns {boolean} `true` if the token is a comma token.
279
+ */
280
+ function isCommaToken(token) {
281
+ return token.value === "," && token.type === "Punctuator";
282
+ }
262
283
 
263
- return token;
284
+ /**
285
+ * Checks if the given token is a semicolon token or not.
286
+ *
287
+ * @param {Token} token - The token to check.
288
+ * @returns {boolean} `true` if the token is a semicolon token.
289
+ */
290
+ function isSemicolonToken(token) {
291
+ return token.value === ";" && token.type === "Punctuator";
292
+ }
293
+
294
+ /**
295
+ * Checks if the given token is a colon token or not.
296
+ *
297
+ * @param {Token} token - The token to check.
298
+ * @returns {boolean} `true` if the token is a colon token.
299
+ */
300
+ function isColonToken(token) {
301
+ return token.value === ":" && token.type === "Punctuator";
302
+ }
303
+
304
+ /**
305
+ * Checks if the given token is an opening parenthesis token or not.
306
+ *
307
+ * @param {Token} token - The token to check.
308
+ * @returns {boolean} `true` if the token is an opening parenthesis token.
309
+ */
310
+ function isOpeningParenToken(token) {
311
+ return token.value === "(" && token.type === "Punctuator";
312
+ }
313
+
314
+ /**
315
+ * Checks if the given token is a closing parenthesis token or not.
316
+ *
317
+ * @param {Token} token - The token to check.
318
+ * @returns {boolean} `true` if the token is a closing parenthesis token.
319
+ */
320
+ function isClosingParenToken(token) {
321
+ return token.value === ")" && token.type === "Punctuator";
322
+ }
323
+
324
+ /**
325
+ * Checks if the given token is an opening square bracket token or not.
326
+ *
327
+ * @param {Token} token - The token to check.
328
+ * @returns {boolean} `true` if the token is an opening square bracket token.
329
+ */
330
+ function isOpeningBracketToken(token) {
331
+ return token.value === "[" && token.type === "Punctuator";
332
+ }
333
+
334
+ /**
335
+ * Checks if the given token is a closing square bracket token or not.
336
+ *
337
+ * @param {Token} token - The token to check.
338
+ * @returns {boolean} `true` if the token is a closing square bracket token.
339
+ */
340
+ function isClosingBracketToken(token) {
341
+ return token.value === "]" && token.type === "Punctuator";
342
+ }
343
+
344
+ /**
345
+ * Checks if the given token is an opening brace token or not.
346
+ *
347
+ * @param {Token} token - The token to check.
348
+ * @returns {boolean} `true` if the token is an opening brace token.
349
+ */
350
+ function isOpeningBraceToken(token) {
351
+ return token.value === "{" && token.type === "Punctuator";
352
+ }
353
+
354
+ /**
355
+ * Checks if the given token is a closing brace token or not.
356
+ *
357
+ * @param {Token} token - The token to check.
358
+ * @returns {boolean} `true` if the token is a closing brace token.
359
+ */
360
+ function isClosingBraceToken(token) {
361
+ return token.value === "}" && token.type === "Punctuator";
362
+ }
363
+
364
+ /**
365
+ * Checks if the given token is a comment token or not.
366
+ *
367
+ * @param {Token} token - The token to check.
368
+ * @returns {boolean} `true` if the token is a comment token.
369
+ */
370
+ function isCommentToken(token) {
371
+ return token.type === "Line" || token.type === "Block" || token.type === "Shebang";
372
+ }
373
+
374
+ /**
375
+ * Checks if the given token is a keyword token or not.
376
+ *
377
+ * @param {Token} token - The token to check.
378
+ * @returns {boolean} `true` if the token is a keyword token.
379
+ */
380
+ function isKeywordToken(token) {
381
+ return token.type === "Keyword";
264
382
  }
265
383
 
266
384
  /**
@@ -271,13 +389,18 @@ function getArrowToken(node, sourceCode) {
271
389
  * @returns {Token} `(` token.
272
390
  */
273
391
  function getOpeningParenOfParams(node, sourceCode) {
274
- let token = node.id ? sourceCode.getTokenAfter(node.id) : sourceCode.getFirstToken(node);
275
-
276
- while (token.value !== "(") {
277
- token = sourceCode.getTokenAfter(token);
278
- }
392
+ return node.id
393
+ ? sourceCode.getTokenAfter(node.id, isOpeningParenToken)
394
+ : sourceCode.getFirstToken(node, isOpeningParenToken);
395
+ }
279
396
 
280
- return token;
397
+ /**
398
+ * Creates a version of the LINEBREAK_MATCHER regex with the global flag.
399
+ * Global regexes are mutable, so this needs to be a function instead of a constant.
400
+ * @returns {RegExp} A global regular expression that matches line terminators
401
+ */
402
+ function createGlobalLinebreakMatcher() {
403
+ return new RegExp(LINEBREAK_MATCHER.source, "g");
281
404
  }
282
405
 
283
406
  const lineIndexCache = new WeakMap();
@@ -291,7 +414,7 @@ function getLineIndices(sourceCode) {
291
414
 
292
415
  if (!lineIndexCache.has(sourceCode)) {
293
416
  const lineIndices = [0];
294
- const lineEndingPattern = /\r\n|[\r\n\u2028\u2029]/g;
417
+ const lineEndingPattern = createGlobalLinebreakMatcher();
295
418
  let match;
296
419
 
297
420
  /*
@@ -319,6 +442,9 @@ function getLineIndices(sourceCode) {
319
442
  //------------------------------------------------------------------------------
320
443
 
321
444
  module.exports = {
445
+ LINEBREAKS,
446
+ LINEBREAK_MATCHER,
447
+ STATEMENT_LIST_PARENTS,
322
448
 
323
449
  /**
324
450
  * Determines whether two adjacent tokens are on the same line.
@@ -340,6 +466,29 @@ module.exports = {
340
466
  isInLoop,
341
467
  isArrayFromMethod,
342
468
  isParenthesised,
469
+ createGlobalLinebreakMatcher,
470
+
471
+ isArrowToken,
472
+ isClosingBraceToken,
473
+ isClosingBracketToken,
474
+ isClosingParenToken,
475
+ isColonToken,
476
+ isCommaToken,
477
+ isCommentToken,
478
+ isKeywordToken,
479
+ isNotClosingBraceToken: negate(isClosingBraceToken),
480
+ isNotClosingBracketToken: negate(isClosingBracketToken),
481
+ isNotClosingParenToken: negate(isClosingParenToken),
482
+ isNotColonToken: negate(isColonToken),
483
+ isNotCommaToken: negate(isCommaToken),
484
+ isNotOpeningBraceToken: negate(isOpeningBraceToken),
485
+ isNotOpeningBracketToken: negate(isOpeningBracketToken),
486
+ isNotOpeningParenToken: negate(isOpeningParenToken),
487
+ isNotSemicolonToken: negate(isSemicolonToken),
488
+ isOpeningBraceToken,
489
+ isOpeningBracketToken,
490
+ isOpeningParenToken,
491
+ isSemicolonToken,
343
492
 
344
493
  /**
345
494
  * Checks whether or not a given node is a string literal.
@@ -1040,7 +1189,7 @@ module.exports = {
1040
1189
  let end = null;
1041
1190
 
1042
1191
  if (node.type === "ArrowFunctionExpression") {
1043
- const arrowToken = getArrowToken(node, sourceCode);
1192
+ const arrowToken = sourceCode.getTokenBefore(node.body, isArrowToken);
1044
1193
 
1045
1194
  start = arrowToken.loc.start;
1046
1195
  end = arrowToken.loc.end;
@@ -1150,5 +1299,22 @@ module.exports = {
1150
1299
  default:
1151
1300
  return false;
1152
1301
  }
1302
+ },
1303
+
1304
+ /**
1305
+ * Determines whether the given node is a `null` literal.
1306
+ * @param {ASTNode} node The node to check
1307
+ * @returns {boolean} `true` if the node is a `null` literal
1308
+ */
1309
+ isNullLiteral(node) {
1310
+
1311
+ /*
1312
+ * Checking `node.value === null` does not guarantee that a literal is a null literal.
1313
+ * When parsing values that cannot be represented in the current environment (e.g. unicode
1314
+ * regexes in Node 4), `node.value` is set to `null` because it wouldn't be possible to
1315
+ * set `node.value` to a unicode regex. To make sure a literal is actually `null`, check
1316
+ * `node.regex` instead. Also see: https://github.com/eslint/eslint/issues/8020
1317
+ */
1318
+ return node.type === "Literal" && node.value === null && !node.regex;
1153
1319
  }
1154
1320
  };
@@ -467,8 +467,8 @@ class CodePathState {
467
467
  * Creates the next path from own true/false fork context.
468
468
  */
469
469
  const prevForkContext =
470
- context.kind === "&&" ? context.trueForkContext :
471
- /* kind === "||" */ context.falseForkContext;
470
+ context.kind === "&&" ? context.trueForkContext
471
+ /* kind === "||" */ : context.falseForkContext;
472
472
 
473
473
  forkContext.replaceHead(prevForkContext.makeNext(0, -1));
474
474
  prevForkContext.clear();
@@ -13,7 +13,7 @@ const lodash = require("lodash"),
13
13
  eslint = require("../eslint"),
14
14
  configRule = require("./config-rule"),
15
15
  ConfigOps = require("./config-ops"),
16
- recConfig = require("../../conf/eslint.json");
16
+ recConfig = require("../../conf/eslint-recommended");
17
17
 
18
18
  const debug = require("debug")("eslint:autoconfig");
19
19
 
@@ -300,8 +300,8 @@ class Registry {
300
300
  // (https://github.com/eslint/eslint/issues/5992)
301
301
  // (https://github.com/eslint/eslint/issues/7860)
302
302
  if (
303
- lintedRegistry.rules[result.ruleId]
304
- && lintedRegistry.rules[result.ruleId][ruleSetIdx]
303
+ lintedRegistry.rules[result.ruleId] &&
304
+ lintedRegistry.rules[result.ruleId][ruleSetIdx]
305
305
  ) {
306
306
  lintedRegistry.rules[result.ruleId][ruleSetIdx].errorCount += 1;
307
307
  }
@@ -23,7 +23,7 @@ const fs = require("fs"),
23
23
  stripBom = require("strip-bom"),
24
24
  stripComments = require("strip-json-comments"),
25
25
  stringify = require("json-stable-stringify"),
26
- defaultOptions = require("../../conf/eslint.json"),
26
+ defaultOptions = require("../../conf/eslint-recommended"),
27
27
  requireUncached = require("require-uncached");
28
28
 
29
29
  const debug = require("debug")("eslint:config-file");
@@ -364,10 +364,10 @@ function applyExtends(config, filePath, relativeTo) {
364
364
  if (parentPath === "eslint:recommended") {
365
365
 
366
366
  /*
367
- * Add an explicit substitution for eslint:recommended to conf/eslint.json
368
- * this lets us use the eslint.json file as the recommended rules
367
+ * Add an explicit substitution for eslint:recommended to
368
+ * conf/eslint-recommended.js.
369
369
  */
370
- parentPath = path.resolve(__dirname, "../../conf/eslint.json");
370
+ parentPath = path.resolve(__dirname, "../../conf/eslint-recommended.js");
371
371
  } else if (parentPath === "eslint:all") {
372
372
 
373
373
  /*
@@ -380,9 +380,9 @@ function applyExtends(config, filePath, relativeTo) {
380
380
  * If the `extends` path is relative, use the directory of the current configuration
381
381
  * file as the reference point. Otherwise, use as-is.
382
382
  */
383
- parentPath = (!path.isAbsolute(parentPath) ?
384
- path.join(relativeTo || path.dirname(filePath), parentPath) :
385
- parentPath
383
+ parentPath = (!path.isAbsolute(parentPath)
384
+ ? path.join(relativeTo || path.dirname(filePath), parentPath)
385
+ : parentPath
386
386
  );
387
387
  }
388
388
 
@@ -390,6 +390,13 @@ function applyExtends(config, filePath, relativeTo) {
390
390
  debug(`Loading ${parentPath}`);
391
391
  return ConfigOps.merge(load(parentPath, false, relativeTo), previousValue);
392
392
  } catch (e) {
393
+ if (parentPath.indexOf("plugin:") === 0 || parentPath.indexOf("eslint:") === 0) {
394
+ e.message = `Failed to load config "${parentPath}" to extend from.`;
395
+ e.messageTemplate = "extend-config-missing";
396
+ e.messageData = {
397
+ configName: parentPath
398
+ };
399
+ }
393
400
 
394
401
  /*
395
402
  * If the file referenced by `extends` failed to load, add the path
@@ -17,7 +17,7 @@ const util = require("util"),
17
17
  ConfigOps = require("./config-ops"),
18
18
  getSourceCodeOfFiles = require("../util/source-code-util").getSourceCodeOfFiles,
19
19
  npmUtil = require("../util/npm-util"),
20
- recConfig = require("../../conf/eslint.json"),
20
+ recConfig = require("../../conf/eslint-recommended"),
21
21
  log = require("../logging");
22
22
 
23
23
  const debug = require("debug")("eslint:config-initializer");
package/lib/config.js CHANGED
@@ -234,8 +234,9 @@ class Config {
234
234
  }
235
235
 
236
236
  /**
237
- * Build a config object merging the base config (conf/eslint.json), the
238
- * environments config (conf/environments.js) and eventually the user config.
237
+ * Build a config object merging the base config (conf/eslint-recommended),
238
+ * the environments config (conf/environments.js) and eventually the user
239
+ * config.
239
240
  * @param {string} filePath a file in whose directory we start looking for a local config
240
241
  * @returns {Object} config object
241
242
  */
package/lib/eslint.js CHANGED
@@ -14,7 +14,7 @@ const assert = require("assert"),
14
14
  escope = require("escope"),
15
15
  levn = require("levn"),
16
16
  blankScriptAST = require("../conf/blank-script.json"),
17
- DEFAULT_PARSER = require("../conf/eslint.json").parser,
17
+ DEFAULT_PARSER = require("../conf/eslint-recommended").parser,
18
18
  replacements = require("../conf/replacements.json"),
19
19
  CodePathAnalyzer = require("./code-path-analysis/code-path-analyzer"),
20
20
  ConfigOps = require("./config/config-ops"),
@@ -864,8 +864,8 @@ module.exports = (function() {
864
864
  (parseResult && parseResult.services ? parseResult.services : {})
865
865
  );
866
866
 
867
- const rule = ruleCreator.create ? ruleCreator.create(ruleContext) :
868
- ruleCreator(ruleContext);
867
+ const rule = ruleCreator.create ? ruleCreator.create(ruleContext)
868
+ : ruleCreator(ruleContext);
869
869
 
870
870
  // add all the node types as listeners
871
871
  Object.keys(rule).forEach(nodeType => {
@@ -1192,7 +1192,7 @@ module.exports = (function() {
1192
1192
  * @returns {Object} Object mapping rule IDs to their default configurations
1193
1193
  */
1194
1194
  api.defaults = function() {
1195
- return require("../conf/eslint.json");
1195
+ return require("../conf/eslint-recommended");
1196
1196
  };
1197
1197
 
1198
1198
  /**
@@ -4,6 +4,12 @@
4
4
  */
5
5
  "use strict";
6
6
 
7
+ //------------------------------------------------------------------------------
8
+ // Requirements
9
+ //------------------------------------------------------------------------------
10
+
11
+ const astUtils = require("../ast-utils");
12
+
7
13
  //------------------------------------------------------------------------------
8
14
  // Rule Definition
9
15
  //------------------------------------------------------------------------------
@@ -136,10 +142,7 @@ module.exports = {
136
142
  loc: arrowBody.loc.start,
137
143
  message: "Expected block statement surrounding arrow body.",
138
144
  fix(fixer) {
139
- const lastTokenBeforeBody = sourceCode.getTokensBetween(sourceCode.getFirstToken(node), arrowBody)
140
- .reverse()
141
- .find(token => token.value !== "(");
142
-
145
+ const lastTokenBeforeBody = sourceCode.getLastTokenBetween(sourceCode.getFirstToken(node), arrowBody, astUtils.isNotOpeningParenToken);
143
146
  const firstBodyToken = sourceCode.getTokenAfter(lastTokenBeforeBody);
144
147
 
145
148
  return fixer.replaceTextRange(