eslint 7.23.0 → 7.27.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.
Files changed (62) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/README.md +7 -2
  3. package/bin/eslint.js +2 -12
  4. package/lib/cli-engine/cli-engine.js +2 -7
  5. package/lib/cli-engine/file-enumerator.js +1 -1
  6. package/lib/cli-engine/formatters/html.js +193 -9
  7. package/lib/init/autoconfig.js +2 -2
  8. package/lib/init/config-file.js +1 -0
  9. package/lib/init/config-initializer.js +14 -1
  10. package/lib/init/npm-utils.js +1 -0
  11. package/lib/linter/apply-disable-directives.js +15 -3
  12. package/lib/linter/linter.js +9 -7
  13. package/lib/linter/node-event-generator.js +43 -6
  14. package/lib/rule-tester/rule-tester.js +14 -10
  15. package/lib/rules/comma-dangle.js +16 -7
  16. package/lib/rules/comma-spacing.js +1 -1
  17. package/lib/rules/complexity.js +2 -3
  18. package/lib/rules/consistent-return.js +2 -2
  19. package/lib/rules/eol-last.js +2 -7
  20. package/lib/rules/indent.js +8 -9
  21. package/lib/rules/max-lines-per-function.js +2 -3
  22. package/lib/rules/max-lines.js +32 -7
  23. package/lib/rules/max-params.js +2 -3
  24. package/lib/rules/max-statements.js +2 -3
  25. package/lib/rules/no-fallthrough.js +2 -8
  26. package/lib/rules/no-implicit-coercion.js +37 -0
  27. package/lib/rules/no-multi-assign.js +15 -2
  28. package/lib/rules/no-restricted-imports.js +61 -24
  29. package/lib/rules/no-unused-vars.js +53 -16
  30. package/lib/rules/no-useless-backreference.js +1 -2
  31. package/lib/rules/no-useless-computed-key.js +8 -2
  32. package/lib/rules/no-warning-comments.js +1 -1
  33. package/lib/rules/object-curly-newline.js +19 -4
  34. package/lib/rules/radix.js +19 -3
  35. package/lib/rules/require-atomic-updates.js +23 -20
  36. package/lib/rules/spaced-comment.js +2 -2
  37. package/lib/rules/utils/ast-utils.js +2 -2
  38. package/lib/shared/deprecation-warnings.js +12 -3
  39. package/lib/shared/string-utils.js +22 -0
  40. package/lib/source-code/source-code.js +6 -5
  41. package/lib/source-code/token-store/utils.js +4 -12
  42. package/messages/{all-files-ignored.txt → all-files-ignored.js} +10 -2
  43. package/messages/extend-config-missing.js +13 -0
  44. package/messages/failed-to-read-json.js +11 -0
  45. package/messages/file-not-found.js +10 -0
  46. package/messages/{no-config-found.txt → no-config-found.js} +9 -1
  47. package/messages/plugin-conflict.js +22 -0
  48. package/messages/plugin-invalid.js +16 -0
  49. package/messages/plugin-missing.js +19 -0
  50. package/messages/{print-config-with-directory-path.txt → print-config-with-directory-path.js} +6 -0
  51. package/messages/whitespace-found.js +11 -0
  52. package/package.json +10 -13
  53. package/lib/cli-engine/formatters/html-template-message.html +0 -8
  54. package/lib/cli-engine/formatters/html-template-page.html +0 -115
  55. package/lib/cli-engine/formatters/html-template-result.html +0 -6
  56. package/messages/extend-config-missing.txt +0 -5
  57. package/messages/failed-to-read-json.txt +0 -3
  58. package/messages/file-not-found.txt +0 -2
  59. package/messages/plugin-conflict.txt +0 -7
  60. package/messages/plugin-invalid.txt +0 -8
  61. package/messages/plugin-missing.txt +0 -11
  62. package/messages/whitespace-found.txt +0 -3
@@ -196,6 +196,17 @@ module.exports = {
196
196
 
197
197
  }
198
198
 
199
+ /**
200
+ * Checks whether a node is a sibling of the rest property or not.
201
+ * @param {ASTNode} node a node to check
202
+ * @returns {boolean} True if the node is a sibling of the rest property, otherwise false.
203
+ */
204
+ function hasRestSibling(node) {
205
+ return node.type === "Property" &&
206
+ node.parent.type === "ObjectPattern" &&
207
+ REST_PROPERTY_TYPE.test(node.parent.properties[node.parent.properties.length - 1].type);
208
+ }
209
+
199
210
  /**
200
211
  * Determines if a variable has a sibling rest property
201
212
  * @param {Variable} variable eslint-scope variable object.
@@ -204,16 +215,10 @@ module.exports = {
204
215
  */
