eslint 5.0.0-alpha.4 → 5.1.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/CHANGELOG.md CHANGED
@@ -1,3 +1,63 @@
1
+ v5.1.0 - July 8, 2018
2
+
3
+ * 7328f99 Build: package.json update for eslint-config-eslint release (ESLint Jenkins)
4
+ * b161f6b Build: Include prerelease install info in release blog post (#10463) (Kevin Partington)
5
+ * b2df738 Fix: prefer-object-spread duplicated comma (fixes #10512, fixes #10532) (#10524) (Toru Nagashima)
6
+ * d8c3a25 Fix: wrap-regex doesn't work in some expression(fixes #10573) (#10576) (薛定谔的猫)
7
+ * 114f42e Docs: Clarify option defaults in max-lines-per-function docs (#10569) (Chris Harwood)
8
+ * 63f36f7 Fix: sort-keys in an object that contains spread (fixes #10261) (#10495) (katerberg)
9
+ * 601a5c4 Fix: Prefer-const rule crashing on array destructuring (fixes #10520) (#10527) (Michael Mason)
10
+ * 143890a Update: Adjust grammar of error/warnings fixable (#10546) (Matt Mischuk)
11
+ * 8ee39c5 Chore: small refactor config-validator (#10565) (薛定谔的猫)
12
+ * 100f1be Docs: add note about release issues to readme (#10572) (Teddy Katz)
13
+ * 02efeac Fix: do not fail on nested unknown operators (#10561) (Rubén Norte)
14
+ * 92b19ca Chore: use eslintrc overrides(dogfooding) (#10566) (薛定谔的猫)
15
+ * 076a6b6 Docs: add actionable fix to no-irregular-whitespace (#10558) (Matteo Collina)
16
+ * de663ec Docs: Only successfully linted files are cached (fixes #9802) (#10557) (Kevin Partington)
17
+ * f0e22fc Upgrade: globals@11.7.0 (#10497) (薛定谔的猫)
18
+ * 8a2ff2c Docs: adding a section about disable rules for some files (#10536) (Wellington Soares)
19
+ * f22a3f8 Docs: fix a word in no-implied-eval (#10539) (Dan Homola)
20
+ * 20d8bbd Docs: add missing paragraph about "custom parsers" (#10547) (Pig Fang)
21
+ * b7addf6 Update: deprecate no-catch-shadow (fixes #10466) (#10526) (Toru Nagashima)
22
+ * e862dc3 Fix: Remove autofixer for no-debugger (fixes #10242) (#10509) (Teddy Katz)
23
+
24
+ v5.0.1 - June 25, 2018
25
+
26
+ * 196c102 Fix: valid-jsdoc should allow optional returns for async (fixes #10386) (#10480) (Mark Banner)
27
+ * 4c823bd Docs: Fix max-lines-per-function correct code's max value (#10513) (Rhys Bower)
28
+
29
+ v5.0.0 - June 22, 2018
30
+
31
+ * 0feedfd New: Added max-lines-per-function rule (fixes #9842) (#10188) (peteward44)
32
+ * daefbdb Upgrade: eslint-scope and espree to 4.0.0 (refs #10458) (#10500) (Brandon Mills)
33
+ * 077358b Docs: no-process-exit: recommend process.exitCode (#10478) (Andres Kalle)
34
+ * f93d6ff Fix: do not fail on unknown operators from custom parsers (fixes #10475) (#10476) (Rubén Norte)
35
+ * 05343fd Fix: add parens for yield statement (fixes #10432) (#10468) (Pig Fang)
36
+ * d477c5e Fix: check destructuring for "no-shadow-restricted-names" (fixes #10467) (#10470) (Pig Fang)
37
+ * 7a7580b Update: Add considerPropertyDescriptor option to func-name-matching (#9078) (Dieter Luypaert)
38
+ * e0a0418 Fix: crash on optional catch binding (#10429) (Toru Nagashima)
39
+ * de4dba9 Docs: styling team members (#10460) (薛定谔的猫)
40
+ * 5e453a3 Docs: display team members in tables. (#10433) (薛定谔的猫)
41
+ * b1895eb Docs: Restore intentional spelling mistake (#10459) (Wilfred Hughes)
42
+
43
+ v5.0.0-rc.0 - June 9, 2018
44
+
45
+ * abf400d Update: Add ignoreDestructing option to camelcase rule (fixes #9807) (#10373) (Andrew Lunny)
46
+ * e2b394d Upgrade: espree and eslint-scope to rc versions (#10457) (Kevin Partington)
47
+ * a370da2 Chore: small opt to improve readability (#10241) (薛定谔的猫)
48
+ * 640bf07 Update: Fixes multiline no-warning-comments rule. (fixes #9884) (#10381) (Scott Stern)
49
+ * 831c39a Build: Adding rc release script to package.json (#10456) (Kevin Partington)
50
+ * dc4075e Update: fix false negative in no-use-before-define (fixes #10227) (#10396) (Toru Nagashima)
51
+ * 3721841 Docs: Add new experimental syntax policy to README (fixes #9804) (#10408) (Kevin Partington)
52
+ * d0aae3c Docs: Create docs landing page (#10453) (Kevin Partington)
53
+ * fe8bec3 Fix: fix writing config file when `source` is `prompt` (#10422) (Pig Fang)
54
+ * 917108d Update: Add requireParamType option to valid-jsdoc (fixes #6753) (#10220) (Tomasz Sterna)
55
+ * 1984c21 Docs: move custom parsers docs into a page (fixes #9919) (#10431) (Pig Fang)
56
+ * 400d4b5 Docs: Add rest and spread operator changes to migration guide (#10416) (Yannick Croissant)
57
+ * e7bdd02 Upgrade: Consume espree@4.0.0-alpha.1 (#10410) (Kevin Partington)
58
+ * 3e9f33a Fix: prevent crashing from JSON parsing error (fixes #10364) (#10376) (Pig Fang)
59
+ * 636457d Fix: parse later ES files in `eslint --init` (fixes #10003) (#10378) (Pig Fang)
60
+
1
61
  v5.0.0-alpha.4 - May 28, 2018
2
62
 
3
63
  * ce3e62a Docs: remove test coverage badge (#10407) (薛定谔的猫)
package/README.md CHANGED
@@ -145,7 +145,9 @@ ESLint has full support for ECMAScript 3, 5 (default), 2015, 2016, 2017, and 201
145
145
 
146
146
  ### What about experimental features?
147
147
 
148
- ESLint doesn't natively support experimental ECMAScript language features. You can use [babel-eslint](https://github.com/babel/babel-eslint) to use any option available in Babel.
148
+ ESLint's parser only officially supports the latest final ECMAScript standard. We will make changes to core rules in order to avoid crashes on stage 3 ECMAScript syntax proposals (as long as they are implemented using the correct experimental ESTree syntax). We may make changes to core rules to better work with language extensions (such as JSX, Flow, and TypeScript) on a case-by-case basis.
149
+
150
+ In other cases (including if rules need to warn on more or fewer cases due to new syntax, rather than just not crashing), we recommend you use other parsers and/or rule plugins. If you are using Babel, you can use the [babel-eslint](https://github.com/babel/babel-eslint) parser and [eslint-plugin-babel](https://github.com/babel/eslint-plugin-babel) to use any option available in Babel.
149
151
 
150
152
  Once a language feature has been adopted into the ECMAScript standard (stage 4 according to the [TC39 process](https://tc39.github.io/process-document/)), we will accept issues and pull requests related to the new feature, subject to our [contributing guidelines](https://eslint.org/docs/developer-guide/contributing). Until then, please use the appropriate parser and plugin(s) for your experimental feature.
151
153
 
@@ -155,7 +157,7 @@ Join our [Mailing List](https://groups.google.com/group/eslint) or [Chatroom](ht
155
157
 
156
158
  ## Releases
157
159
 
158
- We have scheduled releases every two weeks on Friday or Saturday.
160
+ We have scheduled releases every two weeks on Friday or Saturday. You can follow a [release issue](https://github.com/eslint/eslint/issues?q=is%3Aopen+is%3Aissue+label%3Arelease) for updates about the scheduling of any particular release.
159
161
 
160
162
  ## Semantic Versioning Policy
161
163
 
@@ -193,34 +195,148 @@ These folks keep the project moving and are resources for help.
193
195
 
194
196
  ### Technical Steering Committee (TSC)
195
197
 
196
- * Nicholas C. Zakas ([@nzakas](https://github.com/nzakas))
197
- * Ilya Volodin ([@ilyavolodin](https://github.com/ilyavolodin))
198
- * Brandon Mills ([@btmills](https://github.com/btmills))
199
- * Gyandeep Singh ([@gyandeeps](https://github.com/gyandeeps))
200
- * Toru Nagashima ([@mysticatea](https://github.com/mysticatea))
201
- * Alberto Rodríguez ([@alberto](https://github.com/alberto))
202
- * Kai Cataldo ([@kaicataldo](https://github.com/kaicataldo))
203
- * Teddy Katz ([@not-an-aardvark](https://github.com/not-an-aardvark))
204
- * Kevin Partington ([@platinumazure](https://github.com/platinumazure))
198
+ <table>
199
+ <tbody>
200
+ <tr>
201
+ <td align="center" valign="top" width="11%">
202
+ <a href="https://github.com/nzakas">
203
+ <img src="https://github.com/nzakas.png?s=75" width="75px" height="75px"><br/>
204
+ <sub>Nicholas C. Zakas</sub></a>
205
+ </td>
206
+ <td align="center" valign="top" width="11%">
207
+ <a href="https://github.com/ilyavolodin">
208
+ <img src="https://github.com/ilyavolodin.png?s=75" width="75px" height="75px"><br/>
209
+ <sub>Ilya Volodin</sub></a>
210
+ </td>
211
+ <td align="center" valign="top" width="11%">
212
+ <a href="https://github.com/btmills">
213
+ <img src="https://github.com/btmills.png?s=75" width="75px" height="75px"><br/>
214
+ <sub>Brandon Mills</sub></a>
215
+ </td>
216
+ <td align="center" valign="top" width="11%">
217
+ <a href="https://github.com/gyandeeps">
218
+ <img src="https://github.com/gyandeeps.png?s=75" width="75px" height="75px"><br/>
219
+ <sub>Gyandeep Singh</sub></a>
220
+ </td>
221
+ <td align="center" valign="top" width="11%">
222
+ <a href="https://github.com/mysticatea">
223
+ <img src="https://github.com/mysticatea.png?s=75" width="75px" height="75px"><br/>
224
+ <sub>Toru Nagashima</sub></a>
225
+ </td>
226
+ <td align="center" valign="top" width="11%">
227
+ <a href="https://github.com/alberto">
228
+ <img src="https://github.com/alberto.png?s=75" width="75px" height="75px"><br/>
229
+ <sub>Alberto Rodríguez</sub></a>
230
+ </td>
231
+ <td align="center" valign="top" width="11%">
232
+ <a href="https://github.com/kaicataldo">
233
+ <img src="https://github.com/kaicataldo.png?s=75" width="75px" height="75px"><br/>
234
+ <sub>Kai Cataldo</sub></a>
235
+ </td>
236
+ <td align="center" valign="top" width="11%">
237
+ <a href="https://github.com/not-an-aardvark">
238
+ <img src="https://github.com/not-an-aardvark.png?s=75" width="75px" height="75px"><br/>
239
+ <sub>Teddy Katz</sub></a>
240
+ </td>
241
+ <td align="center" valign="top" width="11%">
242
+ <a href="https://github.com/platinumazure">
243
+ <img src="https://github.com/platinumazure.png?s=75" width="75px" height="75px"><br/>
244
+ <sub>Kevin Partington</sub></a>
245
+ </td>
246
+ </tr>
247
+ </tbody>
248
+ </table>
205
249
 
206
250
  ### Development Team
207
251
 
208
- * Mathias Schreck ([@lo1tuma](https://github.com/lo1tuma))
209
- * Jamund Ferguson ([@xjamundx](https://github.com/xjamundx))
210
- * Ian VanSchooten ([@ianvs](https://github.com/ianvs))
211
- * Burak Yiğit Kaya ([@byk](https://github.com/byk))
212
- * Michael Ficarra ([@michaelficarra](https://github.com/michaelficarra))
213
- * Mark Pedrotti ([@pedrottimark](https://github.com/pedrottimark))
214
- * Oleg Gaidarenko ([@markelog](https://github.com/markelog))
215
- * Mike Sherov ([@mikesherov](https://github.com/mikesherov))
216
- * Henry Zhu ([@hzoo](https://github.com/hzoo))
217
- * Marat Dulin ([@mdevils](https://github.com/mdevils))
218
- * Alexej Yaroshevich ([@zxqfox](https://github.com/zxqfox))
219
- * Vitor Balocco ([@vitorbal](https://github.com/vitorbal))
220
- * James Henry ([@JamesHenry](https://github.com/JamesHenry))
221
- * Reyad Attiyat ([@soda0289](https://github.com/soda0289))
222
- * 薛定谔的猫 ([@Aladdin-ADD](https://github.com/Aladdin-ADD))
223
- * Victor Hom ([@VictorHom](https://github.com/VictorHom))
252
+ <table>
253
+ <tbody>
254
+ <tr>
255
+ <td align="center" valign="top" width="11%">
256
+ <a href="https://github.com/lo1tuma">
257
+ <img src="https://github.com/lo1tuma.png?s=75" width="75px" height="75px"><br/>
258
+ <sub>Mathias Schreck</sub></a>
259
+ </td>
260
+ <td align="center" valign="top" width="11%">
261
+ <a href="https://github.com/xjamundx">
262
+ <img src="https://github.com/xjamundx.png?s=75" width="75px" height="75px"><br/>
263
+ <sub>Jamund Ferguson</sub></a>
264
+ </td>
265
+ <td align="center" valign="top" width="11%">
266
+ <a href="https://github.com/ianvs">
267
+ <img src="https://github.com/ianvs.png?s=75" width="75px" height="75px"><br/>
268
+ <sub>Ian VanSchooten</sub></a>
269
+ </td>
270
+ <td align="center" valign="top" width="11%">
271
+ <a href="https://github.com/byk">
272
+ <img src="https://github.com/byk.png?s=75" width="75px" height="75px"><br/>
273
+ <sub>Burak Yiğit Kaya</sub></a>
274
+ </td>
275
+ <td align="center" valign="top" width="11%">
276
+ <a href="https://github.com/michaelficarra">
277
+ <img src="https://github.com/michaelficarra.png?s=75" width="75px" height="75px"><br/>
278
+ <sub>Michael Ficarra</sub></a>
279
+ </td>
280
+ <td align="center" valign="top" width="11%">
281
+ <a href="https://github.com/pedrottimark">
282
+ <img src="https://github.com/pedrottimark.png?s=75" width="75px" height="75px"><br/>
283
+ <sub>Mark Pedrotti</sub></a>
284
+ </td>
285
+ <td align="center" valign="top" width="11%">
286
+ <a href="https://github.com/markelog">
287
+ <img src="https://github.com/markelog.png?s=75" width="75px" height="75px"><br/>
288
+ <sub>Oleg Gaidarenko</sub></a>
289
+ </td>
290
+ <td align="center" valign="top" width="11%">
291
+ <a href="https://github.com/mikesherov">
292
+ <img src="https://github.com/mikesherov.png?s=75" width="75px" height="75px"><br/>
293
+ <sub>Mike Sherov</sub></a>
294
+ </td>
295
+ </tr>
296
+ <tr>
297
+ <td align="center" valign="top" width="11%">
298
+ <a href="https://github.com/hzoo">
299
+ <img src="https://github.com/hzoo.png?s=75" width="75px" height="75px"><br/>
300
+ <sub>Henry Zhu</sub></a>
301
+ </td>
302
+ <td align="center" valign="top" width="11%">
303
+ <a href="https://github.com/mdevils">
304
+ <img src="https://github.com/mdevils.png?s=75" width="75px" height="75px"><br/>
305
+ <sub>Marat Dulin</sub></a>
306
+ </td>
307
+ <td align="center" valign="top" width="11%">
308
+ <a href="https://github.com/zxqfox">
309
+ <img src="https://github.com/zxqfox.png?s=75" width="75px" height="75px"><br/>
310
+ <sub>Alexej Yaroshevich</sub></a>
311
+ </td>
312
+ <td align="center" valign="top" width="11%">
313
+ <a href="https://github.com/vitorbal">
314
+ <img src="https://github.com/vitorbal.png?s=75" width="75px" height="75px"><br/>
315
+ <sub>Vitor Balocco</sub></a>
316
+ </td>
317
+ <td align="center" valign="top" width="11%">
318
+ <a href="https://github.com/JamesHenry">
319
+ <img src="https://github.com/JamesHenry.png?s=75" width="75px" height="75px"><br/>
320
+ <sub>James Henry</sub></a>
321
+ </td>
322
+ <td align="center" valign="top" width="11%">
323
+ <a href="https://github.com/soda0289">
324
+ <img src="https://github.com/soda0289.png?s=75" width="75px" height="75px"><br/>
325
+ <sub>Reyad Attiyat</sub></a>
326
+ </td>
327
+ <td align="center" valign="top" width="11%">
328
+ <a href="https://github.com/Aladdin-ADD">
329
+ <img src="https://github.com/Aladdin-ADD.png?s=75" width="75px" height="75px"><br/>
330
+ <sub>薛定谔的猫</sub></a>
331
+ </td>
332
+ <td align="center" valign="top" width="11%">
333
+ <a href="https://github.com/VictorHom">
334
+ <img src="https://github.com/VictorHom.png?s=75" width="75px" height="75px"><br/>
335
+ <sub>Victor Hom</sub></a>
336
+ </td>
337
+ </tr>
338
+ </tbody>
339
+ </table>
224
340
 
225
341
  ## Sponsors
226
342
 
@@ -69,6 +69,7 @@ module.exports = {
69
69
  "max-depth": "off",
70
70
  "max-len": "off",
71
71
  "max-lines": "off",
72
+ "max-lines-per-function": "off",
72
73
  "max-nested-callbacks": "off",
73
74
  "max-params": "off",
74
75
  "max-statements": "off",
@@ -30,6 +30,17 @@ function isCaseNode(node) {
30
30
  return Boolean(node.test);
31
31
  }
32
32
 
33
+ /**
34
+ * Checks whether the given logical operator is taken into account for the code
35
+ * path analysis.
36
+ *
37
+ * @param {string} operator - The operator found in the LogicalExpression node
38
+ * @returns {boolean} `true` if the operator is "&&" or "||"
39
+ */
40
+ function isHandledLogicalOperator(operator) {
41
+ return operator === "&&" || operator === "||";
42
+ }
43
+
33
44
  /**
34
45
  * Checks whether or not a given logical expression node goes different path
35
46
  * between the `true` case and the `false` case.
@@ -49,7 +60,7 @@ function isForkingByTrueOrFalse(node) {
49
60
  return parent.test === node;
50
61
 
51
62
  case "LogicalExpression":
52
- return true;
63
+ return isHandledLogicalOperator(parent.operator);
53
64
 
54
65
  default:
55
66
  return false;
@@ -230,7 +241,10 @@ function preprocess(analyzer, node) {
230
241
 
231
242
  switch (parent.type) {
232
243
  case "LogicalExpression":
233
- if (parent.right === node) {
244
+ if (
245
+ parent.right === node &&
246
+ isHandledLogicalOperator(parent.operator)
247
+ ) {
234
248
  state.makeLogicalRight();
235
249
  }
236
250
  break;
@@ -361,7 +375,12 @@ function processCodePathToEnter(analyzer, node) {
361
375
  break;
362
376
 
363
377
  case "LogicalExpression":
364
- state.pushChoiceContext(node.operator, isForkingByTrueOrFalse(node));
378
+ if (isHandledLogicalOperator(node.operator)) {
379
+ state.pushChoiceContext(
380
+ node.operator,
381
+ isForkingByTrueOrFalse(node)
382
+ );
383
+ }
365
384
  break;
366
385
 
367
386
  case "ConditionalExpression":
@@ -430,10 +449,15 @@ function processCodePathToExit(analyzer, node) {
430
449
  switch (node.type) {
431
450
  case "IfStatement":
432
451
  case "ConditionalExpression":
433
- case "LogicalExpression":
434
452
  state.popChoiceContext();
435
453
  break;
436
454
 
455
+ case "LogicalExpression":
456
+ if (isHandledLogicalOperator(node.operator)) {
457
+ state.popChoiceContext();
458
+ }
459
+ break;
460
+
437
461
  case "SwitchStatement":
438
462
  state.popSwitchContext();
439
463
  break;
@@ -115,6 +115,11 @@ function loadJSONConfigFile(filePath) {
115
115
  } catch (e) {
116
116
  debug(`Error reading JSON file: ${filePath}`);
117
117
  e.message = `Cannot read config file: ${filePath}\nError: ${e.message}`;
118
+ e.messageTemplate = "failed-to-read-json";
119
+ e.messageData = {
120
+ path: filePath,
121
+ message: e.message
122
+ };
118
123
  throw e;
119
124
  }
120
125
  }
@@ -239,15 +239,16 @@ function configureRules(answers, config) {
239
239
  * @returns {Object} config object
240
240
  */
241
241
  function processAnswers(answers) {
242
- let config = { rules: {}, env: {} };
242
+ let config = { rules: {}, env: {}, parserOptions: {} };
243
243
 
244
- if (answers.es6) {
245
- config.env.es6 = true;
244
+ config.parserOptions.ecmaVersion = answers.ecmaVersion;
245
+ if (answers.ecmaVersion >= 2015) {
246
246
  if (answers.modules) {
247
- config.parserOptions = config.parserOptions || {};
248
247
  config.parserOptions.sourceType = "module";
249
248
  }
249
+ config.env.es6 = true;
250
250
  }
251
+
251
252
  if (answers.commonjs) {
252
253
  config.env.commonjs = true;
253
254
  }
@@ -514,10 +515,18 @@ function promptUser() {
514
515
  // continue with the questions otherwise...
515
516
  return inquirer.prompt([
516
517
  {
517
- type: "confirm",
518
- name: "es6",
519
- message: "Are you using ECMAScript 6 features?",
520
- default: false
518
+ type: "list",
519
+ name: "ecmaVersion",
520
+ message: "Which version of ECMAScript do you use?",
521
+ choices: [
522
+ { name: "ES3", value: 3 },
523
+ { name: "ES5", value: 5 },
524
+ { name: "ES2015", value: 2015 },
525
+ { name: "ES2016", value: 2016 },
526
+ { name: "ES2017", value: 2017 },
527
+ { name: "ES2018", value: 2018 }
528
+ ],
529
+ default: 1 // This is the index in the choices list
521
530
  },
522
531
  {
523
532
  type: "confirm",
@@ -525,7 +534,7 @@ function promptUser() {
525
534
  message: "Are you using ES6 modules?",
526
535
  default: false,
527
536
  when(answers) {
528
- return answers.es6 === true;
537
+ return answers.ecmaVersion >= 2015;
529
538
  }
530
539
  },
531
540
  {
@@ -614,7 +623,7 @@ function promptUser() {
614
623
  const config = processAnswers(totalAnswers);
615
624
  const modules = getModulesList(config);
616
625
 
617
- return askInstallModules(modules).then(() => writeFile(config, earlyAnswers.format));
626
+ return askInstallModules(modules).then(() => writeFile(config, answers.format));
618
627
  });
619
628
  });
620
629
  });
@@ -23,10 +23,15 @@ const ruleValidators = new WeakMap();
23
23
  let validateSchema;
24
24
 
25
25
  // Defitions for deprecation warnings.
26
- const deprecationWarningMessages = Object.freeze({
26
+ const deprecationWarningMessages = {
27
27
  ESLINT_LEGACY_ECMAFEATURES: "The 'ecmaFeatures' config file property is deprecated, and has no effect.",
28
28
  ESLINT_LEGACY_OBJECT_REST_SPREAD: "The 'parserOptions.ecmaFeatures.experimentalObjectRestSpread' option is deprecated. Use 'parserOptions.ecmaVersion' instead."
29
- });
29
+ };
30
+ const severityMap = {
31
+ error: 2,
32
+ warn: 1,
33
+ off: 0
34
+ };
30
35
 
31
36
  /**
32
37
  * Gets a complete options schema for a rule.
@@ -65,12 +70,14 @@ function getRuleOptionsSchema(rule) {
65
70
  */
66
71
  function validateRuleSeverity(options) {
67
72
  const severity = Array.isArray(options) ? options[0] : options;
73
+ const normSeverity = typeof severity === "string" ? severityMap[severity.toLowerCase()] : severity;
68
74
 
69
- if (severity !== 0 && severity !== 1 && severity !== 2 && !(typeof severity === "string" && /^(?:off|warn|error)$/i.test(severity))) {
70
- throw new Error(`\tSeverity should be one of the following: 0 = off, 1 = warn, 2 = error (you passed '${util.inspect(severity).replace(/'/g, "\"").replace(/\n/g, "")}').\n`);
75
+ if (normSeverity === 0 || normSeverity === 1 || normSeverity === 2) {
76
+ return normSeverity;
71
77
  }
72
78
 
73
- return severity;
79
+ throw new Error(`\tSeverity should be one of the following: 0 = off, 1 = warn, 2 = error (you passed '${util.inspect(severity).replace(/'/g, "\"").replace(/\n/g, "")}').\n`);
80
+
74
81
  }
75
82
 
76
83
  /**
@@ -116,7 +123,7 @@ function validateRuleOptions(rule, ruleId, options, source) {
116
123
  try {
117
124
  const severity = validateRuleSeverity(options);
118
125
 
119
- if (severity !== 0 && !(typeof severity === "string" && severity.toLowerCase() === "off")) {
126
+ if (severity !== 0) {
120
127
  validateRuleSchema(rule, Array.isArray(options) ? options.slice(1) : []);
121
128
  }
122
129
  } catch (err) {
package/lib/config.js CHANGED
@@ -209,7 +209,7 @@ class Config {
209
209
  const localConfigHierarchyCache = this.configCache.getHierarchyLocalConfigs(localConfigDirectory);
210
210
 
211
211
  if (localConfigHierarchyCache) {
212
- const localConfigHierarchy = localConfigHierarchyCache.concat(configs.reverse());
212
+ const localConfigHierarchy = localConfigHierarchyCache.concat(configs);
213
213
 
214
214
  this.configCache.setHierarchyLocalConfigs(searched, localConfigHierarchy);
215
215
  return localConfigHierarchy;
@@ -232,7 +232,7 @@ class Config {
232
232
  }
233
233
 
234
234
  debug(`Using ${localConfigFile}`);
235
- configs.push(localConfig);
235
+ configs.unshift(localConfig);
236
236
  searched.push(localConfigDirectory);
237
237
 
238
238
  // Stop traversing if a config is found with the root flag set
@@ -248,7 +248,7 @@ class Config {
248
248
  const personalConfig = this.getPersonalConfig();
249
249
 
250
250
  if (personalConfig) {
251
- configs.push(personalConfig);
251
+ configs.unshift(personalConfig);
252
252
  } else if (!hasRules(this.options) && !this.options.baseConfig) {
253
253
 
254
254
  // No config file, no manual configuration, and no rules, so error.
@@ -265,7 +265,7 @@ class Config {
265
265
  }
266
266
 
267
267
  // Set the caches for the parent directories
268
- this.configCache.setHierarchyLocalConfigs(searched, configs.reverse());
268
+ this.configCache.setHierarchyLocalConfigs(searched, configs);
269
269
 
270
270
  return configs;
271
271
  }
@@ -89,7 +89,7 @@ module.exports = function(results) {
89
89
 
90
90
  if (fixableErrorCount > 0 || fixableWarningCount > 0) {
91
91
  output += chalk[summaryColor].bold([
92
- " ", fixableErrorCount, pluralize(" error", fixableErrorCount), ", ",
92
+ " ", fixableErrorCount, pluralize(" error", fixableErrorCount), " and ",
93
93
  fixableWarningCount, pluralize(" warning", fixableWarningCount),
94
94
  " potentially fixable with the `--fix` option.\n"
95
95
  ].join(""));
@@ -176,6 +176,11 @@ class IgnoredPaths {
176
176
  packageJSONOptions = JSON.parse(fs.readFileSync(packageJSONPath, "utf8"));
177
177
  } catch (e) {
178
178
  debug("Could not read package.json file to check eslintIgnore property");
179
+ e.messageTemplate = "failed-to-read-json";
180
+ e.messageData = {
181
+ path: packageJSONPath,
182
+ message: e.message
183
+ };
179
184
  throw e;
180
185
  }
181
186
 
@@ -231,7 +236,7 @@ class IgnoredPaths {
231
236
  /**
232
237
  * Determine whether a file path is included in the default or custom ignore patterns
233
238
  * @param {string} filepath Path to check
234
- * @param {string} [category=null] check 'default', 'custom' or both (null)
239
+ * @param {string} [category=undefined] check 'default', 'custom' or both (undefined)
235
240
  * @returns {boolean} true if the file path matches one or more patterns, false otherwise
236
241
  */
237
242
  contains(filepath, category) {
@@ -240,12 +245,11 @@ class IgnoredPaths {
240
245
  const absolutePath = path.resolve(this.options.cwd, filepath);
241
246
  const relativePath = pathUtil.getRelativePath(absolutePath, this.baseDir);
242
247
 
243
- if ((typeof category === "undefined") || (category === "default")) {
244
- result = result || (this.ig.default.filter([relativePath]).length === 0);
245
- }
246
-
247
- if ((typeof category === "undefined") || (category === "custom")) {
248
- result = result || (this.ig.custom.filter([relativePath]).length === 0);
248
+ if (typeof category === "undefined") {
249
+ result = (this.ig.default.filter([relativePath]).length === 0) ||
250
+ (this.ig.custom.filter([relativePath]).length === 0);
251
+ } else {
252
+ result = (this.ig[category].filter([relativePath]).length === 0);
249
253
  }
250
254
 
251
255
  return result;
@@ -22,6 +22,9 @@ module.exports = {
22
22
  {
23
23
  type: "object",
24
24
  properties: {
25
+ ignoreDestructuring: {
26
+ type: "boolean"
27
+ },
25
28
  properties: {
26
29
  enum: ["always", "never"]
27
30
  }
@@ -57,6 +60,26 @@ module.exports = {
57
60
  return name.indexOf("_") > -1 && name !== name.toUpperCase();
58
61
  }
59
62
 
63
+ /**
64
+ * Checks if a parent of a node is an ObjectPattern.
65
+ * @param {ASTNode} node The node to check.
66
+ * @returns {boolean} if the node is inside an ObjectPattern
67
+ * @private
68
+ */
69
+ function isInsideObjectPattern(node) {
70
+ let { parent } = node;
71
+
72
+ while (parent) {
73
+ if (parent.type === "ObjectPattern") {
74
+ return true;
75
+ }
76
+
77
+ parent = parent.parent;
78
+ }
79
+
80
+ return false;
81
+ }
82
+
60
83
  /**
61
84
  * Reports an AST node as a rule violation.
62
85
  * @param {ASTNode} node The node to report.
@@ -72,6 +95,7 @@ module.exports = {
72
95
 
73
96
  const options = context.options[0] || {};
74
97
  let properties = options.properties || "";
98
+ const ignoreDestructuring = options.ignoreDestructuring || false;
75
99
 
76
100
  if (properties !== "always" && properties !== "never") {
77
101
  properties = "always";
@@ -113,24 +137,28 @@ module.exports = {
113
137
  } else if (node.parent.type === "Property" || node.parent.type === "AssignmentPattern") {
114
138
 
115
139
  if (node.parent.parent && node.parent.parent.type === "ObjectPattern") {
116
-
117
140
  if (node.parent.shorthand && node.parent.value.left && isUnderscored(name)) {
118
141
 
119
142
  report(node);
120
143
  }
121
144
 
145
+ const assignmentKeyEqualsValue = node.parent.key.name === node.parent.value.name;
146
+
122
147
  // prevent checking righthand side of destructured object
123
- if (node.parent.key === node && node.parent.value !== node) {
148
+ if (!assignmentKeyEqualsValue && node.parent.key === node) {
124
149
  return;
125
150
  }
126
151
 
127
- if (node.parent.value.name && isUnderscored(name)) {
152
+ const valueIsUnderscored = node.parent.value.name && isUnderscored(name);
153
+
154
+ // ignore destructuring if the option is set, unless a new identifier is created
155
+ if (valueIsUnderscored && !(assignmentKeyEqualsValue && ignoreDestructuring)) {
128
156
  report(node);
129
157
  }
130
158
  }
131
159
 
132
- // "never" check properties
133
- if (properties === "never") {
160
+ // "never" check properties or always ignore destructuring
161
+ if (properties === "never" || (ignoreDestructuring && isInsideObjectPattern(node))) {
134
162
  return;
135
163
  }
136
164