eslint 8.34.0 → 8.39.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 (104) hide show
  1. package/README.md +7 -18
  2. package/conf/rule-type-list.json +2 -2
  3. package/lib/cli-engine/cli-engine.js +2 -2
  4. package/lib/cli-engine/file-enumerator.js +8 -6
  5. package/lib/config/default-config.js +1 -4
  6. package/lib/config/flat-config-array.js +77 -17
  7. package/lib/config/flat-config-schema.js +4 -18
  8. package/lib/eslint/eslint-helpers.js +3 -3
  9. package/lib/linter/linter.js +4 -77
  10. package/lib/rule-tester/flat-rule-tester.js +1 -1
  11. package/lib/rule-tester/rule-tester.js +1 -1
  12. package/lib/rules/block-scoped-var.js +2 -1
  13. package/lib/rules/camelcase.js +5 -4
  14. package/lib/rules/consistent-this.js +4 -2
  15. package/lib/rules/func-names.js +1 -1
  16. package/lib/rules/global-require.js +4 -2
  17. package/lib/rules/handle-callback-err.js +2 -1
  18. package/lib/rules/id-blacklist.js +3 -2
  19. package/lib/rules/id-denylist.js +3 -2
  20. package/lib/rules/id-match.js +3 -2
  21. package/lib/rules/lines-around-comment.js +11 -0
  22. package/lib/rules/logical-assignment-operators.js +4 -4
  23. package/lib/rules/multiline-comment-style.js +42 -3
  24. package/lib/rules/new-parens.js +5 -14
  25. package/lib/rules/no-alert.js +3 -1
  26. package/lib/rules/no-catch-shadow.js +3 -1
  27. package/lib/rules/no-class-assign.js +3 -1
  28. package/lib/rules/no-console.js +3 -2
  29. package/lib/rules/no-const-assign.js +3 -1
  30. package/lib/rules/no-constant-binary-expression.js +36 -27
  31. package/lib/rules/no-constant-condition.js +3 -2
  32. package/lib/rules/no-control-regex.js +1 -1
  33. package/lib/rules/no-div-regex.js +1 -1
  34. package/lib/rules/no-dupe-args.js +3 -1
  35. package/lib/rules/no-else-return.js +13 -12
  36. package/lib/rules/no-eval.js +5 -5
  37. package/lib/rules/no-ex-assign.js +3 -1
  38. package/lib/rules/no-extend-native.js +3 -2
  39. package/lib/rules/no-extra-boolean-cast.js +1 -1
  40. package/lib/rules/no-extra-parens.js +1 -1
  41. package/lib/rules/no-func-assign.js +3 -1
  42. package/lib/rules/no-global-assign.js +3 -2
  43. package/lib/rules/no-implicit-globals.js +3 -2
  44. package/lib/rules/no-implied-eval.js +5 -4
  45. package/lib/rules/no-import-assign.js +5 -3
  46. package/lib/rules/no-invalid-regexp.js +1 -1
  47. package/lib/rules/no-invalid-this.js +2 -2
  48. package/lib/rules/no-label-var.js +2 -1
  49. package/lib/rules/no-lone-blocks.js +8 -6
  50. package/lib/rules/no-lonely-if.js +2 -3
  51. package/lib/rules/no-loop-func.js +3 -1
  52. package/lib/rules/no-misleading-character-class.js +12 -41
  53. package/lib/rules/no-native-reassign.js +3 -2
  54. package/lib/rules/no-new-func.js +7 -6
  55. package/lib/rules/no-new-native-nonconstructor.js +8 -6
  56. package/lib/rules/no-new-object.js +4 -1
  57. package/lib/rules/no-new-symbol.js +8 -6
  58. package/lib/rules/no-obj-calls.js +8 -6
  59. package/lib/rules/no-param-reassign.js +2 -1
  60. package/lib/rules/no-promise-executor-return.js +3 -2
  61. package/lib/rules/no-redeclare.js +3 -3
  62. package/lib/rules/no-regex-spaces.js +4 -2
  63. package/lib/rules/no-restricted-exports.js +2 -1
  64. package/lib/rules/no-restricted-globals.js +4 -2
  65. package/lib/rules/no-setter-return.js +3 -2
  66. package/lib/rules/no-shadow-restricted-names.js +2 -1
  67. package/lib/rules/no-shadow.js +3 -2
  68. package/lib/rules/no-undef-init.js +1 -1
  69. package/lib/rules/no-undef.js +3 -2
  70. package/lib/rules/no-undefined.js +4 -2
  71. package/lib/rules/no-underscore-dangle.js +2 -1
  72. package/lib/rules/no-unmodified-loop-condition.js +2 -2
  73. package/lib/rules/no-unused-expressions.js +4 -5
  74. package/lib/rules/no-unused-vars.js +2 -2
  75. package/lib/rules/no-use-before-define.js +3 -2
  76. package/lib/rules/no-useless-backreference.js +9 -7
  77. package/lib/rules/no-useless-return.js +1 -1
  78. package/lib/rules/no-var.js +2 -2
  79. package/lib/rules/object-shorthand.js +3 -2
  80. package/lib/rules/prefer-arrow-callback.js +2 -2
  81. package/lib/rules/prefer-const.js +1 -1
  82. package/lib/rules/prefer-exponentiation-operator.js +5 -5
  83. package/lib/rules/prefer-named-capture-group.js +8 -8
  84. package/lib/rules/prefer-object-has-own.js +4 -2
  85. package/lib/rules/prefer-object-spread.js +12 -13
  86. package/lib/rules/prefer-promise-reject-errors.js +2 -1
  87. package/lib/rules/prefer-regex-literals.js +26 -27
  88. package/lib/rules/prefer-rest-params.js +5 -2
  89. package/lib/rules/radix.js +11 -11
  90. package/lib/rules/require-atomic-updates.js +2 -2
  91. package/lib/rules/require-unicode-regexp.js +67 -7
  92. package/lib/rules/symbol-description.js +7 -5
  93. package/lib/rules/utils/regular-expressions.js +42 -0
  94. package/lib/rules/valid-typeof.js +4 -4
  95. package/lib/rules/wrap-iife.js +1 -1
  96. package/lib/rules/wrap-regex.js +2 -3
  97. package/lib/rules/yoda.js +1 -1
  98. package/lib/source-code/source-code.js +137 -1
  99. package/lib/source-code/token-store/index.js +1 -1
  100. package/lib/source-code/token-store/utils.js +35 -20
  101. package/messages/no-config-found.js +1 -1
  102. package/package.json +13 -8
  103. package/conf/eslint-all.js +0 -31
  104. package/conf/eslint-recommended.js +0 -76
