eslint 6.2.2 → 6.5.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 +91 -0
- package/README.md +9 -8
- package/bin/eslint.js +38 -12
- package/conf/config-schema.js +1 -0
- package/conf/default-cli-options.js +1 -1
- package/lib/cli-engine/cli-engine.js +2 -4
- package/lib/cli-engine/config-array/config-array.js +6 -0
- package/lib/cli-engine/config-array/extracted-config.js +6 -0
- package/lib/cli-engine/config-array/override-tester.js +2 -2
- package/lib/cli-engine/config-array-factory.js +2 -0
- package/lib/cli-engine/formatters/stylish.js +2 -1
- package/lib/cli-engine/ignored-paths.js +3 -3
- package/lib/cli-engine/lint-result-cache.js +0 -1
- package/lib/cli.js +13 -12
- package/lib/init/config-initializer.js +29 -0
- package/lib/init/config-rule.js +2 -2
- package/lib/init/npm-utils.js +9 -9
- package/lib/linter/apply-disable-directives.js +17 -9
- package/lib/linter/code-path-analysis/debug-helpers.js +1 -1
- package/lib/linter/linter.js +23 -4
- package/lib/options.js +7 -1
- package/lib/rule-tester/rule-tester.js +1 -2
- package/lib/rules/accessor-pairs.js +51 -11
- package/lib/rules/capitalized-comments.js +2 -2
- package/lib/rules/computed-property-spacing.js +18 -1
- package/lib/rules/default-param-last.js +61 -0
- package/lib/rules/eqeqeq.js +7 -19
- package/lib/rules/func-name-matching.js +1 -0
- package/lib/rules/function-paren-newline.js +2 -2
- package/lib/rules/indent-legacy.js +1 -1
- package/lib/rules/indent.js +44 -6
- package/lib/rules/index.js +3 -0
- package/lib/rules/new-parens.js +5 -1
- package/lib/rules/no-extra-bind.js +7 -1
- package/lib/rules/no-extra-boolean-cast.js +12 -2
- package/lib/rules/no-extra-label.js +9 -1
- package/lib/rules/no-extra-parens.js +23 -3
- package/lib/rules/no-import-assign.js +238 -0
- package/lib/rules/no-lone-blocks.js +6 -1
- package/lib/rules/no-obj-calls.js +29 -9
- package/lib/rules/no-octal-escape.js +14 -8
- package/lib/rules/no-regex-spaces.js +106 -45
- package/lib/rules/no-self-assign.js +17 -6
- package/lib/rules/no-sequences.js +2 -2
- package/lib/rules/no-undef-init.js +7 -1
- package/lib/rules/no-unsafe-negation.js +2 -10
- package/lib/rules/no-useless-rename.js +25 -13
- package/lib/rules/no-useless-return.js +3 -2
- package/lib/rules/object-curly-spacing.js +1 -1
- package/lib/rules/object-shorthand.js +35 -9
- package/lib/rules/prefer-named-capture-group.js +3 -15
- package/lib/rules/prefer-numeric-literals.js +4 -0
- package/lib/rules/prefer-regex-literals.js +125 -0
- package/lib/rules/quotes.js +6 -0
- package/lib/rules/space-before-function-paren.js +12 -1
- package/lib/rules/space-in-parens.js +77 -71
- package/lib/rules/use-isnan.js +67 -6
- package/lib/rules/yoda.js +11 -2
- package/lib/shared/logging.js +2 -0
- package/lib/shared/runtime-info.js +163 -0
- package/lib/shared/types.js +2 -0
- package/lib/source-code/source-code.js +3 -4
- package/package.json +3 -1
@@ -40,23 +40,28 @@ module.exports = {
|
|
40
40
|
},
|
41
41
|
additionalProperties: false
|
42
42
|
}
|
43
|
-
]
|
43
|
+
],
|
44
|
+
|
45
|
+
messages: {
|
46
|
+
missingOpeningSpace: "There must be a space after this paren.",
|
47
|
+
missingClosingSpace: "There must be a space before this paren.",
|
48
|
+
rejectedOpeningSpace: "There should be no space after this paren.",
|
49
|
+
rejectedClosingSpace: "There should be no space before this paren."
|
50
|
+
}
|
44
51
|
},
|
45
52
|
|
46
53
|
create(context) {
|
47
|
-
|
48
|
-
const MISSING_SPACE_MESSAGE = "There must be a space inside this paren.",
|
49
|
-
REJECTED_SPACE_MESSAGE = "There should be no spaces inside this paren.",
|
50
|
-
ALWAYS = context.options[0] === "always",
|
54
|
+
const ALWAYS = context.options[0] === "always",
|
51
55
|
exceptionsArrayOptions = (context.options[1] && context.options[1].exceptions) || [],
|
52
56
|
options = {};
|
57
|
+
|
53
58
|
let exceptions;
|
54
59
|
|
55
60
|
if (exceptionsArrayOptions.length) {
|
56
|
-
options.braceException = exceptionsArrayOptions.
|
57
|
-
options.bracketException = exceptionsArrayOptions.
|
58
|
-
options.parenException = exceptionsArrayOptions.
|
59
|
-
options.empty = exceptionsArrayOptions.
|
61
|
+
options.braceException = exceptionsArrayOptions.includes("{}");
|
62
|
+
options.bracketException = exceptionsArrayOptions.includes("[]");
|
63
|
+
options.parenException = exceptionsArrayOptions.includes("()");
|
64
|
+
options.empty = exceptionsArrayOptions.includes("empty");
|
60
65
|
}
|
61
66
|
|
62
67
|
/**
|
@@ -105,7 +110,7 @@ module.exports = {
|
|
105
110
|
* @returns {boolean} True if the token is one of the exceptions for the opener paren
|
106
111
|
*/
|
107
112
|
function isOpenerException(token) {
|
108
|
-
return
|
113
|
+
return exceptions.openers.includes(token.value);
|
109
114
|
}
|
110
115
|
|
111
116
|
/**
|
@@ -114,102 +119,95 @@ module.exports = {
|
|
114
119
|
* @returns {boolean} True if the token is one of the exceptions for the closer paren
|
115
120
|
*/
|
116
121
|
function isCloserException(token) {
|
117
|
-
return
|
122
|
+
return exceptions.closers.includes(token.value);
|
118
123
|
}
|
119
124
|
|
120
125
|
/**
|
121
|
-
* Determines if an
|
122
|
-
* @param {Object}
|
123
|
-
* @param {Object}
|
124
|
-
* @returns {boolean} True if the paren
|
126
|
+
* Determines if an opening paren is immediately followed by a required space
|
127
|
+
* @param {Object} openingParenToken The paren token
|
128
|
+
* @param {Object} tokenAfterOpeningParen The token after it
|
129
|
+
* @returns {boolean} True if the opening paren is missing a required space
|
125
130
|
*/
|
126
|
-
function
|
127
|
-
if (sourceCode.isSpaceBetweenTokens(
|
131
|
+
function openerMissingSpace(openingParenToken, tokenAfterOpeningParen) {
|
132
|
+
if (sourceCode.isSpaceBetweenTokens(openingParenToken, tokenAfterOpeningParen)) {
|
128
133
|
return false;
|
129
134
|
}
|
130
135
|
|
131
|
-
if (
|
132
|
-
|
133
|
-
return false;
|
134
|
-
}
|
135
|
-
return !isOpenerException(right);
|
136
|
+
if (!options.empty && astUtils.isClosingParenToken(tokenAfterOpeningParen)) {
|
137
|
+
return false;
|
136
138
|
}
|
137
|
-
return isOpenerException(right);
|
138
139
|
|
140
|
+
if (ALWAYS) {
|
141
|
+
return !isOpenerException(tokenAfterOpeningParen);
|
142
|
+
}
|
143
|
+
return isOpenerException(tokenAfterOpeningParen);
|
139
144
|
}
|
140
145
|
|
141
146
|
/**
|
142
|
-
* Determines if an
|
143
|
-
* @param {Object}
|
144
|
-
* @param {Object}
|
145
|
-
* @returns {boolean} True if the paren
|
147
|
+
* Determines if an opening paren is immediately followed by a disallowed space
|
148
|
+
* @param {Object} openingParenToken The paren token
|
149
|
+
* @param {Object} tokenAfterOpeningParen The token after it
|
150
|
+
* @returns {boolean} True if the opening paren has a disallowed space
|
146
151
|
*/
|
147
|
-
function
|
148
|
-
if (astUtils.
|
152
|
+
function openerRejectsSpace(openingParenToken, tokenAfterOpeningParen) {
|
153
|
+
if (!astUtils.isTokenOnSameLine(openingParenToken, tokenAfterOpeningParen)) {
|
149
154
|
return false;
|
150
155
|
}
|
151
156
|
|
152
|
-
if (
|
157
|
+
if (tokenAfterOpeningParen.type === "Line") {
|
153
158
|
return false;
|
154
159
|
}
|
155
160
|
|
156
|
-
if (
|
157
|
-
return
|
161
|
+
if (!sourceCode.isSpaceBetweenTokens(openingParenToken, tokenAfterOpeningParen)) {
|
162
|
+
return false;
|
158
163
|
}
|
159
|
-
return isCloserException(left);
|
160
164
|
|
165
|
+
if (ALWAYS) {
|
166
|
+
return isOpenerException(tokenAfterOpeningParen);
|
167
|
+
}
|
168
|
+
return !isOpenerException(tokenAfterOpeningParen);
|
161
169
|
}
|
162
170
|
|
163
171
|
/**
|
164
|
-
* Determines if
|
165
|
-
* @param {Object}
|
166
|
-
* @param {Object}
|
167
|
-
* @returns {boolean} True if the paren
|
172
|
+
* Determines if a closing paren is immediately preceeded by a required space
|
173
|
+
* @param {Object} tokenBeforeClosingParen The token before the paren
|
174
|
+
* @param {Object} closingParenToken The paren token
|
175
|
+
* @returns {boolean} True if the closing paren is missing a required space
|
168
176
|
*/
|
169
|
-
function
|
170
|
-
if (
|
171
|
-
return false;
|
172
|
-
}
|
173
|
-
|
174
|
-
if (!astUtils.isTokenOnSameLine(left, right)) {
|
177
|
+
function closerMissingSpace(tokenBeforeClosingParen, closingParenToken) {
|
178
|
+
if (sourceCode.isSpaceBetweenTokens(tokenBeforeClosingParen, closingParenToken)) {
|
175
179
|
return false;
|
176
180
|
}
|
177
181
|
|
178
|
-
if (!
|
182
|
+
if (!options.empty && astUtils.isOpeningParenToken(tokenBeforeClosingParen)) {
|
179
183
|
return false;
|
180
184
|
}
|
181
185
|
|
182
186
|
if (ALWAYS) {
|
183
|
-
return
|
187
|
+
return !isCloserException(tokenBeforeClosingParen);
|
184
188
|
}
|
185
|
-
return
|
186
|
-
|
189
|
+
return isCloserException(tokenBeforeClosingParen);
|
187
190
|
}
|
188
191
|
|
189
192
|
/**
|
190
|
-
* Determines if
|
191
|
-
* @param {Object}
|
192
|
-
* @param {Object}
|
193
|
-
* @returns {boolean} True if the paren
|
193
|
+
* Determines if a closer paren is immediately preceeded by a disallowed space
|
194
|
+
* @param {Object} tokenBeforeClosingParen The token before the paren
|
195
|
+
* @param {Object} closingParenToken The paren token
|
196
|
+
* @returns {boolean} True if the closing paren has a disallowed space
|
194
197
|
*/
|
195
|
-
function
|
196
|
-
if (astUtils.
|
198
|
+
function closerRejectsSpace(tokenBeforeClosingParen, closingParenToken) {
|
199
|
+
if (!astUtils.isTokenOnSameLine(tokenBeforeClosingParen, closingParenToken)) {
|
197
200
|
return false;
|
198
201
|
}
|
199
202
|
|
200
|
-
if (!
|
201
|
-
return false;
|
202
|
-
}
|
203
|
-
|
204
|
-
if (!sourceCode.isSpaceBetweenTokens(left, right)) {
|
203
|
+
if (!sourceCode.isSpaceBetweenTokens(tokenBeforeClosingParen, closingParenToken)) {
|
205
204
|
return false;
|
206
205
|
}
|
207
206
|
|
208
207
|
if (ALWAYS) {
|
209
|
-
return isCloserException(
|
208
|
+
return isCloserException(tokenBeforeClosingParen);
|
210
209
|
}
|
211
|
-
return !isCloserException(
|
212
|
-
|
210
|
+
return !isCloserException(tokenBeforeClosingParen);
|
213
211
|
}
|
214
212
|
|
215
213
|
//--------------------------------------------------------------------------
|
@@ -225,44 +223,53 @@ module.exports = {
|
|
225
223
|
const prevToken = tokens[i - 1];
|
226
224
|
const nextToken = tokens[i + 1];
|
227
225
|
|
226
|
+
// if token is not an opening or closing paren token, do nothing
|
228
227
|
if (!astUtils.isOpeningParenToken(token) && !astUtils.isClosingParenToken(token)) {
|
229
228
|
return;
|
230
229
|
}
|
231
230
|
|
232
|
-
if
|
231
|
+
// if token is an opening paren and is not followed by a required space
|
232
|
+
if (token.value === "(" && openerMissingSpace(token, nextToken)) {
|
233
233
|
context.report({
|
234
234
|
node,
|
235
235
|
loc: token.loc.start,
|
236
|
-
|
236
|
+
messageId: "missingOpeningSpace",
|
237
237
|
fix(fixer) {
|
238
238
|
return fixer.insertTextAfter(token, " ");
|
239
239
|
}
|
240
240
|
});
|
241
|
-
}
|
241
|
+
}
|
242
|
+
|
243
|
+
// if token is an opening paren and is followed by a disallowed space
|
244
|
+
if (token.value === "(" && openerRejectsSpace(token, nextToken)) {
|
242
245
|
context.report({
|
243
246
|
node,
|
244
247
|
loc: token.loc.start,
|
245
|
-
|
248
|
+
messageId: "rejectedOpeningSpace",
|
246
249
|
fix(fixer) {
|
247
250
|
return fixer.removeRange([token.range[1], nextToken.range[0]]);
|
248
251
|
}
|
249
252
|
});
|
250
|
-
}
|
253
|
+
}
|
251
254
|
|
252
|
-
|
255
|
+
// if token is a closing paren and is not preceded by a required space
|
256
|
+
if (token.value === ")" && closerMissingSpace(prevToken, token)) {
|
253
257
|
context.report({
|
254
258
|
node,
|
255
259
|
loc: token.loc.start,
|
256
|
-
|
260
|
+
messageId: "missingClosingSpace",
|
257
261
|
fix(fixer) {
|
258
262
|
return fixer.insertTextBefore(token, " ");
|
259
263
|
}
|
260
264
|
});
|
261
|
-
}
|
265
|
+
}
|
266
|
+
|
267
|
+
// if token is a closing paren and is preceded by a disallowed space
|
268
|
+
if (token.value === ")" && closerRejectsSpace(prevToken, token)) {
|
262
269
|
context.report({
|
263
270
|
node,
|
264
271
|
loc: token.loc.start,
|
265
|
-
|
272
|
+
messageId: "rejectedClosingSpace",
|
266
273
|
fix(fixer) {
|
267
274
|
return fixer.removeRange([prevToken.range[1], token.range[0]]);
|
268
275
|
}
|
@@ -271,6 +278,5 @@ module.exports = {
|
|
271
278
|
});
|
272
279
|
}
|
273
280
|
};
|
274
|
-
|
275
281
|
}
|
276
282
|
};
|
package/lib/rules/use-isnan.js
CHANGED
@@ -5,6 +5,19 @@
|
|
5
5
|
|
6
6
|
"use strict";
|
7
7
|
|
8
|
+
//------------------------------------------------------------------------------
|
9
|
+
// Helpers
|
10
|
+
//------------------------------------------------------------------------------
|
11
|
+
|
12
|
+
/**
|
13
|
+
* Determines if the given node is a NaN `Identifier` node.
|
14
|
+
* @param {ASTNode|null} node The node to check.
|
15
|
+
* @returns {boolean} `true` if the node is 'NaN' identifier.
|
16
|
+
*/
|
17
|
+
function isNaNIdentifier(node) {
|
18
|
+
return Boolean(node) && node.type === "Identifier" && node.name === "NaN";
|
19
|
+
}
|
20
|
+
|
8
21
|
//------------------------------------------------------------------------------
|
9
22
|
// Rule Definition
|
10
23
|
//------------------------------------------------------------------------------
|
@@ -20,21 +33,69 @@ module.exports = {
|
|
20
33
|
url: "https://eslint.org/docs/rules/use-isnan"
|
21
34
|
},
|
22
35
|
|
23
|
-
schema: [
|
36
|
+
schema: [
|
37
|
+
{
|
38
|
+
type: "object",
|
39
|
+
properties: {
|
40
|
+
enforceForSwitchCase: {
|
41
|
+
type: "boolean",
|
42
|
+
default: false
|
43
|
+
}
|
44
|
+
},
|
45
|
+
additionalProperties: false
|
46
|
+
}
|
47
|
+
],
|
48
|
+
|
24
49
|
messages: {
|
25
|
-
|
50
|
+
comparisonWithNaN: "Use the isNaN function to compare with NaN.",
|
51
|
+
switchNaN: "'switch(NaN)' can never match a case clause. Use Number.isNaN instead of the switch.",
|
52
|
+
caseNaN: "'case NaN' can never match. Use Number.isNaN before the switch."
|
26
53
|
}
|
27
54
|
},
|
28
55
|
|
29
56
|
create(context) {
|
30
57
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
58
|
+
const enforceForSwitchCase = context.options[0] && context.options[0].enforceForSwitchCase;
|
59
|
+
|
60
|
+
/**
|
61
|
+
* Checks the given `BinaryExpression` node.
|
62
|
+
* @param {ASTNode} node The node to check.
|
63
|
+
* @returns {void}
|
64
|
+
*/
|
65
|
+
function checkBinaryExpression(node) {
|
66
|
+
if (
|
67
|
+
/^(?:[<>]|[!=]=)=?$/u.test(node.operator) &&
|
68
|
+
(isNaNIdentifier(node.left) || isNaNIdentifier(node.right))
|
69
|
+
) {
|
70
|
+
context.report({ node, messageId: "comparisonWithNaN" });
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
/**
|
75
|
+
* Checks the discriminant and all case clauses of the given `SwitchStatement` node.
|
76
|
+
* @param {ASTNode} node The node to check.
|
77
|
+
* @returns {void}
|
78
|
+
*/
|
79
|
+
function checkSwitchStatement(node) {
|
80
|
+
if (isNaNIdentifier(node.discriminant)) {
|
81
|
+
context.report({ node, messageId: "switchNaN" });
|
82
|
+
}
|
83
|
+
|
84
|
+
for (const switchCase of node.cases) {
|
85
|
+
if (isNaNIdentifier(switchCase.test)) {
|
86
|
+
context.report({ node: switchCase, messageId: "caseNaN" });
|
35
87
|
}
|
36
88
|
}
|
89
|
+
}
|
90
|
+
|
91
|
+
const listeners = {
|
92
|
+
BinaryExpression: checkBinaryExpression
|
37
93
|
};
|
38
94
|
|
95
|
+
if (enforceForSwitchCase) {
|
96
|
+
listeners.SwitchStatement = checkSwitchStatement;
|
97
|
+
}
|
98
|
+
|
99
|
+
return listeners;
|
39
100
|
}
|
40
101
|
};
|
package/lib/rules/yoda.js
CHANGED
@@ -274,13 +274,22 @@ module.exports = {
|
|
274
274
|
* @returns {string} A string representation of the node with the sides and operator flipped
|
275
275
|
*/
|
276
276
|
function getFlippedString(node) {
|
277
|
+
const tokenBefore = sourceCode.getTokenBefore(node);
|
277
278
|
const operatorToken = sourceCode.getFirstTokenBetween(node.left, node.right, token => token.value === node.operator);
|
278
279
|
const textBeforeOperator = sourceCode.getText().slice(sourceCode.getTokenBefore(operatorToken).range[1], operatorToken.range[0]);
|
279
280
|
const textAfterOperator = sourceCode.getText().slice(operatorToken.range[1], sourceCode.getTokenAfter(operatorToken).range[0]);
|
280
281
|
const leftText = sourceCode.getText().slice(node.range[0], sourceCode.getTokenBefore(operatorToken).range[1]);
|
281
|
-
const
|
282
|
+
const firstRightToken = sourceCode.getTokenAfter(operatorToken);
|
283
|
+
const rightText = sourceCode.getText().slice(firstRightToken.range[0], node.range[1]);
|
282
284
|
|
283
|
-
|
285
|
+
let prefix = "";
|
286
|
+
|
287
|
+
if (tokenBefore && tokenBefore.range[1] === node.range[0] &&
|
288
|
+
!astUtils.canTokensBeAdjacent(tokenBefore, firstRightToken)) {
|
289
|
+
prefix = " ";
|
290
|
+
}
|
291
|
+
|
292
|
+
return prefix + rightText + textBeforeOperator + OPERATOR_FLIP_MAP[operatorToken.value] + textAfterOperator + leftText;
|
284
293
|
}
|
285
294
|
|
286
295
|
//--------------------------------------------------------------------------
|
package/lib/shared/logging.js
CHANGED
@@ -12,6 +12,7 @@ module.exports = {
|
|
12
12
|
|
13
13
|
/**
|
14
14
|
* Cover for console.log
|
15
|
+
* @param {...any} args The elements to log.
|
15
16
|
* @returns {void}
|
16
17
|
*/
|
17
18
|
info(...args) {
|
@@ -20,6 +21,7 @@ module.exports = {
|
|
20
21
|
|
21
22
|
/**
|
22
23
|
* Cover for console.error
|
24
|
+
* @param {...any} args The elements to log.
|
23
25
|
* @returns {void}
|
24
26
|
*/
|
25
27
|
error(...args) {
|
@@ -0,0 +1,163 @@
|
|
1
|
+
/**
|
2
|
+
* @fileoverview Utility to get information about the execution environment.
|
3
|
+
* @author Kai Cataldo
|
4
|
+
*/
|
5
|
+
|
6
|
+
"use strict";
|
7
|
+
|
8
|
+
//------------------------------------------------------------------------------
|
9
|
+
// Requirements
|
10
|
+
//------------------------------------------------------------------------------
|
11
|
+
|
12
|
+
const path = require("path");
|
13
|
+
const spawn = require("cross-spawn");
|
14
|
+
const { isEmpty } = require("lodash");
|
15
|
+
const log = require("../shared/logging");
|
16
|
+
const packageJson = require("../../package.json");
|
17
|
+
|
18
|
+
//------------------------------------------------------------------------------
|
19
|
+
// Helpers
|
20
|
+
//------------------------------------------------------------------------------
|
21
|
+
|
22
|
+
/**
|
23
|
+
* Generates and returns execution environment information.
|
24
|
+
* @returns {string} A string that contains execution environment information.
|
25
|
+
*/
|
26
|
+
function environment() {
|
27
|
+
const cache = new Map();
|
28
|
+
|
29
|
+
/**
|
30
|
+
* Checks if a path is a child of a directory.
|
31
|
+
* @param {string} parentPath - The parent path to check.
|
32
|
+
* @param {string} childPath - The path to check.
|
33
|
+
* @returns {boolean} Whether or not the given path is a child of a directory.
|
34
|
+
*/
|
35
|
+
function isChildOfDirectory(parentPath, childPath) {
|
36
|
+
return !path.relative(parentPath, childPath).startsWith("..");
|
37
|
+
}
|
38
|
+
|
39
|
+
/**
|
40
|
+
* Synchronously executes a shell command and formats the result.
|
41
|
+
* @param {string} cmd - The command to execute.
|
42
|
+
* @param {Array} args - The arguments to be executed with the command.
|
43
|
+
* @returns {string} The version returned by the command.
|
44
|
+
*/
|
45
|
+
function execCommand(cmd, args) {
|
46
|
+
const key = [cmd, ...args].join(" ");
|
47
|
+
|
48
|
+
if (cache.has(key)) {
|
49
|
+
return cache.get(key);
|
50
|
+
}
|
51
|
+
|
52
|
+
const process = spawn.sync(cmd, args, { encoding: "utf8" });
|
53
|
+
|
54
|
+
if (process.error) {
|
55
|
+
throw process.error;
|
56
|
+
}
|
57
|
+
|
58
|
+
const result = process.stdout.trim();
|
59
|
+
|
60
|
+
cache.set(key, result);
|
61
|
+
return result;
|
62
|
+
}
|
63
|
+
|
64
|
+
/**
|
65
|
+
* Normalizes a version number.
|
66
|
+
* @param {string} versionStr - The string to normalize.
|
67
|
+
* @returns {string} The normalized version number.
|
68
|
+
*/
|
69
|
+
function normalizeVersionStr(versionStr) {
|
70
|
+
return versionStr.startsWith("v") ? versionStr : `v${versionStr}`;
|
71
|
+
}
|
72
|
+
|
73
|
+
/**
|
74
|
+
* Gets bin version.
|
75
|
+
* @param {string} bin - The bin to check.
|
76
|
+
* @returns {string} The normalized version returned by the command.
|
77
|
+
*/
|
78
|
+
function getBinVersion(bin) {
|
79
|
+
const binArgs = ["--version"];
|
80
|
+
|
81
|
+
try {
|
82
|
+
return normalizeVersionStr(execCommand(bin, binArgs));
|
83
|
+
} catch (e) {
|
84
|
+
log.error(`Error finding ${bin} version running the command \`${bin} ${binArgs.join(" ")}\``);
|
85
|
+
throw e;
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
/**
|
90
|
+
* Gets installed npm package version.
|
91
|
+
* @param {string} pkg - The package to check.
|
92
|
+
* @param {boolean} global - Whether to check globally or not.
|
93
|
+
* @returns {string} The normalized version returned by the command.
|
94
|
+
*/
|
95
|
+
function getNpmPackageVersion(pkg, { global = false } = {}) {
|
96
|
+
const npmBinArgs = ["bin", "-g"];
|
97
|
+
const npmLsArgs = ["ls", "--depth=0", "--json", "eslint"];
|
98
|
+
|
99
|
+
if (global) {
|
100
|
+
npmLsArgs.push("-g");
|
101
|
+
}
|
102
|
+
|
103
|
+
try {
|
104
|
+
const parsedStdout = JSON.parse(execCommand("npm", npmLsArgs));
|
105
|
+
|
106
|
+
/*
|
107
|
+
* Checking globally returns an empty JSON object, while local checks
|
108
|
+
* include the name and version of the local project.
|
109
|
+
*/
|
110
|
+
if (isEmpty(parsedStdout) || !(parsedStdout.dependencies && parsedStdout.dependencies.eslint)) {
|
111
|
+
return "Not found";
|
112
|
+
}
|
113
|
+
|
114
|
+
const [, processBinPath] = process.argv;
|
115
|
+
let npmBinPath;
|
116
|
+
|
117
|
+
try {
|
118
|
+
npmBinPath = execCommand("npm", npmBinArgs);
|
119
|
+
} catch (e) {
|
120
|
+
log.error(`Error finding npm binary path when running command \`npm ${npmBinArgs.join(" ")}\``);
|
121
|
+
throw e;
|
122
|
+
}
|
123
|
+
|
124
|
+
const isGlobal = isChildOfDirectory(npmBinPath, processBinPath);
|
125
|
+
let pkgVersion = parsedStdout.dependencies.eslint.version;
|
126
|
+
|
127
|
+
if ((global && isGlobal) || (!global && !isGlobal)) {
|
128
|
+
pkgVersion += " (Currently used)";
|
129
|
+
}
|
130
|
+
|
131
|
+
return normalizeVersionStr(pkgVersion);
|
132
|
+
} catch (e) {
|
133
|
+
log.error(`Error finding ${pkg} version running the command \`npm ${npmLsArgs.join(" ")}\``);
|
134
|
+
throw e;
|
135
|
+
}
|
136
|
+
}
|
137
|
+
|
138
|
+
return [
|
139
|
+
"Environment Info:",
|
140
|
+
"",
|
141
|
+
`Node version: ${getBinVersion("node")}`,
|
142
|
+
`npm version: ${getBinVersion("npm")}`,
|
143
|
+
`Local ESLint version: ${getNpmPackageVersion("eslint", { global: false })}`,
|
144
|
+
`Global ESLint version: ${getNpmPackageVersion("eslint", { global: true })}`
|
145
|
+
].join("\n");
|
146
|
+
}
|
147
|
+
|
148
|
+
/**
|
149
|
+
* Returns version of currently executing ESLint.
|
150
|
+
* @returns {string} The version from the currently executing ESLint's package.json.
|
151
|
+
*/
|
152
|
+
function version() {
|
153
|
+
return `v${packageJson.version}`;
|
154
|
+
}
|
155
|
+
|
156
|
+
//------------------------------------------------------------------------------
|
157
|
+
// Public Interface
|
158
|
+
//------------------------------------------------------------------------------
|
159
|
+
|
160
|
+
module.exports = {
|
161
|
+
environment,
|
162
|
+
version
|
163
|
+
};
|
package/lib/shared/types.js
CHANGED
@@ -36,6 +36,7 @@ module.exports = {};
|
|
36
36
|
* @property {ParserOptions} [parserOptions] The parser options.
|
37
37
|
* @property {string[]} [plugins] The plugin specifiers.
|
38
38
|
* @property {string} [processor] The processor specifier.
|
39
|
+
* @property {boolean|undefined} reportUnusedDisableDirectives The flag to report unused `eslint-disable` comments.
|
39
40
|
* @property {boolean} [root] The root flag.
|
40
41
|
* @property {Record<string, RuleConf>} [rules] The rule settings.
|
41
42
|
* @property {Object} [settings] The shared settings.
|
@@ -54,6 +55,7 @@ module.exports = {};
|
|
54
55
|
* @property {ParserOptions} [parserOptions] The parser options.
|
55
56
|
* @property {string[]} [plugins] The plugin specifiers.
|
56
57
|
* @property {string} [processor] The processor specifier.
|
58
|
+
* @property {boolean|undefined} reportUnusedDisableDirectives The flag to report unused `eslint-disable` comments.
|
57
59
|
* @property {Record<string, RuleConf>} [rules] The rule settings.
|
58
60
|
* @property {Object} [settings] The shared settings.
|
59
61
|
*/
|
@@ -93,7 +93,6 @@ class SourceCode extends TokenStore {
|
|
93
93
|
* @param {ScopeManager|null} textOrConfig.scopeManager - The scope of this source code.
|
94
94
|
* @param {Object|null} textOrConfig.visitorKeys - The visitor keys to traverse AST.
|
95
95
|
* @param {ASTNode} [astIfNoConfig] - The Program node of the AST representing the code. This AST should be created from the text that BOM was stripped.
|
96
|
-
* @constructor
|
97
96
|
*/
|
98
97
|
constructor(textOrConfig, astIfNoConfig) {
|
99
98
|
let text, ast, parserServices, scopeManager, visitorKeys;
|
@@ -206,9 +205,9 @@ class SourceCode extends TokenStore {
|
|
206
205
|
|
207
206
|
/**
|
208
207
|
* Gets the source code for the given node.
|
209
|
-
* @param {ASTNode
|
210
|
-
* @param {int
|
211
|
-
* @param {int
|
208
|
+
* @param {ASTNode} [node] The AST node to get the text for.
|
209
|
+
* @param {int} [beforeCount] The number of characters before the node to retrieve.
|
210
|
+
* @param {int} [afterCount] The number of characters after the node to retrieve.
|
212
211
|
* @returns {string} The text representing the AST node.
|
213
212
|
* @public
|
214
213
|
*/
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "eslint",
|
3
|
-
"version": "6.
|
3
|
+
"version": "6.5.1",
|
4
4
|
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
|
5
5
|
"description": "An AST-based pattern checker for JavaScript.",
|
6
6
|
"bin": {
|
@@ -10,6 +10,7 @@
|
|
10
10
|
"scripts": {
|
11
11
|
"test": "node Makefile.js test",
|
12
12
|
"lint": "node Makefile.js lint",
|
13
|
+
"fix": "node Makefile.js lint -- fix",
|
13
14
|
"fuzz": "node Makefile.js fuzz",
|
14
15
|
"generate-release": "node Makefile.js generateRelease",
|
15
16
|
"generate-alpharelease": "node Makefile.js generatePrerelease -- alpha",
|
@@ -96,6 +97,7 @@
|
|
96
97
|
"eslint-config-eslint": "file:packages/eslint-config-eslint",
|
97
98
|
"eslint-plugin-eslint-plugin": "^2.0.1",
|
98
99
|
"eslint-plugin-internal-rules": "file:tools/internal-rules",
|
100
|
+
"eslint-plugin-jsdoc": "^15.9.5",
|
99
101
|
"eslint-plugin-node": "^9.0.0",
|
100
102
|
"eslint-release": "^1.2.0",
|
101
103
|
"eslump": "^2.0.0",
|