eslint 4.5.0 → 4.7.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.
Files changed (49) hide show
  1. package/CHANGELOG.md +98 -0
  2. package/bin/eslint.js +2 -1
  3. package/conf/eslint-recommended.js +1 -0
  4. package/lib/ast-utils.js +20 -17
  5. package/lib/cli-engine.js +51 -124
  6. package/lib/code-path-analysis/code-path-analyzer.js +8 -4
  7. package/lib/code-path-analysis/code-path-segment.js +2 -1
  8. package/lib/code-path-analysis/code-path-state.js +21 -14
  9. package/lib/code-path-analysis/code-path.js +3 -2
  10. package/lib/code-path-analysis/fork-context.js +2 -1
  11. package/lib/config/autoconfig.js +2 -4
  12. package/lib/config/config-initializer.js +9 -5
  13. package/lib/config/config-ops.js +15 -15
  14. package/lib/config.js +8 -12
  15. package/lib/formatters/codeframe.js +1 -1
  16. package/lib/formatters/stylish.js +1 -1
  17. package/lib/ignored-paths.js +0 -2
  18. package/lib/linter.js +468 -638
  19. package/lib/report-translator.js +274 -0
  20. package/lib/rules/function-paren-newline.js +221 -0
  21. package/lib/rules/generator-star-spacing.js +70 -19
  22. package/lib/rules/indent-legacy.js +3 -2
  23. package/lib/rules/indent.js +15 -6
  24. package/lib/rules/key-spacing.js +2 -1
  25. package/lib/rules/newline-per-chained-call.js +20 -3
  26. package/lib/rules/no-extra-parens.js +75 -33
  27. package/lib/rules/no-invalid-this.js +2 -1
  28. package/lib/rules/no-tabs.js +1 -1
  29. package/lib/rules/no-undef-init.js +4 -0
  30. package/lib/rules/no-unmodified-loop-condition.js +1 -1
  31. package/lib/rules/no-unused-vars.js +47 -4
  32. package/lib/rules/padded-blocks.js +2 -2
  33. package/lib/rules/prefer-arrow-callback.js +1 -2
  34. package/lib/rules/quote-props.js +4 -2
  35. package/lib/rules/quotes.js +1 -2
  36. package/lib/rules/space-before-blocks.js +1 -1
  37. package/lib/rules/valid-jsdoc.js +2 -2
  38. package/lib/rules.js +48 -3
  39. package/lib/testers/rule-tester.js +27 -51
  40. package/lib/timing.js +2 -2
  41. package/lib/util/apply-disable-directives.js +131 -0
  42. package/lib/util/fix-tracker.js +1 -2
  43. package/lib/util/npm-util.js +21 -4
  44. package/lib/util/source-code-fixer.js +5 -14
  45. package/lib/util/source-code.js +3 -5
  46. package/package.json +8 -8
  47. package/lib/rule-context.js +0 -241
  48. package/lib/testers/event-generator-tester.js +0 -62
  49. package/lib/testers/test-parser.js +0 -48
