eslint 4.10.0 → 4.11.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 +36 -22
- package/conf/default-cli-options.js +5 -3
- package/lib/ast-utils.js +81 -41
- package/lib/cli-engine.js +27 -12
- package/lib/code-path-analysis/code-path-analyzer.js +8 -4
- package/lib/code-path-analysis/code-path-segment.js +4 -2
- package/lib/code-path-analysis/code-path-state.js +4 -2
- package/lib/config/autoconfig.js +14 -12
- package/lib/config/config-file.js +8 -51
- package/lib/config/config-initializer.js +10 -6
- package/lib/config/config-ops.js +21 -21
- package/lib/config/config-rule.js +24 -24
- package/lib/config/config-validator.js +38 -36
- package/lib/config/plugins.js +8 -35
- package/lib/config.js +12 -8
- package/lib/formatters/junit.js +21 -15
- package/lib/formatters/tap.js +5 -3
- package/lib/ignored-paths.js +4 -2
- package/lib/linter.js +16 -10
- package/lib/rules/.eslintrc.yml +2 -2
- package/lib/rules/array-bracket-newline.js +20 -20
- package/lib/rules/array-bracket-spacing.js +28 -28
- package/lib/rules/array-callback-return.js +13 -9
- package/lib/rules/array-element-newline.js +8 -8
- package/lib/rules/arrow-body-style.js +12 -6
- package/lib/rules/arrow-parens.js +4 -2
- package/lib/rules/brace-style.js +14 -14
- package/lib/rules/computed-property-spacing.js +22 -22
- package/lib/rules/consistent-return.js +4 -4
- package/lib/rules/consistent-this.js +4 -2
- package/lib/rules/curly.js +13 -9
- package/lib/rules/dot-notation.js +5 -5
- package/lib/rules/func-call-spacing.js +4 -2
- package/lib/rules/getter-return.js +2 -1
- package/lib/rules/indent-legacy.js +20 -12
- package/lib/rules/indent.js +77 -73
- package/lib/rules/key-spacing.js +5 -3
- package/lib/rules/lines-around-directive.js +16 -12
- package/lib/rules/max-statements-per-line.js +5 -3
- package/lib/rules/newline-after-var.js +8 -6
- package/lib/rules/newline-before-return.js +9 -7
- package/lib/rules/no-await-in-loop.js +17 -9
- package/lib/rules/no-bitwise.js +5 -3
- package/lib/rules/no-catch-shadow.js +4 -2
- package/lib/rules/no-console.js +2 -1
- package/lib/rules/no-else-return.js +17 -11
- package/lib/rules/no-empty-character-class.js +11 -11
- package/lib/rules/no-extra-parens.js +16 -8
- package/lib/rules/no-extra-semi.js +5 -3
- package/lib/rules/no-global-assign.js +4 -2
- package/lib/rules/no-implicit-coercion.js +6 -6
- package/lib/rules/no-implied-eval.js +2 -1
- package/lib/rules/no-label-var.js +4 -2
- package/lib/rules/no-lone-blocks.js +3 -3
- package/lib/rules/no-loop-func.js +8 -4
- package/lib/rules/no-native-reassign.js +4 -2
- package/lib/rules/no-param-reassign.js +4 -2
- package/lib/rules/no-regex-spaces.js +1 -1
- package/lib/rules/no-restricted-properties.js +10 -10
- package/lib/rules/no-return-await.js +6 -6
- package/lib/rules/no-self-assign.js +4 -2
- package/lib/rules/no-sequences.js +6 -4
- package/lib/rules/no-trailing-spaces.js +13 -7
- package/lib/rules/no-unreachable.js +4 -2
- package/lib/rules/no-use-before-define.js +13 -11
- package/lib/rules/no-useless-call.js +1 -25
- package/lib/rules/no-useless-escape.js +23 -22
- package/lib/rules/no-useless-return.js +14 -8
- package/lib/rules/no-whitespace-before-property.js +4 -2
- package/lib/rules/object-curly-newline.js +9 -2
- package/lib/rules/object-curly-spacing.js +20 -20
- package/lib/rules/object-shorthand.js +41 -33
- package/lib/rules/operator-assignment.js +9 -9
- package/lib/rules/operator-linebreak.js +12 -10
- package/lib/rules/padding-line-between-statements.js +4 -2
- package/lib/rules/prefer-arrow-callback.js +12 -10
- package/lib/rules/prefer-const.js +18 -10
- package/lib/rules/prefer-destructuring.js +4 -2
- package/lib/rules/prefer-numeric-literals.js +4 -2
- package/lib/rules/prefer-promise-reject-errors.js +16 -16
- package/lib/rules/prefer-rest-params.js +4 -2
- package/lib/rules/prefer-spread.js +1 -25
- package/lib/rules/prefer-template.js +33 -29
- package/lib/rules/quote-props.js +8 -8
- package/lib/rules/semi-style.js +44 -19
- package/lib/rules/semi.js +5 -3
- package/lib/rules/sort-imports.js +5 -3
- package/lib/rules/space-unary-ops.js +61 -61
- package/lib/rules/strict.js +8 -8
- package/lib/rules/valid-typeof.js +4 -4
- package/lib/rules/wrap-iife.js +4 -4
- package/lib/rules/yoda.js +9 -7
- package/lib/testers/rule-tester.js +43 -34
- package/lib/token-store/backward-token-cursor.js +5 -3
- package/lib/token-store/forward-token-cursor.js +5 -3
- package/lib/token-store/utils.js +8 -4
- package/lib/util/glob.js +1 -1
- package/lib/util/naming.js +112 -0
- package/lib/util/node-event-generator.js +10 -10
- package/lib/util/safe-emitter.js +1 -1
- package/lib/util/source-code-fixer.js +4 -2
- package/lib/util/source-code.js +2 -1
- package/package.json +6 -5
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,39 @@
|
|
1
|
+
v4.11.0 - November 10, 2017
|
2
|
+
|
3
|
+
* d4557a6 Docs: disallow use of the comma operator using no-restricted-syntax (#9585) (薛定谔的猫)
|
4
|
+
* d602f9e Upgrade: espree v3.5.2 (#9611) (Kai Cataldo)
|
5
|
+
* 4def876 Chore: avoid handling rules instances in config-validator (#9364) (Teddy Katz)
|
6
|
+
* fe5ac7e Chore: fix incorrect comment in safe-emitter.js (#9605) (Teddy Katz)
|
7
|
+
* 6672fae Docs: Fixed a typo on lines-between-class-members doc (#9603) (Moinul Hossain)
|
8
|
+
* 980ecd3 Chore: Update copyright and license info (#9599) (薛定谔的猫)
|
9
|
+
* cc2c7c9 Build: use Node 8 in appveyor (#9595) (薛定谔的猫)
|
10
|
+
* 2542f04 Docs: Add missing options for `lines-around-comment` (#9589) (Clément Fiorio)
|
11
|
+
* b6a7490 Build: ensure fuzzer tests get run with `npm test` (#9590) (Teddy Katz)
|
12
|
+
* 1073bc5 Build: remove shelljs-nodecli (refs #9533) (#9588) (Teddy Katz)
|
13
|
+
* 7e3bf6a Fix: edge-cases of semi-style (#9560) (Toru Nagashima)
|
14
|
+
* e5a37ce Fix: object-curly-newline for flow code (#9458) (Tiddo Langerak)
|
15
|
+
* 9064b9c Chore: add equalTokens in ast-utils. (#9500) (薛定谔的猫)
|
16
|
+
* b7c5b19 Fix: Correct [object Object] output of error.data. (#9561) (Jonathan Pool)
|
17
|
+
* 51c8cf0 Docs: Disambiguate definition of Update tag (#9584) (Jonathan Pool)
|
18
|
+
* afc3c75 Docs: clarify what eslint-config-eslint is (#9582) (Teddy Katz)
|
19
|
+
* aedae9d Docs: fix spelling in valid-typeof example (#9574) (Maksim Degtyarev)
|
20
|
+
* 4c5aaf3 Docs: Fix typo in no-underscore-dangle rule (#9567) (Fabien Lucas)
|
21
|
+
* 3623600 Chore: upgrade ajv@5.3.0 (#9557) (薛定谔的猫)
|
22
|
+
* 1b606cd Chore: Remove an indirect dependency on jsonify (#9444) (Rouven Weßling)
|
23
|
+
* 4d7d7ab Update: Resolve npm installed formatters (#5900) (#9464) (Tom Erik Støwer)
|
24
|
+
* accc490 Fix: Files with no failures get "passing" testcase (#9547) (Samuel Levy)
|
25
|
+
* ab0f66d Docs: Add examples to better show rule coverage. (#9548) (Jonathan Pool)
|
26
|
+
* 88d2303 Chore: Add object-property-newline tests to increase coverage. (#9553) (Jonathan Pool)
|
27
|
+
* 7f37b1c Build: test Node 9 on Travis (#9556) (Teddy Katz)
|
28
|
+
* acccfbd Docs: Minor rephrase in `no-invalid-this`. (#9542) (Francisc)
|
29
|
+
* 8f9c0fe Docs: improve id-match usage advice (#9544) (Teddy Katz)
|
30
|
+
* a9606a3 Fix: invalid tests with super (fixes #9539) (#9545) (Teddy Katz)
|
31
|
+
* 8e1a095 Chore: enable a modified version of multiline-comment-style on codebase (#9452) (Teddy Katz)
|
32
|
+
* cb60285 Chore: remove commented test for HTML formatter (#9532) (Teddy Katz)
|
33
|
+
* 06b491e Docs: fix duplicate entries in changelog (#9530) (Teddy Katz)
|
34
|
+
* 2224733 Chore: use eslint-plugin-rulesdir instead of --rulesdir for self-linting (#9164) (Teddy Katz)
|
35
|
+
* 9cf4ebe Docs: add .md to link(for github users) (#9529) (薛定谔的猫)
|
36
|
+
|
1
37
|
v4.10.0 - October 27, 2017
|
2
38
|
|
3
39
|
* bb6e60a Fix: Improve the doc for no-restricted-modules rule (fixes #9437) (#9495) (vibss2397)
|
@@ -36,28 +72,6 @@ v4.10.0 - October 27, 2017
|
|
36
72
|
* 052c504 Docs: suggest deleting branches after merging PRs (#9449) (Teddy Katz)
|
37
73
|
* b31e55a Chore: move internal rules out of lib/ (#9448) (Teddy Katz)
|
38
74
|
* a7521e3 Docs: improve examples for multiline-comment-style (#9440) (Teddy Katz)
|
39
|
-
* 235c7dd 4.9.0 (ESLint Jenkins)
|
40
|
-
* b6f31a9 Build: changelog update for 4.9.0 (ESLint Jenkins)
|
41
|
-
* 85388fb Fix: Correct error and test messages to fit config search path (#9428) (Jonathan Pool)
|
42
|
-
* 62a323c Fix: Add class options for `lines-around-comment` (fixes #8564) (#8565) (Ed Lee)
|
43
|
-
* 8eb4aae New: multiline-comment-style rule (fixes #8320) (#9389) (薛定谔的猫)
|
44
|
-
* db41408 Chore: avoid applying eslint-env comments twice (#9278) (Teddy Katz)
|
45
|
-
* febb897 Chore: avoid loose equality assertions (#9415) (Teddy Katz)
|
46
|
-
* 2247efa Update: Add FunctionExpression to require-jsdoc (fixes #5867) (#9395) (Kai Cataldo)
|
47
|
-
* 6791d18 Docs: Corrected noun to verb. (#9438) (Jonathan Pool)
|
48
|
-
* b02fbb6 Update: custom messages for no-restricted-* (refs #8400) (Maja Wichrowska)
|
49
|
-
* 02732bd Docs: Reorganized to avoid misunderstandings. (#9434) (Jonathan Pool)
|
50
|
-
* d9466b8 Docs: Correct time forecast for tests. (#9432) (Jonathan Pool)
|
51
|
-
* f7ed84f Docs: Add instruction re home-directory config files (refs #7729) (#9426) (Jonathan Pool)
|
52
|
-
* 30d018b Chore: Add Aladdin-ADD & VictorHom to README (#9424) (Kai Cataldo)
|
53
|
-
* 2d8a303 Docs: fix examples for prefer-numeric-literals (#9155) (Lutz Lengemann)
|
54
|
-
* d7610f5 Docs: Add jquery warning to prefer-destructuring (#9409) (Thomas Grainger)
|
55
|
-
* e835dd1 Docs: clarify no-mixed-operators (fixes #8051) (Ruxandra Fediuc)
|
56
|
-
* 51360c8 Docs: update block-spacing details (fixes #8743) (#9375) (Victor Hom)
|
57
|
-
* 6767857 Update: fix ignored nodes in indent rule when using tabs (fixes #9392) (#9393) (Robin Houston)
|
58
|
-
* 37dde77 Chore: Refactor SourceCode#getJSDocComment (#9403) (Kai Cataldo)
|
59
|
-
* 9fedd51 Chore: Add missing space in blog post template (#9407) (Kevin Partington)
|
60
|
-
* 7654c99 Docs: add installing prerequisites in readme. (#9401) (薛定谔的猫)
|
61
75
|
|
62
76
|
v4.9.0 - October 14, 2017
|
63
77
|
|
@@ -17,9 +17,11 @@ module.exports = {
|
|
17
17
|
ignorePath: null,
|
18
18
|
cache: false,
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
/*
|
21
|
+
* in order to honor the cacheFile option if specified
|
22
|
+
* this option should not have a default value otherwise
|
23
|
+
* it will always be used
|
24
|
+
*/
|
23
25
|
cacheLocation: "",
|
24
26
|
cacheFile: ".eslintcache",
|
25
27
|
fix: false,
|
package/lib/ast-utils.js
CHANGED
@@ -406,6 +406,31 @@ function createGlobalLinebreakMatcher() {
|
|
406
406
|
return new RegExp(LINEBREAK_MATCHER.source, "g");
|
407
407
|
}
|
408
408
|
|
409
|
+
/**
|
410
|
+
* Checks whether or not the tokens of two given nodes are same.
|
411
|
+
* @param {ASTNode} left - A node 1 to compare.
|
412
|
+
* @param {ASTNode} right - A node 2 to compare.
|
413
|
+
* @param {SourceCode} sourceCode - The ESLint source code object.
|
414
|
+
* @returns {boolean} the source code for the given node.
|
415
|
+
*/
|
416
|
+
function equalTokens(left, right, sourceCode) {
|
417
|
+
const tokensL = sourceCode.getTokens(left);
|
418
|
+
const tokensR = sourceCode.getTokens(right);
|
419
|
+
|
420
|
+
if (tokensL.length !== tokensR.length) {
|
421
|
+
return false;
|
422
|
+
}
|
423
|
+
for (let i = 0; i < tokensL.length; ++i) {
|
424
|
+
if (tokensL[i].type !== tokensR[i].type ||
|
425
|
+
tokensL[i].value !== tokensR[i].value
|
426
|
+
) {
|
427
|
+
return false;
|
428
|
+
}
|
429
|
+
}
|
430
|
+
|
431
|
+
return true;
|
432
|
+
}
|
433
|
+
|
409
434
|
//------------------------------------------------------------------------------
|
410
435
|
// Public Interface
|
411
436
|
//------------------------------------------------------------------------------
|
@@ -438,6 +463,7 @@ module.exports = {
|
|
438
463
|
isArrayFromMethod,
|
439
464
|
isParenthesised,
|
440
465
|
createGlobalLinebreakMatcher,
|
466
|
+
equalTokens,
|
441
467
|
|
442
468
|
isArrowToken,
|
443
469
|
isClosingBraceToken,
|
@@ -620,15 +646,17 @@ module.exports = {
|
|
620
646
|
node = parent;
|
621
647
|
break;
|
622
648
|
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
649
|
+
/*
|
650
|
+
* If the upper function is IIFE, checks the destination of the return value.
|
651
|
+
* e.g.
|
652
|
+
* obj.foo = (function() {
|
653
|
+
* // setup...
|
654
|
+
* return function foo() { ... };
|
655
|
+
* })();
|
656
|
+
* obj.foo = (() =>
|
657
|
+
* function foo() { ... }
|
658
|
+
* )();
|
659
|
+
*/
|
632
660
|
case "ReturnStatement": {
|
633
661
|
const func = getUpperFunction(parent);
|
634
662
|
|
@@ -645,23 +673,27 @@ module.exports = {
|
|
645
673
|
node = parent.parent;
|
646
674
|
break;
|
647
675
|
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
676
|
+
/*
|
677
|
+
* e.g.
|
678
|
+
* var obj = { foo() { ... } };
|
679
|
+
* var obj = { foo: function() { ... } };
|
680
|
+
* class A { constructor() { ... } }
|
681
|
+
* class A { foo() { ... } }
|
682
|
+
* class A { get foo() { ... } }
|
683
|
+
* class A { set foo() { ... } }
|
684
|
+
* class A { static foo() { ... } }
|
685
|
+
*/
|
656
686
|
case "Property":
|
657
687
|
case "MethodDefinition":
|
658
688
|
return parent.value !== node;
|
659
689
|
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
690
|
+
/*
|
691
|
+
* e.g.
|
692
|
+
* obj.foo = function foo() { ... };
|
693
|
+
* Foo = function() { ... };
|
694
|
+
* [obj.foo = function foo() { ... }] = a;
|
695
|
+
* [Foo = function() { ... }] = a;
|
696
|
+
*/
|
665
697
|
case "AssignmentExpression":
|
666
698
|
case "AssignmentPattern":
|
667
699
|
if (parent.left.type === "MemberExpression") {
|
@@ -676,8 +708,10 @@ module.exports = {
|
|
676
708
|
}
|
677
709
|
return true;
|
678
710
|
|
679
|
-
|
680
|
-
|
711
|
+
/*
|
712
|
+
* e.g.
|
713
|
+
* var Foo = function() { ... };
|
714
|
+
*/
|
681
715
|
case "VariableDeclarator":
|
682
716
|
return !(
|
683
717
|
isAnonymous &&
|
@@ -686,10 +720,12 @@ module.exports = {
|
|
686
720
|
startsWithUpperCase(parent.id.name)
|
687
721
|
);
|
688
722
|
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
723
|
+
/*
|
724
|
+
* e.g.
|
725
|
+
* var foo = function foo() { ... }.bind(obj);
|
726
|
+
* (function foo() { ... }).call(obj);
|
727
|
+
* (function foo() { ... }).apply(obj, []);
|
728
|
+
*/
|
693
729
|
case "MemberExpression":
|
694
730
|
return (
|
695
731
|
parent.object !== node ||
|
@@ -700,10 +736,12 @@ module.exports = {
|
|
700
736
|
isNullOrUndefined(parent.parent.arguments[0])
|
701
737
|
);
|
702
738
|
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
739
|
+
/*
|
740
|
+
* e.g.
|
741
|
+
* Reflect.apply(function() {}, obj, []);
|
742
|
+
* Array.from([], function() {}, obj);
|
743
|
+
* list.forEach(function() {}, obj);
|
744
|
+
*/
|
707
745
|
case "CallExpression":
|
708
746
|
if (isReflectApply(parent.callee)) {
|
709
747
|
return (
|
@@ -930,8 +968,10 @@ module.exports = {
|
|
930
968
|
node.type === "FunctionDeclaration" ||
|
931
969
|
node.type === "FunctionExpression" ||
|
932
970
|
|
933
|
-
|
934
|
-
|
971
|
+
/*
|
972
|
+
* Do not check arrow functions with implicit return.
|
973
|
+
* `() => "use strict";` returns the string `"use strict"`.
|
974
|
+
*/
|
935
975
|
(node.type === "ArrowFunctionExpression" && node.body.type === "BlockStatement")
|
936
976
|
) {
|
937
977
|
const statements = node.type === "Program" ? node.body : node.body.body;
|
@@ -954,7 +994,7 @@ module.exports = {
|
|
954
994
|
|
955
995
|
/**
|
956
996
|
* Determines whether this node is a decimal integer literal. If a node is a decimal integer literal, a dot added
|
957
|
-
after the node will be parsed as a decimal point, rather than a property-access dot.
|
997
|
+
* after the node will be parsed as a decimal point, rather than a property-access dot.
|
958
998
|
* @param {ASTNode} node - The node to check.
|
959
999
|
* @returns {boolean} `true` if this node is a decimal integer.
|
960
1000
|
* @example
|
@@ -1183,12 +1223,12 @@ module.exports = {
|
|
1183
1223
|
},
|
1184
1224
|
|
1185
1225
|
/**
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1191
|
-
|
1226
|
+
* Gets the parenthesized text of a node. This is similar to sourceCode.getText(node), but it also includes any parentheses
|
1227
|
+
* surrounding the node.
|
1228
|
+
* @param {SourceCode} sourceCode The source code object
|
1229
|
+
* @param {ASTNode} node An expression node
|
1230
|
+
* @returns {string} The text representing the node, with all surrounding parentheses included
|
1231
|
+
*/
|
1192
1232
|
getParenthesisedText(sourceCode, node) {
|
1193
1233
|
let leftToken = sourceCode.getFirstToken(node);
|
1194
1234
|
let rightToken = sourceCode.getLastToken(node);
|
package/lib/cli-engine.js
CHANGED
@@ -24,12 +24,16 @@ const fs = require("fs"),
|
|
24
24
|
fileEntryCache = require("file-entry-cache"),
|
25
25
|
globUtil = require("./util/glob-util"),
|
26
26
|
validator = require("./config/config-validator"),
|
27
|
-
stringify = require("json-stable-stringify"),
|
27
|
+
stringify = require("json-stable-stringify-without-jsonify"),
|
28
28
|
hash = require("./util/hash"),
|
29
|
+
ModuleResolver = require("./util/module-resolver"),
|
30
|
+
naming = require("./util/naming"),
|
29
31
|
pkg = require("../package.json");
|
30
32
|
|
31
33
|
const debug = require("debug")("eslint:cli-engine");
|
32
34
|
|
35
|
+
const resolver = new ModuleResolver();
|
36
|
+
|
33
37
|
//------------------------------------------------------------------------------
|
34
38
|
// Typedefs
|
35
39
|
//------------------------------------------------------------------------------
|
@@ -405,9 +409,13 @@ class CLIEngine {
|
|
405
409
|
});
|
406
410
|
}
|
407
411
|
|
408
|
-
Object.keys(this.options.rules
|
409
|
-
|
410
|
-
|
412
|
+
if (this.options.rules && Object.keys(this.options.rules).length) {
|
413
|
+
const loadedRules = this.linter.getRules();
|
414
|
+
|
415
|
+
Object.keys(this.options.rules).forEach(name => {
|
416
|
+
validator.validateRuleOptions(loadedRules.get(name), name, this.options.rules[name], "CLI");
|
417
|
+
});
|
418
|
+
}
|
411
419
|
|
412
420
|
this.config = new Config(this.options, this.linter);
|
413
421
|
}
|
@@ -542,10 +550,10 @@ class CLIEngine {
|
|
542
550
|
if (result.messages.length) {
|
543
551
|
|
544
552
|
/*
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
553
|
+
* if a file contains errors or warnings we don't want to
|
554
|
+
* store the file in the cache so we can guarantee that
|
555
|
+
* next execution will also operate on this file
|
556
|
+
*/
|
549
557
|
fileCache.removeEntry(result.filePath);
|
550
558
|
} else {
|
551
559
|
|
@@ -670,15 +678,22 @@ class CLIEngine {
|
|
670
678
|
// replace \ with / for Windows compatibility
|
671
679
|
format = format.replace(/\\/g, "/");
|
672
680
|
|
681
|
+
const cwd = this.options ? this.options.cwd : process.cwd();
|
682
|
+
const namespace = naming.getNamespaceFromTerm(format);
|
683
|
+
|
673
684
|
let formatterPath;
|
674
685
|
|
675
686
|
// if there's a slash, then it's a file
|
676
|
-
if (format.indexOf("/") > -1) {
|
677
|
-
const cwd = this.options ? this.options.cwd : process.cwd();
|
678
|
-
|
687
|
+
if (!namespace && format.indexOf("/") > -1) {
|
679
688
|
formatterPath = path.resolve(cwd, format);
|
680
689
|
} else {
|
681
|
-
|
690
|
+
try {
|
691
|
+
const npmFormat = naming.normalizePackageName(format, "eslint-formatter");
|
692
|
+
|
693
|
+
formatterPath = resolver.resolve(npmFormat, `${cwd}/node_modules`);
|
694
|
+
} catch (e) {
|
695
|
+
formatterPath = `./formatters/${format}`;
|
696
|
+
}
|
682
697
|
}
|
683
698
|
|
684
699
|
try {
|
@@ -598,8 +598,10 @@ class CodePathAnalyzer {
|
|
598
598
|
preprocess(this, node);
|
599
599
|
}
|
600
600
|
|
601
|
-
|
602
|
-
|
601
|
+
/*
|
602
|
+
* Updates the code path.
|
603
|
+
* And emits onCodePathStart/onCodePathSegmentStart events.
|
604
|
+
*/
|
603
605
|
processCodePathToEnter(this, node);
|
604
606
|
|
605
607
|
// Emits node events.
|
@@ -618,8 +620,10 @@ class CodePathAnalyzer {
|
|
618
620
|
leaveNode(node) {
|
619
621
|
this.currentNode = node;
|
620
622
|
|
621
|
-
|
622
|
-
|
623
|
+
/*
|
624
|
+
* Updates the code path.
|
625
|
+
* And emits onCodePathStart/onCodePathSegmentStart events.
|
626
|
+
*/
|
623
627
|
processCodePathToExit(this, node);
|
624
628
|
|
625
629
|
// Emits node events.
|
@@ -141,8 +141,10 @@ class CodePathSegment {
|
|
141
141
|
static newUnreachable(id, allPrevSegments) {
|
142
142
|
const segment = new CodePathSegment(id, CodePathSegment.flattenUnusedSegments(allPrevSegments), false);
|
143
143
|
|
144
|
-
|
145
|
-
|
144
|
+
/*
|
145
|
+
* In `if (a) return a; foo();` case, the unreachable segment preceded by
|
146
|
+
* the return statement is not used but must not be remove.
|
147
|
+
*/
|
146
148
|
CodePathSegment.markUsed(segment);
|
147
149
|
|
148
150
|
return segment;
|
@@ -774,8 +774,10 @@ class CodePathState {
|
|
774
774
|
// Sets the normal path as the next.
|
775
775
|
this.forkContext.replaceHead(normalSegments);
|
776
776
|
|
777
|
-
|
778
|
-
|
777
|
+
/*
|
778
|
+
* If both paths of the `try` block and the `catch` block are
|
779
|
+
* unreachable, the next path becomes unreachable as well.
|
780
|
+
*/
|
779
781
|
if (!context.lastOfTryIsReachable && !context.lastOfCatchIsReachable) {
|
780
782
|
this.forkContext.makeUnreachable();
|
781
783
|
}
|
package/lib/config/autoconfig.js
CHANGED
@@ -61,13 +61,13 @@ function makeRegistryItems(rulesConfig) {
|
|
61
61
|
}
|
62
62
|
|
63
63
|
/**
|
64
|
-
* Creates an object in which to store rule configs and error counts
|
65
|
-
*
|
66
|
-
* Unless a rulesConfig is provided at construction, the registry will not contain
|
67
|
-
* any rules, only methods. This will be useful for building up registries manually.
|
68
|
-
*
|
69
|
-
* Registry class
|
70
|
-
*/
|
64
|
+
* Creates an object in which to store rule configs and error counts
|
65
|
+
*
|
66
|
+
* Unless a rulesConfig is provided at construction, the registry will not contain
|
67
|
+
* any rules, only methods. This will be useful for building up registries manually.
|
68
|
+
*
|
69
|
+
* Registry class
|
70
|
+
*/
|
71
71
|
class Registry {
|
72
72
|
|
73
73
|
/**
|
@@ -293,11 +293,13 @@ class Registry {
|
|
293
293
|
|
294
294
|
lintResults.forEach(result => {
|
295
295
|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
296
|
+
/*
|
297
|
+
* It is possible that the error is from a configuration comment
|
298
|
+
* in a linted file, in which case there may not be a config
|
299
|
+
* set in this ruleSetIdx.
|
300
|
+
* (https://github.com/eslint/eslint/issues/5992)
|
301
|
+
* (https://github.com/eslint/eslint/issues/7860)
|
302
|
+
*/
|
301
303
|
if (
|
302
304
|
lintedRegistry.rules[result.ruleId] &&
|
303
305
|
lintedRegistry.rules[result.ruleId][ruleSetIdx]
|
@@ -13,11 +13,11 @@ const fs = require("fs"),
|
|
13
13
|
path = require("path"),
|
14
14
|
ConfigOps = require("./config-ops"),
|
15
15
|
validator = require("./config-validator"),
|
16
|
-
pathUtil = require("../util/path-util"),
|
17
16
|
ModuleResolver = require("../util/module-resolver"),
|
17
|
+
naming = require("../util/naming"),
|
18
18
|
pathIsInside = require("path-is-inside"),
|
19
19
|
stripComments = require("strip-json-comments"),
|
20
|
-
stringify = require("json-stable-stringify"),
|
20
|
+
stringify = require("json-stable-stringify-without-jsonify"),
|
21
21
|
requireUncached = require("require-uncached");
|
22
22
|
|
23
23
|
const debug = require("debug")("eslint:config-file");
|
@@ -29,7 +29,7 @@ const debug = require("debug")("eslint:config-file");
|
|
29
29
|
/**
|
30
30
|
* Determines sort order for object keys for json-stable-stringify
|
31
31
|
*
|
32
|
-
* see: https://github.com/
|
32
|
+
* see: https://github.com/samn/json-stable-stringify#cmp
|
33
33
|
*
|
34
34
|
* @param {Object} a The first comparison object ({key: akey, value: avalue})
|
35
35
|
* @param {Object} b The second comparison object ({key: bkey, value: bvalue})
|
@@ -436,50 +436,6 @@ function applyExtends(config, configContext, filePath, relativeTo) {
|
|
436
436
|
return config;
|
437
437
|
}
|
438
438
|
|
439
|
-
/**
|
440
|
-
* Brings package name to correct format based on prefix
|
441
|
-
* @param {string} name The name of the package.
|
442
|
-
* @param {string} prefix Can be either "eslint-plugin" or "eslint-config
|
443
|
-
* @returns {string} Normalized name of the package
|
444
|
-
* @private
|
445
|
-
*/
|
446
|
-
function normalizePackageName(name, prefix) {
|
447
|
-
|
448
|
-
/*
|
449
|
-
* On Windows, name can come in with Windows slashes instead of Unix slashes.
|
450
|
-
* Normalize to Unix first to avoid errors later on.
|
451
|
-
* https://github.com/eslint/eslint/issues/5644
|
452
|
-
*/
|
453
|
-
if (name.indexOf("\\") > -1) {
|
454
|
-
name = pathUtil.convertPathToPosix(name);
|
455
|
-
}
|
456
|
-
|
457
|
-
if (name.charAt(0) === "@") {
|
458
|
-
|
459
|
-
/*
|
460
|
-
* it's a scoped package
|
461
|
-
* package name is "eslint-config", or just a username
|
462
|
-
*/
|
463
|
-
const scopedPackageShortcutRegex = new RegExp(`^(@[^/]+)(?:/(?:${prefix})?)?$`),
|
464
|
-
scopedPackageNameRegex = new RegExp(`^${prefix}(-|$)`);
|
465
|
-
|
466
|
-
if (scopedPackageShortcutRegex.test(name)) {
|
467
|
-
name = name.replace(scopedPackageShortcutRegex, `$1/${prefix}`);
|
468
|
-
} else if (!scopedPackageNameRegex.test(name.split("/")[1])) {
|
469
|
-
|
470
|
-
/*
|
471
|
-
* for scoped packages, insert the eslint-config after the first / unless
|
472
|
-
* the path is already @scope/eslint or @scope/eslint-config-xxx
|
473
|
-
*/
|
474
|
-
name = name.replace(/^@([^/]+)\/(.*)$/, `@$1/${prefix}-$2`);
|
475
|
-
}
|
476
|
-
} else if (name.indexOf(`${prefix}-`) !== 0) {
|
477
|
-
name = `${prefix}-${name}`;
|
478
|
-
}
|
479
|
-
|
480
|
-
return name;
|
481
|
-
}
|
482
|
-
|
483
439
|
/**
|
484
440
|
* Resolves a configuration file path into the fully-formed path, whether filename
|
485
441
|
* or package name.
|
@@ -505,12 +461,12 @@ function resolve(filePath, relativeTo) {
|
|
505
461
|
const pluginName = filePath.slice(7, filePath.lastIndexOf("/"));
|
506
462
|
const configName = filePath.slice(filePath.lastIndexOf("/") + 1);
|
507
463
|
|
508
|
-
normalizedPackageName = normalizePackageName(pluginName, "eslint-plugin");
|
464
|
+
normalizedPackageName = naming.normalizePackageName(pluginName, "eslint-plugin");
|
509
465
|
debug(`Attempting to resolve ${normalizedPackageName}`);
|
510
466
|
filePath = resolver.resolve(normalizedPackageName, getLookupPath(relativeTo));
|
511
467
|
return { filePath, configName, configFullName };
|
512
468
|
}
|
513
|
-
normalizedPackageName = normalizePackageName(filePath, "eslint-config");
|
469
|
+
normalizedPackageName = naming.normalizePackageName(filePath, "eslint-config");
|
514
470
|
debug(`Attempting to resolve ${normalizedPackageName}`);
|
515
471
|
filePath = resolver.resolve(normalizedPackageName, getLookupPath(relativeTo));
|
516
472
|
return { filePath, configFullName: filePath };
|
@@ -545,8 +501,10 @@ function loadFromDisk(resolvedPath, configContext) {
|
|
545
501
|
}
|
546
502
|
}
|
547
503
|
|
504
|
+
const ruleMap = configContext.linterContext.getRules();
|
505
|
+
|
548
506
|
// validate the configuration before continuing
|
549
|
-
validator.validate(config, resolvedPath.configFullName,
|
507
|
+
validator.validate(config, resolvedPath.configFullName, ruleMap.get.bind(ruleMap), configContext.linterContext.environments);
|
550
508
|
|
551
509
|
/*
|
552
510
|
* If an `extends` property is defined, it represents a configuration file to use as
|
@@ -614,7 +572,6 @@ module.exports = {
|
|
614
572
|
resolve,
|
615
573
|
write,
|
616
574
|
applyExtends,
|
617
|
-
normalizePackageName,
|
618
575
|
CONFIG_FILES,
|
619
576
|
|
620
577
|
/**
|
@@ -201,14 +201,18 @@ function configureRules(answers, config) {
|
|
201
201
|
// Now that we know which rules to disable, strip out configs with errors
|
202
202
|
registry = registry.stripFailingConfigs();
|
203
203
|
|
204
|
-
|
205
|
-
|
204
|
+
/*
|
205
|
+
* If there is only one config that results in no errors for a rule, we should use it.
|
206
|
+
* createConfig will only add rules that have one configuration in the registry.
|
207
|
+
*/
|
206
208
|
const singleConfigs = registry.createConfig().rules;
|
207
209
|
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
210
|
+
/*
|
211
|
+
* The "sweet spot" for number of options in a config seems to be two (severity plus one option).
|
212
|
+
* Very often, a third option (usually an object) is available to address
|
213
|
+
* edge cases, exceptions, or unique situations. We will prefer to use a config with
|
214
|
+
* specificity of two.
|
215
|
+
*/
|
212
216
|
const specTwoConfigs = registry.filterBySpecificity(2).createConfig().rules;
|
213
217
|
|
214
218
|
// Maybe a specific combination using all three options works
|
package/lib/config/config-ops.js
CHANGED
@@ -105,27 +105,27 @@ module.exports = {
|
|
105
105
|
merge: function deepmerge(target, src, combine, isRule) {
|
106
106
|
|
107
107
|
/*
|
108
|
-
The MIT License (MIT)
|
109
|
-
|
110
|
-
Copyright (c) 2012 Nicholas Fisher
|
111
|
-
|
112
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
113
|
-
of this software and associated documentation files (the "Software"), to deal
|
114
|
-
in the Software without restriction, including without limitation the rights
|
115
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
116
|
-
copies of the Software, and to permit persons to whom the Software is
|
117
|
-
furnished to do so, subject to the following conditions:
|
118
|
-
|
119
|
-
The above copyright notice and this permission notice shall be included in
|
120
|
-
all copies or substantial portions of the Software.
|
121
|
-
|
122
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
123
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
124
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
125
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
126
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
127
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
128
|
-
THE SOFTWARE.
|
108
|
+
* The MIT License (MIT)
|
109
|
+
*
|
110
|
+
* Copyright (c) 2012 Nicholas Fisher
|
111
|
+
*
|
112
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
113
|
+
* of this software and associated documentation files (the "Software"), to deal
|
114
|
+
* in the Software without restriction, including without limitation the rights
|
115
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
116
|
+
* copies of the Software, and to permit persons to whom the Software is
|
117
|
+
* furnished to do so, subject to the following conditions:
|
118
|
+
*
|
119
|
+
* The above copyright notice and this permission notice shall be included in
|
120
|
+
* all copies or substantial portions of the Software.
|
121
|
+
*
|
122
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
123
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
124
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
125
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
126
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
127
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
128
|
+
* THE SOFTWARE.
|
129
129
|
*/
|
130
130
|
|
131
131
|
/*
|