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.
Files changed (63) hide show
  1. package/CHANGELOG.md +91 -0
  2. package/README.md +9 -8
  3. package/bin/eslint.js +38 -12
  4. package/conf/config-schema.js +1 -0
  5. package/conf/default-cli-options.js +1 -1
  6. package/lib/cli-engine/cli-engine.js +2 -4
  7. package/lib/cli-engine/config-array/config-array.js +6 -0
  8. package/lib/cli-engine/config-array/extracted-config.js +6 -0
  9. package/lib/cli-engine/config-array/override-tester.js +2 -2
  10. package/lib/cli-engine/config-array-factory.js +2 -0
  11. package/lib/cli-engine/formatters/stylish.js +2 -1
  12. package/lib/cli-engine/ignored-paths.js +3 -3
  13. package/lib/cli-engine/lint-result-cache.js +0 -1
  14. package/lib/cli.js +13 -12
  15. package/lib/init/config-initializer.js +29 -0
  16. package/lib/init/config-rule.js +2 -2
  17. package/lib/init/npm-utils.js +9 -9
  18. package/lib/linter/apply-disable-directives.js +17 -9
  19. package/lib/linter/code-path-analysis/debug-helpers.js +1 -1
  20. package/lib/linter/linter.js +23 -4
  21. package/lib/options.js +7 -1
  22. package/lib/rule-tester/rule-tester.js +1 -2
  23. package/lib/rules/accessor-pairs.js +51 -11
  24. package/lib/rules/capitalized-comments.js +2 -2
  25. package/lib/rules/computed-property-spacing.js +18 -1
  26. package/lib/rules/default-param-last.js +61 -0
  27. package/lib/rules/eqeqeq.js +7 -19
  28. package/lib/rules/func-name-matching.js +1 -0
  29. package/lib/rules/function-paren-newline.js +2 -2
  30. package/lib/rules/indent-legacy.js +1 -1
  31. package/lib/rules/indent.js +44 -6
  32. package/lib/rules/index.js +3 -0
  33. package/lib/rules/new-parens.js +5 -1
  34. package/lib/rules/no-extra-bind.js +7 -1
  35. package/lib/rules/no-extra-boolean-cast.js +12 -2
  36. package/lib/rules/no-extra-label.js +9 -1
  37. package/lib/rules/no-extra-parens.js +23 -3
  38. package/lib/rules/no-import-assign.js +238 -0
  39. package/lib/rules/no-lone-blocks.js +6 -1
  40. package/lib/rules/no-obj-calls.js +29 -9
  41. package/lib/rules/no-octal-escape.js +14 -8
  42. package/lib/rules/no-regex-spaces.js +106 -45
  43. package/lib/rules/no-self-assign.js +17 -6
  44. package/lib/rules/no-sequences.js +2 -2
  45. package/lib/rules/no-undef-init.js +7 -1
  46. package/lib/rules/no-unsafe-negation.js +2 -10
  47. package/lib/rules/no-useless-rename.js +25 -13
  48. package/lib/rules/no-useless-return.js +3 -2
  49. package/lib/rules/object-curly-spacing.js +1 -1
  50. package/lib/rules/object-shorthand.js +35 -9
  51. package/lib/rules/prefer-named-capture-group.js +3 -15
  52. package/lib/rules/prefer-numeric-literals.js +4 -0
  53. package/lib/rules/prefer-regex-literals.js +125 -0
  54. package/lib/rules/quotes.js +6 -0
  55. package/lib/rules/space-before-function-paren.js +12 -1
  56. package/lib/rules/space-in-parens.js +77 -71
  57. package/lib/rules/use-isnan.js +67 -6
  58. package/lib/rules/yoda.js +11 -2
  59. package/lib/shared/logging.js +2 -0
  60. package/lib/shared/runtime-info.js +163 -0
  61. package/lib/shared/types.js +2 -0
  62. package/lib/source-code/source-code.js +3 -4
  63. 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.indexOf("{}") !== -1;
57
- options.bracketException = exceptionsArrayOptions.indexOf("[]") !== -1;
58
- options.parenException = exceptionsArrayOptions.indexOf("()") !== -1;
59
- options.empty = exceptionsArrayOptions.indexOf("empty") !== -1;
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 token.type === "Punctuator" && exceptions.openers.indexOf(token.value) >= 0;
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 token.type === "Punctuator" && exceptions.closers.indexOf(token.value) >= 0;
122
+ return exceptions.closers.includes(token.value);
118
123
  }
119
124
 