package/CHANGELOG.md CHANGED
@@ -1,3 +1,101 @@
1
+ v4.7.1 - September 18, 2017
2
+
3
+ * 08656db Fix: Handle nested disable directive correctly (fixes #9318) (#9322) (Gyandeep Singh)
4
+ * 9226495 Revert "Chore: rewrite parseListConfig for a small perf gain." (#9325) (薛定谔的猫)
5
+
6
+ v4.7.0 - September 15, 2017
7
+
8
+ * 787b78b Upgrade: Espree v3.5.1 (fixes #9153) (#9314) (Brandon Mills)
9
+ * 1488b51 Update: run rules after `node.parent` is already set (fixes #9122) (#9283) (Teddy Katz)
10
+ * 4431d68 Docs: fix wrong config in max-len example. (#9309) (薛定谔的猫)
11
+ * 7d24dde Docs: Fix code snippet to refer to the correct option (#9313) (Ruben Tytgat)
12
+ * 12388d4 Chore: rewrite parseListConfig for a small perf gain. (#9300) (薛定谔的猫)
13
+ * ce1f084 Update: fix MemberExpression handling in no-extra-parens (fixes #9156) (jackyho112)
14
+ * 0c720a3 Update: allow autofixing when using processors (fixes #7510) (#9090) (Teddy Katz)
15
+ * 838df76 Chore: upgrade deps. (#9289) (薛定谔的猫)
16
+ * f12def6 Update: indent flatTernary option to handle `return` (fixes #9285) (#9296) (Teddy Katz)
17
+ * e220687 Fix: remove autofix for var undef inits (fixes #9231) (#9288) (Victor Hom)
18
+ * 002e199 Docs: fix no-restricted-globals wrong config. (#9305) (薛定谔的猫)
19
+ * fcfe91a Docs: fix wrong config in id-length example. (#9303) (薛定谔的猫)
20
+ * 2731f94 Update: make newline-per-chained-call fixable (#9149) (João Granado)
21
+ * 61f1093 Chore: avoid monkeypatching Linter instances in RuleTester (#9276) (Teddy Katz)
22
+ * 28929cb Chore: remove Linter#reset (refs #9161) (#9268) (Teddy Katz)
23
+ * abc8634 Build: re-run browserify when generating site (#9275) (Teddy Katz)
24
+ * 7685fed Fix: IIFE and arrow functions in no-invalid-this (fixes #9126) (#9258) (Toru Nagashima)
25
+ * 2b1eba2 Chore: enable eslint-plugin/no-deprecated-context-methods (#9279) (Teddy Katz)
26
+ * 981f933 Fix: reuse the AST of source code object in verify (#9256) (Toru Nagashima)
27
+ * cd698ba Docs: move RuleTester documentation to Node.js API page (#9273) (Teddy Katz)
28
+ * 4ae7ad3 Docs: fix inaccuracy in `npm run perf` description (#9274) (Teddy Katz)
29
+ * cad45bd Docs: improve documentation for rule contexts (#9272) (Teddy Katz)
30
+ * 3b0c6fd Chore: remove extraneous linter properties (refs #9161) (#9267) (Teddy Katz)
31
+ * c3231b3 Docs: Fix typo in array-bracket-newline.md (#9269) (宋文强)
32
+ * 51132d6 Fix: Formatters keep trailing '.' if preceded by a space (fixes #9154) (#9247) (i-ron-y)
33
+ * 88d5d4d Chore: remove undocumented Linter#markVariableAsUsed method (refs #9161) (#9266) (Teddy Katz)
34
+ * 09414cf Chore: remove internal Linter#getDeclaredVariables method (refs #9161) (#9264) (Teddy Katz)
35
+ * f31f59d Chore: prefer smaller scope for variables in codebase (#9265) (Teddy Katz)
36
+ * 3693e4e Chore: remove undocumented Linter#getScope method (#9253) (Teddy Katz)
37
+ * 5d7eb81 Chore: refactor config hash caching in CLIEngine (#9260) (Teddy Katz)
38
+ * 1a76c4d Chore: remove SourceCode passthroughs from Linter.prototype (refs #9161) (#9263) (Teddy Katz)
39
+ * 40ae27b Chore: avoid relying on Linter#getScope/markVariableAsUsed in tests (#9252) (Teddy Katz)
40
+ * b383d81 Chore: make executeOnFile a pure function in CLIEngine (#9262) (Teddy Katz)
41
+ * 5e0e579 Chore: avoid internal SourceCode methods in Linter tests (refs #9161) (#9223) (Teddy Katz)
42
+ * adab827 Chore: remove unused eslint-disable comment (#9251) (Teddy Katz)
43
+ * 31e4ec8 Chore: use consistent names for apply-disable-directives in tests (#9246) (Teddy Katz)
44
+ * 7ba46e6 Fix: shebang error in eslint-disable-new-line; add tests (fixes #9238) (#9240) (i-ron-y)
45
+ * 8f6546c Chore: remove undocumented defaults() method (refs #9161) (#9237) (Teddy Katz)
46
+ * 82d8b73 Docs: Fix error in example code for sort-imports (fixes #8734) (#9245) (i-ron-y)
47
+ * a32ec36 Update: refactor eslint-disable comment processing (#9216) (Teddy Katz)
48
+ * 583f0b8 Chore: avoid using globals in CLIEngine tests (#9242) (Teddy Katz)
49
+ * c8bf687 Chore: upgrade eslint-plugin-eslint-plugin@1.0.0 (#9234) (薛定谔的猫)
50
+ * 3c41a05 Chore: always normalize rules to new API in rules.js (#9236) (Teddy Katz)
51
+ * c5f4227 Chore: move logic for handling missing rules to rules.js (#9235) (Teddy Katz)
52
+ * bf1e344 Chore: create report translators lazily (#9221) (Teddy Katz)
53
+ * 2eedc1f Chore: remove currentFilename prop from Linter instances (refs #9161) (#9219) (Teddy Katz)
54
+ * 5566e94 Docs: Replace misleading CLA links (#9133) (#9232) (i-ron-y)
55
+ * c991630 Chore: remove ConfigOps.normalize in favor of ConfigOps.getRuleSeverity (#9224) (Teddy Katz)
56
+ * 171962a Chore: remove internal Linter#getAncestors helper (refs #9161) (#9222) (Teddy Katz)
57
+ * a567499 Chore: avoid storing list of problems on Linter instance (refs #9161) (#9214) (Teddy Katz)
58
+ * ed6d088 Chore: avoid relying on undocumented Linter#getFilename API in tests (#9218) (Teddy Katz)
59
+
60
+ v4.6.1 - September 3, 2017
61
+
62
+ * bdec46d Build: avoid process leak when generating website (#9217) (Teddy Katz)
63
+ * cb74b87 Fix: avoid adding globals when an env is used with `false` (fixes #9202) (#9203) (Teddy Katz)
64
+ * f9b7544 Docs: Correct a typo in generator-star-spacing documentation (#9205) (Ethan Rutherford)
65
+ * e5c5e83 Build: Fixing issue with docs generation (Fixes #9199) (#9200) (Ilya Volodin)
66
+
67
+ v4.6.0 - September 1, 2017
68
+
69
+ * 56dd769 Docs: fix link format in prefer-arrow-callback.md (#9198) (Vse Mozhet Byt)
70
+ * 6becf91 Update: add eslint version to error output. (fixes #9037) (#9071) (薛定谔的猫)
71
+ * 0e09973 New: function-paren-newline rule (fixes #6074) (#8102) (Teddy Katz)
72
+ * 88a64cc Chore: Make parseJsonConfig() a pure function in Linter (#9186) (Teddy Katz)
73
+ * 1bbac51 Fix: avoid breaking eslint-plugin-eslint-comments (fixes #9193) (#9196) (Teddy Katz)
74
+ * 3e8b70a Fix: off-by-one error in eslint-disable comment checking (#9195) (Teddy Katz)
75
+ * 73815f6 Docs: rewrite prefer-arrow-callback documentation (fixes #8950) (#9077) (Charles E. Morgan)
76
+ * 0d3a854 Chore: avoid mutating report descriptors in report-translator (#9189) (Teddy Katz)
77
+ * 2db356b Update: no-unused-vars Improve message to include the allowed patterns (#9176) (Eli White)
78
+ * 8fbaf0a Update: Add configurability to generator-star-spacing (#8985) (Ethan Rutherford)
79
+ * 8ed779c Chore: remove currentScopes property from Linter instances (refs #9161) (#9187) (Teddy Katz)
80
+ * af4ad60 Fix: Handle error when running init without npm (#9169) (Gabriel Aumala)
81
+ * 4b94c6c Chore: make parse() a pure function in Linter (refs #9161) (#9183) (Teddy Katz)
82
+ * 1be5634 Chore: don't make Linter a subclass of EventEmitter (refs #9161) (#9177) (Teddy Katz)
83
+ * e95af9b Chore: don't include internal test helpers in npm package (#9160) (Teddy Katz)
84
+ * 6fb32e1 Chore: avoid using private Linter APIs in astUtils tests (refs #9161) (#9173) (Teddy Katz)
85
+ * de6dccd Docs: add documentation for Linter methods (refs #6525) (#9151) (Teddy Katz)
86
+ * 2d90030 Chore: remove unused assignment. (#9182) (薛定谔的猫)
87
+ * d672aef Chore: refactor reporting logic (refs #9161) (#9168) (Teddy Katz)
88
+ * 5ab0434 Fix: indent crash on sparse arrays with "off" option (fixes #9157) (#9166) (Teddy Katz)
89
+ * c147b97 Chore: Make SourceCodeFixer accept text instead of a SourceCode instance (#9178) (Teddy Katz)
90
+ * f127423 Chore: avoid using private Linter APIs in Linter tests (refs #9161) (#9175) (Teddy Katz)
91
+ * 2334335 Chore: avoid using private Linter APIs in SourceCode tests (refs #9161) (#9174) (Teddy Katz)
92
+ * 2dc243a Chore: avoid using internal Linter APIs in RuleTester (refs #9161) (#9172) (Teddy Katz)
93
+ * d6e436f Fix: no-extra-parens reported some parenthesized IIFEs (fixes #9140) (#9158) (Teddy Katz)
94
+ * e6b115c Build: Add an edit link to the rule docs’ metadata (#9049) (Jed Fox)
95
+ * fcb7bb4 Chore: avoid unnecessarily complex forEach calls in no-extra-parens (#9159) (Teddy Katz)
96
+ * ffa021e Docs: quotes rule - when does \n require backticks (#9135) (avimar)
97
+ * 60c5148 Chore: improve coverage in lib/*.js (#9130) (Teddy Katz)
98
+
1
99
  v4.5.0 - August 18, 2017
2
100
 
3
101
  * decdd2c Update: allow arbitrary nodes to be ignored in `indent` (fixes #8594) (#9105) (Teddy Katz)
package/bin/eslint.js CHANGED
@@ -43,9 +43,10 @@ process.once("uncaughtException", err => {
43
43
 
44
44
  if (typeof err.messageTemplate === "string" && err.messageTemplate.length > 0) {
45
45
  const template = lodash.template(fs.readFileSync(path.resolve(__dirname, `../messages/${err.messageTemplate}.txt`), "utf-8"));
46
+ const pkg = require("../package.json");
46
47
 
47
48
  console.error("\nOops! Something went wrong! :(");
48
- console.error(`\n${template(err.messageData || {})}`);
49
+ console.error(`\nESLint: ${pkg.version}.\n${template(err.messageData || {})}`);
49
50
  } else {
50
51
 
51
52
  console.error(err.message);
@@ -44,6 +44,7 @@ module.exports = {
44
44
  "func-name-matching": "off",
45
45
  "func-names": "off",
46
46
  "func-style": "off",
47
+ "function-paren-newline": "off",
47
48
  "generator-star-spacing": "off",
48
49
  "getter-return": "off",
49
50
  "global-require": "off",
package/lib/ast-utils.js CHANGED
@@ -626,6 +626,9 @@ module.exports = {
626
626
  // // setup...
627
627
  // return function foo() { ... };
628
628
  // })();
629
+ // obj.foo = (() =>
630
+ // function foo() { ... }
631
+ // )();
629
632
  case "ReturnStatement": {
630
633
  const func = getUpperFunction(parent);
631
634
 
@@ -635,6 +638,12 @@ module.exports = {
635
638
  node = func.parent;
636
639
  break;
637
640
  }
641
+ case "ArrowFunctionExpression":
642
+ if (node !== parent.body || !isCallee(parent)) {
643
+ return true;
644
+ }
645
+ node = parent.parent;
646
+ break;
638
647
 
639
648
  // e.g.
640
649
  // var obj = { foo() { ... } };
@@ -655,16 +664,15 @@ module.exports = {
655
664
  // [Foo = function() { ... }] = a;
656
665
  case "AssignmentExpression":
657
666
  case "AssignmentPattern":
658
- if (parent.right === node) {
659
- if (parent.left.type === "MemberExpression") {
660
- return false;
661
- }
662
- if (isAnonymous &&
663
- parent.left.type === "Identifier" &&
664
- startsWithUpperCase(parent.left.name)
665
- ) {
666
- return false;
667
- }
667
+ if (parent.left.type === "MemberExpression") {
668
+ return false;
669
+ }
670
+ if (
671
+ isAnonymous &&
672
+ parent.left.type === "Identifier" &&
673
+ startsWithUpperCase(parent.left.name)
674
+ ) {
675
+ return false;
668
676
  }
669
677
  return true;
670
678
 
@@ -809,19 +817,14 @@ module.exports = {
809
817
  return 17;
810
818
 
811
819
  case "CallExpression":
812
-
813
- // IIFE is allowed to have parens in any position (#655)
814
- if (node.callee.type === "FunctionExpression") {
815
- return -1;
816
- }
817
820
  return 18;
818
821
 
819
822
  case "NewExpression":
820
823
  return 19;
821
824
 
822
- // no default
825
+ default:
826
+ return 20;
823
827
  }
824
- return 20;
825
828
  },
826
829
 
827
830
  /**
package/lib/cli-engine.js CHANGED
@@ -142,15 +142,9 @@ function calculateStatsPerRun(results) {
142
142
  * @private
143
143
  */
144
144
  function processText(text, configHelper, filename, fix, allowInlineConfig, linter) {
145
-
146
- // clear all existing settings for a new file
147
- linter.reset();
148
-
149
145
  let filePath,
150
- messages,
151
146
  fileExtension,
152
- processor,
153
- fixedResult;
147
+ processor;
154
148
 
155
149
  if (filename) {
156
150
  filePath = path.resolve(filename);
@@ -174,51 +168,28 @@ function processText(text, configHelper, filename, fix, allowInlineConfig, linte
174
168
  }
175
169
  }
176
170
 
177
- if (processor) {
178
- debug("Using processor");
179
- const parsedBlocks = processor.preprocess(text, filename);
180
- const unprocessedMessages = [];
181
-
182
- parsedBlocks.forEach(block => {
183
- unprocessedMessages.push(linter.verify(block, config, {
184
- filename,
185
- allowInlineConfig
186
- }));
187
- });
188
-
189
- // TODO(nzakas): Figure out how fixes might work for processors
190
-
191
- messages = processor.postprocess(unprocessedMessages, filename);
192
-
193
- } else {
171
+ const autofixingEnabled = typeof fix !== "undefined" && (!processor || processor.supportsAutofix);
194
172
 
195
- if (fix) {
196
- fixedResult = linter.verifyAndFix(text, config, {
197
- filename,
198
- allowInlineConfig,
199
- fix
200
- });
201
- messages = fixedResult.messages;
202
- } else {
203
- messages = linter.verify(text, config, {
204
- filename,
205
- allowInlineConfig
206
- });
207
- }
208
- }
173
+ const fixedResult = linter.verifyAndFix(text, config, {
174
+ filename,
175
+ allowInlineConfig,
176
+ fix: !!autofixingEnabled && fix,
177
+ preprocess: processor && (rawText => processor.preprocess(rawText, filename)),
178
+ postprocess: processor && (problemLists => processor.postprocess(problemLists, filename))
179
+ });
209
180
 
210
- const stats = calculateStatsPerFile(messages);
181
+ const stats = calculateStatsPerFile(fixedResult.messages);
211
182
 
212
183
  const result = {
213
184
  filePath: filename,
214
- messages,
185
+ messages: fixedResult.messages,
215
186
  errorCount: stats.errorCount,
216
187
  warningCount: stats.warningCount,
217
188
  fixableErrorCount: stats.fixableErrorCount,
218
189
  fixableWarningCount: stats.fixableWarningCount
219
190
  };
220
191
 
221
- if (fixedResult && fixedResult.fixed) {
192
+ if (fixedResult.fixed) {
222
193
  result.output = fixedResult.output;
223
194
  }
224
195
 
@@ -372,6 +343,8 @@ function getCacheFile(cacheFile, cwd) {
372
343
  return resolvedCacheFile;
373
344
  }
374
345
 
346
+ const configHashCache = new WeakMap();
347
+
375
348
  //------------------------------------------------------------------------------
376
349
  // Public Interface
377
350
  //------------------------------------------------------------------------------
@@ -493,11 +466,9 @@ class CLIEngine {
493
466
  * @returns {Object} The results for all files that were linted.
494
467
  */
495
468
  executeOnFiles(patterns) {
496
- const results = [],
497
- options = this.options,
469
+ const options = this.options,
498
470
  fileCache = this._fileCache,
499
471
  configHelper = this.config;
500
- let prevConfig; // the previous configuration used
501
472
  const cacheFile = getCacheFile(this.options.cacheLocation || this.options.cacheFile, this.options.cwd);
502
473
 
503
474
  if (!options.cache && fs.existsSync(cacheFile)) {
@@ -512,42 +483,18 @@ class CLIEngine {
512
483
  function hashOfConfigFor(filename) {
513
484
  const config = configHelper.getConfig(filename);
514
485
 
515
- if (!prevConfig) {
516
- prevConfig = {};
517
- }
518
-
519
- // reuse the previously hashed config if the config hasn't changed
520
- if (prevConfig.config !== config) {
521
-
522
- /*
523
- * config changed so we need to calculate the hash of the config
524
- * and the hash of the plugins being used
525
- */
526
- prevConfig.config = config;
527
-
528
- const eslintVersion = pkg.version;
529
-
530
- prevConfig.hash = hash(`${eslintVersion}_${stringify(config)}`);
486
+ if (!configHashCache.has(config)) {
487
+ configHashCache.set(config, hash(`${pkg.version}_${stringify(config)}`));
531
488
  }
532
489
 
533
- return prevConfig.hash;
490
+ return configHashCache.get(config);
534
491
  }
535
492
 
536
- /**
537
- * Executes the linter on a file defined by the `filename`. Skips
538
- * unsupported file extensions and any files that are already linted.
539
- * @param {string} filename The resolved filename of the file to be linted
540
- * @param {boolean} warnIgnored always warn when a file is ignored
541
- * @param {Linter} linter Linter context
542
- * @returns {void}
543
- */
544
- function executeOnFile(filename, warnIgnored, linter) {
545
- let hashOfConfig,
546
- descriptor;
547
-
548
- if (warnIgnored) {
549
- results.push(createIgnoreResult(filename, options.cwd));
550
- return;
493
+ const startTime = Date.now();
494
+ const fileList = globUtil.listFilesToProcess(this.resolveFileGlobPatterns(patterns), options);
495
+ const results = fileList.map(fileInfo => {
496
+ if (fileInfo.ignored) {
497
+ return createIgnoreResult(fileInfo.filename, options.cwd);
551
498
  }
552
499
 
553
500
  if (options.cache) {
@@ -557,15 +504,12 @@ class CLIEngine {
557
504
  * with the metadata and the flag that determines if
558
505
  * the file has changed
559
506
  */
560
- descriptor = fileCache.getFileDescriptor(filename);
561
- const meta = descriptor.meta || {};
562
-
563
- hashOfConfig = hashOfConfigFor(filename);
564
-
565
- const changed = descriptor.changed || meta.hashOfConfig !== hashOfConfig;
507
+ const descriptor = fileCache.getFileDescriptor(fileInfo.filename);
508
+ const hashOfConfig = hashOfConfigFor(fileInfo.filename);
509
+ const changed = descriptor.changed || descriptor.meta.hashOfConfig !== hashOfConfig;
566
510
 
567
511
  if (!changed) {
568
- debug(`Skipping file since hasn't changed: ${filename}`);
512
+ debug(`Skipping file since hasn't changed: ${fileInfo.filename}`);
569
513
 
570
514
  /*
571
515
  * Add the the cached results (always will be 0 error and
@@ -573,63 +517,45 @@ class CLIEngine {
573
517
  * failed, in order to guarantee that next execution will
574
518
  * process those files as well.
575
519
  */
576
- results.push(descriptor.meta.results);
577
-
578
- // move to the next file
579
- return;
520
+ return descriptor.meta.results;
580
521
  }
581
522
  }
582
523
 
583
- debug(`Processing ${filename}`);
524
+ debug(`Processing ${fileInfo.filename}`);
584
525
 
585
- const res = processFile(filename, configHelper, options, linter);
586
-
587
- if (options.cache) {
526
+ return processFile(fileInfo.filename, configHelper, options, this.linter);
527
+ });
588
528
 
589
- /*
590
- * if a file contains errors or warnings we don't want to
591
- * store the file in the cache so we can guarantee that
592
- * next execution will also operate on this file
593
- */
594
- if (res.errorCount > 0 || res.warningCount > 0) {
595
- debug(`File has problems, skipping it: ${filename}`);
529
+ if (options.cache) {
530
+ results.forEach(result => {
531
+ if (result.messages.length) {
596
532
 
597
- // remove the entry from the cache
598
- fileCache.removeEntry(filename);
533
+ /*
534
+ * if a file contains errors or warnings we don't want to
535
+ * store the file in the cache so we can guarantee that
536
+ * next execution will also operate on this file
537
+ */
538
+ fileCache.removeEntry(result.filePath);
599
539
  } else {
600
540
 
601
541
  /*
602
542
  * since the file passed we store the result here
603
- * TODO: check this as we might not need to store the
604
- * successful runs as it will always should be 0 errors and
605
- * 0 warnings.
543
+ * TODO: it might not be necessary to store the results list in the cache,
544
+ * since it should always be 0 errors/warnings
606
545
  */
607
- descriptor.meta.hashOfConfig = hashOfConfig;
608
- descriptor.meta.results = res;
609
- }
610
- }
611
-
612
- results.push(res);
613
- }
546
+ const descriptor = fileCache.getFileDescriptor(result.filePath);
614
547
 
615
- const startTime = Date.now();
616
-
617
-
618
- patterns = this.resolveFileGlobPatterns(patterns);
619
- const fileList = globUtil.listFilesToProcess(patterns, options);
620
-
621
- fileList.forEach(fileInfo => {
622
- executeOnFile(fileInfo.filename, fileInfo.ignored, this.linter);
623
- });
624
-
625
- const stats = calculateStatsPerRun(results);
626
-
627
- if (options.cache) {
548
+ descriptor.meta.hashOfConfig = hashOfConfigFor(result.filePath);
549
+ descriptor.meta.results = result;
550
+ }
551
+ });
628
552
 
629
553
  // persist the cache to disk
630
554
  fileCache.reconcile();
631
555
  }
632
556
 
557
+ const stats = calculateStatsPerRun(results);
558
+
633
559
  debug(`Linting complete in: ${Date.now() - startTime}ms`);
634
560
 
635
561
  return {
@@ -713,7 +639,6 @@ class CLIEngine {
713
639
  */
714
640
  getFormatter(format) {
715
641
 
716
- let formatterPath;
717
642
 
718
643
  // default is stylish
719
644
  format = format || "stylish";
@@ -724,6 +649,8 @@ class CLIEngine {
724
649
  // replace \ with / for Windows compatibility
725
650
  format = format.replace(/\\/g, "/");
726
651
 
652
+ let formatterPath;
653
+
727
654
  // if there's a slash, then it's a file
728
655
  if (format.indexOf("/") > -1) {
729
656
  const cwd = this.options ? this.options.cwd : process.cwd();
@@ -154,7 +154,8 @@ function forwardCurrentToHead(analyzer, node) {
154
154
  analyzer.emitter.emit(
155
155
  "onCodePathSegmentEnd",
156
156
  currentSegment,
157
- node);
157
+ node
158
+ );
158
159
  }
159
160
  }
160
161
  }
@@ -175,7 +176,8 @@ function forwardCurrentToHead(analyzer, node) {
175
176
  analyzer.emitter.emit(
176
177
  "onCodePathSegmentStart",
177
178
  headSegment,
178
- node);
179
+ node
180
+ );
179
181
  }
180
182
  }
181
183
  }
@@ -202,7 +204,8 @@ function leaveFromCurrentSegment(analyzer, node) {
202
204
  analyzer.emitter.emit(
203
205
  "onCodePathSegmentEnd",
204
206
  currentSegment,
205
- node);
207
+ node
208
+ );
206
209
  }
207
210
  }
208
211
 
@@ -369,7 +372,8 @@ function processCodePathToEnter(analyzer, node) {
369
372
  case "SwitchStatement":
370
373
  state.pushSwitchContext(
371
374
  node.cases.some(isCaseNode),
372
- astUtils.getLabel(node));
375
+ astUtils.getLabel(node)
376
+ );
373
377
  break;
374
378
 
375
379
  case "TryStatement":
@@ -164,7 +164,8 @@ class CodePathSegment {
164
164
  return new CodePathSegment(
165
165
  id,
166
166
  flattenUnusedSegments(allPrevSegments),
167
- allPrevSegments.some(isReachable));
167
+ allPrevSegments.some(isReachable)
168
+ );
168
169
  }
169
170
 
170
171
  /**
@@ -843,21 +843,23 @@ class CodePathState {
843
843
  * This segment will leave at the end of this finally block.
844
844
  */
845
845
  const segments = forkContext.makeNext(-1, -1);
846
- let j;
847
846
 
848
847
  for (let i = 0; i < forkContext.count; ++i) {
849
848
  const prevSegsOfLeavingSegment = [headOfLeavingSegments[i]];
850
849
 
851
- for (j = 0; j < returned.segmentsList.length; ++j) {
850
+ for (let j = 0; j < returned.segmentsList.length; ++j) {
852
851
  prevSegsOfLeavingSegment.push(returned.segmentsList[j][i]);
853
852
  }
854
- for (j = 0; j < thrown.segmentsList.length; ++j) {
853
+ for (let j = 0; j < thrown.segmentsList.length; ++j) {
855
854
  prevSegsOfLeavingSegment.push(thrown.segmentsList[j][i]);
856
855
  }
857
856
 
858
- segments.push(CodePathSegment.newNext(
859
- this.idGenerator.next(),
860
- prevSegsOfLeavingSegment));
857
+ segments.push(
858
+ CodePathSegment.newNext(
859
+ this.idGenerator.next(),
860
+ prevSegsOfLeavingSegment
861
+ )
862
+ );
861
863
  }
862
864
 
863
865
  this.pushForkContext(true);
@@ -982,7 +984,6 @@ class CodePathState {
982
984
 
983
985
  const forkContext = this.forkContext;
984
986
  const brokenForkContext = this.popBreakContext().brokenForkContext;
985
- let choiceContext;
986
987
 
987
988
  // Creates a looped path.
988
989
  switch (context.type) {
@@ -992,11 +993,12 @@ class CodePathState {
992
993
  makeLooped(
993
994
  this,
994
995
  forkContext.head,
995
- context.continueDestSegments);
996
+ context.continueDestSegments
997
+ );
996
998
  break;
997
999
 
998
1000
  case "DoWhileStatement": {
999
- choiceContext = this.popChoiceContext();
1001
+ const choiceContext = this.popChoiceContext();
1000
1002
 
1001
1003
  if (!choiceContext.processed) {
1002
1004
  choiceContext.trueForkContext.add(forkContext.head);
@@ -1013,7 +1015,8 @@ class CodePathState {
1013
1015
  makeLooped(
1014
1016
  this,
1015
1017
  segmentsList[i],
1016
- context.entrySegments);
1018
+ context.entrySegments
1019
+ );
1017
1020
  }
1018
1021
  break;
1019
1022
  }
@@ -1024,7 +1027,8 @@ class CodePathState {
1024
1027
  makeLooped(
1025
1028
  this,
1026
1029
  forkContext.head,
1027
- context.leftSegments);
1030
+ context.leftSegments
1031
+ );
1028
1032
  break;
1029
1033
 
1030
1034
  /* istanbul ignore next */
@@ -1149,7 +1153,8 @@ class CodePathState {
1149
1153
  finalizeTestSegmentsOfFor(
1150
1154
  context,
1151
1155
  choiceContext,
1152
- forkContext.head);
1156
+ forkContext.head
1157
+ );
1153
1158
  } else {
1154
1159
  context.endOfInitSegments = forkContext.head;
1155
1160
  }
@@ -1180,13 +1185,15 @@ class CodePathState {
1180
1185
  makeLooped(
1181
1186
  this,
1182
1187
  context.endOfUpdateSegments,
1183
- context.testSegments);
1188
+ context.testSegments
1189
+ );
1184
1190
  }
1185
1191
  } else if (context.testSegments) {
1186
1192
  finalizeTestSegmentsOfFor(
1187
1193
  context,
1188
1194
  choiceContext,
1189
- forkContext.head);
1195
+ forkContext.head
1196
+ );
1190
1197
  } else {
1191
1198
  context.endOfInitSegments = forkContext.head;
1192
1199
  }
@@ -51,7 +51,8 @@ class CodePath {
51
51
  Object.defineProperty(
52
52
  this,
53
53
  "internal",
54
- { value: new CodePathState(new IdGenerator(`${id}_`), onLooped) });
54
+ { value: new CodePathState(new IdGenerator(`${id}_`), onLooped) }
55
+ );
55
56
 
56
57
  // Adds this into `childCodePaths` of `upper`.
57
58
  if (upper) {
@@ -205,7 +206,7 @@ class CodePath {
205
206
 
206
207
  // Call the callback when the first time.
207
208
  if (!skippedSegment) {
208
- callback.call(this, segment, controller); // eslint-disable-line callback-return
209
+ callback.call(this, segment, controller);
209
210
  if (segment === lastSegment) {
210
211
  controller.skip();
211
212
  }
@@ -254,7 +254,8 @@ class ForkContext {
254
254
  return new ForkContext(
255
255
  parentContext.idGenerator,
256
256
  parentContext,
257
- (forkLeavingPath ? 2 : 1) * parentContext.count);
257
+ (forkLeavingPath ? 2 : 1) * parentContext.count
258
+ );
258
259
  }
259
260
  }
260
261
 
@@ -269,10 +269,8 @@ class Registry {
269
269
  * @returns {Registry} New registry with errorCount populated
270
270
  */
271
271
  lintSourceCode(sourceCodes, config, cb) {
272
- let ruleSetIdx,
273
- lintedRegistry;
272
+ let lintedRegistry = new Registry();
274
273
 
275
- lintedRegistry = new Registry();
276
274
  lintedRegistry.rules = Object.assign({}, this.rules);
277
275
 
278
276
  const ruleSets = lintedRegistry.buildRuleSets();
@@ -287,7 +285,7 @@ class Registry {
287
285
  filenames.forEach(filename => {
288
286
  debug(`Linting file: ${filename}`);
289
287
 
290
- ruleSetIdx = 0;
288
+ let ruleSetIdx = 0;
291
289
 
292
290
  ruleSets.forEach(ruleSet => {
293
291
  const lintConfig = Object.assign({}, config, { rules: ruleSet });