eslint 9.9.1 → 9.11.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.
@@ -17,9 +17,6 @@ const
17
17
  espree = require("espree"),
18
18
  merge = require("lodash.merge"),
19
19
  pkg = require("../../package.json"),
20
- {
21
- directivesPattern
22
- } = require("../shared/directives"),
23
20
  {
24
21
  Legacy: {
25
22
  ConfigOps,
@@ -30,7 +27,7 @@ const
30
27
  Traverser = require("../shared/traverser"),
31
28
  { SourceCode } = require("../languages/js/source-code"),
32
29
  applyDisableDirectives = require("./apply-disable-directives"),
33
- ConfigCommentParser = require("./config-comment-parser"),
30
+ { ConfigCommentParser } = require("@eslint/plugin-kit"),
34
31
  NodeEventGenerator = require("./node-event-generator"),
35
32
  createReportTranslator = require("./report-translator"),
36
33
  Rules = require("./rules"),
@@ -56,6 +53,8 @@ const parserSymbol = Symbol.for("eslint.RuleTester.parser");
56
53
  const { LATEST_ECMA_VERSION } = require("../../conf/ecma-version");
57
54
  const { VFile } = require("./vfile");
58
55
  const { ParserService } = require("../services/parser-service");
56
+ const { FileContext } = require("./file-context");
57
+ const { ProcessorService } = require("../services/processor-service");
59
58
  const STEP_KIND_VISIT = 1;
60
59
  const STEP_KIND_CALL = 2;
61
60
 
@@ -334,7 +333,7 @@ function createDisableDirectives({ type, value, justification, node }, ruleMappe
334
333
  directives: [], // valid disable directives
335
334
  directiveProblems: [] // problems in directives
336
335
  };
337
- const parentDirective = { node, ruleIds };
336
+ const parentDirective = { node, value, ruleIds };
338
337
 
339
338
  for (const ruleId of directiveRules) {
340
339
 
@@ -402,15 +401,20 @@ function getDirectiveComments(sourceCode, ruleMapper, warnInlineConfig, config)
402
401
  });
403
402
 
404
403
  sourceCode.getInlineConfigNodes().filter(token => token.type !== "Shebang").forEach(comment => {
405
- const { directivePart, justificationPart } = commentParser.extractDirectiveComment(comment.value);
406
404
 
407
- const match = directivesPattern.exec(directivePart);
405
+ const directive = commentParser.parseDirective(comment.value);
408
406
 
409
- if (!match) {
407
+ if (!directive) {
410
408
  return;
411
409
  }
412
- const directiveText = match[1];
413
- const lineCommentSupported = /^eslint-disable-(next-)?line$/u.test(directiveText);
410
+
411
+ const {
412
+ label,
413
+ value,
414
+ justification: justificationPart
415
+ } = directive;
416
+
417
+ const lineCommentSupported = /^eslint-disable-(next-)?line$/u.test(label);
414
418
 
415
419
  if (comment.type === "Line" && !lineCommentSupported) {
416
420
  return;
@@ -419,7 +423,7 @@ function getDirectiveComments(sourceCode, ruleMapper, warnInlineConfig, config)
419
423
  const loc = sourceCode.getLoc(comment);
420
424
 
421
425
  if (warnInlineConfig) {
422
- const kind = comment.type === "Block" ? `/*${directiveText}*/` : `//${directiveText}`;
426
+ const kind = comment.type === "Block" ? `/*${label}*/` : `//${label}`;
423
427
 
424
428
  problems.push(createLintingProblem({
425
429
  ruleId: null,
@@ -430,8 +434,8 @@ function getDirectiveComments(sourceCode, ruleMapper, warnInlineConfig, config)
430
434
  return;
431
435
  }
432
436
 
433
- if (directiveText === "eslint-disable-line" && loc.start.line !== loc.end.line) {
434
- const message = `${directiveText} comment should not span multiple lines.`;
437
+ if (label === "eslint-disable-line" && loc.start.line !== loc.end.line) {
438
+ const message = `${label} comment should not span multiple lines.`;
435
439
 
436
440
  problems.push(createLintingProblem({
437
441
  ruleId: null,
@@ -441,17 +445,15 @@ function getDirectiveComments(sourceCode, ruleMapper, warnInlineConfig, config)
441
445
  return;
442
446
  }
443
447
 
444
- const directiveValue = directivePart.slice(match.index + directiveText.length);
445
-
446
- switch (directiveText) {
448
+ switch (label) {
447
449
  case "eslint-disable":
448
450
  case "eslint-enable":
449
451
  case "eslint-disable-next-line":
450
452
  case "eslint-disable-line": {
451
- const directiveType = directiveText.slice("eslint-".length);
453
+ const directiveType = label.slice("eslint-".length);
452
454
  const { directives, directiveProblems } = createDisableDirectives({
453
455
  type: directiveType,
454
- value: directiveValue,
456
+ value,
455
457
  justification: justificationPart,
456
458
  node: comment
457
459
  }, ruleMapper, jslang, sourceCode);
@@ -462,16 +464,16 @@ function getDirectiveComments(sourceCode, ruleMapper, warnInlineConfig, config)
462
464
  }
463
465
 
464
466
  case "exported":
465
- Object.assign(exportedVariables, commentParser.parseListConfig(directiveValue, comment));
467
+ Object.assign(exportedVariables, commentParser.parseListConfig(value));
466
468
  break;
467
469
 
468
470
  case "globals":
469
471
  case "global":
470
- for (const [id, { value }] of Object.entries(commentParser.parseStringConfig(directiveValue, comment))) {
472
+ for (const [id, idSetting] of Object.entries(commentParser.parseStringConfig(value))) {
471
473
  let normalizedValue;
472
474
 
473
475
  try {
474
- normalizedValue = ConfigOps.normalizeConfigGlobal(value);
476
+ normalizedValue = ConfigOps.normalizeConfigGlobal(idSetting);
475
477
  } catch (err) {
476
478
  problems.push(createLintingProblem({
477
479
  ruleId: null,
@@ -494,9 +496,9 @@ function getDirectiveComments(sourceCode, ruleMapper, warnInlineConfig, config)
494
496
  break;
495
497
 
496
498
  case "eslint": {
497
- const parseResult = commentParser.parseJsonConfig(directiveValue);
499
+ const parseResult = commentParser.parseJSONLikeConfig(value);
498
500
 
499
- if (parseResult.success) {
501
+ if (parseResult.ok) {
500
502
  Object.keys(parseResult.config).forEach(name => {
501
503
  const rule = ruleMapper(name);
502
504
  const ruleValue = parseResult.config[name];
@@ -713,7 +715,7 @@ function findEslintEnv(text) {
713
715
  if (match[0].endsWith("*/")) {
714
716
  retv = Object.assign(
715
717
  retv || {},
716
- commentParser.parseListConfig(commentParser.extractDirectiveComment(match[1]).directivePart)
718
+ commentParser.parseListConfig(commentParser.parseDirective(match[0].slice(2, -2)).value)
717
719
  );
718
720
  }
719
721
  }
@@ -979,24 +981,18 @@ function runRules(
979
981
  * All rule contexts will inherit from this object. This avoids the performance penalty of copying all the
980
982
  * properties once for each rule.
981
983
  */
982
- const sharedTraversalContext = Object.freeze(
983
- {
984
- getCwd: () => cwd,
985
- cwd,
986
- getFilename: () => filename,
987
- filename,
988
- getPhysicalFilename: () => physicalFilename || filename,
989
- physicalFilename: physicalFilename || filename,
990
- getSourceCode: () => sourceCode,
991
- sourceCode,
992
- parserOptions: {
993
- ...languageOptions.parserOptions
994
- },
995
- parserPath: parserName,
996
- languageOptions,
997
- settings
998
- }
999
- );
984
+ const sharedTraversalContext = new FileContext({
985
+ cwd,
986
+ filename,
987
+ physicalFilename: physicalFilename || filename,
988
+ sourceCode,
989
+ parserOptions: {
990
+ ...languageOptions.parserOptions
991
+ },
992
+ parserPath: parserName,
993
+ languageOptions,
994
+ settings
995
+ });
1000
996
 
1001
997
  const lintingProblems = [];
1002
998
 
@@ -1297,27 +1293,18 @@ class Linter {
1297
1293
  }
1298
1294
 
1299
1295
  /**
1300
- * Same as linter.verify, except without support for processors.
1301
- * @param {string|SourceCode} textOrSourceCode The text to parse or a SourceCode object.
1296
+ * Lint using eslintrc and without processors.
1297
+ * @param {VFile} file The file to lint.
1302
1298
  * @param {ConfigData} providedConfig An ESLintConfig instance to configure everything.
1303
1299
  * @param {VerifyOptions} [providedOptions] The optional filename of the file being checked.
1304
1300
  * @throws {Error} If during rule execution.
1305
1301
  * @returns {(LintMessage|SuppressedLintMessage)[]} The results as an array of messages or an empty array if no messages.
1306
1302
  */
1307
- _verifyWithoutProcessors(textOrSourceCode, providedConfig, providedOptions) {
1303
+ #eslintrcVerifyWithoutProcessors(file, providedConfig, providedOptions) {
1304
+
1308
1305
  const slots = internalSlotsMap.get(this);
1309
1306
  const config = providedConfig || {};
1310
1307
  const options = normalizeVerifyOptions(providedOptions, config);
1311
- let text;
1312
-
1313
- // evaluate arguments
1314
- if (typeof textOrSourceCode === "string") {
1315
- slots.lastSourceCode = null;
1316
- text = textOrSourceCode;
1317
- } else {
1318
- slots.lastSourceCode = textOrSourceCode;
1319
- text = textOrSourceCode.text;
1320
- }
1321
1308
 
1322
1309
  // Resolve parser.
1323
1310
  let parserName = DEFAULT_PARSER_NAME;
@@ -1344,7 +1331,7 @@ class Linter {
1344
1331
 
1345
1332
  // search and apply "eslint-env *".
1346
1333
  const envInFile = options.allowInlineConfig && !options.warnInlineConfig
1347
- ? findEslintEnv(text)
1334
+ ? findEslintEnv(file.body)
1348
1335
  : {};
1349
1336
  const resolvedEnvConfig = Object.assign({ builtin: true }, config.env, envInFile);
1350
1337
  const enabledEnvs = Object.keys(resolvedEnvConfig)
@@ -1360,9 +1347,6 @@ class Linter {
1360
1347
  parser,
1361
1348
  parserOptions
1362
1349
  });
1363
- const file = new VFile(options.filename, text, {
1364
- physicalPath: providedOptions.physicalFilename
1365
- });
1366
1350
 
1367
1351
  if (!slots.lastSourceCode) {
1368
1352
  let t;
@@ -1473,6 +1457,36 @@ class Linter {
1473
1457
  .sort((problemA, problemB) => problemA.line - problemB.line || problemA.column - problemB.column),
1474
1458
  reportUnusedDisableDirectives: options.reportUnusedDisableDirectives
1475
1459
  });
1460
+
1461
+ }
1462
+
1463
+ /**
1464
+ * Same as linter.verify, except without support for processors.
1465
+ * @param {string|SourceCode} textOrSourceCode The text to parse or a SourceCode object.
1466
+ * @param {ConfigData} providedConfig An ESLintConfig instance to configure everything.
1467
+ * @param {VerifyOptions} [providedOptions] The optional filename of the file being checked.
1468
+ * @throws {Error} If during rule execution.
1469
+ * @returns {(LintMessage|SuppressedLintMessage)[]} The results as an array of messages or an empty array if no messages.
1470
+ */
1471
+ _verifyWithoutProcessors(textOrSourceCode, providedConfig, providedOptions) {
1472
+ const slots = internalSlotsMap.get(this);
1473
+ const filename = normalizeFilename(providedOptions.filename || "<input>");
1474
+ let text;
1475
+
1476
+ // evaluate arguments
1477
+ if (typeof textOrSourceCode === "string") {
1478
+ slots.lastSourceCode = null;
1479
+ text = textOrSourceCode;
1480
+ } else {
1481
+ slots.lastSourceCode = textOrSourceCode;
1482
+ text = textOrSourceCode.text;
1483
+ }
1484
+
1485
+ const file = new VFile(filename, text, {
1486
+ physicalPath: providedOptions.physicalFilename
1487
+ });
1488
+
1489
+ return this.#eslintrcVerifyWithoutProcessors(file, providedConfig, providedOptions);
1476
1490
  }
1477
1491
 
1478
1492
  /**
@@ -1542,102 +1556,91 @@ class Linter {
1542
1556
  * @returns {(LintMessage|SuppressedLintMessage)[]} The found problems.
1543
1557
  */
1544
1558
  _verifyWithFlatConfigArrayAndProcessor(textOrSourceCode, config, options, configForRecursive) {
1559
+ const slots = internalSlotsMap.get(this);
1545
1560
  const filename = options.filename || "<input>";
1546
1561
  const filenameToExpose = normalizeFilename(filename);
1547
1562
  const physicalFilename = options.physicalFilename || filenameToExpose;
1548
1563
  const text = ensureText(textOrSourceCode);
1564
+ const file = new VFile(filenameToExpose, text, {
1565
+ physicalPath: physicalFilename
1566
+ });
1567
+
1549
1568
  const preprocess = options.preprocess || (rawText => [rawText]);
1550
1569
  const postprocess = options.postprocess || (messagesList => messagesList.flat());
1570
+
1571
+ const processorService = new ProcessorService();
1572
+ const preprocessResult = processorService.preprocessSync(file, {
1573
+ processor: {
1574
+ preprocess,
1575
+ postprocess
1576
+ }
1577
+ });
1578
+
1579
+ if (!preprocessResult.ok) {
1580
+ return preprocessResult.errors;
1581
+ }
1582
+
1551
1583
  const filterCodeBlock =
1552
1584
  options.filterCodeBlock ||
1553
1585
  (blockFilename => blockFilename.endsWith(".js"));
1554
1586
  const originalExtname = path.extname(filename);
1587
+ const { files } = preprocessResult;
1555
1588
 
1556
- let blocks;
1557
-
1558
- try {
1559
- blocks = preprocess(text, filenameToExpose);
1560
- } catch (ex) {
1561
-
1562
- // If the message includes a leading line number, strip it:
1563
- const message = `Preprocessing error: ${ex.message.replace(/^line \d+:/iu, "").trim()}`;
1564
-
1565
- debug("%s\n%s", message, ex.stack);
1566
-
1567
- return [
1568
- {
1569
- ruleId: null,
1570
- fatal: true,
1571
- severity: 2,
1572
- message,
1573
- line: ex.lineNumber,
1574
- column: ex.column,
1575
- nodeType: null
1576
- }
1577
- ];
1578
- }
1579
-
1580
- const messageLists = blocks.map((block, i) => {
1581
- debug("A code block was found: %o", block.filename || "(unnamed)");
1589
+ const messageLists = files.map(block => {
1590
+ debug("A code block was found: %o", block.path || "(unnamed)");
1582
1591
 
1583
1592
  // Keep the legacy behavior.
1584
1593
  if (typeof block === "string") {
1585
1594
  return this._verifyWithFlatConfigArrayAndWithoutProcessors(block, config, options);
1586
1595
  }
1587
1596
 
1588
- const blockText = block.text;
1589
- const blockName = path.join(filename, `${i}_${block.filename}`);
1590
-
1591
1597
  // Skip this block if filtered.
1592
- if (!filterCodeBlock(blockName, blockText)) {
1598
+ if (!filterCodeBlock(block.path, block.body)) {
1593
1599
  debug("This code block was skipped.");
1594
1600
  return [];
1595
1601
  }
1596
1602
 
1597
1603
  // Resolve configuration again if the file content or extension was changed.
1598
- if (configForRecursive && (text !== blockText || path.extname(blockName) !== originalExtname)) {
1604
+ if (configForRecursive && (text !== block.rawBody || path.extname(block.path) !== originalExtname)) {
1599
1605
  debug("Resolving configuration again because the file content or extension was changed.");
1600
1606
  return this._verifyWithFlatConfigArray(
1601
- blockText,
1607
+ block.rawBody,
1602
1608
  configForRecursive,
1603
- { ...options, filename: blockName, physicalFilename }
1609
+ { ...options, filename: block.path, physicalFilename: block.physicalPath }
1604
1610
  );
1605
1611
  }
1606
1612
 
1613
+ slots.lastSourceCode = null;
1614
+
1607
1615
  // Does lint.
1608
- return this._verifyWithFlatConfigArrayAndWithoutProcessors(
1609
- blockText,
1616
+ return this.#flatVerifyWithoutProcessors(
1617
+ block,
1610
1618
  config,
1611
- { ...options, filename: blockName, physicalFilename }
1619
+ { ...options, filename: block.path, physicalFilename: block.physicalPath }
1612
1620
  );
1613
1621
  });
1614
1622
 
1615
- return postprocess(messageLists, filenameToExpose);
1623
+ return processorService.postprocessSync(file, messageLists, {
1624
+ processor: {
1625
+ preprocess,
1626
+ postprocess
1627
+ }
1628
+ });
1616
1629
  }
1617
1630
 
1618
1631
  /**
1619
- * Same as linter.verify, except without support for processors.
1620
- * @param {string|SourceCode} textOrSourceCode The text to parse or a SourceCode object.
1632
+ * Verify using flat config and without any processors.
1633
+ * @param {VFile} file The file to lint.
1621
1634
  * @param {FlatConfig} providedConfig An ESLintConfig instance to configure everything.
1622
1635
  * @param {VerifyOptions} [providedOptions] The optional filename of the file being checked.
1623
1636
  * @throws {Error} If during rule execution.
1624
1637
  * @returns {(LintMessage|SuppressedLintMessage)[]} The results as an array of messages or an empty array if no messages.
1625
1638
  */
1626
- _verifyWithFlatConfigArrayAndWithoutProcessors(textOrSourceCode, providedConfig, providedOptions) {
1639
+ #flatVerifyWithoutProcessors(file, providedConfig, providedOptions) {
1640
+
1627
1641
  const slots = internalSlotsMap.get(this);
1628
1642
  const config = providedConfig || {};
1629
1643
  const options = normalizeVerifyOptions(providedOptions, config);
1630
- let text;
1631
-
1632
- // evaluate arguments
1633
- if (typeof textOrSourceCode === "string") {
1634
- slots.lastSourceCode = null;
1635
- text = textOrSourceCode;
1636
- } else {
1637
- slots.lastSourceCode = textOrSourceCode;
1638
- text = textOrSourceCode.text;
1639
- }
1640
-
1641
1644
  const languageOptions = config.languageOptions;
1642
1645
 
1643
1646
  languageOptions.ecmaVersion = normalizeEcmaVersionForLanguageOptions(
@@ -1668,9 +1671,6 @@ class Linter {
1668
1671
  }
1669
1672
 
1670
1673
  const settings = config.settings || {};
1671
- const file = new VFile(options.filename, text, {
1672
- physicalPath: providedOptions.physicalFilename
1673
- });
1674
1674
 
1675
1675
  if (!slots.lastSourceCode) {
1676
1676
  let t;
@@ -1962,6 +1962,37 @@ class Linter {
1962
1962
  ruleFilter: options.ruleFilter,
1963
1963
  configuredRules
1964
1964
  });
1965
+
1966
+
1967
+ }
1968
+
1969
+ /**
1970
+ * Same as linter.verify, except without support for processors.
1971
+ * @param {string|SourceCode} textOrSourceCode The text to parse or a SourceCode object.
1972
+ * @param {FlatConfig} providedConfig An ESLintConfig instance to configure everything.
1973
+ * @param {VerifyOptions} [providedOptions] The optional filename of the file being checked.
1974
+ * @throws {Error} If during rule execution.
1975
+ * @returns {(LintMessage|SuppressedLintMessage)[]} The results as an array of messages or an empty array if no messages.
1976
+ */
1977
+ _verifyWithFlatConfigArrayAndWithoutProcessors(textOrSourceCode, providedConfig, providedOptions) {
1978
+ const slots = internalSlotsMap.get(this);
1979
+ const filename = normalizeFilename(providedOptions.filename || "<input>");
1980
+ let text;
1981
+
1982
+ // evaluate arguments
1983
+ if (typeof textOrSourceCode === "string") {
1984
+ slots.lastSourceCode = null;
1985
+ text = textOrSourceCode;
1986
+ } else {
1987
+ slots.lastSourceCode = textOrSourceCode;
1988
+ text = textOrSourceCode.text;
1989
+ }
1990
+
1991
+ const file = new VFile(filename, text, {
1992
+ physicalPath: providedOptions.physicalFilename
1993
+ });
1994
+
1995
+ return this.#flatVerifyWithoutProcessors(file, providedConfig, providedOptions);
1965
1996
  }
1966
1997
 
1967
1998
  /**
@@ -2062,77 +2093,78 @@ class Linter {
2062
2093
  * @returns {(LintMessage|SuppressedLintMessage)[]} The found problems.
2063
2094
  */
2064
2095
  _verifyWithProcessor(textOrSourceCode, config, options, configForRecursive) {
2096
+ const slots = internalSlotsMap.get(this);
2065
2097
  const filename = options.filename || "<input>";
2066
2098
  const filenameToExpose = normalizeFilename(filename);
2067
2099
  const physicalFilename = options.physicalFilename || filenameToExpose;
2068
2100
  const text = ensureText(textOrSourceCode);
2101
+ const file = new VFile(filenameToExpose, text, {
2102
+ physicalPath: physicalFilename
2103
+ });
2104
+
2069
2105
  const preprocess = options.preprocess || (rawText => [rawText]);
2070
2106
  const postprocess = options.postprocess || (messagesList => messagesList.flat());
2071
- const filterCodeBlock =
2072
- options.filterCodeBlock ||
2073
- (blockFilename => blockFilename.endsWith(".js"));
2074
- const originalExtname = path.extname(filename);
2075
-
2076
- let blocks;
2077
2107
 
2078
- try {
2079
- blocks = preprocess(text, filenameToExpose);
2080
- } catch (ex) {
2108
+ const processorService = new ProcessorService();
2109
+ const preprocessResult = processorService.preprocessSync(file, {
2110
+ processor: {
2111
+ preprocess,
2112
+ postprocess
2113
+ }
2114
+ });
2081
2115
 
2082
- // If the message includes a leading line number, strip it:
2083
- const message = `Preprocessing error: ${ex.message.replace(/^line \d+:/iu, "").trim()}`;
2116
+ if (!preprocessResult.ok) {
2117
+ return preprocessResult.errors;
2118
+ }
2084
2119
 
2085
- debug("%s\n%s", message, ex.stack);
2120
+ const filterCodeBlock =
2121
+ options.filterCodeBlock ||
2122
+ (blockFilePath => blockFilePath.endsWith(".js"));
2123
+ const originalExtname = path.extname(filename);
2086
2124
 
2087
- return [
2088
- {
2089
- ruleId: null,
2090
- fatal: true,
2091
- severity: 2,
2092
- message,
2093
- line: ex.lineNumber,
2094
- column: ex.column,
2095
- nodeType: null
2096
- }
2097
- ];
2098
- }
2125
+ const { files } = preprocessResult;
2099
2126
 
2100
- const messageLists = blocks.map((block, i) => {
2101
- debug("A code block was found: %o", block.filename || "(unnamed)");
2127
+ const messageLists = files.map(block => {
2128
+ debug("A code block was found: %o", block.path ?? "(unnamed)");
2102
2129
 
2103
2130
  // Keep the legacy behavior.
2104
2131
  if (typeof block === "string") {
2105
2132
  return this._verifyWithoutProcessors(block, config, options);
2106
2133
  }
2107
2134
 
2108
- const blockText = block.text;
2109
- const blockName = path.join(filename, `${i}_${block.filename}`);
2110
-
2111
2135
  // Skip this block if filtered.
2112
- if (!filterCodeBlock(blockName, blockText)) {
2136
+ if (!filterCodeBlock(block.path, block.body)) {
2113
2137
  debug("This code block was skipped.");
2114
2138
  return [];
2115
2139
  }
2116
2140
 
2117
2141
  // Resolve configuration again if the file content or extension was changed.
2118
- if (configForRecursive && (text !== blockText || path.extname(blockName) !== originalExtname)) {
2142
+ if (configForRecursive && (text !== block.rawBody || path.extname(block.path) !== originalExtname)) {
2119
2143
  debug("Resolving configuration again because the file content or extension was changed.");
2120
2144
  return this._verifyWithConfigArray(
2121
- blockText,
2145
+ block.rawBody,
2122
2146
  configForRecursive,
2123
- { ...options, filename: blockName, physicalFilename }
2147
+ { ...options, filename: block.path, physicalFilename: block.physicalPath }
2124
2148
  );
2125
2149
  }
2126
2150
 
2151
+ slots.lastSourceCode = null;
2152
+
2127
2153
  // Does lint.
2128
- return this._verifyWithoutProcessors(
2129
- blockText,
2154
+ return this.#eslintrcVerifyWithoutProcessors(
2155
+ block,
2130
2156
  config,
2131
- { ...options, filename: blockName, physicalFilename }
2157
+ { ...options, filename: block.path, physicalFilename: block.physicalPath }
2132
2158
  );
2133
2159
  });
2134
2160
 
2135
- return postprocess(messageLists, filenameToExpose);
2161
+ return processorService.postprocessSync(file, messageLists, {
2162
+ processor: {
2163
+ preprocess,
2164
+ postprocess
2165
+ }
2166
+ });
2167
+
2136
2168
  }
2137
2169
 
2138
2170
  /**
@@ -85,6 +85,13 @@ class VFile {
85
85
  */
86
86
  body;
87
87
 
88
+ /**
89
+ * The raw body of the file, including a BOM if present.
90
+ * @type {string|Uint8Array}
91
+ * @readonly
92
+ */
93
+ rawBody;
94
+
88
95
  /**
89
96
  * Indicates whether the file has a byte order mark (BOM).
90
97
  * @type {boolean}
@@ -104,8 +111,8 @@ class VFile {
104
111
  this.physicalPath = physicalPath ?? path;
105
112
  this.bom = hasUnicodeBOM(body);
106
113
  this.body = stripUnicodeBOM(body);
114
+ this.rawBody = body;
107
115
  }
108
-
109
116
  }
110
117
 
111
118
  module.exports = { VFile };
@@ -11,6 +11,7 @@
11
11
  //------------------------------------------------------------------------------
12
12
 
13
13
  const { getGraphemeCount } = require("../shared/string-utils");
14
+ const { getModuleExportName } = require("./utils/ast-utils");
14
15
 
15
16
  //------------------------------------------------------------------------------
16
17
  // Rule Definition
@@ -116,7 +117,14 @@ module.exports = {
116
117
  }
117
118
  return properties && !parent.computed && parent.key.name === node.name;
118
119
  },
120
+ ImportSpecifier(parent, node) {
121
+ return (
122
+ parent.local === node &&
123
+ getModuleExportName(parent.imported) !== getModuleExportName(parent.local)
124
+ );
125
+ },
119
126
  ImportDefaultSpecifier: true,
127
+ ImportNamespaceSpecifier: true,
120
128
  RestElement: true,
121
129
  FunctionExpression: true,
122
130
  ArrowFunctionExpression: true,