205
216
  function hasRestSpreadSibling(variable) {
206
217
  if (config.ignoreRestSiblings) {
207
- return variable.defs.some(def => {
208
- const propertyNode = def.name.parent;
209
- const patternNode = propertyNode.parent;
210
-
211
- return (
212
- propertyNode.type === "Property" &&
213
- patternNode.type === "ObjectPattern" &&
214
- REST_PROPERTY_TYPE.test(patternNode.properties[patternNode.properties.length - 1].type)
215
- );
216
- });
218
+ const hasRestSiblingDefinition = variable.defs.some(def => hasRestSibling(def.name.parent));
219
+ const hasRestSiblingReference = variable.references.some(ref => hasRestSibling(ref.identifier.parent));
220
+
221
+ return hasRestSiblingDefinition || hasRestSiblingReference;
217
222
  }
218
223
 
219
224
  return false;
@@ -405,6 +410,31 @@ module.exports = {
405
410
  );
406
411
  }
407
412
 
413
+ /**
414
+ * Checks whether a given node is unused expression or not.
415
+ * @param {ASTNode} node The node itself
416
+ * @returns {boolean} The node is an unused expression.
417
+ * @private
418
+ */
419
+ function isUnusedExpression(node) {
420
+ const parent = node.parent;
421
+
422
+ if (parent.type === "ExpressionStatement") {
423
+ return true;
424
+ }
425
+
426
+ if (parent.type === "SequenceExpression") {
427
+ const isLastExpression = parent.expressions[parent.expressions.length - 1] === node;
428
+
429
+ if (!isLastExpression) {
430
+ return true;
431
+ }
432
+ return isUnusedExpression(parent);
433
+ }
434
+
435
+ return false;
436
+ }
437
+
408
438
  /**
409
439
  * Checks whether a given reference is a read to update itself or not.
410
440
  * @param {eslint-scope.Reference} ref A reference to check.
@@ -415,7 +445,6 @@ module.exports = {
415
445
  function isReadForItself(ref, rhsNode) {
416
446
  const id = ref.identifier;
417
447
  const parent = id.parent;
418
- const grandparent = parent.parent;
419
448
 
420
449
  return ref.isRead() && (
421
450
 
@@ -423,12 +452,12 @@ module.exports = {
423
452
  (// in RHS of an assignment for itself. e.g. `a = a + 1`
424
453
  ((
425
454
  parent.type === "AssignmentExpression" &&
426
- grandparent.type === "ExpressionStatement" &&
455
+ isUnusedExpression(parent) &&
427
456
  parent.left === id
428
457
  ) ||
429
458
  (
430
459
  parent.type === "UpdateExpression" &&
431
- grandparent.type === "ExpressionStatement"
460
+ isUnusedExpression(parent)
432
461
  ) || rhsNode &&
433
462
  isInside(id, rhsNode) &&
434
463
  !isInsideOfStorableFunction(id, rhsNode)))
@@ -619,10 +648,18 @@ module.exports = {
619
648
 
620
649
  // Report the first declaration.
621
650
  if (unusedVar.defs.length > 0) {
651
+
652
+ // report last write reference, https://github.com/eslint/eslint/issues/14324
653
+ const writeReferences = unusedVar.references.filter(ref => ref.isWrite() && ref.from.variableScope === unusedVar.scope.variableScope);
654
+
655
+ let referenceToReport;
656
+
657
+ if (writeReferences.length > 0) {
658
+ referenceToReport = writeReferences[writeReferences.length - 1];
659
+ }
660
+
622
661
  context.report({
623
- node: unusedVar.references.length ? unusedVar.references[
624
- unusedVar.references.length - 1
625
- ].identifier : unusedVar.identifiers[0],
662
+ node: referenceToReport ? referenceToReport.identifier : unusedVar.identifiers[0],
626
663
  messageId: "unusedVar",
627
664
  data: unusedVar.references.some(ref => ref.isWrite())
628
665
  ? getAssignedMessageData(unusedVar)
@@ -11,7 +11,6 @@
11
11
 
12
12
  const { CALL, CONSTRUCT, ReferenceTracker, getStringIfConstant } = require("eslint-utils");
13
13
  const { RegExpParser, visitRegExpAST } = require("regexpp");
14
- const lodash = require("lodash");
15
14
 
16
15
  //------------------------------------------------------------------------------
17
16
  // Helpers
@@ -137,7 +136,7 @@ module.exports = {
137
136
 
138
137
  // the opposite of the previous when the regex is matching backward in a lookbehind context.
139
138
  messageId = "backward";
140
- } else if (lodash.last(groupCut).type === "Alternative") {
139
+ } else if (groupCut[groupCut.length - 1].type === "Alternative") {
141
140
 
142
141
  // group's and bref's ancestor nodes below the lowest common ancestor are sibling alternatives => they're disjunctive.
143
142
  messageId = "disjunctive";
@@ -8,7 +8,6 @@
8
8
  // Requirements
9
9
  //------------------------------------------------------------------------------
10
10
 
11
- const lodash = require("lodash");
12
11
  const astUtils = require("./utils/ast-utils");
13
12
 
14
13
  //------------------------------------------------------------------------------
@@ -95,9 +94,16 @@ module.exports = {
95
94
  }
96
95
  }
97
96
 
97
+ /**
98
+ * A no-op function to act as placeholder for checking a node when the `enforceForClassMembers` option is `false`.
99
+ * @returns {void}
100
+ * @private
101
+ */
102
+ function noop() {}
103
+
98
104
  return {
99
105
  Property: check,
100
- MethodDefinition: enforceForClassMembers ? check : lodash.noop
106
+ MethodDefinition: enforceForClassMembers ? check : noop
101
107
  };
