eslint 9.11.1 → 9.13.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.
@@ -12,10 +12,10 @@
12
12
  const fs = require("node:fs/promises");
13
13
  const { existsSync } = require("node:fs");
14
14
  const path = require("node:path");
15
- const findUp = require("find-up");
16
15
  const { version } = require("../../package.json");
17
16
  const { Linter } = require("../linter");
18
17
  const { getRuleFromConfig } = require("../config/flat-config-helpers");
18
+ const { defaultConfig } = require("../config/default-config");
19
19
  const {
20
20
  Legacy: {
21
21
  ConfigOps: {
@@ -39,9 +39,9 @@ const {
39
39
  processOptions
40
40
  } = require("./eslint-helpers");
41
41
  const { pathToFileURL } = require("node:url");
42
- const { FlatConfigArray } = require("../config/flat-config-array");
43
42
  const LintResultCache = require("../cli-engine/lint-result-cache");
44
43
  const { Retrier } = require("@humanwhocodes/retry");
44
+ const { ConfigLoader, LegacyConfigLoader } = require("../config/config-loader");
45
45
 
46
46
  /*
47
47
  * This is necessary to allow overwriting writeFile for testing purposes.
@@ -53,6 +53,7 @@ const { Retrier } = require("@humanwhocodes/retry");
53
53
  //------------------------------------------------------------------------------
54
54
 
55
55
  // For VSCode IntelliSense
56
+ /** @typedef {import("../cli-engine/cli-engine").ConfigArray} ConfigArray */
56
57
  /** @typedef {import("../shared/types").ConfigData} ConfigData */
57
58
  /** @typedef {import("../shared/types").DeprecatedRuleInfo} DeprecatedRuleInfo */
58
59
  /** @typedef {import("../shared/types").LintMessage} LintMessage */
@@ -97,24 +98,8 @@ const { Retrier } = require("@humanwhocodes/retry");
97
98
  // Helpers
98
99
  //------------------------------------------------------------------------------
99
100
 
100
- const FLAT_CONFIG_FILENAMES = [
101
- "eslint.config.js",
102
- "eslint.config.mjs",
103
- "eslint.config.cjs"
104
- ];
105
- const FLAT_CONFIG_FILENAMES_WITH_TS = [
106
- ...FLAT_CONFIG_FILENAMES,
107
- "eslint.config.ts",
108
- "eslint.config.mts",
109
- "eslint.config.cts"
110
- ];
111
101
  const debug = require("debug")("eslint:eslint");
112
102
  const privateMembers = new WeakMap();
113
-
114
- /**
115
- * @type {Map<string, string>}
116
- */
117
- const importedConfigFileModificationTime = new Map();
118
103
  const removedFormatters = new Set([
119
104
  "checkstyle",
120
105
  "codeframe",
@@ -196,12 +181,13 @@ const usedDeprecatedRulesCache = new WeakMap();
196
181
  */
197
182
  function getOrFindUsedDeprecatedRules(eslint, maybeFilePath) {
198
183
  const {
199
- configs,
200
- options: { cwd }
184
+ options: { cwd },
185
+ configLoader
201
186
  } = privateMembers.get(eslint);
202
187
  const filePath = path.isAbsolute(maybeFilePath)
203
188
  ? maybeFilePath
204
189
  : getPlaceholderPath(cwd);
190
+ const configs = configLoader.getCachedConfigArrayForFile(filePath);
205
191
  const config = configs.getConfig(filePath);
206
192
 
207
193
  // Most files use the same config, so cache it.
@@ -270,269 +256,38 @@ function compareResultsByFilePath(a, b) {
270
256
  return 0;
271
257
  }
272
258
 
273
- /**
274
- * Searches from the current working directory up until finding the
275
- * given flat config filename.
276
- * @param {string} cwd The current working directory to search from.
277
- * @param {boolean} hasUnstableTSConfigFlag `true` if the `unstable_ts_config` flag is enabled, `false` if it's not.
278
- * @returns {Promise<string|undefined>} The filename if found or `undefined` if not.
279
- */
280
- function findFlatConfigFile(cwd, hasUnstableTSConfigFlag) {
281
- const filenames = hasUnstableTSConfigFlag ? FLAT_CONFIG_FILENAMES_WITH_TS : FLAT_CONFIG_FILENAMES;
282
-
283
- return findUp(
284
- filenames,
285
- { cwd }
286
- );
287
- }
288
-
289
- /**
290
- * Check if the file is a TypeScript file.
291
- * @param {string} filePath The file path to check.
292
- * @returns {boolean} `true` if the file is a TypeScript file, `false` if it's not.
293
- */
294
- function isFileTS(filePath) {
295
- const fileExtension = path.extname(filePath);
296
-
297
- return /^\.[mc]?ts$/u.test(fileExtension);
298
- }
299
-
300
- /**
301
- * Check if ESLint is running in Bun.
302
- * @returns {boolean} `true` if the ESLint is running Bun, `false` if it's not.
303
- */
304
- function isRunningInBun() {
305
- return !!globalThis.Bun;
306
- }
307
-
308
- /**
309
- * Check if ESLint is running in Deno.
310
- * @returns {boolean} `true` if the ESLint is running in Deno, `false` if it's not.
311
- */
312
- function isRunningInDeno() {
313
- return !!globalThis.Deno;
314
- }
315
-
316
- /**
317
- * Load the config array from the given filename.
318
- * @param {string} filePath The filename to load from.
319
- * @param {boolean} hasUnstableTSConfigFlag `true` if the `unstable_ts_config` flag is enabled, `false` if it's not.
320
- * @returns {Promise<any>} The config loaded from the config file.
321
- */
322
- async function loadFlatConfigFile(filePath, hasUnstableTSConfigFlag) {
323
- debug(`Loading config from ${filePath}`);
324
-
325
- const fileURL = pathToFileURL(filePath);
326
-
327
- debug(`Config file URL is ${fileURL}`);
328
-
329
- const mtime = (await fs.stat(filePath)).mtime.getTime().toString();
330
-
331
- /*
332
- * Append a query with the config file's modification time (`mtime`) in order
333
- * to import the current version of the config file. Without the query, `import()` would
334
- * cache the config file module by the pathname only, and then always return
335
- * the same version (the one that was actual when the module was imported for the first time).
336
- *
337
- * This ensures that the config file module is loaded and executed again
338
- * if it has been changed since the last time it was imported.
339
- * If it hasn't been changed, `import()` will just return the cached version.
340
- *
341
- * Note that we should not overuse queries (e.g., by appending the current time
342
- * to always reload the config file module) as that could cause memory leaks
343
- * because entries are never removed from the import cache.
344
- */
345
- fileURL.searchParams.append("mtime", mtime);
346
-
347
- /*
348
- * With queries, we can bypass the import cache. However, when import-ing a CJS module,
349
- * Node.js uses the require infrastructure under the hood. That includes the require cache,
350
- * which caches the config file module by its file path (queries have no effect).
351
- * Therefore, we also need to clear the require cache before importing the config file module.
352
- * In order to get the same behavior with ESM and CJS config files, in particular - to reload
353
- * the config file only if it has been changed, we track file modification times and clear
354
- * the require cache only if the file has been changed.
355
- */
356
- if (importedConfigFileModificationTime.get(filePath) !== mtime) {
357
- delete require.cache[filePath];
358
- }
359
-
360
- const isTS = isFileTS(filePath) && hasUnstableTSConfigFlag;
361
-
362
- const isBun = isRunningInBun();
363
-
364
- const isDeno = isRunningInDeno();
365
-
366
- if (isTS && !isDeno && !isBun) {
367
-
368
- const createJiti = await import("jiti").then(jitiModule => jitiModule.default, () => {
369
- throw new Error("The 'jiti' library is required for loading TypeScript configuration files. Make sure to install it.");
370
- });
371
-
372
- /*
373
- * Disabling `moduleCache` allows us to reload a
374
- * config file when the last modified timestamp changes.
375
- */
376
-
377
- const jiti = createJiti(__filename, { moduleCache: false });
378
-
379
- if (typeof jiti?.import !== "function") {
380
- throw new Error("You are using an outdated version of the 'jiti' library. Please update to the latest version of 'jiti' to ensure compatibility and access to the latest features.");
381
- }
382
-
383
- const config = await jiti.import(fileURL.href);
384
-
385
- importedConfigFileModificationTime.set(filePath, mtime);
386
-
387
- return config?.default ?? config;
388
- }
389
-
390
- const config = (await import(fileURL.href)).default;
391
-
392
- importedConfigFileModificationTime.set(filePath, mtime);
393
-
394
- return config;
395
- }
396
259
 
397
260
  /**
398
261
  * Determines which config file to use. This is determined by seeing if an
399
262
  * override config file was passed, and if so, using it; otherwise, as long
400
263
  * as override config file is not explicitly set to `false`, it will search
401
264
  * upwards from the cwd for a file named `eslint.config.js`.
265
+ *
266
+ * This function is used primarily by the `--inspect-config` option. For now,
267
+ * we will maintain the existing behavior, which is to search up from the cwd.
402
268
  * @param {ESLintOptions} options The ESLint instance options.
403
- * @param {boolean} hasUnstableTSConfigFlag `true` if the `unstable_ts_config` flag is enabled, `false` if it's not.
404
- * @returns {Promise<{configFilePath:string|undefined;basePath:string;error:Error|null}>} Location information for
269
+ * @param {boolean} allowTS `true` if the `unstable_ts_config` flag is enabled, `false` if it's not.
270
+ * @returns {Promise<{configFilePath:string|undefined;basePath:string}>} Location information for
405
271
  * the config file.
406
272
  */
407
- async function locateConfigFileToUse({ configFile, cwd }, hasUnstableTSConfigFlag) {
408
-
409
- // determine where to load config file from
410
- let configFilePath;
411
- let basePath = cwd;
412
- let error = null;
413
-
414
- if (typeof configFile === "string") {
415
- debug(`Override config file path is ${configFile}`);
416
- configFilePath = path.resolve(cwd, configFile);
417
- } else if (configFile !== false) {
418
- debug("Searching for eslint.config.js");
419
- configFilePath = await findFlatConfigFile(cwd, hasUnstableTSConfigFlag);
420
-
421
- if (configFilePath) {
422
- basePath = path.resolve(path.dirname(configFilePath));
423
- } else {
424
- error = new Error("Could not find config file.");
425
- error.messageTemplate = "config-file-missing";
426
- }
273
+ async function locateConfigFileToUse({ configFile, cwd }, allowTS) {
427
274
 
275
+ const configLoader = new ConfigLoader({
276
+ cwd,
277
+ allowTS,
278
+ configFile
279
+ });
280
+
281
+ const configFilePath = await configLoader.findConfigFileForPath(path.join(cwd, "__placeholder__.js"));
282
+
283
+ if (!configFilePath) {
284
+ throw new Error("No ESLint configuration file was found.");
428
285
  }
429
286
 
430
287
  return {
431
288
  configFilePath,
432
- basePath,
433
- error
289
+ basePath: configFile ? cwd : path.dirname(configFilePath)
434
290
  };
435
-
436
- }
437
-
438
- /**
439
- * Calculates the config array for this run based on inputs.
440
- * @param {ESLint} eslint The instance to create the config array for.
441
- * @param {ESLintOptions} options The ESLint instance options.
442
- * @returns {Promise<typeof FlatConfigArray>} The config array for `eslint``.
443
- */
444
- async function calculateConfigArray(eslint, {
445
- cwd,
446
- baseConfig,
447
- overrideConfig,
448
- configFile,
449
- ignore: shouldIgnore,
450
- ignorePatterns
451
- }) {
452
-
453
- // check for cached instance
454
- const slots = privateMembers.get(eslint);
455
-
456
- if (slots.configs) {
457
- return slots.configs;
458
- }
459
-
460
- const hasUnstableTSConfigFlag = eslint.hasFlag("unstable_ts_config");
461
-
462
- const { configFilePath, basePath, error } = await locateConfigFileToUse({ configFile, cwd }, hasUnstableTSConfigFlag);
463
-
464
- // config file is required to calculate config
465
- if (error) {
466
- throw error;
467
- }
468
-
469
- const configs = new FlatConfigArray(baseConfig || [], { basePath, shouldIgnore });
470
-
471
- // load config file
472
- if (configFilePath) {
473
- const fileConfig = await loadFlatConfigFile(configFilePath, hasUnstableTSConfigFlag);
474
-
475
- if (Array.isArray(fileConfig)) {
476
- configs.push(...fileConfig);
477
- } else {
478
- configs.push(fileConfig);
479
- }
480
- }
481
-
482
- // add in any configured defaults
483
- configs.push(...slots.defaultConfigs);
484
-
485
- // append command line ignore patterns
486
- if (ignorePatterns && ignorePatterns.length > 0) {
487
-
488
- let relativeIgnorePatterns;
489
-
490
- /*
491
- * If the config file basePath is different than the cwd, then
492
- * the ignore patterns won't work correctly. Here, we adjust the
493
- * ignore pattern to include the correct relative path. Patterns
494
- * passed as `ignorePatterns` are relative to the cwd, whereas
495
- * the config file basePath can be an ancestor of the cwd.
496
- */
497
- if (basePath === cwd) {
498
- relativeIgnorePatterns = ignorePatterns;
499
- } else {
500
-
501
- // In minimatch patterns, only `/` can be used as path separator
502
- const relativeIgnorePath = path.relative(basePath, cwd).replaceAll(path.sep, "/");
503
-
504
- relativeIgnorePatterns = ignorePatterns.map(pattern => {
505
- const negated = pattern.startsWith("!");
506
- const basePattern = negated ? pattern.slice(1) : pattern;
507
-
508
- return (negated ? "!" : "") +
509
- path.posix.join(relativeIgnorePath, basePattern);
510
- });
511
- }
512
-
513
- /*
514
- * Ignore patterns are added to the end of the config array
515
- * so they can override default ignores.
516
- */
517
- configs.push({
518
- ignores: relativeIgnorePatterns
519
- });
520
- }
521
-
522
- if (overrideConfig) {
523
- if (Array.isArray(overrideConfig)) {
524
- configs.push(...overrideConfig);
525
- } else {
526
- configs.push(overrideConfig);
527
- }
528
- }
529
-
530
- await configs.normalize();
531
-
532
- // cache the config array for this instance
533
- slots.configs = configs;
534
-
535
- return configs;
536
291
  }
537
292
 
538
293
  /**
@@ -678,6 +433,12 @@ class ESLint {
678
433
  */
679
434
  static configType = "flat";
680
435
 
436
+ /**
437
+ * The loader to use for finding config files.
438
+ * @type {ConfigLoader|LegacyConfigLoader}
439
+ */
440
+ #configLoader;
441
+
681
442
  /**
682
443
  * Creates a new instance of the main ESLint API.
683
444
  * @param {ESLintOptions} options The options for this instance.
@@ -701,15 +462,34 @@ class ESLint {
701
462
  ? new LintResultCache(cacheFilePath, processedOptions.cacheStrategy)
702
463
  : null;
703
464
 
465
+ const configLoaderOptions = {
466
+ cwd: processedOptions.cwd,
467
+ baseConfig: processedOptions.baseConfig,
468
+ overrideConfig: processedOptions.overrideConfig,
469
+ configFile: processedOptions.configFile,
470
+ ignoreEnabled: processedOptions.ignore,
471
+ ignorePatterns: processedOptions.ignorePatterns,
472
+ defaultConfigs,
473
+ allowTS: processedOptions.flags.includes("unstable_ts_config")
474
+ };
475
+
476
+ this.#configLoader = processedOptions.flags.includes("unstable_config_lookup_from_file")
477
+ ? new ConfigLoader(configLoaderOptions)
478
+ : new LegacyConfigLoader(configLoaderOptions);
479
+
480
+ debug(`Using config loader ${this.#configLoader.constructor.name}`);
481
+
704
482
  privateMembers.set(this, {
705
483
  options: processedOptions,
706
484
  linter,
707
485
  cacheFilePath,
708
486
  lintResultCache,
709
487
  defaultConfigs,
710
- configs: null
488
+ configs: null,
489
+ configLoader: this.#configLoader
711
490
  });
712
491
 
492
+
713
493
  /**
714
494
  * If additional plugins are passed in, add that to the default
715
495
  * configs for this instance.
@@ -744,6 +524,15 @@ class ESLint {
744
524
  return version;
745
525
  }
746
526
 
527
+ /**
528
+ * The default configuration that ESLint uses internally. This is provided for tooling that wants to calculate configurations using the same defaults as ESLint.
529
+ * Keep in mind that the default configuration may change from version to version, so you shouldn't rely on any particular keys or values to be present.
530
+ * @type {ConfigArray}
531
+ */
532
+ static get defaultConfig() {
533
+ return defaultConfig;
534
+ }
535
+
747
536
  /**
748
537
  * Outputs fixes from the given results to files.
749
538
  * @param {LintResult[]} results The lint results.
@@ -813,20 +602,10 @@ class ESLint {
813
602
 
814
603
  const resultRules = new Map();
815
604
  const {
816
- configs,
605
+ configLoader,
817
606
  options: { cwd }
818
607
  } = privateMembers.get(this);
819
608
 
820
- /*
821
- * We can only accurately return rules meta information for linting results if the
822
- * results were created by this instance. Otherwise, the necessary rules data is
823
- * not available. So if the config array doesn't already exist, just throw an error
824
- * to let the user know we can't do anything here.
825
- */
826
- if (!configs) {
827
- throw createExtraneousResultsError();
828
- }
829
-
830
609
  for (const result of results) {
831
610
 
832
611
  /*
@@ -845,6 +624,14 @@ class ESLint {
845
624
  * All of the plugin and rule information is contained within the
846
625
  * calculated config for the given file.
847
626
  */
627
+ let configs;
628
+
629
+ try {
630
+ configs = configLoader.getCachedConfigArrayForFile(filePath);
631
+ } catch {
632
+ throw createExtraneousResultsError();
633
+ }
634
+
848
635
  const config = configs.getConfig(filePath);
849
636
 
850
637
  if (!config) {
@@ -919,7 +706,6 @@ class ESLint {
919
706
 
920
707
  debug(`Using file patterns: ${normalizedPatterns}`);
921
708
 
922
- const configs = await calculateConfigArray(this, eslintOptions);
923
709
  const {
924
710
  allowInlineConfig,
925
711
  cache,
@@ -955,7 +741,7 @@ class ESLint {
955
741
  patterns: normalizedPatterns,
956
742
  cwd,
957
743
  globInputPaths,
958
- configs,
744
+ configLoader: this.#configLoader,
959
745
  errorOnUnmatchedPattern
960
746
  });
961
747
  const controller = new AbortController();
@@ -972,8 +758,9 @@ class ESLint {
972
758
  */
973
759
  const results = await Promise.all(
974
760
 
975
- filePaths.map(filePath => {
761
+ filePaths.map(async filePath => {
976
762
 
763
+ const configs = await this.#configLoader.loadConfigArrayForFile(filePath);
977
764
  const config = configs.getConfig(filePath);
978
765
 
979
766
  /*
@@ -1111,7 +898,6 @@ class ESLint {
1111
898
  linter,
1112
899
  options: eslintOptions
1113
900
  } = privateMembers.get(this);
1114
- const configs = await calculateConfigArray(this, eslintOptions);
1115
901
  const {
1116
902
  allowInlineConfig,
1117
903
  cwd,
@@ -1125,21 +911,21 @@ class ESLint {
1125
911
  const startTime = Date.now();
1126
912
  const fixTypesSet = fixTypes ? new Set(fixTypes) : null;
1127
913
  const resolvedFilename = path.resolve(cwd, filePath || "__placeholder__.js");
1128
- const config = configs.getConfig(resolvedFilename);
1129
-
1130
- const fixer = getFixerForFixTypes(fix, fixTypesSet, config);
914
+ const configs = await this.#configLoader.loadConfigArrayForFile(resolvedFilename);
915
+ const configStatus = configs?.getConfigStatus(resolvedFilename) ?? "unconfigured";
1131
916
 
1132
917
  // Clear the last used config arrays.
1133
- if (resolvedFilename && await this.isPathIgnored(resolvedFilename)) {
918
+ if (resolvedFilename && configStatus !== "matched") {
1134
919
  const shouldWarnIgnored = typeof warnIgnored === "boolean" ? warnIgnored : constructorWarnIgnored;
1135
920
 
1136
921
  if (shouldWarnIgnored) {
1137
- const configStatus = configs.getConfigStatus(resolvedFilename);
1138
-
1139
922
  results.push(createIgnoreResult(resolvedFilename, cwd, configStatus));
1140
923
  }
1141
924
  } else {
1142
925
 
926
+ const config = configs.getConfig(resolvedFilename);
927
+ const fixer = getFixerForFixTypes(fix, fixTypesSet, config);
928
+
1143
929
  // Do lint.
1144
930
  results.push(verifyText({
1145
931
  text: code,
@@ -1271,7 +1057,14 @@ class ESLint {
1271
1057
  }
1272
1058
  const options = privateMembers.get(this).options;
1273
1059
  const absolutePath = path.resolve(options.cwd, filePath);
1274
- const configs = await calculateConfigArray(this, options);
1060
+ const configs = await this.#configLoader.loadConfigArrayForFile(absolutePath);
1061
+
1062
+ if (!configs) {
1063
+ const error = new Error("Could not find config file.");
1064
+
1065
+ error.messageTemplate = "config-file-missing";
1066
+ throw error;
1067
+ }
1275
1068
 
1276
1069
  return configs.getConfig(absolutePath);
1277
1070
  }
@@ -1279,14 +1072,22 @@ class ESLint {
1279
1072
  /**
1280
1073
  * Finds the config file being used by this instance based on the options
1281
1074
  * passed to the constructor.
1075
+ * @param {string} [filePath] The path of the file to find the config file for.
1282
1076
  * @returns {Promise<string|undefined>} The path to the config file being used or
1283
1077
  * `undefined` if no config file is being used.
1284
1078
  */
1285
- async findConfigFile() {
1079
+ findConfigFile(filePath) {
1286
1080
  const options = privateMembers.get(this).options;
1287
- const { configFilePath } = await locateConfigFileToUse(options, this.hasFlag("unstable_ts_config"));
1288
1081
 
1289
- return configFilePath;
1082
+ /*
1083
+ * Because the new config lookup scheme skips the current directory
1084
+ * and looks into the parent directories, we need to use a placeholder
1085
+ * directory to ensure the file in cwd is checked.
1086
+ */
1087
+ const fakeCwd = path.join(options.cwd, "__placeholder__");
1088
+
1089
+ return this.#configLoader.findConfigFileForPath(filePath ?? fakeCwd)
1090
+ .catch(() => void 0);
1290
1091
  }
1291
1092
 
1292
1093
  /**
@@ -12,6 +12,7 @@
12
12
  const { SourceCode } = require("./source-code");
13
13
  const createDebug = require("debug");
14
14
  const astUtils = require("../../shared/ast-utils");
15
+ const espree = require("espree");
15
16
  const eslintScope = require("eslint-scope");
16
17
  const evk = require("eslint-visitor-keys");
17
18
  const { validateLanguageOptions } = require("./validate-language-options");
@@ -69,6 +70,13 @@ module.exports = {
69
70
  nodeTypeKey: "type",
70
71
  visitorKeys: evk.KEYS,
71
72
 
73
+ defaultLanguageOptions: {
74
+ sourceType: "module",
75
+ ecmaVersion: "latest",
76
+ parser: espree,
77
+ parserOptions: {}
78
+ },
79
+
72
80
  validateLanguageOptions,
73
81
 
74
82
  /**
@@ -1643,29 +1643,26 @@ class Linter {
1643
1643
  const options = normalizeVerifyOptions(providedOptions, config);
1644
1644
  const languageOptions = config.languageOptions;
1645
1645
 
1646
- languageOptions.ecmaVersion = normalizeEcmaVersionForLanguageOptions(
1647
- languageOptions.ecmaVersion
1648
- );
1649
-
1650
- // double check that there is a parser to avoid mysterious error messages
1651
- if (!languageOptions.parser) {
1652
- throw new TypeError(`No parser specified for ${options.filename}`);
1653
- }
1646
+ if (config.language === jslang) {
1647
+ languageOptions.ecmaVersion = normalizeEcmaVersionForLanguageOptions(
1648
+ languageOptions.ecmaVersion
1649
+ );
1654
1650
 
1655
- // Espree expects this information to be passed in
1656
- if (isEspree(languageOptions.parser)) {
1657
- const parserOptions = languageOptions.parserOptions;
1651
+ // Espree expects this information to be passed in
1652
+ if (isEspree(languageOptions.parser)) {
1653
+ const parserOptions = languageOptions.parserOptions;
1658
1654
 
1659
- if (languageOptions.sourceType) {
1655
+ if (languageOptions.sourceType) {
1660
1656
 
1661
- parserOptions.sourceType = languageOptions.sourceType;
1657
+ parserOptions.sourceType = languageOptions.sourceType;
1662
1658
 
1663
- if (
1664
- parserOptions.sourceType === "module" &&
1665
- parserOptions.ecmaFeatures &&
1666
- parserOptions.ecmaFeatures.globalReturn
1667
- ) {
1668
- parserOptions.ecmaFeatures.globalReturn = false;
1659
+ if (
1660
+ parserOptions.sourceType === "module" &&
1661
+ parserOptions.ecmaFeatures &&
1662
+ parserOptions.ecmaFeatures.globalReturn
1663
+ ) {
1664
+ parserOptions.ecmaFeatures.globalReturn = false;
1665
+ }
1669
1666
  }
1670
1667
  }
1671
1668
  }