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.
- package/CHANGELOG.md +98 -0
- package/bin/eslint.js +2 -1
- package/conf/eslint-recommended.js +1 -0
- package/lib/ast-utils.js +20 -17
- package/lib/cli-engine.js +51 -124
- package/lib/code-path-analysis/code-path-analyzer.js +8 -4
- package/lib/code-path-analysis/code-path-segment.js +2 -1
- package/lib/code-path-analysis/code-path-state.js +21 -14
- package/lib/code-path-analysis/code-path.js +3 -2
- package/lib/code-path-analysis/fork-context.js +2 -1
- package/lib/config/autoconfig.js +2 -4
- package/lib/config/config-initializer.js +9 -5
- package/lib/config/config-ops.js +15 -15
- package/lib/config.js +8 -12
- package/lib/formatters/codeframe.js +1 -1
- package/lib/formatters/stylish.js +1 -1
- package/lib/ignored-paths.js +0 -2
- package/lib/linter.js +468 -638
- package/lib/report-translator.js +274 -0
- package/lib/rules/function-paren-newline.js +221 -0
- package/lib/rules/generator-star-spacing.js +70 -19
- package/lib/rules/indent-legacy.js +3 -2
- package/lib/rules/indent.js +15 -6
- package/lib/rules/key-spacing.js +2 -1
- package/lib/rules/newline-per-chained-call.js +20 -3
- package/lib/rules/no-extra-parens.js +75 -33
- package/lib/rules/no-invalid-this.js +2 -1
- package/lib/rules/no-tabs.js +1 -1
- package/lib/rules/no-undef-init.js +4 -0
- package/lib/rules/no-unmodified-loop-condition.js +1 -1
- package/lib/rules/no-unused-vars.js +47 -4
- package/lib/rules/padded-blocks.js +2 -2
- package/lib/rules/prefer-arrow-callback.js +1 -2
- package/lib/rules/quote-props.js +4 -2
- package/lib/rules/quotes.js +1 -2
- package/lib/rules/space-before-blocks.js +1 -1
- package/lib/rules/valid-jsdoc.js +2 -2
- package/lib/rules.js +48 -3
- package/lib/testers/rule-tester.js +27 -51
- package/lib/timing.js +2 -2
- package/lib/util/apply-disable-directives.js +131 -0
- package/lib/util/fix-tracker.js +1 -2
- package/lib/util/npm-util.js +21 -4
- package/lib/util/source-code-fixer.js +5 -14
- package/lib/util/source-code.js +3 -5
- package/package.json +8 -8
- package/lib/rule-context.js +0 -241
- package/lib/testers/event-generator-tester.js +0 -62
- 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);
|
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.
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
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
|
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
|
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 (!
|
516
|
-
|
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
|
490
|
+
return configHashCache.get(config);
|
534
491
|
}
|
535
492
|
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
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
|
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
|
-
|
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
|
-
|
586
|
-
|
587
|
-
if (options.cache) {
|
526
|
+
return processFile(fileInfo.filename, configHelper, options, this.linter);
|
527
|
+
});
|
588
528
|
|
589
|
-
|
590
|
-
|
591
|
-
|
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
|
-
|
598
|
-
|
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:
|
604
|
-
*
|
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
|
608
|
-
descriptor.meta.results = res;
|
609
|
-
}
|
610
|
-
}
|
611
|
-
|
612
|
-
results.push(res);
|
613
|
-
}
|
546
|
+
const descriptor = fileCache.getFileDescriptor(result.filePath);
|
614
547
|
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
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":
|
@@ -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(
|
859
|
-
|
860
|
-
|
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);
|
209
|
+
callback.call(this, segment, controller);
|
209
210
|
if (segment === lastSegment) {
|
210
211
|
controller.skip();
|
211
212
|
}
|
package/lib/config/autoconfig.js
CHANGED
@@ -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
|
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 });
|