102
108
  }
103
109
  };
@@ -5,7 +5,7 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const { escapeRegExp } = require("lodash");
8
+ const escapeRegExp = require("escape-string-regexp");
9
9
  const astUtils = require("./utils/ast-utils");
10
10
 
11
11
  const CHAR_LIMIT = 40;
@@ -10,7 +10,6 @@
10
10
  //------------------------------------------------------------------------------
11
11
 
12
12
  const astUtils = require("./utils/ast-utils");
13
- const lodash = require("lodash");
14
13
 
15
14
  //------------------------------------------------------------------------------
16
15
  // Helpers
@@ -69,6 +68,24 @@ function normalizeOptionValue(value) {
69
68
  return { multiline, minProperties, consistent };
70
69
  }
71
70
 
71
+ /**
72
+ * Checks if a value is an object.
73
+ * @param {any} value The value to check
74
+ * @returns {boolean} `true` if the value is an object, otherwise `false`
75
+ */
76
+ function isObject(value) {
77
+ return typeof value === "object" && value !== null;
78
+ }
79
+
80
+ /**
81
+ * Checks if an option is a node-specific option
82
+ * @param {any} option The option to check
83
+ * @returns {boolean} `true` if the option is node-specific, otherwise `false`
84
+ */
85
+ function isNodeSpecificOption(option) {
86
+ return isObject(option) || typeof option === "string";
87
+ }
88
+
72
89
  /**
73
90
  * Normalizes a given option value.
74
91
  * @param {string|Object|undefined} options An option value to parse.
@@ -80,9 +97,7 @@ function normalizeOptionValue(value) {
80
97
  * }} Normalized option object.
81
98
  */