package/README.md CHANGED
@@ -16,8 +16,7 @@
16
16
  [Report Bugs](https://eslint.org/docs/latest/contribute/report-bugs) |
17
17
  [Code of Conduct](https://eslint.org/conduct) |
18
18
  [Twitter](https://twitter.com/geteslint) |
19
- [Mailing List](https://groups.google.com/group/eslint) |
20
- [Chat Room](https://eslint.org/chat)
19
+ [Discord](https://eslint.org/chat)
21
20
 
22
21
  ESLint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code. In many ways, it is similar to JSLint and JSHint with a few exceptions:
23
22
 
@@ -129,7 +128,7 @@ Once a language feature has been adopted into the ECMAScript standard (stage 4 a
129
128
 
130
129
  ### Where to ask for help?
131
130
 
132
- Join our [Mailing List](https://groups.google.com/group/eslint) or [Chatroom](https://eslint.org/chat).
131
+ Open a [discussion](https://github.com/eslint/eslint/discussions) or stop by our [Discord server](https://eslint.org/chat).
133
132
 
134
133
  ### Why doesn't ESLint lock dependency versions?
135
134
 
@@ -213,11 +212,6 @@ The people who manage releases, review feature requests, and meet regularly to e
213
212
  Nicholas C. Zakas
214
213
  </a>
215
214
  </td><td align="center" valign="top" width="11%">
216
- <a href="https://github.com/btmills">
217
- <img src="https://github.com/btmills.png?s=75" width="75" height="75"><br />
218
- Brandon Mills
219
- </a>
220
- </td><td align="center" valign="top" width="11%">
221
215
  <a href="https://github.com/mdjermanovic">
222
216
  <img src="https://github.com/mdjermanovic.png?s=75" width="75" height="75"><br />
223
217
  Milos Djermanovic
@@ -250,14 +244,9 @@ The people who review and fix bugs and help triage issues.
250
244
  Bryan Mishkin
251
245
  </a>
252
246
  </td><td align="center" valign="top" width="11%">
253
- <a href="https://github.com/SaraSoueidan">
254
- <img src="https://github.com/SaraSoueidan.png?s=75" width="75" height="75"><br />
255
- Sara Soueidan
256
- </a>
257
- </td><td align="center" valign="top" width="11%">
258
- <a href="https://github.com/yeonjuan">
259
- <img src="https://github.com/yeonjuan.png?s=75" width="75" height="75"><br />
260
- YeonJuan
247
+ <a href="https://github.com/fasttime">
248
+ <img src="https://github.com/fasttime.png?s=75" width="75" height="75"><br />
249
+ Francesco Trotta
261
250
  </a>
262
251
  </td></tr></tbody></table>
263
252
 
@@ -293,8 +282,8 @@ The following companies, organizations, and individuals support ESLint's ongoing
293
282
  <h3>Platinum Sponsors</h3>
294
283
  <p><a href="#"><img src="https://images.opencollective.com/2021-frameworks-fund/logo.png" alt="Chrome Frameworks Fund" height="undefined"></a> <a href="https://automattic.com"><img src="https://images.opencollective.com/automattic/d0ef3e1/logo.png" alt="Automattic" height="undefined"></a></p><h3>Gold Sponsors</h3>
295
284
  <p><a href="https://ridicorp.com/career/"><img src="https://images.opencollective.com/ridi-corporation/175dcf3/logo.png" alt="RIDI" height="96"></a> <a href="https://engineering.salesforce.com"><img src="https://images.opencollective.com/salesforce/ca8f997/logo.png" alt="Salesforce" height="96"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="96"></a></p><h3>Silver Sponsors</h3>
296
- <p><a href="https://sentry.io"><img src="https://avatars.githubusercontent.com/u/1396951?v=4" alt="Sentry" height="64"></a> <a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a></p><h3>Bronze Sponsors</h3>
297
- <p><a href="https://paydaysay.com/"><img src="https://images.opencollective.com/payday-say-organization/9cd2467/logo.png" alt="PayDay Say" height="32"></a> <a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://nx.dev"><img src="https://images.opencollective.com/nx/0efbe42/logo.png" alt="Nx (by Nrwl)" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="https://icons8.com"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8: free icons, photos, illustrations, and music" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://transloadit.com/"><img src="https://avatars.githubusercontent.com/u/125754?v=4" alt="Transloadit" height="32"></a> <a href="https://www.ignitionapp.com"><img src="https://avatars.githubusercontent.com/u/5753491?v=4" alt="Ignition" height="32"></a> <a href="https://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774?v=4" alt="HeroCoders" height="32"></a> <a href="https://quickbookstoolhub.com"><img src="https://avatars.githubusercontent.com/u/95090305?u=e5bc398ef775c9ed19f955c675cdc1fb6abf01df&v=4" alt="QuickBooks Tool hub" height="32"></a></p>
285
+ <p><a href="https://sentry.io"><img src="https://avatars.githubusercontent.com/u/1396951?v=4" alt="Sentry" height="64"></a> <a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a> <a href="https://americanexpress.io"><img src="https://avatars.githubusercontent.com/u/3853301?v=4" alt="American Express" height="64"></a></p><h3>Bronze Sponsors</h3>
286
+ <p><a href="https://twicsy.com/buy-instagram-likes"><img src="https://images.opencollective.com/twicsy/7af290f/avatar.png" alt="Twicsy" height="32"></a> <a href="https://paydaysay.com/"><img src="https://images.opencollective.com/payday-say-organization/9cd2467/logo.png" alt="PayDay Say" height="32"></a> <a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://nx.dev"><img src="https://images.opencollective.com/nx/0efbe42/logo.png" alt="Nx (by Nrwl)" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="https://icons8.com"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8: free icons, photos, illustrations, and music" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://transloadit.com/"><img src="https://avatars.githubusercontent.com/u/125754?v=4" alt="Transloadit" height="32"></a> <a href="https://www.ignitionapp.com"><img src="https://avatars.githubusercontent.com/u/5753491?v=4" alt="Ignition" height="32"></a> <a href="https://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774?v=4" alt="HeroCoders" height="32"></a> <a href="https://quickbookstoolhub.com"><img src="https://avatars.githubusercontent.com/u/95090305?u=e5bc398ef775c9ed19f955c675cdc1fb6abf01df&v=4" alt="QuickBooks Tool hub" height="32"></a></p>
298
287
  <!--sponsorsend-->
299
288
 
300
289
  ## Technology Sponsors
@@ -6,12 +6,12 @@
6
6
  ],
7
7
  "deprecated": {
8
8
  "name": "Deprecated",
9
- "description": "These rules have been deprecated in accordance with the <a href=\"/docs/use/rule-deprecation\">deprecation policy</a>, and replaced by newer rules:",
9
+ "description": "These rules have been deprecated in accordance with the <a href=\"{{ '/use/rule-deprecation' | url }}\">deprecation policy</a>, and replaced by newer rules:",
10
10
  "rules": []
11
11
  },
12
12
  "removed": {
13
13
  "name": "Removed",
14
- "description": "These rules from older versions of ESLint (before the <a href=\"/docs/use/rule-deprecation\">deprecation policy</a> existed) have been replaced by newer rules:",
14
+ "description": "These rules from older versions of ESLint (before the <a href=\"{{ '/use/rule-deprecation' | url }}\">deprecation policy</a> existed) have been replaced by newer rules:",
15
15
  "rules": [
16
16
  { "removed": "generator-star", "replacedBy": ["generator-star-spacing"] },
17
17
  { "removed": "global-strict", "replacedBy": ["strict"] },
@@ -615,8 +615,8 @@ class CLIEngine {
615
615
  useEslintrc: options.useEslintrc,
616
616
  builtInRules,
617
617
  loadRules,
618
- getEslintRecommendedConfig: () => require("../../conf/eslint-recommended.js"),
619
- getEslintAllConfig: () => require("../../conf/eslint-all.js")
618
+ getEslintRecommendedConfig: () => require("@eslint/js").configs.recommended,
619
+ getEslintAllConfig: () => require("@eslint/js").configs.all
620
620
  });
621
621
  const fileEnumerator = new FileEnumerator({
622
622
  configArrayFactory,
@@ -217,8 +217,8 @@ class FileEnumerator {
217
217
  cwd = process.cwd(),
218
218
  configArrayFactory = new CascadingConfigArrayFactory({
219
219
  cwd,
220
- getEslintRecommendedConfig: () => require("../../conf/eslint-recommended.js"),
221
- getEslintAllConfig: () => require("../../conf/eslint-all.js")
220
+ getEslintRecommendedConfig: () => require("@eslint/js").configs.recommended,
221
+ getEslintAllConfig: () => require("@eslint/js").configs.all
222
222
  }),
223
223
  extensions = null,
224
224
  globInputPaths = true,
@@ -349,7 +349,7 @@ class FileEnumerator {
349
349
  return this._iterateFilesWithFile(absolutePath);
350
350
  }
351
351
  if (globInputPaths && isGlobPattern(pattern)) {
352
- return this._iterateFilesWithGlob(absolutePath, isDot);
352
+ return this._iterateFilesWithGlob(pattern, isDot);
353
353
  }
354
354
 
355
355
  return [];
@@ -398,15 +398,17 @@ class FileEnumerator {
398
398
  _iterateFilesWithGlob(pattern, dotfiles) {
399
399
  debug(`Glob: ${pattern}`);
400
400
 
401
- const directoryPath = path.resolve(getGlobParent(pattern));
402
- const globPart = pattern.slice(directoryPath.length + 1);
401
+ const { cwd } = internalSlotsMap.get(this);
402
+ const directoryPath = path.resolve(cwd, getGlobParent(pattern));
403
+ const absolutePath = path.resolve(cwd, pattern);
404
+ const globPart = absolutePath.slice(directoryPath.length + 1);
403
405
 
404
406
  /*
405
407
  * recursive if there are `**` or path separators in the glob part.
406
408
  * Otherwise, patterns such as `src/*.js`, it doesn't need recursive.
407
409
  */
408
410
  const recursive = /\*\*|\/|\\/u.test(globPart);
409
- const selector = new Minimatch(pattern, minimatchOpts);
411
+ const selector = new Minimatch(absolutePath, minimatchOpts);
410
412
 
411
413
  debug(`recursive? ${recursive}`);
412
414
 
@@ -19,9 +19,6 @@ exports.defaultConfig = [
19
19
  {
20
20
  plugins: {
21
21
  "@": {
22
- parsers: {
23
- espree: require("espree")
24
- },
25
22
 
26
23
  /*
27
24
  * Because we try to delay loading rules until absolutely
@@ -43,7 +40,7 @@ exports.defaultConfig = [
43
40
  languageOptions: {
44
41
  sourceType: "module",
45
42
  ecmaVersion: "latest",
46
- parser: "@/espree",
43
+ parser: require("espree"),
47
44
  parserOptions: {}
48
45
  }
49
46
  },
@@ -13,7 +13,7 @@ const { ConfigArray, ConfigArraySymbol } = require("@humanwhocodes/config-array"
13
13
  const { flatConfigSchema } = require("./flat-config-schema");
14
14
  const { RuleValidator } = require("./rule-validator");
15
15
  const { defaultConfig } = require("./default-config");
16
- const recommendedConfig = require("../../conf/eslint-recommended");
16
+ const jsPlugin = require("@eslint/js");
17
17
 
18
18
  //-----------------------------------------------------------------------------
19
19
  // Helpers
@@ -36,6 +36,45 @@ function splitPluginIdentifier(identifier) {
36
36
  };
37
37
  }
38
38
 
39
+ /**
40
+ * Returns the name of an object in the config by reading its `meta` key.
41
+ * @param {Object} object The object to check.
42
+ * @returns {string?} The name of the object if found or `null` if there
43
+ * is no name.
44
+ */
45
+ function getObjectId(object) {
46
+
47
+ // first check old-style name
48
+ let name = object.name;
49
+
50
+ if (!name) {
51
+
52
+ if (!object.meta) {
53
+ return null;
54
+ }
55
+
56
+ name = object.meta.name;
57
+
58
+ if (!name) {
59
+ return null;
60
+ }
61
+ }
62
+
63
+ // now check for old-style version
64
+ let version = object.version;
65
+
66
+ if (!version) {
67
+ version = object.meta && object.meta.version;
68
+ }
69
+
70
+ // if there's a version then append that
71
+ if (version) {
72
+ return `${name}@${version}`;
73
+ }
74
+
75
+ return name;
76
+ }
77
+
39
78
  const originalBaseConfig = Symbol("originalBaseConfig");
40
79
 
41
80
  //-----------------------------------------------------------------------------
@@ -96,17 +135,23 @@ class FlatConfigArray extends ConfigArray {
96
135
  */
97
136
  [ConfigArraySymbol.preprocessConfig](config) {
98
137
  if (config === "eslint:recommended") {
99
- return recommendedConfig;
138
+
139
+ // if we are in a Node.js environment warn the user
140
+ if (typeof process !== "undefined" && process.emitWarning) {
141
+ process.emitWarning("The 'eslint:recommended' string configuration is deprecated and will be replaced by the @eslint/js package's 'recommended' config.");
142
+ }
143
+
144
+ return jsPlugin.configs.recommended;
100
145
  }
101
146
 
102
147
  if (config === "eslint:all") {
103
148
 
104
- /*
105
- * Load `eslint-all.js` here instead of at the top level to avoid loading all rule modules
106
- * when it isn't necessary. `eslint-all.js` reads `meta` of rule objects to filter out deprecated ones,
107
- * so requiring `eslint-all.js` module loads all rule modules as a consequence.
108
- */
109
- return require("../../conf/eslint-all");
149
+ // if we are in a Node.js environment warn the user
150
+ if (typeof process !== "undefined" && process.emitWarning) {
151
+ process.emitWarning("The 'eslint:all' string configuration is deprecated and will be replaced by the @eslint/js package's 'all' config.");
152
+ }
153
+
154
+ return jsPlugin.configs.all;
110
155
  }
111
156
 
112
157
  /*
@@ -145,16 +190,15 @@ class FlatConfigArray extends ConfigArray {
145
190
 
146
191
  // Check parser value
147
192
  if (languageOptions && languageOptions.parser) {
148
- if (typeof languageOptions.parser === "string") {
149
- const { pluginName, objectName: localParserName } = splitPluginIdentifier(languageOptions.parser);
193
+ const { parser } = languageOptions;
150
194
 
151
- parserName = languageOptions.parser;
195
+ if (typeof parser === "object") {
196
+ parserName = getObjectId(parser);
152
197
 
153
- if (!plugins || !plugins[pluginName] || !plugins[pluginName].parsers || !plugins[pluginName].parsers[localParserName]) {
154
- throw new TypeError(`Key "parser": Could not find "${localParserName}" in plugin "${pluginName}".`);
198
+ if (!parserName) {
199
+ invalidParser = true;
155
200
  }
156
201
 
157
- languageOptions.parser = plugins[pluginName].parsers[localParserName];
158
202
  } else {
159
203
  invalidParser = true;
160
204
  }
@@ -172,6 +216,13 @@ class FlatConfigArray extends ConfigArray {
172
216
  }
173
217
 
174
218
  config.processor = plugins[pluginName].processors[localProcessorName];
219
+ } else if (typeof processor === "object") {
220
+ processorName = getObjectId(processor);
221
+
222
+ if (!processorName) {
223
+ invalidProcessor = true;
224
+ }
225
+
175
226
  } else {
176
227
  invalidProcessor = true;
177
228
  }
@@ -185,16 +236,25 @@ class FlatConfigArray extends ConfigArray {
185
236
  value: function() {
186
237
 
187
238
  if (invalidParser) {
188
- throw new Error("Caching is not supported when parser is an object.");
239
+ throw new Error("Could not serialize parser object (missing 'meta' object).");
189
240
  }
190
241
 
191
242
  if (invalidProcessor) {
192
- throw new Error("Caching is not supported when processor is an object.");
243
+ throw new Error("Could not serialize processor object (missing 'meta' object).");
193
244
  }
194
245
 
195
246
  return {
196
247
  ...this,
197
- plugins: Object.keys(plugins),
248
+ plugins: Object.entries(plugins).map(([namespace, plugin]) => {
249
+
250
+ const pluginId = getObjectId(plugin);
251
+
252
+ if (!pluginId) {
253
+ return namespace;
254
+ }
255
+
256
+ return `${namespace}:${pluginId}`;
257
+ }),
198
258
  languageOptions: {
199
259
  ...languageOptions,
200
260
  parser: parserName
@@ -179,18 +179,6 @@ function assertIsObject(value) {
179
179
  }
180
180
  }
181
181
 
182
- /**
183
- * Validates that a value is an object or a string.
184
- * @param {any} value The value to check.
185
- * @returns {void}
186
- * @throws {TypeError} If the value isn't an object or a string.
187
- */
188
- function assertIsObjectOrString(value) {
189
- if ((!value || typeof value !== "object") && typeof value !== "string") {
190
- throw new TypeError("Expected an object or string.");
191
- }
192
- }
193
-
194
182
  //-----------------------------------------------------------------------------
195
183
  // Low-Level Schemas
196
184
  //-----------------------------------------------------------------------------
@@ -242,15 +230,13 @@ const globalsSchema = {
242
230
  const parserSchema = {
243
231
  merge: "replace",
244
232
  validate(value) {
245
- assertIsObjectOrString(value);
246
233
 
247
- if (typeof value === "object" && typeof value.parse !== "function" && typeof value.parseForESLint !== "function") {
248
- throw new TypeError("Expected object to have a parse() or parseForESLint() method.");
234
+ if (!value || typeof value !== "object" ||
235
+ (typeof value.parse !== "function" && typeof value.parseForESLint !== "function")
236
+ ) {
237
+ throw new TypeError("Expected object with parse() or parseForESLint() method.");
249
238
  }
250
239
 
251
- if (typeof value === "string") {
252
- assertIsPluginMemberName(value);
253
- }
254
240
  }
255
241
  };
256
242
 
@@ -223,7 +223,7 @@ function globMatch({ basePath, pattern }) {
223
223
  * should be thrown when a pattern is unmatched.
224
224
  * @returns {Promise<Array<string>>} An array of matching file paths
225
225
  * or an empty array if there are no matches.
226
- * @throws {UnmatchedSearchPatternsErrror} If there is a pattern that doesn't
226
+ * @throws {UnmatchedSearchPatternsError} If there is a pattern that doesn't
227
227
  * match any files.
228
228
  */
229
229
  async function globSearch({
@@ -526,9 +526,9 @@ async function findFiles({
526
526
  }
527
527
 
528
528
  // save patterns for later use based on whether globs are enabled
529
- if (globInputPaths && isGlobPattern(filePath)) {
529
+ if (globInputPaths && isGlobPattern(pattern)) {
530
530
 
531
- const basePath = globParent(filePath);
531
+ const basePath = path.resolve(cwd, globParent(pattern));
532
532
 
533
533
  // group in cwd if possible and split out others
534
534
  if (isPathInside(basePath, cwd)) {
@@ -857,63 +857,6 @@ function parse(text, languageOptions, filePath) {
857
857
  }
858
858
  }
859
859
 
860
- /**
861
- * Gets the scope for the current node
862
- * @param {ScopeManager} scopeManager The scope manager for this AST
863
- * @param {ASTNode} currentNode The node to get the scope of
864
- * @returns {eslint-scope.Scope} The scope information for this node
865
- */
866
- function getScope(scopeManager, currentNode) {
867
-
868
- // On Program node, get the outermost scope to avoid return Node.js special function scope or ES modules scope.
869
- const inner = currentNode.type !== "Program";
870
-
871
- for (let node = currentNode; node; node = node.parent) {
872
- const scope = scopeManager.acquire(node, inner);
873
-
874
- if (scope) {
875
- if (scope.type === "function-expression-name") {
876
- return scope.childScopes[0];
877
- }
878
- return scope;
879
- }
880
- }
881
-
882
- return scopeManager.scopes[0];
883
- }
884
-
885
- /**
886
- * Marks a variable as used in the current scope
887
- * @param {ScopeManager} scopeManager The scope manager for this AST. The scope may be mutated by this function.
888
- * @param {ASTNode} currentNode The node currently being traversed
889
- * @param {LanguageOptions} languageOptions The options used to parse this text
890
- * @param {string} name The name of the variable that should be marked as used.
891
- * @returns {boolean} True if the variable was found and marked as used, false if not.
892
- */
893
- function markVariableAsUsed(scopeManager, currentNode, languageOptions, name) {
894
- const parserOptions = languageOptions.parserOptions;
895
- const sourceType = languageOptions.sourceType;
896
- const hasGlobalReturn =
897
- (parserOptions.ecmaFeatures && parserOptions.ecmaFeatures.globalReturn) ||
898
- sourceType === "commonjs";
899
- const specialScope = hasGlobalReturn || sourceType === "module";
900
- const currentScope = getScope(scopeManager, currentNode);
901
-
902
- // Special Node.js scope means we need to start one level deeper
903
- const initialScope = currentScope.type === "global" && specialScope ? currentScope.childScopes[0] : currentScope;
904
-
905
- for (let scope = initialScope; scope; scope = scope.upper) {
906
- const variable = scope.variables.find(scopeVar => scopeVar.name === name);
907
-
908
- if (variable) {
909
- variable.eslintUsed = true;
910
- return true;
911
- }
912
- }
913
-
914
- return false;
915
- }
916
-
917
860
  /**
918
861
  * Runs a rule, and gets its listeners
919
862
  * @param {Rule} rule A normalized rule with a `create` method
@@ -930,22 +873,6 @@ function createRuleListeners(rule, ruleContext) {
930
873
  }
931
874
  }
932
875
 
933
- /**
934
- * Gets all the ancestors of a given node
935
- * @param {ASTNode} node The node
936
- * @returns {ASTNode[]} All the ancestor nodes in the AST, not including the provided node, starting
937
- * from the root node and going inwards to the parent node.
938
- */
939
- function getAncestors(node) {
940
- const ancestorsStartingAtParent = [];
941
-
942
- for (let ancestor = node.parent; ancestor; ancestor = ancestor.parent) {
943
- ancestorsStartingAtParent.push(ancestor);
944
- }
945
-
946
- return ancestorsStartingAtParent.reverse();
947
- }
948
-
949
876
  // methods that exist on SourceCode object
950
877
  const DEPRECATED_SOURCECODE_PASSTHROUGHS = {
951
878
  getSource: "getText",
@@ -1021,14 +948,14 @@ function runRules(sourceCode, configuredRules, ruleMapper, parserName, languageO
1021
948
  Object.assign(
1022
949
  Object.create(BASE_TRAVERSAL_CONTEXT),
1023
950
  {
1024
- getAncestors: () => getAncestors(currentNode),
1025
- getDeclaredVariables: sourceCode.scopeManager.getDeclaredVariables.bind(sourceCode.scopeManager),
951
+ getAncestors: () => sourceCode.getAncestors(currentNode),
952
+ getDeclaredVariables: node => sourceCode.getDeclaredVariables(node),
1026
953
  getCwd: () => cwd,
1027
954
  getFilename: () => filename,
1028
955
  getPhysicalFilename: () => physicalFilename || filename,
1029
- getScope: () => getScope(sourceCode.scopeManager, currentNode),
956
+ getScope: () => sourceCode.getScope(currentNode),
1030
957
  getSourceCode: () => sourceCode,
1031
- markVariableAsUsed: name => markVariableAsUsed(sourceCode.scopeManager, currentNode, languageOptions, name),
958
+ markVariableAsUsed: name => sourceCode.markVariableAsUsed(name, currentNode),
1032
959
  parserOptions: {
1033
960
  ...languageOptions.parserOptions
1034
961
  },
@@ -345,7 +345,7 @@ class FlatRuleTester {
345
345
  * @returns {void}
346
346
  */
347
347
  static setDefaultConfig(config) {
348
- if (typeof config !== "object") {
348
+ if (typeof config !== "object" || config === null) {
349
349
  throw new TypeError("FlatRuleTester.setDefaultConfig: config must be an object");
350
350
  }
351
351
  sharedDefaultConfig = config;
@@ -412,7 +412,7 @@ class RuleTester {
412
412
  * @returns {void}
413
413
  */
414
414
  static setDefaultConfig(config) {
415
- if (typeof config !== "object") {
415
+ if (typeof config !== "object" || config === null) {
416
416
  throw new TypeError("RuleTester.setDefaultConfig: config must be an object");
417
417
  }
418
418
  defaultConfig = config;
@@ -28,6 +28,7 @@ module.exports = {
28
28
 
29
29
  create(context) {
30
30
  let stack = [];
31
+ const sourceCode = context.getSourceCode();
31
32
 
32
33
  /**
33
34
  * Makes a block scope.
@@ -83,7 +84,7 @@ module.exports = {
83
84
  }
84
85
 
85
86
  // Gets declared variables, and checks its references.
86
- const variables = context.getDeclaredVariables(node);
87
+ const variables = sourceCode.getDeclaredVariables(node);
87
88
 
88
89
  for (let i = 0; i < variables.length; ++i) {
89
90
 
@@ -73,6 +73,7 @@ module.exports = {
73
73
  const ignoreImports = options.ignoreImports;
74
74
  const ignoreGlobals = options.ignoreGlobals;
75
75
  const allow = options.allow || [];
76
+ const sourceCode = context.getSourceCode();
76
77
 
77
78
  //--------------------------------------------------------------------------
78
79
  // Helpers
@@ -245,8 +246,8 @@ module.exports = {
245
246
  return {
246
247
 
247
248
  // Report camelcase of global variable references ------------------
248
- Program() {
249
- const scope = context.getScope();
249
+ Program(node) {
250
+ const scope = sourceCode.getScope(node);
250
251
 
251
252
  if (!ignoreGlobals) {
252
253
 
@@ -295,7 +296,7 @@ module.exports = {
295
296
  "ClassExpression",
296
297
  "CatchClause"
297
298
  ]](node) {
298
- for (const variable of context.getDeclaredVariables(node)) {
299
+ for (const variable of sourceCode.getDeclaredVariables(node)) {
299
300
  if (isGoodName(variable.name)) {
300
301
  continue;
301
302
  }
@@ -345,7 +346,7 @@ module.exports = {
345
346
 
346
347
  // Report camelcase in import --------------------------------------
347
348
  ImportDeclaration(node) {
348
- for (const variable of context.getDeclaredVariables(node)) {
349
+ for (const variable of sourceCode.getDeclaredVariables(node)) {
349
350
  if (isGoodName(variable.name)) {
350
351
  continue;
351
352
  }
@@ -36,6 +36,7 @@ module.exports = {
36
36
 
37
37
  create(context) {
38
38
  let aliases = [];
39
+ const sourceCode = context.getSourceCode();
39
40
 
40
41
  if (context.options.length === 0) {
41
42
  aliases.push("that");
@@ -115,10 +116,11 @@ module.exports = {
115
116
 
116
117
  /**
117
118
  * Check each alias to ensure that is was assigned to the correct value.
119
+ * @param {ASTNode} node The node that represents the scope to check.
118
120
  * @returns {void}
119
121
  */
120
- function ensureWasAssigned() {
121
- const scope = context.getScope();
122
+ function ensureWasAssigned(node) {
123
+ const scope = sourceCode.getScope(node);
122
124
 
123
125
  aliases.forEach(alias => {
124
126
  checkWasAssigned(alias, scope);
@@ -159,7 +159,7 @@ module.exports = {
159
159
  function handleFunction(node) {
160
160
 
161
161
  // Skip recursive functions.
162
- const nameVar = context.getDeclaredVariables(node)[0];
162
+ const nameVar = sourceCode.getDeclaredVariables(node)[0];
163
163
 
164
164
  if (isFunctionName(nameVar) && nameVar.references.length > 0) {
165
165
  return;
@@ -71,12 +71,14 @@ module.exports = {
71
71
  },
72
72
 
73
73
  create(context) {
74
+ const sourceCode = context.getSourceCode();
75
+
74
76
  return {
75
77
  CallExpression(node) {
76
- const currentScope = context.getScope();
78
+ const currentScope = sourceCode.getScope(node);
77
79
 
78
80
  if (node.callee.name === "require" && !isShadowed(currentScope, node.callee)) {
79
- const isGoodRequire = context.getAncestors().every(parent => ACCEPTABLE_PARENTS.has(parent.type));
81
+ const isGoodRequire = sourceCode.getAncestors(node).every(parent => ACCEPTABLE_PARENTS.has(parent.type));
80
82
 
81
83
  if (!isGoodRequire) {
82
84
  context.report({ node, messageId: "unexpected" });
@@ -38,6 +38,7 @@ module.exports = {
38
38
  create(context) {
39
39
 
40
40
  const errorArgument = context.options[0] || "err";
41
+ const sourceCode = context.getSourceCode();
41
42
 
42
43
  /**
43
44
  * Checks if the given argument should be interpreted as a regexp pattern.
@@ -79,7 +80,7 @@ module.exports = {
79
80
  * @returns {void}
80
81
  */
81
82
  function checkForError(node) {
82
- const scope = context.getScope(),
83
+ const scope = sourceCode.getScope(node),
83
84
  parameters = getParameters(scope),
84
85
  firstParameter = parameters[0];
85
86
 
@@ -140,6 +140,7 @@ module.exports = {
140
140
 
141
141
  const denyList = new Set(context.options);
142
142
  const reportedNodes = new Set();
143
+ const sourceCode = context.getSourceCode();
143
144
 
144
145
  let globalScope;
145
146
 
@@ -231,8 +232,8 @@ module.exports = {
231
232
 
232
233
  return {
233
234
 
234
- Program() {
235
- globalScope = context.getScope();
235
+ Program(node) {
236
+ globalScope = sourceCode.getScope(node);
236
237
  },
237
238
 
238
239
  Identifier(node) {