eslint 3.16.1 → 3.19.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 +103 -0
- package/README.md +1 -0
- package/conf/eslint-recommended.js +2 -0
- package/lib/ast-utils.js +3 -67
- package/lib/code-path-analysis/code-path-analyzer.js +2 -7
- package/lib/code-path-analysis/debug-helpers.js +17 -16
- package/lib/config/config-file.js +68 -38
- package/lib/config/config-rule.js +14 -10
- package/lib/config/plugins.js +19 -8
- package/lib/eslint.js +11 -10
- package/lib/formatters/codeframe.js +4 -9
- package/lib/formatters/stylish.js +5 -4
- package/lib/ignored-paths.js +6 -0
- package/lib/internal-rules/internal-no-invalid-meta.js +2 -40
- package/lib/rules/array-callback-return.js +15 -5
- package/lib/rules/arrow-body-style.js +2 -2
- package/lib/rules/arrow-parens.js +9 -3
- package/lib/rules/capitalized-comments.js +2 -1
- package/lib/rules/comma-dangle.js +3 -2
- package/lib/rules/comma-spacing.js +4 -14
- package/lib/rules/comma-style.js +8 -14
- package/lib/rules/complexity.js +14 -8
- package/lib/rules/consistent-return.js +17 -10
- package/lib/rules/curly.js +2 -2
- package/lib/rules/dot-notation.js +12 -6
- package/lib/rules/func-name-matching.js +18 -7
- package/lib/rules/func-names.js +20 -5
- package/lib/rules/keyword-spacing.js +19 -4
- package/lib/rules/line-comment-position.js +15 -5
- package/lib/rules/lines-around-comment.js +19 -0
- package/lib/rules/lines-around-directive.js +1 -1
- package/lib/rules/max-params.js +17 -4
- package/lib/rules/max-statements.js +11 -10
- package/lib/rules/new-parens.js +7 -21
- package/lib/rules/no-compare-neg-zero.js +53 -0
- package/lib/rules/no-cond-assign.js +4 -17
- package/lib/rules/no-else-return.js +19 -4
- package/lib/rules/no-empty-function.js +9 -16
- package/lib/rules/no-extra-parens.js +110 -121
- package/lib/rules/no-extra-semi.js +16 -3
- package/lib/rules/no-global-assign.js +1 -1
- package/lib/rules/no-implicit-coercion.js +21 -8
- package/lib/rules/no-invalid-regexp.js +2 -1
- package/lib/rules/no-multiple-empty-lines.js +2 -4
- package/lib/rules/no-native-reassign.js +1 -1
- package/lib/rules/no-negated-in-lhs.js +1 -1
- package/lib/rules/no-new-func.js +6 -8
- package/lib/rules/no-new.js +2 -6
- package/lib/rules/no-param-reassign.js +37 -7
- package/lib/rules/no-process-exit.js +2 -10
- package/lib/rules/no-restricted-properties.js +2 -0
- package/lib/rules/no-restricted-syntax.js +32 -21
- package/lib/rules/no-return-await.js +1 -1
- package/lib/rules/no-sequences.js +2 -2
- package/lib/rules/no-sync.js +8 -13
- package/lib/rules/no-unsafe-negation.js +1 -1
- package/lib/rules/no-unused-expressions.js +10 -1
- package/lib/rules/no-unused-vars.js +12 -12
- package/lib/rules/no-use-before-define.js +1 -1
- package/lib/rules/no-useless-computed-key.js +12 -1
- package/lib/rules/no-useless-escape.js +8 -2
- package/lib/rules/no-useless-return.js +13 -2
- package/lib/rules/nonblock-statement-body-position.js +114 -0
- package/lib/rules/object-curly-spacing.js +2 -2
- package/lib/rules/object-shorthand.js +10 -3
- package/lib/rules/operator-assignment.js +20 -3
- package/lib/rules/padded-blocks.js +37 -31
- package/lib/rules/prefer-const.js +1 -1
- package/lib/rules/prefer-destructuring.js +1 -1
- package/lib/rules/quotes.js +1 -0
- package/lib/rules/semi-spacing.js +2 -15
- package/lib/rules/semi.js +17 -13
- package/lib/rules/sort-vars.js +3 -5
- package/lib/rules/space-before-function-paren.js +53 -77
- package/lib/rules/space-in-parens.js +4 -8
- package/lib/rules/space-unary-ops.js +19 -1
- package/lib/rules/strict.js +8 -2
- package/lib/rules/yoda.js +2 -2
- package/lib/testers/rule-tester.js +44 -13
- package/lib/util/fix-tracker.js +121 -0
- package/lib/util/glob-util.js +1 -1
- package/lib/util/node-event-generator.js +274 -4
- package/lib/util/source-code-fixer.js +3 -9
- package/lib/util/source-code.js +99 -2
- package/lib/util/traverser.js +16 -25
- package/package.json +34 -34
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,106 @@
|
|
1
|
+
v3.19.0 - March 31, 2017
|
2
|
+
|
3
|
+
* e09132f Fix: no-extra-parens false positive with exports and object literals (#8359) (Teddy Katz)
|
4
|
+
* 91baed4 Update: allow custom messages in no-restricted-syntax (fixes #8298) (#8357) (Vitor Balocco)
|
5
|
+
* 35c93e6 Fix: prevent space-before-function-paren from checking type annotations (#8349) (Teddy Katz)
|
6
|
+
* 3342e9f Fix: don't modify operator precedence in operator-assignment autofixer (#8358) (Teddy Katz)
|
7
|
+
* f88375f Docs: clarify that no-unsafe-negation is in eslint:recommended (#8371) (Teddy Katz)
|
8
|
+
* 02f0d27 Docs: Add soda0289 to Development Team (#8367) (Kai Cataldo)
|
9
|
+
* 155424c Fix: ignore empty path in patterns (fixes #8362) (#8364) (alberto)
|
10
|
+
* 27616a8 Fix: prefer-const false positive with object spread (fixes #8187) (#8297) (Vitor Balocco)
|
11
|
+
* 8569a90 Docs: add note about git's linebreak handling to linebreak-style docs (#8361) (Teddy Katz)
|
12
|
+
* 5878593 Chore: fix invalid syntax in no-param-reassign test (#8360) (Teddy Katz)
|
13
|
+
* 1b1046b Fix: don't classify plugins that throw errors as "missing" (fixes #6874) (#8323) (Teddy Katz)
|
14
|
+
* 29f4ba5 Fix: no-useless-computed-key invalid autofix for getters and setters (#8335) (Teddy Katz)
|
15
|
+
* 0541eaf Fix: no-implicit-coercion invalid autofix with consecutive identifiers (#8340) (Teddy Katz)
|
16
|
+
* 41b9786 Fix: no-extra-parens false positive with objects following arrows (#8339) (Teddy Katz)
|
17
|
+
* 3146167 Fix: `eslint.verify` should not mutate config argument (fixes #8329) (#8334) (alberto)
|
18
|
+
* 927de90 Fix: dot-notation autofix produces invalid syntax for integer properties (#8332) (Teddy Katz)
|
19
|
+
* a9d1bea Fix: comma-style autofix produces errors on parenthesized elements (#8331) (Teddy Katz)
|
20
|
+
* d52173f Fix: don't generate invalid options in config-rule (#8326) (Teddy Katz)
|
21
|
+
* 6eda3b5 Fix: no-extra-parens invalid autofix in for-of statements (#8337) (Teddy Katz)
|
22
|
+
* 6c819d8 Fix: dot-notation autofix produces errors on parenthesized computed keys (#8330) (Teddy Katz)
|
23
|
+
* 2d883d7 Fix: object-shorthand autofix produces errors on parenthesized functions (#8328) (Teddy Katz)
|
24
|
+
* cd9b774 Fix: quotes false positive with backtick option in method names (#8327) (Teddy Katz)
|
25
|
+
* d064ba2 Fix: no-else-return false positive for ifs in single-statement position (#8338) (Teddy Katz)
|
26
|
+
* 6a718ba Chore: enable max-statements-per-line on ESLint codebase (#8321) (Teddy Katz)
|
27
|
+
* 614b62e Chore: update sinon calls to deprecated API. (#8310) (alberto)
|
28
|
+
* 0491572 Chore: use precalculated counts in codeframe formatter (#8296) (Vitor Balocco)
|
29
|
+
* 8733e6a Chore: Fix incorrect error location properties in tests (#8307) (alberto)
|
30
|
+
* c4ffb49 Chore: Fix typos in test option assertions (#8305) (Teddy Katz)
|
31
|
+
* 79a97cb Upgrade: devDependencies (#8303) (alberto)
|
32
|
+
* e4da200 Upgrade: Mocha to 3.2.0 (#8299) (Ilya Volodin)
|
33
|
+
* 2f144ca Fix: operator-assignment autofix errors with parentheses (fixes #8293) (#8294) (Teddy Katz)
|
34
|
+
* 7521cd5 Chore: update token logic in rules to use ast-utils (#8288) (Teddy Katz)
|
35
|
+
* 9b509ce Chore: refactor space-before-function-paren rule (#8284) (Teddy Katz)
|
36
|
+
* ddc6350 Fix: no-param-reassign false positive on destructuring (fixes #8279) (#8281) (Teddy Katz)
|
37
|
+
* f8176b3 Chore: improve test coverage for node-event-generator (#8287) (Teddy Katz)
|
38
|
+
* 602e9c2 Docs: fix incorrect selector examples (#8278) (Teddy Katz)
|
39
|
+
|
40
|
+
v3.18.0 - March 17, 2017
|
41
|
+
|
42
|
+
* 85f74ca Fix: broken code path of direct nested loops (fixes #8248) (#8274) (Toru Nagashima)
|
43
|
+
* a61c359 Fix: Ignore hidden folders when resolving globs (fixes #8259) (#8270) (Ian VanSchooten)
|
44
|
+
* 6f05546 Chore: convert StubModuleResolver in config tests to ES6 class (#8265) (Teddy Katz)
|
45
|
+
* 0c0fc31 Fix: false positive of no-extra-parens about spread and sequense (#8275) (Toru Nagashima)
|
46
|
+
* e104973 Docs: remove self-reference in no-restricted-syntax docs (#8277) (Vitor Balocco)
|
47
|
+
* 23eca51 Update: Add allowTaggedTemplates to no-unused-expressions (fixes #7632) (#8253) (Kevin Partington)
|
48
|
+
* f9ede3f Upgrade: doctrine to 2.0.0 (#8269) (alberto)
|
49
|
+
* 1b678a6 New: allow rules to listen for AST selectors (fixes #5407) (#7833) (Teddy Katz)
|
50
|
+
* 63ca0c5 Chore: use precalculated counts in stylish formatter (#8251) (alberto)
|
51
|
+
* 47c3171 Fix: typo in console.error (#8258) (Jan Peer Stöcklmair)
|
52
|
+
* e74ed6d Chore: convert Traverser to ES6 class (refs #7849) (#8232) (Teddy Katz)
|
53
|
+
* 13eead9 Fix: sort-vars crash on mixed destructuring declarations (#8245) (Teddy Katz)
|
54
|
+
* 133f489 Fix: func-name-matching crash on destructuring assignment to functions (#8247) (Teddy Katz)
|
55
|
+
* a34b9c4 Fix: func-name-matching crash on non-string literal computed keys (#8246) (Teddy Katz)
|
56
|
+
* 7276e6d Docs: remove unneeded semicolons in arrow-parens.md (#8249) (Dmitry Gershun)
|
57
|
+
* 8c40a25 concat-stream known to be vulnerable prior 1.5.2 (#8228) (Samuel)
|
58
|
+
* 149c055 Upgrade: mock-fs to v4.2.0 (fixes #8194) (#8243) (Teddy Katz)
|
59
|
+
* a83bff9 Build: remove unneeded json config in demo (fixes #8237) (#8242) (alberto)
|
60
|
+
* df12137 Docs: fix typos (#8235) (Gyandeep Singh)
|
61
|
+
* b5e9788 Chore: rename no-extra-parens methods (#8225) (Vitor Balocco)
|
62
|
+
* 7f8afe6 Update: no-extra-parens overlooked spread and superClass (fixes #8175) (#8209) (Toru Nagashima)
|
63
|
+
* ce6ff56 Docs: set recommended true for no-global-assign (fixes #8215) (#8218) (BinYi LIU)
|
64
|
+
* 5b5c236 Fix: wrong comment when module not found in config (fixes #8192) (#8196) (alberto)
|
65
|
+
|
66
|
+
v3.17.1 - March 6, 2017
|
67
|
+
|
68
|
+
* f8c8e6e Build: change mock-fs path without SSH (fixes #8207) (#8208) (Toru Nagashima)
|
69
|
+
* f713f11 Fix: nonblock-statement-body-position multiline error (fixes #8202) (#8203) (Teddy Katz)
|
70
|
+
* 41e3d9c Fix: `operator-assignment` with parenthesized expression (fixes #8190) (#8197) (alberto)
|
71
|
+
* 5e3bca7 Chore: add eslint-plugin-eslint-plugin (#8198) (Teddy Katz)
|
72
|
+
* 580da36 Chore: add missing `output` property to tests (#8195) (alberto)
|
73
|
+
|
74
|
+
v3.17.0 - March 3, 2017
|
75
|
+
|
76
|
+
* 4fdf6d7 Update: deprecate `applyDefaultPatterns` in `line-comment-position` (#8183) (alberto)
|
77
|
+
* 25e5817 Fix: Don't autofix `+ +a` to `++a` in space-unary-ops (#8176) (Alan Pierce)
|
78
|
+
* a6ce8f9 Build: Sort rules before dumping them to doc files (#8154) (Danny Andrews)
|
79
|
+
* 0af9057 Chore: Upgrade to a patched version of mock-fs (fixes #8177) (#8188) (Teddy Katz)
|
80
|
+
* bf4d8cf Update: ignore eslint comments in lines-arount-comment (fixes #4345) (#8155) (alberto)
|
81
|
+
* dad20ad New: add SourceCode#getLocFromIndex and #getIndexFromLoc (fixes #8073) (#8158) (Teddy Katz)
|
82
|
+
* 18a519f Update: let RuleTester cases assert that no autofix occurs (fixes #8157) (#8163) (Teddy Katz)
|
83
|
+
* a30eb8d Docs: improve documentation for RuleTester cases (#8162) (Teddy Katz)
|
84
|
+
* a78ec9f Chore: upgrade `coveralls` to ^2.11.16 (#8161) (alberto)
|
85
|
+
* d02bd11 Fix: padded-blocks autofix problems with comments (#8149) (alberto)
|
86
|
+
* 9994889 Docs: Add missing space to `create` in `no-use-before-define` (#8166) (Justin Anastos)
|
87
|
+
* 4d542ba Docs: Remove unneeded statement about autofix (#8164) (alberto)
|
88
|
+
* 20daea5 New: no-compare-neg-zero rule (#8091) (薛定谔的猫)
|
89
|
+
* 4d35a81 Fix: Add a utility to avoid autofix conflicts (fixes #7928, fixes #8026) (#8067) (Alan Pierce)
|
90
|
+
* 287e882 New: nonblock-statement-body-position rule (fixes #6067) (#8108) (Teddy Katz)
|
91
|
+
* 7f1f4e5 Chore: remove unneeded devDeps `linefix` and `gh-got` (#8160) (alberto)
|
92
|
+
* ca1694b Update: ignore negative ranges in fixes (#8133) (alberto)
|
93
|
+
* 163d751 Docs: `lines-around-comment` doesn't disallow empty lines (#8151) (alberto)
|
94
|
+
* 1c84922 Chore: upgrade eslint-plugin-node (#8156) (alberto)
|
95
|
+
* 1ee5c27 Fix: Make RuleTester handle empty-string cases gracefully (fixes #8142) (#8143) (Teddy Katz)
|
96
|
+
* 044bc10 Docs: Add details about "--fix" option for "sort-imports" rule (#8077) (Olivier Audard)
|
97
|
+
* 3fec54a Add option to ignore property in no-param-reassign (#8087) (Christian Bundy)
|
98
|
+
* 4e52cfc Fix: Improve keyword-spacing typescript support (fixes #8110) (#8111) (Reyad Attiyat)
|
99
|
+
* 7ff42e8 New: Allow regexes in RuleTester (fixes #7837) (#8115) (Daniel Lo Nigro)
|
100
|
+
* cbd7ded Build: display rules’ meta data in their docs (fixes #5774) (#8127) (Wilson Kurniawan)
|
101
|
+
* da8e8af Update: include function name in report message if possible (fixes #7260) (#8058) (Dieter Luypaert)
|
102
|
+
* 8f91e32 Fix: `ignoreRestSiblings` option didn't cover arguments (fixes #8119) (#8120) (Toru Nagashima)
|
103
|
+
|
1
104
|
v3.16.1 - February 22, 2017
|
2
105
|
|
3
106
|
* ff8a80c Fix: duplicated autofix output for inverted fix ranges (fixes #8116) (#8117) (Teddy Katz)
|
package/README.md
CHANGED
@@ -130,6 +130,7 @@ These folks keep the project moving and are resources for help.
|
|
130
130
|
* Kevin Partington ([@platinumazure](https://github.com/platinumazure))
|
131
131
|
* Vitor Balocco ([@vitorbal](https://github.com/vitorbal))
|
132
132
|
* James Henry ([@JamesHenry](https://github.com/JamesHenry))
|
133
|
+
* Reyad Attiyat ([@soda0289](https://github.com/soda0289))
|
133
134
|
|
134
135
|
## Releases
|
135
136
|
|
@@ -84,6 +84,7 @@ module.exports = {
|
|
84
84
|
"no-case-declarations": "error",
|
85
85
|
"no-catch-shadow": "off",
|
86
86
|
"no-class-assign": "error",
|
87
|
+
"no-compare-neg-zero": "off",
|
87
88
|
"no-cond-assign": "error",
|
88
89
|
"no-confusing-arrow": "off",
|
89
90
|
"no-console": "error",
|
@@ -209,6 +210,7 @@ module.exports = {
|
|
209
210
|
"no-warning-comments": "off",
|
210
211
|
"no-whitespace-before-property": "off",
|
211
212
|
"no-with": "off",
|
213
|
+
"nonblock-statement-body-position": "off",
|
212
214
|
"object-curly-newline": "off",
|
213
215
|
"object-curly-spacing": ["off", "never"],
|
214
216
|
"object-property-newline": "off",
|
package/lib/ast-utils.js
CHANGED
@@ -10,7 +10,6 @@
|
|
10
10
|
//------------------------------------------------------------------------------
|
11
11
|
|
12
12
|
const esutils = require("esutils");
|
13
|
-
const lodash = require("lodash");
|
14
13
|
|
15
14
|
//------------------------------------------------------------------------------
|
16
15
|
// Helpers
|
@@ -24,6 +23,8 @@ const bindOrCallOrApplyPattern = /^(?:bind|call|apply)$/;
|
|
24
23
|
const breakableTypePattern = /^(?:(?:Do)?While|For(?:In|Of)?|Switch)Statement$/;
|
25
24
|
const thisTagPattern = /^[\s*]*@this/m;
|
26
25
|
|
26
|
+
|
27
|
+
const COMMENTS_IGNORE_PATTERN = /^\s*(?:eslint|jshint\s+|jslint\s+|istanbul\s+|globals?\s+|exported\s+|jscs)/;
|
27
28
|
const LINEBREAKS = new Set(["\r\n", "\r", "\n", "\u2028", "\u2029"]);
|
28
29
|
const LINEBREAK_MATCHER = /\r\n|[\r\n\u2028\u2029]/;
|
29
30
|
|
@@ -403,45 +404,12 @@ function createGlobalLinebreakMatcher() {
|
|
403
404
|
return new RegExp(LINEBREAK_MATCHER.source, "g");
|
404
405
|
}
|
405
406
|
|
406
|
-
const lineIndexCache = new WeakMap();
|
407
|
-
|
408
|
-
/**
|
409
|
-
* Gets the range index for the first character in each of the lines of `sourceCode`.
|
410
|
-
* @param {SourceCode} sourceCode A sourceCode object
|
411
|
-
* @returns {number[]} The indices of the first characters in the each of the lines of the code
|
412
|
-
*/
|
413
|
-
function getLineIndices(sourceCode) {
|
414
|
-
|
415
|
-
if (!lineIndexCache.has(sourceCode)) {
|
416
|
-
const lineIndices = [0];
|
417
|
-
const lineEndingPattern = createGlobalLinebreakMatcher();
|
418
|
-
let match;
|
419
|
-
|
420
|
-
/*
|
421
|
-
* Previously, this function was implemented using a regex that
|
422
|
-
* matched a sequence of non-linebreak characters followed by a
|
423
|
-
* linebreak, then adding the lengths of the matches. However,
|
424
|
-
* this caused a catastrophic backtracking issue when the end
|
425
|
-
* of a file contained a large number of non-newline characters.
|
426
|
-
* To avoid this, the current implementation just matches newlines
|
427
|
-
* and uses match.index to get the correct line start indices.
|
428
|
-
*/
|
429
|
-
|
430
|
-
while ((match = lineEndingPattern.exec(sourceCode.text))) {
|
431
|
-
lineIndices.push(match.index + match[0].length);
|
432
|
-
}
|
433
|
-
|
434
|
-
// Store the sourceCode object in a WeakMap to avoid iterating over all of the lines every time a sourceCode object is passed in.
|
435
|
-
lineIndexCache.set(sourceCode, lineIndices);
|
436
|
-
}
|
437
|
-
return lineIndexCache.get(sourceCode);
|
438
|
-
}
|
439
|
-
|
440
407
|
//------------------------------------------------------------------------------
|
441
408
|
// Public Interface
|
442
409
|
//------------------------------------------------------------------------------
|
443
410
|
|
444
411
|
module.exports = {
|
412
|
+
COMMENTS_IGNORE_PATTERN,
|
445
413
|
LINEBREAKS,
|
446
414
|
LINEBREAK_MATCHER,
|
447
415
|
STATEMENT_LIST_PARENTS,
|
@@ -1207,38 +1175,6 @@ module.exports = {
|
|
1207
1175
|
};
|
1208
1176
|
},
|
1209
1177
|
|
1210
|
-
/*
|
1211
|
-
* Converts a range index into a (line, column) pair.
|
1212
|
-
* @param {SourceCode} sourceCode A SourceCode object
|
1213
|
-
* @param {number} rangeIndex The range index of a character in a file
|
1214
|
-
* @returns {Object} A {line, column} location object with a 0-indexed column
|
1215
|
-
*/
|
1216
|
-
getLocationFromRangeIndex(sourceCode, rangeIndex) {
|
1217
|
-
const lineIndices = getLineIndices(sourceCode);
|
1218
|
-
|
1219
|
-
/*
|
1220
|
-
* lineIndices is a sorted list of indices of the first character of each line.
|
1221
|
-
* To figure out which line rangeIndex is on, determine the last index at which rangeIndex could
|
1222
|
-
* be inserted into lineIndices to keep the list sorted.
|
1223
|
-
*/
|
1224
|
-
const lineNumber = lodash.sortedLastIndex(lineIndices, rangeIndex);
|
1225
|
-
|
1226
|
-
return { line: lineNumber, column: rangeIndex - lineIndices[lineNumber - 1] };
|
1227
|
-
|
1228
|
-
},
|
1229
|
-
|
1230
|
-
/**
|
1231
|
-
* Converts a (line, column) pair into a range index.
|
1232
|
-
* @param {SourceCode} sourceCode A SourceCode object
|
1233
|
-
* @param {Object} loc A line/column location
|
1234
|
-
* @param {number} loc.line The line number of the location (1-indexed)
|
1235
|
-
* @param {number} loc.column The column number of the location (0-indexed)
|
1236
|
-
* @returns {number} The range index of the location in the file.
|
1237
|
-
*/
|
1238
|
-
getRangeIndexFromLocation(sourceCode, loc) {
|
1239
|
-
return getLineIndices(sourceCode)[loc.line - 1] + loc.column;
|
1240
|
-
},
|
1241
|
-
|
1242
1178
|
/**
|
1243
1179
|
* Gets the parenthesized text of a node. This is similar to sourceCode.getText(node), but it also includes any parentheses
|
1244
1180
|
* surrounding the node.
|
@@ -512,13 +512,8 @@ function processCodePathToExit(analyzer, node) {
|
|
512
512
|
break;
|
513
513
|
}
|
514
514
|
|
515
|
-
|
516
|
-
|
517
|
-
* the node type is the same as the parent node type.
|
518
|
-
*/
|
519
|
-
if (!dontForward && (!node.parent || node.type !== node.parent.type)) {
|
520
|
-
|
521
|
-
// Emits onCodePathSegmentStart events if updated.
|
515
|
+
// Emits onCodePathSegmentStart events if updated.
|
516
|
+
if (!dontForward) {
|
522
517
|
forwardCurrentToHead(analyzer, node);
|
523
518
|
}
|
524
519
|
debug.dumpState(node, state, true);
|
@@ -107,22 +107,23 @@ module.exports = {
|
|
107
107
|
text += "style=\"rounded,dashed,filled\",fillcolor=\"#FF9800\",label=\"<<unreachable>>\\n";
|
108
108
|
}
|
109
109
|
|
110
|
-
if (segment.internal.nodes.length > 0) {
|
111
|
-
text +=
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
110
|
+
if (segment.internal.nodes.length > 0 || segment.internal.exitNodes.length > 0) {
|
111
|
+
text += [].concat(
|
112
|
+
segment.internal.nodes.map(node => {
|
113
|
+
switch (node.type) {
|
114
|
+
case "Identifier": return `${node.type} (${node.name})`;
|
115
|
+
case "Literal": return `${node.type} (${node.value})`;
|
116
|
+
default: return node.type;
|
117
|
+
}
|
118
|
+
}),
|
119
|
+
segment.internal.exitNodes.map(node => {
|
120
|
+
switch (node.type) {
|
121
|
+
case "Identifier": return `${node.type}:exit (${node.name})`;
|
122
|
+
case "Literal": return `${node.type}:exit (${node.value})`;
|
123
|
+
default: return `${node.type}:exit`;
|
124
|
+
}
|
125
|
+
})
|
126
|
+
).join("\\n");
|
126
127
|
} else {
|
127
128
|
text += "????";
|
128
129
|
}
|
@@ -183,6 +183,22 @@ function loadPackageJSONConfigFile(filePath) {
|
|
183
183
|
}
|
184
184
|
}
|
185
185
|
|
186
|
+
/**
|
187
|
+
* Creates an error to notify about a missing config to extend from.
|
188
|
+
* @param {string} configName The name of the missing config.
|
189
|
+
* @returns {Error} The error object to throw
|
190
|
+
* @private
|
191
|
+
*/
|
192
|
+
function configMissingError(configName) {
|
193
|
+
const error = new Error(`Failed to load config "${configName}" to extend from.`);
|
194
|
+
|
195
|
+
error.messageTemplate = "extend-config-missing";
|
196
|
+
error.messageData = {
|
197
|
+
configName
|
198
|
+
};
|
199
|
+
return error;
|
200
|
+
}
|
201
|
+
|
186
202
|
/**
|
187
203
|
* Loads a configuration file regardless of the source. Inspects the file path
|
188
204
|
* to determine the correctly way to load the config file.
|
@@ -199,6 +215,9 @@ function loadConfigFile(file) {
|
|
199
215
|
config = loadJSConfigFile(filePath);
|
200
216
|
if (file.configName) {
|
201
217
|
config = config.configs[file.configName];
|
218
|
+
if (!config) {
|
219
|
+
throw configMissingError(file.configFullName);
|
220
|
+
}
|
202
221
|
}
|
203
222
|
break;
|
204
223
|
|
@@ -340,6 +359,33 @@ function getLookupPath(configFilePath) {
|
|
340
359
|
return path.join(basedir, "node_modules");
|
341
360
|
}
|
342
361
|
|
362
|
+
/**
|
363
|
+
* Resolves a eslint core config path
|
364
|
+
* @param {string} name The eslint config name.
|
365
|
+
* @returns {string} The resolved path of the config.
|
366
|
+
* @private
|
367
|
+
*/
|
368
|
+
function getEslintCoreConfigPath(name) {
|
369
|
+
if (name === "eslint:recommended") {
|
370
|
+
|
371
|
+
/*
|
372
|
+
* Add an explicit substitution for eslint:recommended to
|
373
|
+
* conf/eslint-recommended.js.
|
374
|
+
*/
|
375
|
+
return path.resolve(__dirname, "../../conf/eslint-recommended.js");
|
376
|
+
}
|
377
|
+
|
378
|
+
if (name === "eslint:all") {
|
379
|
+
|
380
|
+
/*
|
381
|
+
* Add an explicit substitution for eslint:all to conf/eslint-all.js
|
382
|
+
*/
|
383
|
+
return path.resolve(__dirname, "../../conf/eslint-all.js");
|
384
|
+
}
|
385
|
+
|
386
|
+
throw configMissingError(name);
|
387
|
+
}
|
388
|
+
|
343
389
|
/**
|
344
390
|
* Applies values from the "extends" field in a configuration file.
|
345
391
|
* @param {Object} config The configuration information.
|
@@ -360,43 +406,23 @@ function applyExtends(config, filePath, relativeTo) {
|
|
360
406
|
|
361
407
|
// Make the last element in an array take the highest precedence
|
362
408
|
config = configExtends.reduceRight((previousValue, parentPath) => {
|
363
|
-
|
364
|
-
if (parentPath === "eslint:recommended") {
|
365
|
-
|
366
|
-
/*
|
367
|
-
* Add an explicit substitution for eslint:recommended to
|
368
|
-
* conf/eslint-recommended.js.
|
369
|
-
*/
|
370
|
-
parentPath = path.resolve(__dirname, "../../conf/eslint-recommended.js");
|
371
|
-
} else if (parentPath === "eslint:all") {
|
372
|
-
|
373
|
-
/*
|
374
|
-
* Add an explicit substitution for eslint:all to conf/eslint-all.js
|
375
|
-
*/
|
376
|
-
parentPath = path.resolve(__dirname, "../../conf/eslint-all.js");
|
377
|
-
} else if (isFilePath(parentPath)) {
|
378
|
-
|
379
|
-
/*
|
380
|
-
* If the `extends` path is relative, use the directory of the current configuration
|
381
|
-
* file as the reference point. Otherwise, use as-is.
|
382
|
-
*/
|
383
|
-
parentPath = (!path.isAbsolute(parentPath)
|
384
|
-
? path.join(relativeTo || path.dirname(filePath), parentPath)
|
385
|
-
: parentPath
|
386
|
-
);
|
387
|
-
}
|
388
|
-
|
389
409
|
try {
|
410
|
+
if (parentPath.startsWith("eslint:")) {
|
411
|
+
parentPath = getEslintCoreConfigPath(parentPath);
|
412
|
+
} else if (isFilePath(parentPath)) {
|
413
|
+
|
414
|
+
/*
|
415
|
+
* If the `extends` path is relative, use the directory of the current configuration
|
416
|
+
* file as the reference point. Otherwise, use as-is.
|
417
|
+
*/
|
418
|
+
parentPath = (path.isAbsolute(parentPath)
|
419
|
+
? parentPath
|
420
|
+
: path.join(relativeTo || path.dirname(filePath), parentPath)
|
421
|
+
);
|
422
|
+
}
|
390
423
|
debug(`Loading ${parentPath}`);
|
391
424
|
return ConfigOps.merge(load(parentPath, false, relativeTo), previousValue);
|
392
425
|
} 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
|
-
}
|
400
426
|
|
401
427
|
/*
|
402
428
|
* If the file referenced by `extends` failed to load, add the path
|
@@ -462,7 +488,10 @@ function normalizePackageName(name, prefix) {
|
|
462
488
|
* or package name.
|
463
489
|
* @param {string} filePath The filepath to resolve.
|
464
490
|
* @param {string} [relativeTo] The path to resolve relative to.
|
465
|
-
* @returns {Object}
|
491
|
+
* @returns {Object} An object containing 3 properties:
|
492
|
+
* - 'filePath' (required) the resolved path that can be used directly to load the configuration.
|
493
|
+
* - 'configName' the name of the configuration inside the plugin.
|
494
|
+
* - 'configFullName' the name of the configuration as used in the eslint config (e.g. 'plugin:node/recommended').
|
466
495
|
* @private
|
467
496
|
*/
|
468
497
|
function resolve(filePath, relativeTo) {
|
@@ -471,14 +500,15 @@ function resolve(filePath, relativeTo) {
|
|
471
500
|
}
|
472
501
|
let normalizedPackageName;
|
473
502
|
|
474
|
-
if (filePath.
|
475
|
-
const
|
503
|
+
if (filePath.startsWith("plugin:")) {
|
504
|
+
const configFullName = filePath;
|
505
|
+
const pluginName = filePath.substr(7, filePath.lastIndexOf("/") - 7);
|
476
506
|
const configName = filePath.substr(filePath.lastIndexOf("/") + 1, filePath.length - filePath.lastIndexOf("/") - 1);
|
477
507
|
|
478
|
-
normalizedPackageName = normalizePackageName(
|
508
|
+
normalizedPackageName = normalizePackageName(pluginName, "eslint-plugin");
|
479
509
|
debug(`Attempting to resolve ${normalizedPackageName}`);
|
480
510
|
filePath = resolver.resolve(normalizedPackageName, getLookupPath(relativeTo));
|
481
|
-
return { filePath, configName };
|
511
|
+
return { filePath, configName, configFullName };
|
482
512
|
}
|
483
513
|
normalizedPackageName = normalizePackageName(filePath, "eslint-config");
|
484
514
|
debug(`Attempting to resolve ${normalizedPackageName}`);
|
@@ -223,7 +223,7 @@ class RuleConfigSet {
|
|
223
223
|
/**
|
224
224
|
* Add rule configurations from a schema object
|
225
225
|
* @param {Object} obj Schema item with type === "object"
|
226
|
-
* @returns {
|
226
|
+
* @returns {boolean} true if at least one schema for the object could be generated, false otherwise
|
227
227
|
*/
|
228
228
|
addObject(obj) {
|
229
229
|
const objectConfigSet = {
|
@@ -258,7 +258,10 @@ class RuleConfigSet {
|
|
258
258
|
|
259
259
|
if (objectConfigSet.objectConfigs.length > 0) {
|
260
260
|
this.ruleConfigs = this.ruleConfigs.concat(combineArrays(this.ruleConfigs, objectConfigSet.objectConfigs));
|
261
|
+
return true;
|
261
262
|
}
|
263
|
+
|
264
|
+
return false;
|
262
265
|
}
|
263
266
|
}
|
264
267
|
|
@@ -271,20 +274,21 @@ function generateConfigsFromSchema(schema) {
|
|
271
274
|
const configSet = new RuleConfigSet();
|
272
275
|
|
273
276
|
if (Array.isArray(schema)) {
|
274
|
-
|
277
|
+
for (const opt of schema) {
|
275
278
|
if (opt.enum) {
|
276
279
|
configSet.addEnums(opt.enum);
|
277
|
-
}
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
}
|
280
|
+
} else if (opt.type && opt.type === "object") {
|
281
|
+
if (!configSet.addObject(opt)) {
|
282
|
+
break;
|
283
|
+
}
|
282
284
|
|
283
|
-
|
285
|
+
// TODO (IanVS): support oneOf
|
286
|
+
} else {
|
284
287
|
|
285
|
-
//
|
288
|
+
// If we don't know how to fill in this option, don't fill in any of the following options.
|
289
|
+
break;
|
286
290
|
}
|
287
|
-
}
|
291
|
+
}
|
288
292
|
}
|
289
293
|
configSet.addErrorSeverity();
|
290
294
|
return configSet.ruleConfigs;
|
package/lib/config/plugins.js
CHANGED
@@ -127,14 +127,25 @@ module.exports = {
|
|
127
127
|
if (!plugins[shortName]) {
|
128
128
|
try {
|
129
129
|
plugin = require(longName);
|
130
|
-
} catch (
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
130
|
+
} catch (pluginLoadErr) {
|
131
|
+
try {
|
132
|
+
|
133
|
+
// Check whether the plugin exists
|
134
|
+
require.resolve(longName);
|
135
|
+
} catch (missingPluginErr) {
|
136
|
+
|
137
|
+
// If the plugin can't be resolved, display the missing plugin error (usually a config or install error)
|
138
|
+
debug(`Failed to load plugin ${longName}.`);
|
139
|
+
missingPluginErr.message = `Failed to load plugin ${pluginName}: ${missingPluginErr.message}`;
|
140
|
+
missingPluginErr.messageTemplate = "plugin-missing";
|
141
|
+
missingPluginErr.messageData = {
|
142
|
+
pluginName: longName
|
143
|
+
};
|
144
|
+
throw missingPluginErr;
|
145
|
+
}
|
146
|
+
|
147
|
+
// Otherwise, the plugin exists and is throwing on module load for some reason, so print the stack trace.
|
148
|
+
throw pluginLoadErr;
|
138
149
|
}
|
139
150
|
|
140
151
|
this.define(pluginName, plugin);
|
package/lib/eslint.js
CHANGED
@@ -778,17 +778,18 @@ module.exports = (function() {
|
|
778
778
|
// search and apply "eslint-env *".
|
779
779
|
const envInFile = findEslintEnv(text || textOrSourceCode.text);
|
780
780
|
|
781
|
+
config = Object.assign({}, config);
|
782
|
+
|
781
783
|
if (envInFile) {
|
782
|
-
if (
|
783
|
-
config = Object.assign({}, config || {}, { env: envInFile });
|
784
|
-
} else {
|
785
|
-
config = Object.assign({}, config);
|
784
|
+
if (config.env) {
|
786
785
|
config.env = Object.assign({}, config.env, envInFile);
|
786
|
+
} else {
|
787
|
+
config.env = envInFile;
|
787
788
|
}
|
788
789
|
}
|
789
790
|
|
790
791
|
// process initial config to make it safe to extend
|
791
|
-
config = prepareConfig(config
|
792
|
+
config = prepareConfig(config);
|
792
793
|
|
793
794
|
// only do this for text
|
794
795
|
if (text !== null) {
|
@@ -867,11 +868,11 @@ module.exports = (function() {
|
|
867
868
|
const rule = ruleCreator.create ? ruleCreator.create(ruleContext)
|
868
869
|
: ruleCreator(ruleContext);
|
869
870
|
|
870
|
-
// add all the
|
871
|
-
Object.keys(rule).forEach(
|
872
|
-
api.on(
|
873
|
-
? timing.time(key, rule[
|
874
|
-
: rule[
|
871
|
+
// add all the selectors from the rule as listeners
|
872
|
+
Object.keys(rule).forEach(selector => {
|
873
|
+
api.on(selector, timing.enabled
|
874
|
+
? timing.time(key, rule[selector])
|
875
|
+
: rule[selector]
|
875
876
|
);
|
876
877
|
});
|
877
878
|
} catch (ex) {
|
@@ -101,15 +101,10 @@ module.exports = function(results) {
|
|
101
101
|
const resultsWithMessages = results.filter(result => result.messages.length > 0);
|
102
102
|
|
103
103
|
let output = resultsWithMessages.reduce((resultsOutput, result) => {
|
104
|
-
const messages = result.messages.map(message => {
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
warnings++;
|
109
|
-
}
|
110
|
-
|
111
|
-
return `${formatMessage(message, result)}\n\n`;
|
112
|
-
});
|
104
|
+
const messages = result.messages.map(message => `${formatMessage(message, result)}\n\n`);
|
105
|
+
|
106
|
+
errors += result.errorCount;
|
107
|
+
warnings += result.warningCount;
|
113
108
|
|
114
109
|
return resultsOutput.concat(messages);
|
115
110
|
}, []).join("\n");
|
@@ -28,7 +28,6 @@ function pluralize(word, count) {
|
|
28
28
|
module.exports = function(results) {
|
29
29
|
|
30
30
|
let output = "\n",
|
31
|
-
total = 0,
|
32
31
|
errors = 0,
|
33
32
|
warnings = 0,
|
34
33
|
summaryColor = "yellow";
|
@@ -40,7 +39,9 @@ module.exports = function(results) {
|
|
40
39
|
return;
|
41
40
|
}
|
42
41
|
|
43
|
-
|
42
|
+
errors += result.errorCount;
|
43
|
+
warnings += result.warningCount;
|
44
|
+
|
44
45
|
output += `${chalk.underline(result.filePath)}\n`;
|
45
46
|
|
46
47
|
output += `${table(
|
@@ -50,10 +51,8 @@ module.exports = function(results) {
|
|
50
51
|
if (message.fatal || message.severity === 2) {
|
51
52
|
messageType = chalk.red("error");
|
52
53
|
summaryColor = "red";
|
53
|
-
errors++;
|
54
54
|
} else {
|
55
55
|
messageType = chalk.yellow("warning");
|
56
|
-
warnings++;
|
57
56
|
}
|
58
57
|
|
59
58
|
return [
|
@@ -74,6 +73,8 @@ module.exports = function(results) {
|
|
74
73
|
).split("\n").map(el => el.replace(/(\d+)\s+(\d+)/, (m, p1, p2) => chalk.dim(`${p1}:${p2}`))).join("\n")}\n\n`;
|
75
74
|
});
|
76
75
|
|
76
|
+
const total = errors + warnings;
|
77
|
+
|
77
78
|
if (total > 0) {
|
78
79
|
output += chalk[summaryColor].bold([
|
79
80
|
"\u2716 ", total, pluralize(" problem", total),
|
package/lib/ignored-paths.js
CHANGED
@@ -201,6 +201,12 @@ class IgnoredPaths {
|
|
201
201
|
|
202
202
|
const ig = ignore().add(DEFAULT_IGNORE_DIRS);
|
203
203
|
|
204
|
+
if (this.options.dotfiles !== true) {
|
205
|
+
|
206
|
+
// Ignore hidden folders. (This cannot be ".*", or else it's not possible to unignore hidden files)
|
207
|
+
ig.add([".*/*", "!../"]);
|
208
|
+
}
|
209
|
+
|
204
210
|
if (this.options.ignore) {
|
205
211
|
ig.add(this.ig.custom);
|
206
212
|
}
|