82
99
  function normalizeOptions(options) {
83
- const isNodeSpecificOption = lodash.overSome([lodash.isPlainObject, lodash.isString]);
84
-
85
- if (lodash.isPlainObject(options) && Object.values(options).some(isNodeSpecificOption)) {
100
+ if (isObject(options) && Object.values(options).some(isNodeSpecificOption)) {
86
101
  return {
87
102
  ObjectExpression: normalizeOptionValue(options.ObjectExpression),
88
103
  ObjectPattern: normalizeOptionValue(options.ObjectPattern),
@@ -82,7 +82,8 @@ module.exports = {
82
82
  description: "enforce the consistent use of the radix argument when using `parseInt()`",
83
83
  category: "Best Practices",
84
84
  recommended: false,
85
- url: "https://eslint.org/docs/rules/radix"
85
+ url: "https://eslint.org/docs/rules/radix",
86
+ suggestion: true
86
87
  },
87
88
 
88
89
  schema: [
@@ -95,7 +96,8 @@ module.exports = {
95
96
  missingParameters: "Missing parameters.",
96
97
  redundantRadix: "Redundant radix parameter.",
97
98
  missingRadix: "Missing radix parameter.",
98
- invalidRadix: "Invalid radix parameter, must be an integer between 2 and 36."
99
+ invalidRadix: "Invalid radix parameter, must be an integer between 2 and 36.",
100
+ addRadixParameter10: "Add radix parameter `10` for parsing decimal numbers."
99
101
  }
100
102
  },
101
103
 
@@ -123,7 +125,21 @@ module.exports = {
123
125
  if (mode === MODE_ALWAYS) {
124
126
  context.report({
125
127
  node,
126
- messageId: "missingRadix"
128
+ messageId: "missingRadix",
129
+ suggest: [
130
+ {
131
+ messageId: "addRadixParameter10",
132
+ fix(fixer) {
133
+ const sourceCode = context.getSourceCode();
134
+ const tokens = sourceCode.getTokens(node);
135
+ const lastToken = tokens[tokens.length - 1]; // Parenthesis.
136
+ const secondToLastToken = tokens[tokens.length - 2]; // May or may not be a comma.
137
+ const hasTrailingComma = secondToLastToken.type === "Punctuator" && secondToLastToken.value === ",";
138
+
139
+ return fixer.insertTextBefore(lastToken, hasTrailingComma ? " 10," : ", 10");
140
+ }
141
+ }
142
+ ]
127
143
  });
128
144
  }
129
145
  break;
@@ -13,6 +13,10 @@
13
13
  */
14
14
  function createReferenceMap(scope, outReferenceMap = new Map()) {
15
15
  for (const reference of scope.references) {
16
+ if (reference.resolved === null) {
17
+ continue;
18
+ }
19
+
16
20
  outReferenceMap.set(reference.identifier, reference);
17
21
  }
18
22
  for (const childScope of scope.childScopes) {
@@ -86,42 +90,42 @@ class SegmentInfo {
86
90
  * @returns {void}
87
91
  */
88
92
  initialize(segment) {
89
- const outdatedReadVariableNames = new Set();
90
- const freshReadVariableNames = new Set();
93
+ const outdatedReadVariables = new Set();
94
+ const freshReadVariables = new Set();
91
95
 
92
96
  for (const prevSegment of segment.prevSegments) {
93
97
  const info = this.info.get(prevSegment);
94
98
 
95
99
  if (info) {
96
- info.outdatedReadVariableNames.forEach(Set.prototype.add, outdatedReadVariableNames);
97
- info.freshReadVariableNames.forEach(Set.prototype.add, freshReadVariableNames);
100
+ info.outdatedReadVariables.forEach(Set.prototype.add, outdatedReadVariables);
101
+ info.freshReadVariables.forEach(Set.prototype.add, freshReadVariables);
98
102
  }
99
103
  }
100
104
 
101
- this.info.set(segment, { outdatedReadVariableNames, freshReadVariableNames });
105
+ this.info.set(segment, { outdatedReadVariables, freshReadVariables });
102
106
  }
103
107
 
104
108
  /**
105
109
  * Mark a given variable as read on given segments.
106
110
  * @param {PathSegment[]} segments The segments that it read the variable on.
107
- * @param {string} variableName The variable name to be read.
111
+ * @param {Variable} variable The variable to be read.
108
112
  * @returns {void}
109
113
  */
110
- markAsRead(segments, variableName) {
114
+ markAsRead(segments, variable) {
111
115
  for (const segment of segments) {
112
116
  const info = this.info.get(segment);
113
117
 
114
118
  if (info) {
115
- info.freshReadVariableNames.add(variableName);
119
+ info.freshReadVariables.add(variable);
116
120
 
117
121
  // If a variable is freshly read again, then it's no more out-dated.
118
- info.outdatedReadVariableNames.delete(variableName);
122
+ info.outdatedReadVariables.delete(variable);
119
123
  }
120
124
  }
121
125
  }
122
126
 
123
127
  /**
124
- * Move `freshReadVariableNames` to `outdatedReadVariableNames`.
128
+ * Move `freshReadVariables` to `outdatedReadVariables`.
125
129
  * @param {PathSegment[]} segments The segments to process.
126
130
  * @returns {void}
127
131
  */
@@ -130,8 +134,8 @@ class SegmentInfo {
130
134
  const info = this.info.get(segment);
131
135
 
132
136
  if (info) {
133
- info.freshReadVariableNames.forEach(Set.prototype.add, info.outdatedReadVariableNames);
134
- info.freshReadVariableNames.clear();
137
+ info.freshReadVariables.forEach(Set.prototype.add, info.outdatedReadVariables);
138
+ info.freshReadVariables.clear();
135
139
  }
136
140
  }
137
141
  }
@@ -139,14 +143,14 @@ class SegmentInfo {
139
143
  /**
140
144
  * Check if a given variable is outdated on the current segments.
141
145
  * @param {PathSegment[]} segments The current segments.
142
- * @param {string} variableName The variable name to check.
146
+ * @param {Variable} variable The variable to check.
143
147
  * @returns {boolean} `true` if the variable is outdated on the segments.
144
148
  */
145
- isOutdated(segments, variableName) {
149
+ isOutdated(segments, variable) {
146
150
  for (const segment of segments) {
147
151
  const info = this.info.get(segment);
148
152
 
149
- if (info && info.outdatedReadVariableNames.has(variableName)) {
153
+ if (info && info.outdatedReadVariables.has(variable)) {
150
154
  return true;
151
155
  }
152
156
  }
@@ -214,14 +218,13 @@ module.exports = {
214
218
  if (!reference) {
215
219
  return;
216
220
  }
217
- const name = reference.identifier.name;
218
221
  const variable = reference.resolved;
219
222
  const writeExpr = getWriteExpr(reference);
220
223
  const isMemberAccess = reference.identifier.parent.type === "MemberExpression";
221
224
 
222
225
  // Add a fresh read variable.
223
226
  if (reference.isRead() && !(writeExpr && writeExpr.parent.operator === "=")) {
224
- segmentInfo.markAsRead(codePath.currentSegments, name);
227
+ segmentInfo.markAsRead(codePath.currentSegments, variable);
225
228
  }
226
229
 
227
230
  /*
@@ -245,7 +248,7 @@ module.exports = {
245
248
 
246
249
  /*
247
250
  * Verify assignments.
248
- * If the reference exists in `outdatedReadVariableNames` list, report it.
251
+ * If the reference exists in `outdatedReadVariables` list, report it.
249
252
  */
250
253
  ":expression:exit"(node) {
251
254
  const { codePath, referenceMap } = stack;
@@ -267,9 +270,9 @@ module.exports = {
267
270
  assignmentReferences.delete(node);
268
271
 
269
272
  for (const reference of references) {
270
- const name = reference.identifier.name;
273
+ const variable = reference.resolved;
271
274
 
272
- if (segmentInfo.isOutdated(codePath.currentSegments, name)) {
275
+ if (segmentInfo.isOutdated(codePath.currentSegments, variable)) {
273
276
  context.report({
274
277
  node: node.parent,
275
278
  messageId: "nonAtomicUpdate",
@@ -4,7 +4,7 @@
4
4
  */
5
5
  "use strict";
6
6
 
7
- const lodash = require("lodash");
7
+ const escapeRegExp = require("escape-string-regexp");
8
8
  const astUtils = require("./utils/ast-utils");
9
9
 
10
10
  //------------------------------------------------------------------------------
@@ -17,7 +17,7 @@ const astUtils = require("./utils/ast-utils");
17
17
  * @returns {string} An escaped string.
18
18
  */
19
19
  function escape(s) {
20
- return `(?:${lodash.escapeRegExp(s)})`;
20
+ return `(?:${escapeRegExp(s)})`;
21
21
  }
22
22
 
23
23
  /**
@@ -11,7 +11,7 @@
11
11
 
12
12
  const esutils = require("esutils");
13
13
  const espree = require("espree");
14
- const lodash = require("lodash");
14
+ const escapeRegExp = require("escape-string-regexp");
15
15
  const {
16
16
  breakableTypePattern,
17
17
  createGlobalLinebreakMatcher,
@@ -1756,7 +1756,7 @@ module.exports = {
1756
1756
  * @returns {SourceLocation} The `loc` object.
1757
1757
  */
1758
1758
  getNameLocationInGlobalDirectiveComment(sourceCode, comment, name) {
1759
- const namePattern = new RegExp(`[\\s,]${lodash.escapeRegExp(name)}(?:$|[\\s,:])`, "gu");
1759
+ const namePattern = new RegExp(`[\\s,]${escapeRegExp(name)}(?:$|[\\s,:])`, "gu");
1760
1760
 
1761
1761
  // To ignore the first text "global".
1762
1762
  namePattern.lastIndex = comment.value.indexOf("global") + 6;
@@ -9,7 +9,6 @@
9
9
  //------------------------------------------------------------------------------
10
10
 
11
11
  const path = require("path");
12
- const lodash = require("lodash");
13
12
 
14
13
  //------------------------------------------------------------------------------
15
14
  // Private
@@ -28,6 +27,8 @@ const deprecationWarningMessages = {
28
27
  "projects in order to avoid loading '~/.eslintrc.*' accidentally."
29
28
  };
30
29
 
30
+ const sourceFileErrorCache = new Set();
31
+
31
32
  /**
32
33
  * Emits a deprecation warning containing a given filepath. A new deprecation warning is emitted
33
34
  * for each unique file path, but repeated invocations with the same file path have no effect.
@@ -36,7 +37,15 @@ const deprecationWarningMessages = {
36
37
  * @param {string} errorCode The warning message to show.
37
38
  * @returns {void}
38
39
  */
39
- const emitDeprecationWarning = lodash.memoize((source, errorCode) => {
40
+ function emitDeprecationWarning(source, errorCode) {
41
+ const cacheKey = JSON.stringify({ source, errorCode });
42
+
43
+ if (sourceFileErrorCache.has(cacheKey)) {
44
+ return;
45
+ }
46
+
47
+ sourceFileErrorCache.add(cacheKey);
48
+
40
49
  const rel = path.relative(process.cwd(), source);
41
50
  const message = deprecationWarningMessages[errorCode];
42
51
 
@@ -45,7 +54,7 @@ const emitDeprecationWarning = lodash.memoize((source, errorCode) => {
45
54
  "DeprecationWarning",
46
55
  errorCode
47
56
  );
48
- }, (...args) => JSON.stringify(args));
57
+ }
49
58
 
50
59
  //------------------------------------------------------------------------------
51
60
  // Public Interface
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @fileoverview Utilities to operate on strings.
3
+ * @author Stephen Wade
4
+ */
5
+
6
+ "use strict";
7
+
8
+ /**
9
+ * Converts the first letter of a string to uppercase.
10
+ * @param {string} string The string to operate on
11
+ * @returns {string} The converted string
12
+ */
13
+ function upperCaseFirst(string) {
14
+ if (string.length <= 1) {
15
+ return string.toUpperCase();
16
+ }
17
+ return string[0].toUpperCase() + string.slice(1);
18
+ }
19
+
20
+ module.exports = {
21
+ upperCaseFirst
22
+ };
@@ -12,8 +12,7 @@ const
12
12
  { isCommentToken } = require("eslint-utils"),
13
13
  TokenStore = require("./token-store"),
14
14
  astUtils = require("../shared/ast-utils"),
15
- Traverser = require("../shared/traverser"),
16
- lodash = require("lodash");
15
+ Traverser = require("../shared/traverser");
17
16
 
18
17
  //------------------------------------------------------------------------------
19
18
  // Private
@@ -531,10 +530,12 @@ class SourceCode extends TokenStore {
531
530
  }
532
531
 
533
532
  /*
534
- * To figure out which line rangeIndex is on, determine the last index at which rangeIndex could
535
- * be inserted into lineIndices to keep the list sorted.
533
+ * To figure out which line index is on, determine the last place at which index could
534
+ * be inserted into lineStartIndices to keep the list sorted.
536
535
  */
537
- const lineNumber = lodash.sortedLastIndex(this.lineStartIndices, index);
536
+ const lineNumber = index >= this.lineStartIndices[this.lineStartIndices.length - 1]
537
+ ? this.lineStartIndices.length
538
+ : this.lineStartIndices.findIndex(el => index < el);
538
539
 
539
540
  return { line: lineNumber, column: index - this.lineStartIndices[lineNumber - 1] };
540
541
  }
@@ -4,12 +4,6 @@
4
4
  */
5
5
  "use strict";
6
6
 
7
- //------------------------------------------------------------------------------
8
- // Requirements
9
- //------------------------------------------------------------------------------
10
-
11
- const lodash = require("lodash");
12
-
13
7
  //------------------------------------------------------------------------------
14
8
  // Helpers
15
9
  //------------------------------------------------------------------------------
@@ -29,18 +23,16 @@ function getStartLocation(token) {
29
23
  //------------------------------------------------------------------------------
30
24
 
31
25
  /**
32
- * Binary-searches the index of the first token which is after the given location.
26
+ * Finds the index of the first token which is after the given location.
33
27
  * If it was not found, this returns `tokens.length`.
34
28
  * @param {(Token|Comment)[]} tokens It searches the token in this list.
35
29
  * @param {number} location The location to search.
36
30
  * @returns {number} The found index or `tokens.length`.
37
31
  */
38
32
  exports.search = function search(tokens, location) {
39
- return lodash.sortedIndexBy(
40
- tokens,
41
- { range: [location] },
42
- getStartLocation
43
- );
33
+ const index = tokens.findIndex(el => location <= getStartLocation(el));
34
+
35
+ return index === -1 ? tokens.length : index;
44
36
  };
45
37
 
46
38
  /**
@@ -1,8 +1,16 @@
1
- You are linting "<%= pattern %>", but all of the files matching the glob pattern "<%= pattern %>" are ignored.
1
+ "use strict";
2
2
 
3
- If you don't want to lint these files, remove the pattern "<%= pattern %>" from the list of arguments passed to ESLint.
3
+ module.exports = function(it) {
4
+ const { pattern } = it;
5
+
6
+ return `
7
+ You are linting "${pattern}", but all of the files matching the glob pattern "${pattern}" are ignored.
8
+
9
+ If you don't want to lint these files, remove the pattern "${pattern}" from the list of arguments passed to ESLint.
4
10
 
5
11
  If you do want to lint these files, try the following solutions:
6
12
 
7
13
  * Check your .eslintignore file, or the eslintIgnore property in package.json, to ensure that the files are not configured to be ignored.
8
14
  * Explicitly list the files from this glob that you'd like to lint on the command-line, rather than providing a glob as an argument.
15
+ `.trimLeft();
16
+ };
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ module.exports = function(it) {
4
+ const { configName, importerName } = it;
5
+
6
+ return `
7
+ ESLint couldn't find the config "${configName}" to extend from. Please check that the name of the config is correct.
8
+
9
+ The config "${configName}" was referenced from the config file in "${importerName}".
10
+
11
+ If you still have problems, please stop by https://eslint.org/chat/help to chat with the team.
12
+ `.trimLeft();
13
+ };
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+
3
+ module.exports = function(it) {
4
+ const { path, message } = it;
5
+
6
+ return `
7
+ Failed to read JSON file at ${path}:
8
+
9
+ ${message}
10
+ `.trimLeft();
11
+ };
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+
3
+ module.exports = function(it) {
4
+ const { pattern, globDisabled } = it;
5
+
6
+ return `
7
+ No files matching the pattern "${pattern}"${globDisabled ? " (with disabling globs)" : ""} were found.
8
+ Please check for typing mistakes in the pattern.
9
+ `.trimLeft();
10
+ };
@@ -1,7 +1,15 @@
1
+ "use strict";
2
+
3
+ module.exports = function(it) {
4
+ const { directoryPath } = it;
5
+
6
+ return `
1
7
  ESLint couldn't find a configuration file. To set up a configuration file for this project, please run:
2
8
 
3
9
  eslint --init
4
10
 
5
- ESLint looked for configuration files in <%= directoryPath %> and its ancestors. If it found none, it then looked in your home directory.
11
+ ESLint looked for configuration files in ${directoryPath} and its ancestors. If it found none, it then looked in your home directory.
6
12
 
7
13
  If you think you already have a configuration file or if you need more help, please stop by the ESLint chat room: https://eslint.org/chat/help
14
+ `.trimLeft();
15
+ };
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+
3
+ module.exports = function(it) {
4
+ const { pluginId, plugins } = it;
5
+
6
+ let result = `ESLint couldn't determine the plugin "${pluginId}" uniquely.
7
+ `;
8
+
9
+ for (const { filePath, importerName } of plugins) {
10
+ result += `
11
+ - ${filePath} (loaded in "${importerName}")`;
12
+ }
13
+
14
+ result += `
15
+
16
+ Please remove the "plugins" setting from either config or remove either plugin installation.
17
+
18
+ If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team.
19
+ `;
20
+
21
+ return result;
22
+ };