120
125
  /**
121
- * Determines if an opener paren should have a missing space after it
122
- * @param {Object} left The paren token
123
- * @param {Object} right The token after it
124
- * @returns {boolean} True if the paren should have a space
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 shouldOpenerHaveSpace(left, right) {
127
- if (sourceCode.isSpaceBetweenTokens(left, right)) {
131
+ function openerMissingSpace(openingParenToken, tokenAfterOpeningParen) {
132
+ if (sourceCode.isSpaceBetweenTokens(openingParenToken, tokenAfterOpeningParen)) {
128
133
  return false;
129
134
  }
130
135
 
131
- if (ALWAYS) {
132
- if (astUtils.isClosingParenToken(right)) {
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 closer paren should have a missing space after it
143
- * @param {Object} left The token before the paren
144
- * @param {Object} right The paren token
145
- * @returns {boolean} True if the paren should have a space
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 shouldCloserHaveSpace(left, right) {
148
- if (astUtils.isOpeningParenToken(left)) {
152
+ function openerRejectsSpace(openingParenToken, tokenAfterOpeningParen) {
153
+ if (!astUtils.isTokenOnSameLine(openingParenToken, tokenAfterOpeningParen)) {
149
154
  return false;
150
155
  }
151
156
 
152
- if (sourceCode.isSpaceBetweenTokens(left, right)) {
157
+ if (tokenAfterOpeningParen.type === "Line") {
153
158
  return false;
154
159
  }
155
160
 
156
- if (ALWAYS) {
157
- return !isCloserException(left);
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 an opener paren should not have an existing space after it
165
- * @param {Object} left The paren token
166
- * @param {Object} right The token after it
167
- * @returns {boolean} True if the paren should reject the space
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 shouldOpenerRejectSpace(left, right) {
170
- if (right.type === "Line") {
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 (!sourceCode.isSpaceBetweenTokens(left, right)) {
182
+ if (!options.empty && astUtils.isOpeningParenToken(tokenBeforeClosingParen)) {
179
183
  return false;
180
184
  }
181
185
 
182
186
  if (ALWAYS) {
183
- return isOpenerException(right);
187
+ return !isCloserException(tokenBeforeClosingParen);
184
188
  }
185
- return !isOpenerException(right);
186
-
189
+ return isCloserException(tokenBeforeClosingParen);
187
190
  }
188
191
 
189
192
  /**
190
- * Determines if an closer paren should not have an existing space after it
191
- * @param {Object} left The token before the paren
192
- * @param {Object} right The paren token
193
- * @returns {boolean} True if the paren should reject the space
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 shouldCloserRejectSpace(left, right) {
196
- if (astUtils.isOpeningParenToken(left)) {
198
+ function closerRejectsSpace(tokenBeforeClosingParen, closingParenToken) {
199
+ if (!astUtils.isTokenOnSameLine(tokenBeforeClosingParen, closingParenToken)) {
197
200
  return false;
198
201
  }
199
202
 
200
- if (!astUtils.isTokenOnSameLine(left, right)) {
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(left);
208
+ return isCloserException(tokenBeforeClosingParen);
210
209
  }
211
- return !isCloserException(left);
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 (token.value === "(" && shouldOpenerHaveSpace(token, nextToken)) {
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
- message: MISSING_SPACE_MESSAGE,
236
+ messageId: "missingOpeningSpace",
237
237
  fix(fixer) {
238
238
  return fixer.insertTextAfter(token, " ");
239
239
  }
240
240
  });
241
- } else if (token.value === "(" && shouldOpenerRejectSpace(token, nextToken)) {
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
- message: REJECTED_SPACE_MESSAGE,
248
+ messageId: "rejectedOpeningSpace",
246
249
  fix(fixer) {
247
250
  return fixer.removeRange([token.range[1], nextToken.range[0]]);
248
251
  }
249
252
  });
250
- } else if (token.value === ")" && shouldCloserHaveSpace(prevToken, token)) {
253
+ }
251
254
 
252
- // context.report(node, token.loc.start, MISSING_SPACE_MESSAGE);
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
- message: MISSING_SPACE_MESSAGE,
260
+ messageId: "missingClosingSpace",
257
261
  fix(fixer) {
258
262
  return fixer.insertTextBefore(token, " ");
259
263
  }
260
264
  });
261
- } else if (token.value === ")" && shouldCloserRejectSpace(prevToken, token)) {
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
- message: REJECTED_SPACE_MESSAGE,
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
  };
@@ -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
- useIsNaN: "Use the isNaN function to compare with NaN."
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
- return {
32
- BinaryExpression(node) {
33
- if (/^(?:[<>]|[!=]=)=?$/u.test(node.operator) && (node.left.name === "NaN" || node.right.name === "NaN")) {
34
- context.report({ node, messageId: "useIsNaN" });
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 rightText = sourceCode.getText().slice(sourceCode.getTokenAfter(operatorToken).range[0], node.range[1]);
282
+ const firstRightToken = sourceCode.getTokenAfter(operatorToken);
283
+ const rightText = sourceCode.getText().slice(firstRightToken.range[0], node.range[1]);
282
284
 
283
- return rightText + textBeforeOperator + OPERATOR_FLIP_MAP[operatorToken.value] + textAfterOperator + leftText;
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
  //--------------------------------------------------------------------------
@@ -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
+ };
@@ -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=} node The AST node to get the text for.
210
- * @param {int=} beforeCount The number of characters before the node to retrieve.
211
- * @param {int=} afterCount The number of characters after the node to retrieve.
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.2.2",
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",