webpack 5.108.1 → 5.108.3

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.
@@ -29,6 +29,7 @@ const {
29
29
  } = require("../util/magicComment");
30
30
  const topologicalSort = require("../util/topologicalSort");
31
31
  const {
32
+ A,
32
33
  NodeType,
33
34
  SourceProcessor,
34
35
  equalsLowerCase,
@@ -65,6 +66,7 @@ const {
65
66
  /** @typedef {{ localName: string, value: string }} ValueAtRuleValue */
66
67
 
67
68
  const CC_COLON = ":".charCodeAt(0);
69
+ const CC_HYPHEN_MINUS = "-".charCodeAt(0);
68
70
  const CC_SEMICOLON = ";".charCodeAt(0);
69
71
  const CC_TAB = "\t".charCodeAt(0);
70
72
  const CC_SPACE = " ".charCodeAt(0);
@@ -577,26 +579,27 @@ const isPureBodyAtRule = (name) =>
577
579
 
578
580
  /**
579
581
  * Scan a rule body once: does it hold a direct declaration counted against the enclosing rule (a declaration, or one in a transparent conditional-group at-rule like `@media`/`@supports`/…) and does it hold a nested block (qualified rule or any block-bearing at-rule)?
580
- * @param {{ declarations: Declaration[] | null, childRules: Rule[] | null }} body rule body
582
+ * @param {Declaration[] | null} declarations rule-body declarations
583
+ * @param {Rule[] | null} childRules rule-body child rules
581
584
  * @returns {{ hasDirectDecl: boolean, hasNestedBlock: boolean }} scan result
582
585
  */
583
- const scanRuleBody = (body) => {
584
- let hasDirectDecl = Boolean(
585
- body.declarations && body.declarations.length > 0
586
- );
586
+ const scanRuleBody = (declarations, childRules) => {
587
+ let hasDirectDecl = Boolean(declarations && declarations.length > 0);
587
588
  let hasNestedBlock = false;
588
- if (body.childRules) {
589
- for (const child of body.childRules) {
590
- if (child.type === NodeType.QualifiedRule) {
589
+ if (childRules) {
590
+ for (const child of childRules) {
591
+ const t = A.type(child);
592
+ if (t === NodeType.QualifiedRule) {
591
593
  hasNestedBlock = true;
592
- } else if (child.type === NodeType.AtRule) {
593
- const at = /** @type {AtRule} */ (child);
594
- if (!at.declarations && !at.childRules) continue;
594
+ } else if (t === NodeType.AtRule) {
595
+ const atDecls = A.declarations(child);
596
+ const atChildRules = A.childRules(child);
597
+ if (!atDecls && !atChildRules) continue;
595
598
  hasNestedBlock = true;
596
599
  if (
597
600
  !hasDirectDecl &&
598
- !isPureBodyAtRule(`@${at.name.toLowerCase()}`) &&
599
- scanRuleBody(at).hasDirectDecl
601
+ !isPureBodyAtRule(`@${A.name(child).toLowerCase()}`) &&
602
+ scanRuleBody(atDecls, atChildRules).hasDirectDecl
600
603
  ) {
601
604
  hasDirectDecl = true;
602
605
  }
@@ -686,7 +689,7 @@ const parseValueAtRuleParams = (str) => {
686
689
  */
687
690
  const nextNonWhitespace = (nodes, from) => {
688
691
  let i = from;
689
- while (i < nodes.length && nodes[i].type === NodeType.Whitespace) i++;
692
+ while (i < nodes.length && A.type(nodes[i]) === NodeType.Whitespace) i++;
690
693
  return i;
691
694
  };
692
695
 
@@ -706,21 +709,22 @@ const parseImportPrelude = (prelude) => {
706
709
  let supportsNode;
707
710
 
708
711
  for (const cv of prelude) {
709
- if (cv.type === NodeType.Whitespace) continue;
712
+ const t = A.type(cv);
713
+ if (t === NodeType.Whitespace) continue;
710
714
 
711
715
  if (!urlNode) {
712
- if (cv.type === NodeType.Url || cv.type === NodeType.String) {
716
+ if (t === NodeType.Url || t === NodeType.String) {
713
717
  urlNode = cv;
714
718
  continue;
715
719
  }
716
720
  if (
717
- cv.type === NodeType.Function &&
718
- equalsLowerCase(/** @type {FunctionNode} */ (cv).unescapedName, "url")
721
+ t === NodeType.Function &&
722
+ equalsLowerCase(A.unescapedName(cv), "url")
719
723
  ) {
720
724
  urlNode = cv;
721
725
  continue;
722
726
  }
723
- if (cv.type === NodeType.Ident) {
727
+ if (t === NodeType.Ident) {
724
728
  // CSS Modules: bare ident is a `@value` reference.
725
729
  urlNode = cv;
726
730
  continue;
@@ -729,14 +733,14 @@ const parseImportPrelude = (prelude) => {
729
733
  }
730
734
 
731
735
  if (!layerNode && !supportsNode) {
732
- if (cv.type === NodeType.Ident) {
733
- if (equalsLowerCase(/** @type {Token} */ (cv).unescaped, "layer")) {
736
+ if (t === NodeType.Ident) {
737
+ if (equalsLowerCase(A.unescaped(cv), "layer")) {
734
738
  layerNode = cv;
735
739
  continue;
736
740
  }
737
741
  } else if (
738
- cv.type === NodeType.Function &&
739
- equalsLowerCase(/** @type {FunctionNode} */ (cv).unescapedName, "layer")
742
+ t === NodeType.Function &&
743
+ equalsLowerCase(A.unescapedName(cv), "layer")
740
744
  ) {
741
745
  layerNode = cv;
742
746
  continue;
@@ -745,11 +749,8 @@ const parseImportPrelude = (prelude) => {
745
749
 
746
750
  if (
747
751
  !supportsNode &&
748
- cv.type === NodeType.Function &&
749
- equalsLowerCase(
750
- /** @type {FunctionNode} */ (cv).unescapedName,
751
- "supports"
752
- )
752
+ t === NodeType.Function &&
753
+ equalsLowerCase(A.unescapedName(cv), "supports")
753
754
  ) {
754
755
  supportsNode = /** @type {FunctionNode} */ (cv);
755
756
  continue;
@@ -772,31 +773,28 @@ const parseImportPrelude = (prelude) => {
772
773
  const parseIcssImportRequest = (second, rule, source) => {
773
774
  /** @type {AstNode[] | undefined} */
774
775
  let args;
775
- if (second.type === NodeType.Function) {
776
- args = /** @type {FunctionNode} */ (second).value;
776
+ if (A.type(second) === NodeType.Function) {
777
+ args = A.children(second);
777
778
  } else {
778
- for (const p of rule.prelude) {
779
- if (
780
- p.type === NodeType.SimpleBlock &&
781
- /** @type {SimpleBlock} */ (p).token === "("
782
- ) {
783
- args = /** @type {SimpleBlock} */ (p).value;
779
+ for (const p of A.prelude(rule)) {
780
+ if (A.type(p) === NodeType.SimpleBlock && A.blockToken(p) === "(") {
781
+ args = A.children(p);
784
782
  break;
785
783
  }
786
784
  }
787
785
  }
788
786
  // The first non-whitespace value inside `(...)` must be a string.
789
787
  const innerStrToken =
790
- args && args.find((v) => v.type !== NodeType.Whitespace);
791
- if (!innerStrToken || innerStrToken.type !== NodeType.String) {
788
+ args && args.find((v) => A.type(v) !== NodeType.Whitespace);
789
+ if (!innerStrToken || A.type(innerStrToken) !== NodeType.String) {
792
790
  const errorPos =
793
- second.type === NodeType.Function
794
- ? /** @type {FunctionNode} */ (second).nameEnd + 1
795
- : second.end;
791
+ A.type(second) === NodeType.Function
792
+ ? A.nameEnd(second) + 1
793
+ : A.end(second);
796
794
  return { errorPos };
797
795
  }
798
796
  return {
799
- request: source.slice(innerStrToken.start + 1, innerStrToken.end - 1)
797
+ request: source.slice(A.start(innerStrToken) + 1, A.end(innerStrToken) - 1)
800
798
  };
801
799
  };
802
800
 
@@ -1054,7 +1052,7 @@ class CssParser extends Parser {
1054
1052
  /**
1055
1053
  * Unescape a CSS identifier from a source byte range — for value spans not
1056
1054
  * backed by a single token (string contents, `--` dashed-ident bodies,
1057
- * composed names). Token-backed names use `node.unescaped` instead.
1055
+ * composed names). Token-backed names use `A.unescaped(node)` instead.
1058
1056
  * @param {number} start start offset
1059
1057
  * @param {number} end end offset
1060
1058
  * @returns {string} the unescaped identifier
@@ -1170,10 +1168,10 @@ class CssParser extends Parser {
1170
1168
  const hasBody = Boolean(declarations || childRules);
1171
1169
  let leaf = treatAsLeaf || !hasBody;
1172
1170
  if (!leaf && hasBody) {
1173
- const { hasDirectDecl, hasNestedBlock } = scanRuleBody({
1171
+ const { hasDirectDecl, hasNestedBlock } = scanRuleBody(
1174
1172
  declarations,
1175
1173
  childRules
1176
- });
1174
+ );
1177
1175
  leaf = hasDirectDecl || !hasNestedBlock;
1178
1176
  }
1179
1177
  if (leaf) this.report(preludeStart, preludeEnd);
@@ -1457,21 +1455,22 @@ class CssParser extends Parser {
1457
1455
  };
1458
1456
 
1459
1457
  // Body `{ name: value; … }` is parsed eagerly (§5.4.4) — emit a dep per declaration.
1460
- if (!rule.declarations || rule.blockStart === -1) return second.end;
1461
- for (const decl of rule.declarations) {
1462
- const vals = decl.value;
1458
+ const ruleDecls = A.declarations(rule);
1459
+ if (!ruleDecls || A.blockStart(rule) === -1) return A.end(second);
1460
+ for (const decl of ruleDecls) {
1461
+ const vals = A.children(decl);
1463
1462
  if (vals.length === 0) continue;
1464
- const rawStart = vals[0].start;
1465
- const rawEnd = vals[vals.length - 1].end;
1463
+ const rawStart = A.start(vals[0]);
1464
+ const rawEnd = A.end(vals[vals.length - 1]);
1466
1465
  createDep(
1467
- source.slice(decl.nameStart, decl.nameEnd),
1466
+ source.slice(A.nameStart(decl), A.nameEnd(decl)),
1468
1467
  source.slice(rawStart, rawEnd),
1469
- decl.nameEnd,
1468
+ A.nameEnd(decl),
1470
1469
  rawEnd
1471
1470
  );
1472
1471
  }
1473
1472
 
1474
- return skipWhiteLine(source, rule.blockEnd);
1473
+ return skipWhiteLine(source, A.blockEnd(rule));
1475
1474
  };
1476
1475
 
1477
1476
  /**
@@ -1506,20 +1505,21 @@ class CssParser extends Parser {
1506
1505
  */
1507
1506
  const processLocalOrGlobalFunction = (fn, type) => {
1508
1507
  // Replace `local(` / `global(` (and a leading `:` for the `:local(`/`:global(` selector form) with empty.
1509
- const isColon = input.charCodeAt(fn.start - 1) === CC_COLON;
1510
- const openEnd = fn.nameEnd + 1;
1508
+ const fnStart = A.start(fn);
1509
+ const isColon = input.charCodeAt(fnStart - 1) === CC_COLON;
1510
+ const openEnd = A.nameEnd(fn) + 1;
1511
1511
  module.addPresentationalDependency(
1512
- new ConstDependency("", [isColon ? fn.start - 1 : fn.start, openEnd])
1512
+ new ConstDependency("", [isColon ? fnStart - 1 : fnStart, openEnd])
1513
1513
  );
1514
1514
 
1515
1515
  if (type === 1) {
1516
- for (const cv of fn.value) {
1517
- if (cv.type !== NodeType.Ident) continue;
1518
- let identifier = /** @type {Token} */ (cv).unescaped;
1516
+ for (const cv of A.children(fn)) {
1517
+ if (A.type(cv) !== NodeType.Ident) continue;
1518
+ let identifier = A.unescaped(cv);
1519
1519
  const {
1520
1520
  start: { line: sl, column: sc },
1521
1521
  end: { line: el, column: ec }
1522
- } = cv.loc;
1522
+ } = A.loc(cv);
1523
1523
  const isDashedIdent = isDashedIdentifier(identifier);
1524
1524
  if (isDashedIdent) identifier = identifier.slice(2);
1525
1525
  addCssExport(
@@ -1529,7 +1529,7 @@ class CssParser extends Parser {
1529
1529
  ec,
1530
1530
  identifier,
1531
1531
  getReexport(identifier),
1532
- [cv.start, cv.end],
1532
+ [A.start(cv), A.end(cv)],
1533
1533
  true,
1534
1534
  CssIcssExportDependency.EXPORT_MODE.ONCE,
1535
1535
  isDashedIdent
@@ -1541,7 +1541,7 @@ class CssParser extends Parser {
1541
1541
 
1542
1542
  // Replace the closing `)`.
1543
1543
  module.addPresentationalDependency(
1544
- new ConstDependency("", [fn.end - 1, fn.end])
1544
+ new ConstDependency("", [A.end(fn) - 1, A.end(fn)])
1545
1545
  );
1546
1546
  };
1547
1547
 
@@ -1553,16 +1553,17 @@ class CssParser extends Parser {
1553
1553
  */
1554
1554
  const processLocalAtRule = (atRule, options) => {
1555
1555
  let found = false;
1556
- for (const cv of atRule.prelude) {
1557
- if (cv.type === NodeType.Whitespace) continue;
1556
+ for (const cv of A.prelude(atRule)) {
1557
+ const cvType = A.type(cv);
1558
+ if (cvType === NodeType.Whitespace) continue;
1558
1559
 
1559
- if (cv.type === NodeType.String) {
1560
+ if (cvType === NodeType.String) {
1560
1561
  if (!found && options.string) {
1561
- const value = /** @type {Token} */ (cv).unescaped;
1562
+ const value = A.unescaped(cv);
1562
1563
  const {
1563
1564
  start: { line: sl, column: sc },
1564
1565
  end: { line: el, column: ec }
1565
- } = cv.loc;
1566
+ } = A.loc(cv);
1566
1567
  addCssExport(
1567
1568
  sl,
1568
1569
  sc,
@@ -1570,7 +1571,7 @@ class CssParser extends Parser {
1570
1571
  ec,
1571
1572
  value,
1572
1573
  value,
1573
- [cv.start, cv.end],
1574
+ [A.start(cv), A.end(cv)],
1574
1575
  true,
1575
1576
  CssIcssExportDependency.EXPORT_MODE.ONCE
1576
1577
  );
@@ -1580,9 +1581,9 @@ class CssParser extends Parser {
1580
1581
  continue;
1581
1582
  }
1582
1583
 
1583
- if (cv.type === NodeType.Ident) {
1584
+ if (cvType === NodeType.Ident) {
1584
1585
  if (!found && options.identifier) {
1585
- const identifier = /** @type {Token} */ (cv).unescaped;
1586
+ const identifier = A.unescaped(cv);
1586
1587
  if (
1587
1588
  options.identifier instanceof RegExp &&
1588
1589
  options.identifier.test(identifier)
@@ -1592,7 +1593,7 @@ class CssParser extends Parser {
1592
1593
  const {
1593
1594
  start: { line: sl, column: sc },
1594
1595
  end: { line: el, column: ec }
1595
- } = cv.loc;
1596
+ } = A.loc(cv);
1596
1597
  addCssExport(
1597
1598
  sl,
1598
1599
  sc,
@@ -1600,7 +1601,7 @@ class CssParser extends Parser {
1600
1601
  ec,
1601
1602
  identifier,
1602
1603
  getReexport(identifier),
1603
- [cv.start, cv.end],
1604
+ [A.start(cv), A.end(cv)],
1604
1605
  true,
1605
1606
  CssIcssExportDependency.EXPORT_MODE.ONCE,
1606
1607
  CssIcssExportDependency.EXPORT_TYPE.NORMAL
@@ -1611,9 +1612,9 @@ class CssParser extends Parser {
1611
1612
  continue;
1612
1613
  }
1613
1614
 
1614
- if (cv.type === NodeType.Function) {
1615
+ if (cvType === NodeType.Function) {
1615
1616
  const fn = /** @type {FunctionNode} */ (cv);
1616
- const fname = fn.unescapedName.toLowerCase();
1617
+ const fname = A.unescapedName(fn).toLowerCase();
1617
1618
  const type =
1618
1619
  fname === "local" ? 1 : fname === "global" ? 2 : undefined;
1619
1620
  if (!found && type) {
@@ -1631,7 +1632,7 @@ class CssParser extends Parser {
1631
1632
  }
1632
1633
  }
1633
1634
  }
1634
- return atRule.end;
1635
+ return A.end(atRule);
1635
1636
  };
1636
1637
  /**
1637
1638
  * Emit the ICSS export declaring this module exports the given custom property.
@@ -1724,56 +1725,64 @@ class CssParser extends Parser {
1724
1725
  /** @type {Token | undefined} */
1725
1726
  let identNode;
1726
1727
  let identIdx = -1;
1727
- for (let i = 0; i < fn.value.length; i++) {
1728
- const cv = fn.value[i];
1729
- if (cv.type === NodeType.Whitespace) continue;
1730
- if (cv.type === NodeType.Ident) {
1728
+ const fv = A.children(fn);
1729
+ for (let i = 0; i < fv.length; i++) {
1730
+ const cv = fv[i];
1731
+ if (A.type(cv) === NodeType.Whitespace) continue;
1732
+ if (A.type(cv) === NodeType.Ident) {
1731
1733
  identNode = /** @type {Token} */ (cv);
1732
1734
  identIdx = i;
1733
1735
  }
1734
1736
  break;
1735
1737
  }
1736
- if (!identNode || !isDashedIdentifier(identNode.value)) return;
1738
+ if (!identNode) return;
1737
1739
 
1738
- const identStart = identNode.start;
1739
- const identEnd = identNode.end;
1740
+ const identStart = A.start(identNode);
1741
+ const identEnd = A.end(identNode);
1742
+ // `isDashedIdentifier` on the value without slicing it: a literal `--`
1743
+ // prefix of length >= 3 (escaped dashes don't match, same as the string
1744
+ // form, since the raw bytes aren't `--`).
1745
+ if (
1746
+ identEnd - identStart < 3 ||
1747
+ input.charCodeAt(identStart) !== CC_HYPHEN_MINUS ||
1748
+ input.charCodeAt(identStart + 1) !== CC_HYPHEN_MINUS
1749
+ ) {
1750
+ return;
1751
+ }
1740
1752
 
1741
1753
  let j = identIdx + 1;
1742
- while (j < fn.value.length && fn.value[j].type === NodeType.Whitespace) {
1754
+ while (j < fv.length && A.type(fv[j]) === NodeType.Whitespace) {
1743
1755
  j++;
1744
1756
  }
1745
1757
 
1746
1758
  if (
1747
- j >= fn.value.length ||
1748
- fn.value[j].type !== NodeType.Ident ||
1749
- !equalsLowerCase(/** @type {Token} */ (fn.value[j]).value, "from")
1759
+ j >= fv.length ||
1760
+ A.type(fv[j]) !== NodeType.Ident ||
1761
+ !equalsLowerCase(A.value(fv[j]), "from")
1750
1762
  ) {
1751
1763
  emitDashedIdentExport(identStart, identEnd);
1752
1764
  return;
1753
1765
  }
1754
1766
 
1755
- const fromIdent = fn.value[j];
1767
+ const fromIdent = fv[j];
1756
1768
  j++;
1757
- while (j < fn.value.length && fn.value[j].type === NodeType.Whitespace) {
1769
+ while (j < fv.length && A.type(fv[j]) === NodeType.Whitespace) {
1758
1770
  j++;
1759
1771
  }
1760
- if (j >= fn.value.length) return;
1772
+ if (j >= fv.length) return;
1761
1773
 
1762
- const source = fn.value[j];
1763
- if (
1764
- source.type === NodeType.Ident &&
1765
- /** @type {Token} */ (source).value === "global"
1766
- ) {
1767
- emitDashedIdentFromGlobal(identEnd, source.end);
1774
+ const src = fv[j];
1775
+ if (A.type(src) === NodeType.Ident && A.value(src) === "global") {
1776
+ emitDashedIdentFromGlobal(identEnd, A.end(src));
1768
1777
  return;
1769
1778
  }
1770
- if (source.type === NodeType.String) {
1779
+ if (A.type(src) === NodeType.String) {
1771
1780
  emitDashedIdentImport(
1772
1781
  identStart,
1773
1782
  identEnd,
1774
- fromIdent.start,
1775
- source.end,
1776
- input.slice(source.start + 1, source.end - 1)
1783
+ A.start(fromIdent),
1784
+ A.end(src),
1785
+ input.slice(A.start(src) + 1, A.end(src) - 1)
1777
1786
  );
1778
1787
  }
1779
1788
  };
@@ -1785,16 +1794,14 @@ class CssParser extends Parser {
1785
1794
  */
1786
1795
  const childrenOf = (parent) => {
1787
1796
  if (!parent) return undefined;
1788
- switch (parent.type) {
1797
+ switch (A.type(parent)) {
1789
1798
  case NodeType.Function:
1790
- return /** @type {FunctionNode} */ (parent).value;
1791
1799
  case NodeType.SimpleBlock:
1792
- return /** @type {SimpleBlock} */ (parent).value;
1793
1800
  case NodeType.Declaration:
1794
- return /** @type {Declaration} */ (parent).value;
1801
+ return A.children(parent);
1795
1802
  case NodeType.AtRule:
1796
1803
  case NodeType.QualifiedRule:
1797
- return /** @type {AtRule | QualifiedRule} */ (parent).prelude;
1804
+ return A.prelude(parent);
1798
1805
  default:
1799
1806
  return undefined;
1800
1807
  }
@@ -1833,6 +1840,8 @@ class CssParser extends Parser {
1833
1840
  let currentStructural;
1834
1841
  // Cached on each structural enter and read per value token, so the hot Function / Ident / Url visitors don't re-derive the property / at-rule name on every visit.
1835
1842
  let currentAtRuleName = "";
1843
+ // Set by `handleImportAtRule` for a malformed `@import` so its prelude still emits orphan url() deps; read by `urlActive`. Reset per at-rule enter (replaces an ad-hoc property on the node).
1844
+ let currentUrlRecovery = false;
1836
1845
  /** Whether the current Declaration's property is a localizable known property. */
1837
1846
  let currentDeclIsKnownProperty = false;
1838
1847
  /** Whether the current `composes:` declaration owns the whole value (suppresses value rewrites). */
@@ -1853,13 +1862,16 @@ class CssParser extends Parser {
1853
1862
  */
1854
1863
  const stripBareMarker = (colon, ident, after) => {
1855
1864
  const afterIsWhitespace = Boolean(
1856
- after && after.type === NodeType.Whitespace
1865
+ after && A.type(after) === NodeType.Whitespace
1857
1866
  );
1867
+ const identEnd = A.end(ident);
1858
1868
  const stripEnd =
1859
- afterIsWhitespace && after.start === ident.end ? after.end : ident.end;
1869
+ afterIsWhitespace && A.start(after) === identEnd
1870
+ ? A.end(after)
1871
+ : identEnd;
1860
1872
  if (isModules) {
1861
1873
  module.addPresentationalDependency(
1862
- new ConstDependency("", [colon.start, stripEnd])
1874
+ new ConstDependency("", [A.start(colon), stripEnd])
1863
1875
  );
1864
1876
  }
1865
1877
  return afterIsWhitespace;
@@ -1874,17 +1886,18 @@ class CssParser extends Parser {
1874
1886
  */
1875
1887
  const stripFunctionMarker = (colon, fn, isLocal) => {
1876
1888
  if (!isModules) return;
1877
- let stripLeadEnd = fn.end - 1;
1878
- for (const arg of fn.value) {
1879
- if (arg.type !== NodeType.Whitespace) {
1880
- stripLeadEnd = arg.start;
1889
+ const fnEnd = A.end(fn);
1890
+ let stripLeadEnd = fnEnd - 1;
1891
+ for (const arg of A.children(fn)) {
1892
+ if (A.type(arg) !== NodeType.Whitespace) {
1893
+ stripLeadEnd = A.start(arg);
1881
1894
  break;
1882
1895
  }
1883
1896
  }
1884
1897
  module.addPresentationalDependency(
1885
- new ConstDependency("", [colon.start, stripLeadEnd])
1898
+ new ConstDependency("", [A.start(colon), stripLeadEnd])
1886
1899
  );
1887
- let trailStart = fn.end - 1; // position of `)`
1900
+ let trailStart = fnEnd - 1; // position of `)`
1888
1901
  if (isLocal) {
1889
1902
  while (
1890
1903
  trailStart > 0 &&
@@ -1894,7 +1907,7 @@ class CssParser extends Parser {
1894
1907
  }
1895
1908
  }
1896
1909
  module.addPresentationalDependency(
1897
- new ConstDependency("", [trailStart, fn.end])
1910
+ new ConstDependency("", [trailStart, fnEnd])
1898
1911
  );
1899
1912
  };
1900
1913
 
@@ -1904,37 +1917,33 @@ class CssParser extends Parser {
1904
1917
  * @returns {void}
1905
1918
  */
1906
1919
  const handleAttributeSelector = (block) => {
1907
- const attrParts = block.value;
1920
+ const attrParts = A.children(block);
1908
1921
  let ai = 0;
1909
1922
  while (
1910
1923
  ai < attrParts.length &&
1911
- attrParts[ai].type === NodeType.Whitespace
1924
+ A.type(attrParts[ai]) === NodeType.Whitespace
1912
1925
  ) {
1913
1926
  ai++;
1914
1927
  }
1915
1928
  const attrNameNode = attrParts[ai];
1916
- if (!attrNameNode || attrNameNode.type !== NodeType.Ident) return;
1917
- const attrName = /** @type {Token} */ (attrNameNode).unescaped;
1929
+ if (!attrNameNode || A.type(attrNameNode) !== NodeType.Ident) return;
1930
+ const attrName = A.unescaped(attrNameNode);
1918
1931
  if (!equalsLowerCase(attrName, "class")) return;
1919
1932
  ai++;
1920
1933
  while (
1921
1934
  ai < attrParts.length &&
1922
- attrParts[ai].type === NodeType.Whitespace
1935
+ A.type(attrParts[ai]) === NodeType.Whitespace
1923
1936
  ) {
1924
1937
  ai++;
1925
1938
  }
1926
1939
  // `=` or `~=` (two `Delim` tokens for the latter).
1927
1940
  const op1 = attrParts[ai];
1928
- if (!op1 || op1.type !== NodeType.Delim) return;
1929
- const op1v = /** @type {Token} */ (op1).value;
1941
+ if (!op1 || A.type(op1) !== NodeType.Delim) return;
1942
+ const op1v = A.value(op1);
1930
1943
  if (op1v === "~") {
1931
1944
  ai++;
1932
1945
  const op2 = attrParts[ai];
1933
- if (
1934
- !op2 ||
1935
- op2.type !== NodeType.Delim ||
1936
- /** @type {Token} */ (op2).value !== "="
1937
- ) {
1946
+ if (!op2 || A.type(op2) !== NodeType.Delim || A.value(op2) !== "=") {
1938
1947
  return;
1939
1948
  }
1940
1949
  } else if (op1v !== "=") {
@@ -1943,7 +1952,7 @@ class CssParser extends Parser {
1943
1952
  ai++;
1944
1953
  while (
1945
1954
  ai < attrParts.length &&
1946
- attrParts[ai].type === NodeType.Whitespace
1955
+ A.type(attrParts[ai]) === NodeType.Whitespace
1947
1956
  ) {
1948
1957
  ai++;
1949
1958
  }
@@ -1953,12 +1962,12 @@ class CssParser extends Parser {
1953
1962
  let classNameStart;
1954
1963
  /** @type {number} */
1955
1964
  let classNameEnd;
1956
- if (attrValueNode.type === NodeType.String) {
1957
- classNameStart = attrValueNode.start + 1;
1958
- classNameEnd = attrValueNode.end - 1;
1959
- } else if (attrValueNode.type === NodeType.Ident) {
1960
- classNameStart = attrValueNode.start;
1961
- classNameEnd = attrValueNode.end;
1965
+ if (A.type(attrValueNode) === NodeType.String) {
1966
+ classNameStart = A.start(attrValueNode) + 1;
1967
+ classNameEnd = A.end(attrValueNode) - 1;
1968
+ } else if (A.type(attrValueNode) === NodeType.Ident) {
1969
+ classNameStart = A.start(attrValueNode);
1970
+ classNameEnd = A.end(attrValueNode);
1962
1971
  } else {
1963
1972
  return;
1964
1973
  }
@@ -1998,7 +2007,7 @@ class CssParser extends Parser {
1998
2007
  }
1999
2008
  for (let i = 0; i < values.length; i++) {
2000
2009
  const v = values[i];
2001
- switch (v.type) {
2010
+ switch (A.type(v)) {
2002
2011
  case NodeType.Whitespace:
2003
2012
  break;
2004
2013
  case NodeType.Comma:
@@ -2013,8 +2022,9 @@ class CssParser extends Parser {
2013
2022
  // Look ahead for `:local` / `:global` markers; other pseudos fall through.
2014
2023
  const next = values[i + 1];
2015
2024
  if (!next) break;
2016
- if (next.type === NodeType.Ident) {
2017
- const raw = /** @type {Token} */ (next).value;
2025
+ const nextType = A.type(next);
2026
+ if (nextType === NodeType.Ident) {
2027
+ const raw = A.value(next);
2018
2028
  const isLocal = equalsLowerCase(raw, "local");
2019
2029
  if (isLocal || equalsLowerCase(raw, "global")) {
2020
2030
  const id = isLocal ? "local" : "global";
@@ -2029,12 +2039,12 @@ class CssParser extends Parser {
2029
2039
  this._emitWarning(
2030
2040
  state,
2031
2041
  `Missing whitespace after ':${id}' in '${source.slice(
2032
- v.start,
2033
- findLeftCurly(source, next.end) + 1
2042
+ A.start(v),
2043
+ findLeftCurly(source, A.end(next)) + 1
2034
2044
  )}'`,
2035
2045
  locConverter,
2036
- v.start,
2037
- next.end
2046
+ A.start(v),
2047
+ A.end(next)
2038
2048
  );
2039
2049
  }
2040
2050
  segmentMode = id;
@@ -2042,14 +2052,18 @@ class CssParser extends Parser {
2042
2052
  // Skip past the colon + ident.
2043
2053
  i += 1;
2044
2054
  }
2045
- } else if (next.type === NodeType.Function) {
2055
+ } else if (nextType === NodeType.Function) {
2046
2056
  const fn = /** @type {FunctionNode} */ (next);
2047
- const rawName = fn.unescapedName;
2057
+ const rawName = A.unescapedName(fn);
2048
2058
  const isLocal = equalsLowerCase(rawName, "local");
2049
2059
  if (isLocal || equalsLowerCase(rawName, "global")) {
2050
2060
  // `:local(…)` / `:global(…)`: scope mode to the args and strip the `:name(` … `)` wrapper.
2051
2061
  stripFunctionMarker(v, fn, isLocal);
2052
- walkSelectorList(fn.value, isLocal ? "local" : "global", false);
2062
+ walkSelectorList(
2063
+ A.children(fn),
2064
+ isLocal ? "local" : "global",
2065
+ false
2066
+ );
2053
2067
  // Skip past the colon + function.
2054
2068
  i += 1;
2055
2069
  }
@@ -2058,26 +2072,19 @@ class CssParser extends Parser {
2058
2072
  }
2059
2073
  case NodeType.Function:
2060
2074
  // Any other function (`:not(…)`, `:is(…)`, …): recurse with the segment mode preserved (only `:local(…)` / `:global(…)`, handled above, switch mode).
2061
- walkSelectorList(
2062
- /** @type {FunctionNode} */ (v).value,
2063
- segmentMode,
2064
- false
2065
- );
2075
+ walkSelectorList(A.children(v), segmentMode, false);
2066
2076
  break;
2067
2077
  case NodeType.Hash: {
2068
- if (
2069
- /** @type {HashToken} */ (v).typeFlag !== "id" ||
2070
- segmentMode !== "local"
2071
- ) {
2078
+ if (A.typeFlag(v) !== "id" || segmentMode !== "local") {
2072
2079
  break;
2073
2080
  }
2074
2081
  // ID selectors emit the ICSS export but aren't a `composes:` anchor.
2075
- const idValueStart = v.start + 1;
2076
- const idName = /** @type {Token} */ (v).unescaped;
2082
+ const idValueStart = A.start(v) + 1;
2083
+ const idName = A.unescaped(v);
2077
2084
  const {
2078
2085
  start: { line: idSl, column: idSc },
2079
2086
  end: { line: idEl, column: idEc }
2080
- } = v.loc;
2087
+ } = A.loc(v);
2081
2088
  addCssExport(
2082
2089
  idSl,
2083
2090
  idSc,
@@ -2085,7 +2092,7 @@ class CssParser extends Parser {
2085
2092
  idEc,
2086
2093
  idName,
2087
2094
  getReexport(idName),
2088
- [idValueStart, v.end],
2095
+ [idValueStart, A.end(v)],
2089
2096
  true,
2090
2097
  CssIcssExportDependency.EXPORT_MODE.ONCE
2091
2098
  );
@@ -2094,17 +2101,18 @@ class CssParser extends Parser {
2094
2101
  }
2095
2102
  case NodeType.SimpleBlock: {
2096
2103
  const block = /** @type {SimpleBlock} */ (v);
2097
- if (block.token === "[") {
2104
+ const bt = A.blockToken(block);
2105
+ if (bt === "[") {
2098
2106
  // Attribute selectors `[class="foo"]` localize only in local mode.
2099
2107
  if (segmentMode === "local") handleAttributeSelector(block);
2100
- } else if (block.token === "(") {
2108
+ } else if (bt === "(") {
2101
2109
  // `@scope (.foo)` and other parenthesised selector wrappers — recurse into the `(…)` block.
2102
- walkSelectorList(block.value, segmentMode, false);
2110
+ walkSelectorList(A.children(block), segmentMode, false);
2103
2111
  }
2104
2112
  break;
2105
2113
  }
2106
2114
  case NodeType.Delim: {
2107
- const delim = /** @type {Token} */ (v).value;
2115
+ const delim = A.value(v);
2108
2116
  if (delim === "&") {
2109
2117
  // Pure-mode: a nesting `&` inherits a pure ancestor's purity.
2110
2118
  if (topLevel && pure.ancestorHadLocal()) pure.markLocal();
@@ -2112,14 +2120,14 @@ class CssParser extends Parser {
2112
2120
  }
2113
2121
  if (delim !== ".") break;
2114
2122
  const next = values[i + 1];
2115
- if (!next || next.type !== NodeType.Ident) break;
2123
+ if (!next || A.type(next) !== NodeType.Ident) break;
2116
2124
  if (segmentMode === "local") {
2117
2125
  // `.<ident>` in local mode is a class selector (dep covers the ident bytes only).
2118
- const name = /** @type {Token} */ (next).unescaped;
2126
+ const name = A.unescaped(next);
2119
2127
  const {
2120
2128
  start: { line: sl, column: sc },
2121
2129
  end: { line: el, column: ec }
2122
- } = next.loc;
2130
+ } = A.loc(next);
2123
2131
  addCssExport(
2124
2132
  sl,
2125
2133
  sc,
@@ -2127,7 +2135,7 @@ class CssParser extends Parser {
2127
2135
  ec,
2128
2136
  name,
2129
2137
  getReexport(name),
2130
- [next.start, next.end],
2138
+ [A.start(next), A.end(next)],
2131
2139
  true,
2132
2140
  CssIcssExportDependency.EXPORT_MODE.ONCE
2133
2141
  );
@@ -2136,9 +2144,9 @@ class CssParser extends Parser {
2136
2144
  pure.markLocal();
2137
2145
  } else {
2138
2146
  // `.<ident>` in global mode: not localized, but the ident may be `@value`-defined and need ICSS rewrite.
2139
- const ident = /** @type {Token} */ (next).value;
2147
+ const ident = A.value(next);
2140
2148
  if (!isDashedIdentifier(ident) && icssDefinitions.has(ident)) {
2141
- emitICSSSymbol(ident, next.start, next.end);
2149
+ emitICSSSymbol(ident, A.start(next), A.end(next));
2142
2150
  }
2143
2151
  }
2144
2152
  // Skip the consumed ident.
@@ -2147,9 +2155,9 @@ class CssParser extends Parser {
2147
2155
  }
2148
2156
  case NodeType.Ident: {
2149
2157
  // ICSS rewrite for a bare `@value`-defined ident used as a type-style selector.
2150
- const ident = /** @type {Token} */ (v).value;
2158
+ const ident = A.value(v);
2151
2159
  if (!isDashedIdentifier(ident) && icssDefinitions.has(ident)) {
2152
- emitICSSSymbol(ident, v.start, v.end);
2160
+ emitICSSSymbol(ident, A.start(v), A.end(v));
2153
2161
  }
2154
2162
  break;
2155
2163
  }
@@ -2172,11 +2180,11 @@ class CssParser extends Parser {
2172
2180
  */
2173
2181
  const urlActive = () => {
2174
2182
  if (!this.options.url || !currentStructural) return false;
2175
- if (currentStructural.type === NodeType.AtRule) {
2176
- const at = /** @type {AtRule & { urlRecovery?: boolean }} */ (
2177
- currentStructural
2183
+ if (A.type(currentStructural) === NodeType.AtRule) {
2184
+ return (
2185
+ !equalsLowerCase(A.name(currentStructural), "import") ||
2186
+ currentUrlRecovery
2178
2187
  );
2179
- return !equalsLowerCase(at.name, "import") || Boolean(at.urlRecovery);
2180
2188
  }
2181
2189
  return true;
2182
2190
  };
@@ -2204,10 +2212,11 @@ class CssParser extends Parser {
2204
2212
  */
2205
2213
  const localGlobalActive = () => {
2206
2214
  if (!isModules || !currentStructural) return false;
2207
- if (currentStructural.type === NodeType.AtRule) {
2215
+ const t = A.type(currentStructural);
2216
+ if (t === NodeType.AtRule) {
2208
2217
  return !isLocalHandledAtRule(currentAtRuleName);
2209
2218
  }
2210
- if (currentStructural.type === NodeType.Declaration) {
2219
+ if (t === NodeType.Declaration) {
2211
2220
  return !currentDeclComposesSkip;
2212
2221
  }
2213
2222
  return false;
@@ -2219,12 +2228,13 @@ class CssParser extends Parser {
2219
2228
  */
2220
2229
  const icssActive = () => {
2221
2230
  if (!isModules || !currentStructural) return false;
2222
- if (currentStructural.type === NodeType.AtRule) {
2231
+ const t = A.type(currentStructural);
2232
+ if (t === NodeType.AtRule) {
2223
2233
  return (
2224
2234
  currentAtRuleName !== "@value" && currentAtRuleName !== "@import"
2225
2235
  );
2226
2236
  }
2227
- if (currentStructural.type === NodeType.Declaration) {
2237
+ if (t === NodeType.Declaration) {
2228
2238
  return !currentDeclComposesSkip && !currentDeclIsKnownProperty;
2229
2239
  }
2230
2240
  return false;
@@ -2237,8 +2247,7 @@ class CssParser extends Parser {
2237
2247
  * @returns {void}
2238
2248
  */
2239
2249
  const finishTopLevelRule = (node, blockBearing) => {
2240
- const at = /** @type {AtRule} */ (node);
2241
- if (!blockBearing || at.declarations || at.childRules) {
2250
+ if (!blockBearing || A.declarations(node) || A.childRules(node)) {
2242
2251
  allowImport = false;
2243
2252
  }
2244
2253
  pure.markSeenTopLevelRule();
@@ -2383,8 +2392,8 @@ class CssParser extends Parser {
2383
2392
  '", "'
2384
2393
  )}"`,
2385
2394
  locConverter,
2386
- decl.start,
2387
- decl.end
2395
+ A.start(decl),
2396
+ A.end(decl)
2388
2397
  );
2389
2398
  return;
2390
2399
  }
@@ -2395,8 +2404,8 @@ class CssParser extends Parser {
2395
2404
  const groups = [];
2396
2405
  /** @type {AstNode[]} */
2397
2406
  let currentGroup = [];
2398
- for (const cv of decl.value) {
2399
- if (cv.type === NodeType.Comma) {
2407
+ for (const cv of A.children(decl)) {
2408
+ if (A.type(cv) === NodeType.Comma) {
2400
2409
  groups.push(currentGroup);
2401
2410
  currentGroup = [];
2402
2411
  } else {
@@ -2419,20 +2428,20 @@ class CssParser extends Parser {
2419
2428
 
2420
2429
  for (let i = 0; i < group.length; i++) {
2421
2430
  const cv = group[i];
2422
- if (cv.type === NodeType.Whitespace) continue;
2431
+ if (A.type(cv) === NodeType.Whitespace) continue;
2423
2432
 
2424
2433
  if (phase === "expecting-source") {
2425
- if (cv.type === NodeType.String) {
2434
+ if (A.type(cv) === NodeType.String) {
2426
2435
  fromSource = {
2427
2436
  kind: "string",
2428
- path: source.slice(cv.start + 1, cv.end - 1)
2437
+ path: source.slice(A.start(cv) + 1, A.end(cv) - 1)
2429
2438
  };
2430
2439
  phase = "done";
2431
2440
  continue;
2432
2441
  }
2433
2442
  if (
2434
- cv.type === NodeType.Ident &&
2435
- equalsLowerCase(/** @type {Token} */ (cv).value, "global")
2443
+ A.type(cv) === NodeType.Ident &&
2444
+ equalsLowerCase(A.value(cv), "global")
2436
2445
  ) {
2437
2446
  fromSource = { kind: "global" };
2438
2447
  phase = "done";
@@ -2448,8 +2457,8 @@ class CssParser extends Parser {
2448
2457
  continue;
2449
2458
  }
2450
2459
 
2451
- if (cv.type === NodeType.Ident) {
2452
- const identValue = /** @type {Token} */ (cv).value;
2460
+ if (A.type(cv) === NodeType.Ident) {
2461
+ const identValue = A.value(cv);
2453
2462
  if (
2454
2463
  equalsLowerCase(identValue, "from") &&
2455
2464
  classNames.length > 0 &&
@@ -2459,21 +2468,21 @@ class CssParser extends Parser {
2459
2468
  continue;
2460
2469
  }
2461
2470
  classNames.push({
2462
- start: cv.start,
2463
- end: cv.end,
2471
+ start: A.start(cv),
2472
+ end: A.end(cv),
2464
2473
  isGlobal: false
2465
2474
  });
2466
2475
  continue;
2467
2476
  }
2468
2477
 
2469
- if (cv.type === NodeType.Function) {
2478
+ if (A.type(cv) === NodeType.Function) {
2470
2479
  const fn = /** @type {FunctionNode} */ (cv);
2471
- const isGlobal = equalsLowerCase(fn.unescapedName, "global");
2472
- for (const inner of fn.value) {
2473
- if (inner.type === NodeType.Ident) {
2480
+ const isGlobal = equalsLowerCase(A.unescapedName(fn), "global");
2481
+ for (const inner of A.children(fn)) {
2482
+ if (A.type(inner) === NodeType.Ident) {
2474
2483
  classNames.push({
2475
- start: inner.start,
2476
- end: inner.end,
2484
+ start: A.start(inner),
2485
+ end: A.end(inner),
2477
2486
  isGlobal
2478
2487
  });
2479
2488
  break;
@@ -2500,8 +2509,8 @@ class CssParser extends Parser {
2500
2509
  state,
2501
2510
  errorMessage,
2502
2511
  locConverter,
2503
- errorToken.start,
2504
- errorToken.end
2512
+ A.start(errorToken),
2513
+ A.end(errorToken)
2505
2514
  );
2506
2515
  return;
2507
2516
  }
@@ -2512,13 +2521,13 @@ class CssParser extends Parser {
2512
2521
  }
2513
2522
 
2514
2523
  // Strip the whole `composes: …;` (property name included) plus trailing same-line whitespace. The `;` and that whitespace aren't AST nodes (a block's contents drop them), so scan the source here.
2515
- let resumeAt = decl.end;
2516
- if (source.charCodeAt(decl.end) === CC_SEMICOLON) {
2517
- resumeAt = decl.end + 1;
2524
+ let resumeAt = A.end(decl);
2525
+ if (source.charCodeAt(A.end(decl)) === CC_SEMICOLON) {
2526
+ resumeAt = A.end(decl) + 1;
2518
2527
  while (isCssWhitespace(source.charCodeAt(resumeAt))) resumeAt++;
2519
2528
  }
2520
2529
  module.addPresentationalDependency(
2521
- new ConstDependency("", [decl.nameStart, resumeAt])
2530
+ new ConstDependency("", [A.nameStart(decl), resumeAt])
2522
2531
  );
2523
2532
  };
2524
2533
 
@@ -2530,63 +2539,69 @@ class CssParser extends Parser {
2530
2539
  const emitUrlFunction = (fn, fname) => {
2531
2540
  if (fname === "url" || fname === "src") {
2532
2541
  // Quoted `url("…")` / `src("…")`: first non-whitespace value must be the string token.
2533
- const first = fn.value[nextNonWhitespace(fn.value, 0)];
2534
- if (!first || first.type !== NodeType.String) return;
2542
+ const first = A.children(fn)[nextNonWhitespace(A.children(fn), 0)];
2543
+ if (!first || A.type(first) !== NodeType.String) return;
2535
2544
  const string = /** @type {Token} */ (first);
2536
2545
  if (
2537
2546
  webpackIgnored(
2538
- [lastTokenEndForComments, fn.start],
2539
- string.start,
2540
- string.end
2547
+ [lastTokenEndForComments, A.start(fn)],
2548
+ A.start(string),
2549
+ A.end(string)
2541
2550
  )
2542
2551
  ) {
2543
2552
  return;
2544
2553
  }
2545
2554
  const value = normalizeUrl(
2546
- input.slice(string.start + 1, string.end - 1),
2555
+ input.slice(A.start(string) + 1, A.end(string) - 1),
2547
2556
  true
2548
2557
  );
2549
2558
  // Ignore `url()`, `url('')` and `url("")`, they are valid by spec
2550
2559
  if (value.length === 0) return;
2551
2560
  const dep = new CssUrlDependency(
2552
2561
  value,
2553
- [string.start, string.end],
2562
+ [A.start(string), A.end(string)],
2554
2563
  "string"
2555
2564
  );
2556
- setDepLoc(dep, string.start, string.end);
2565
+ setDepLoc(dep, A.start(string), A.end(string));
2557
2566
  module.addDependency(dep);
2558
2567
  module.addCodeGenerationDependency(dep);
2559
2568
  } else if (IMAGE_SET_FUNCTION.test(fname)) {
2560
2569
  // `image-set(…)`: each comma segment's first string is the URL; advance the magic-comment fence per string.
2561
- lastTokenEndForComments = fn.nameEnd + 1;
2562
- let prevStringEnd = fn.start;
2570
+ lastTokenEndForComments = A.nameEnd(fn) + 1;
2571
+ let prevStringEnd = A.start(fn);
2563
2572
  let firstInSegment = true;
2564
- for (const cv of fn.value) {
2565
- if (cv.type === NodeType.Comma) {
2573
+ for (const cv of A.children(fn)) {
2574
+ if (A.type(cv) === NodeType.Comma) {
2566
2575
  firstInSegment = true;
2567
2576
  continue;
2568
2577
  }
2569
- if (cv.type === NodeType.Whitespace) continue;
2578
+ if (A.type(cv) === NodeType.Whitespace) continue;
2570
2579
  const wasFirst = firstInSegment;
2571
2580
  firstInSegment = false;
2572
- if (!wasFirst || cv.type !== NodeType.String) continue;
2581
+ if (!wasFirst || A.type(cv) !== NodeType.String) continue;
2573
2582
  const string = /** @type {Token} */ (cv);
2574
2583
  const start = prevStringEnd;
2575
- prevStringEnd = string.end;
2584
+ prevStringEnd = A.end(string);
2576
2585
  const value = normalizeUrl(
2577
- input.slice(string.start + 1, string.end - 1),
2586
+ input.slice(A.start(string) + 1, A.end(string) - 1),
2578
2587
  true
2579
2588
  );
2580
2589
  if (value.length === 0) continue;
2581
- if (webpackIgnored([start, string.end], string.start, string.end)) {
2590
+ if (
2591
+ webpackIgnored(
2592
+ [start, A.end(string)],
2593
+ A.start(string),
2594
+ A.end(string)
2595
+ )
2596
+ ) {
2582
2597
  continue;
2583
2598
  }
2584
2599
  const dep = new CssUrlDependency(
2585
2600
  value,
2586
- [string.start, string.end],
2601
+ [A.start(string), A.end(string)],
2587
2602
  "url"
2588
2603
  );
2589
- setDepLoc(dep, string.start, string.end);
2604
+ setDepLoc(dep, A.start(string), A.end(string));
2590
2605
  module.addDependency(dep);
2591
2606
  module.addCodeGenerationDependency(dep);
2592
2607
  }
@@ -2605,24 +2620,24 @@ class CssParser extends Parser {
2605
2620
  state,
2606
2621
  "Any '@import' rules must precede all other rules",
2607
2622
  locConverter,
2608
- at.start,
2609
- at.nameEnd
2623
+ A.start(at),
2624
+ A.nameEnd(at)
2610
2625
  );
2611
2626
  return;
2612
2627
  }
2613
- const importStart = at.start;
2614
- const importNameEnd = at.nameEnd;
2628
+ const importStart = A.start(at);
2629
+ const importNameEnd = A.nameEnd(at);
2615
2630
  // We only accept `;`-terminated @import; block / EOF / `}` ends are silent bails.
2616
- if (source.charCodeAt(at.end) !== CC_SEMICOLON) return;
2631
+ if (source.charCodeAt(A.end(at)) !== CC_SEMICOLON) return;
2617
2632
 
2618
2633
  // Walk the prelude in spec order (URL → layer? → supports? → media query); anything else joins the media query.
2619
2634
  const { urlNode, layerNode, supportsNode } = parseImportPrelude(
2620
- at.prelude
2635
+ A.prelude(at)
2621
2636
  );
2622
2637
 
2623
- const semi = at.end + 1; // position past `;`
2638
+ const semi = A.end(at) + 1; // position past `;`
2624
2639
 
2625
- if (!urlNode || (urlNode.type === NodeType.Ident && !isModules)) {
2640
+ if (!urlNode || (A.type(urlNode) === NodeType.Ident && !isModules)) {
2626
2641
  this._emitWarning(
2627
2642
  state,
2628
2643
  `Expected URL in '${input.slice(importStart, semi)}'`,
@@ -2630,17 +2645,16 @@ class CssParser extends Parser {
2630
2645
  importStart,
2631
2646
  semi
2632
2647
  );
2633
- // A malformed `@import` still emits orphan url() deps from its prelude — flag the node so the value visitors enable url().
2634
- /** @type {AtRule & { urlRecovery?: boolean }} */ (at).urlRecovery =
2635
- true;
2648
+ // A malformed `@import` still emits orphan url() deps from its prelude — flag it so the value visitors enable url().
2649
+ currentUrlRecovery = true;
2636
2650
  return;
2637
2651
  }
2638
2652
 
2639
2653
  /** @type {string} */
2640
2654
  let url;
2641
- if (urlNode.type === NodeType.Ident) {
2655
+ if (A.type(urlNode) === NodeType.Ident) {
2642
2656
  // URL given as identifier — resolve via CSS Modules `@value`.
2643
- const identName = /** @type {Token} */ (urlNode).value;
2657
+ const identName = A.value(urlNode);
2644
2658
  const def = icssDefinitions.get(identName);
2645
2659
  if (!def) {
2646
2660
  this._emitWarning(
@@ -2676,21 +2690,24 @@ class CssParser extends Parser {
2676
2690
  (raw.startsWith("'") && raw.endsWith("'"))
2677
2691
  ? normalizeUrl(raw.slice(1, -1), true)
2678
2692
  : normalizeUrl(raw, false);
2679
- } else if (urlNode.type === NodeType.Url) {
2693
+ } else if (A.type(urlNode) === NodeType.Url) {
2680
2694
  const ut = /** @type {UrlToken} */ (urlNode);
2681
- url = normalizeUrl(input.slice(ut.contentStart, ut.contentEnd), false);
2682
- } else if (urlNode.type === NodeType.String) {
2683
2695
  url = normalizeUrl(
2684
- input.slice(urlNode.start + 1, urlNode.end - 1),
2696
+ input.slice(A.contentStart(ut), A.contentEnd(ut)),
2697
+ false
2698
+ );
2699
+ } else if (A.type(urlNode) === NodeType.String) {
2700
+ url = normalizeUrl(
2701
+ input.slice(A.start(urlNode) + 1, A.end(urlNode) - 1),
2685
2702
  true
2686
2703
  );
2687
2704
  } else {
2688
2705
  // url(...) function — first non-whitespace child is the string.
2689
2706
  /** @type {Token | undefined} */
2690
2707
  let string;
2691
- for (const inner of /** @type {FunctionNode} */ (urlNode).value) {
2692
- if (inner.type === NodeType.Whitespace) continue;
2693
- if (inner.type === NodeType.String) {
2708
+ for (const inner of A.children(urlNode)) {
2709
+ if (A.type(inner) === NodeType.Whitespace) continue;
2710
+ if (A.type(inner) === NodeType.String) {
2694
2711
  string = /** @type {Token} */ (inner);
2695
2712
  }
2696
2713
  break;
@@ -2705,11 +2722,16 @@ class CssParser extends Parser {
2705
2722
  );
2706
2723
  return;
2707
2724
  }
2708
- url = normalizeUrl(input.slice(string.start + 1, string.end - 1), true);
2725
+ url = normalizeUrl(
2726
+ input.slice(A.start(string) + 1, A.end(string) - 1),
2727
+ true
2728
+ );
2709
2729
  }
2710
2730
 
2711
2731
  const newline = skipWhiteLine(input, semi);
2712
- if (webpackIgnored([importNameEnd, urlNode.end], importStart, newline)) {
2732
+ if (
2733
+ webpackIgnored([importNameEnd, A.end(urlNode)], importStart, newline)
2734
+ ) {
2713
2735
  return;
2714
2736
  }
2715
2737
  if (url.length === 0) {
@@ -2723,10 +2745,10 @@ class CssParser extends Parser {
2723
2745
  /** @type {undefined | string} */
2724
2746
  let layer;
2725
2747
  if (layerNode) {
2726
- if (layerNode.type === NodeType.Function) {
2748
+ if (A.type(layerNode) === NodeType.Function) {
2727
2749
  // `layer(<ident>)` — extract content between `(` and `)`.
2728
2750
  const fn = /** @type {FunctionNode} */ (layerNode);
2729
- layer = input.slice(fn.nameEnd + 1, fn.end - 1).trim();
2751
+ layer = input.slice(A.nameEnd(fn) + 1, A.end(fn) - 1).trim();
2730
2752
  } else {
2731
2753
  // Bare `layer` ident — anonymous layer.
2732
2754
  layer = "";
@@ -2737,21 +2759,23 @@ class CssParser extends Parser {
2737
2759
  let supports;
2738
2760
  if (supportsNode) {
2739
2761
  supports = input
2740
- .slice(supportsNode.nameEnd + 1, supportsNode.end - 1)
2762
+ .slice(A.nameEnd(supportsNode) + 1, A.end(supportsNode) - 1)
2741
2763
  .trim();
2742
2764
  }
2743
2765
 
2744
2766
  // Media query = whatever sits between the last url/layer/supports part and the closing `;`, trimmed. Start at the next non-whitespace prelude node (skips the gap, comments included).
2745
2767
  const lastPrefixPart = supportsNode || layerNode || urlNode;
2746
2768
  const afterIdx =
2747
- /** @type {AstNode[]} */ (at.prelude).indexOf(lastPrefixPart) + 1;
2748
- const nextIdx = nextNonWhitespace(at.prelude, afterIdx);
2769
+ /** @type {AstNode[]} */ (A.prelude(at)).indexOf(lastPrefixPart) + 1;
2770
+ const nextIdx = nextNonWhitespace(A.prelude(at), afterIdx);
2749
2771
  const mediaStart =
2750
- nextIdx < at.prelude.length ? at.prelude[nextIdx].start : at.end;
2772
+ nextIdx < A.prelude(at).length
2773
+ ? A.start(A.prelude(at)[nextIdx])
2774
+ : A.end(at);
2751
2775
  /** @type {undefined | string} */
2752
2776
  let media;
2753
- if (mediaStart !== at.end) {
2754
- media = input.slice(mediaStart, at.end).trim();
2777
+ if (mediaStart !== A.end(at)) {
2778
+ media = input.slice(mediaStart, A.end(at)).trim();
2755
2779
  }
2756
2780
 
2757
2781
  const { line: sl, column: sc } = locConverter.get(importStart);
@@ -2793,9 +2817,9 @@ class CssParser extends Parser {
2793
2817
  * @param {AtRule} at the `@value` at-rule
2794
2818
  */
2795
2819
  const handleValueAtRule = (at) => {
2796
- const start = at.start;
2797
- const nameEnd = at.nameEnd;
2798
- const semi = at.end;
2820
+ const start = A.start(at);
2821
+ const nameEnd = A.nameEnd(at);
2822
+ const semi = A.end(at);
2799
2823
  const atRuleEnd =
2800
2824
  source.charCodeAt(semi) === CC_SEMICOLON ? semi + 1 : semi;
2801
2825
  const params = input.slice(nameEnd, semi);
@@ -2956,12 +2980,12 @@ class CssParser extends Parser {
2956
2980
  /** @type {(cvs: AstNode[]) => void} */
2957
2981
  const walkExports = (cvs) => {
2958
2982
  for (const cv of cvs) {
2959
- switch (cv.type) {
2983
+ switch (A.type(cv)) {
2960
2984
  case NodeType.Comma:
2961
2985
  parsedKeywords = Object.create(null);
2962
2986
  break;
2963
2987
  case NodeType.Delim:
2964
- afterExclamation = /** @type {Token} */ (cv).value === "!";
2988
+ afterExclamation = A.value(cv) === "!";
2965
2989
  break;
2966
2990
  case NodeType.Ident: {
2967
2991
  if (isGridTemplate) break;
@@ -2969,7 +2993,7 @@ class CssParser extends Parser {
2969
2993
  afterExclamation = false;
2970
2994
  break;
2971
2995
  }
2972
- const identifier = /** @type {Token} */ (cv).value;
2996
+ const identifier = A.value(cv);
2973
2997
  const keyword = identifier.toLowerCase();
2974
2998
  parsedKeywords[keyword] =
2975
2999
  typeof parsedKeywords[keyword] !== "undefined"
@@ -2981,7 +3005,7 @@ class CssParser extends Parser {
2981
3005
  ) {
2982
3006
  break;
2983
3007
  }
2984
- emit(cv.start, cv.end);
3008
+ emit(A.start(cv), A.end(cv));
2985
3009
  break;
2986
3010
  }
2987
3011
  case NodeType.String: {
@@ -2989,17 +3013,17 @@ class CssParser extends Parser {
2989
3013
  declPropertyName === "animation" ||
2990
3014
  declPropertyName === "animation-name"
2991
3015
  ) {
2992
- emit(cv.start, cv.end, true);
3016
+ emit(A.start(cv), A.end(cv), true);
2993
3017
  }
2994
3018
  if (
2995
3019
  declPropertyName === "grid" ||
2996
3020
  declPropertyName === "grid-template" ||
2997
3021
  declPropertyName === "grid-template-areas"
2998
3022
  ) {
2999
- const areas = /** @type {Token} */ (cv).unescaped;
3023
+ const areas = A.unescaped(cv);
3000
3024
  const matches = matchAll(/\b\w+\b/g, areas);
3001
3025
  for (const match of matches) {
3002
- const areaStart = cv.start + 1 + match.index;
3026
+ const areaStart = A.start(cv) + 1 + match.index;
3003
3027
  emit(areaStart, areaStart + match[0].length, false);
3004
3028
  }
3005
3029
  }
@@ -3007,28 +3031,28 @@ class CssParser extends Parser {
3007
3031
  }
3008
3032
  case NodeType.SimpleBlock: {
3009
3033
  const block = /** @type {SimpleBlock} */ (cv);
3010
- if (block.token === "[") {
3034
+ if (A.blockToken(block) === "[") {
3011
3035
  // Collect identifiers until the first non-ident token (`<line-names> = '[' <custom-ident>* ']'`).
3012
- for (const inner of block.value) {
3013
- if (inner.type === NodeType.Whitespace) continue;
3014
- if (inner.type !== NodeType.Ident) break;
3015
- emit(inner.start, inner.end);
3036
+ for (const inner of A.children(block)) {
3037
+ if (A.type(inner) === NodeType.Whitespace) continue;
3038
+ if (A.type(inner) !== NodeType.Ident) break;
3039
+ emit(A.start(inner), A.end(inner));
3016
3040
  }
3017
3041
  } else if (isGridTemplate) {
3018
- walkExports(block.value);
3042
+ walkExports(A.children(block));
3019
3043
  }
3020
3044
  break;
3021
3045
  }
3022
3046
  case NodeType.Function:
3023
3047
  if (isGridTemplate) {
3024
- walkExports(/** @type {FunctionNode} */ (cv).value);
3048
+ walkExports(A.children(cv));
3025
3049
  }
3026
3050
  break;
3027
3051
  // Other types carry no ICSS-export information.
3028
3052
  }
3029
3053
  }
3030
3054
  };
3031
- walkExports(decl.value);
3055
+ walkExports(A.children(decl));
3032
3056
  };
3033
3057
 
3034
3058
  /**
@@ -3047,27 +3071,26 @@ class CssParser extends Parser {
3047
3071
  ) => {
3048
3072
  const acceptIdent = isKeyframes || isCounterStyle || isContainer;
3049
3073
  const acceptString = isKeyframes;
3050
- for (const cv of at.prelude) {
3051
- if (cv.type === NodeType.Whitespace) continue;
3052
- if (cv.type === NodeType.String) {
3074
+ for (const cv of A.prelude(at)) {
3075
+ const cvType = A.type(cv);
3076
+ if (cvType === NodeType.Whitespace) continue;
3077
+ if (cvType === NodeType.String) {
3053
3078
  if (acceptString) pure.markLocal();
3054
3079
  break;
3055
3080
  }
3056
- if (cv.type === NodeType.Ident) {
3081
+ if (cvType === NodeType.Ident) {
3057
3082
  if (!acceptIdent) break;
3058
- if (isContainer && isContainerKeyword(source, cv.start, cv.end)) {
3083
+ if (
3084
+ isContainer &&
3085
+ isContainerKeyword(source, A.start(cv), A.end(cv))
3086
+ ) {
3059
3087
  continue;
3060
3088
  }
3061
3089
  pure.markLocal();
3062
3090
  break;
3063
3091
  }
3064
- if (cv.type === NodeType.Function) {
3065
- if (
3066
- equalsLowerCase(
3067
- /** @type {FunctionNode} */ (cv).unescapedName,
3068
- "local"
3069
- )
3070
- ) {
3092
+ if (cvType === NodeType.Function) {
3093
+ if (equalsLowerCase(A.unescapedName(cv), "local")) {
3071
3094
  pure.markLocal();
3072
3095
  }
3073
3096
  break;
@@ -3083,7 +3106,8 @@ class CssParser extends Parser {
3083
3106
  enter: (node, parent) => {
3084
3107
  const at = /** @type {AtRule} */ (node);
3085
3108
  const topLevel = parent === null;
3086
- advanceCommentCursor(at.start);
3109
+ currentUrlRecovery = false;
3110
+ advanceCommentCursor(A.start(at));
3087
3111
  const savedAnchor = currentRule.hasLocalAnchor;
3088
3112
  const savedLocalIdentifiers = currentRule.localIdentifiers;
3089
3113
  // Only modules-mode walks mutate `localIdentifiers`; otherwise share
@@ -3091,33 +3115,32 @@ class CssParser extends Parser {
3091
3115
  currentRule.localIdentifiers = isModules
3092
3116
  ? [...savedLocalIdentifiers]
3093
3117
  : savedLocalIdentifiers;
3094
- const name = `@${at.name.toLowerCase()}`;
3118
+ const name = `@${A.name(at).toLowerCase()}`;
3095
3119
  switch (name) {
3096
3120
  case "@namespace": {
3097
3121
  this._emitWarning(
3098
3122
  state,
3099
3123
  "'@namespace' is not supported in bundled CSS",
3100
3124
  locConverter,
3101
- at.start,
3102
- at.nameEnd
3125
+ A.start(at),
3126
+ A.nameEnd(at)
3103
3127
  );
3104
3128
  break;
3105
3129
  }
3106
3130
  case "@charset": {
3107
3131
  if (/** @type {CssModule} */ (module).exportType !== "style") {
3132
+ const atEnd = A.end(at);
3108
3133
  const atRuleEnd =
3109
- source.charCodeAt(at.end) === CC_SEMICOLON
3110
- ? at.end + 1
3111
- : at.end;
3112
- const dep = new ConstDependency("", [at.start, atRuleEnd]);
3134
+ source.charCodeAt(atEnd) === CC_SEMICOLON ? atEnd + 1 : atEnd;
3135
+ const dep = new ConstDependency("", [A.start(at), atRuleEnd]);
3113
3136
  module.addPresentationalDependency(dep);
3114
- const string = at.prelude.find(
3115
- (v) => v.type !== NodeType.Whitespace
3137
+ const string = A.prelude(at).find(
3138
+ (v) => A.type(v) !== NodeType.Whitespace
3116
3139
  );
3117
- if (string && string.type === NodeType.String) {
3140
+ if (string && A.type(string) === NodeType.String) {
3118
3141
  /** @type {CssModuleBuildInfo} */
3119
3142
  (module.buildInfo).charset = source
3120
- .slice(string.start + 1, string.end - 1)
3143
+ .slice(A.start(string) + 1, A.end(string) - 1)
3121
3144
  .toUpperCase();
3122
3145
  }
3123
3146
  }
@@ -3158,11 +3181,11 @@ class CssParser extends Parser {
3158
3181
  // `@scope (.x) to (.y)` — walk the prelude as a selector list.
3159
3182
  if (
3160
3183
  isModules &&
3161
- equalsLowerCase(at.name, "scope") &&
3162
- at.prelude.length > 0
3184
+ equalsLowerCase(A.name(at), "scope") &&
3185
+ A.prelude(at).length > 0
3163
3186
  ) {
3164
3187
  walkSelectorList(
3165
- at.prelude,
3188
+ A.prelude(at),
3166
3189
  /** @type {"local" | "global"} */ (
3167
3190
  mode === "local" ? "local" : "global"
3168
3191
  )
@@ -3175,14 +3198,9 @@ class CssParser extends Parser {
3175
3198
  currentStructural = at;
3176
3199
  currentAtRuleName = name;
3177
3200
  dashed.active = false;
3178
- // `@import` url() is the import target — only walk its prelude for url deps on malformed-import recovery (flagged on the node).
3179
- const atWithRecovery =
3180
- /** @type {AtRule & { urlRecovery?: boolean }} */ (at);
3181
- if (
3182
- this.options.url &&
3183
- (name !== "@import" || atWithRecovery.urlRecovery)
3184
- ) {
3185
- lastTokenEndForComments = at.nameEnd;
3201
+ // `@import` url() is the import target — only walk its prelude for url deps on malformed-import recovery.
3202
+ if (this.options.url && (name !== "@import" || currentUrlRecovery)) {
3203
+ lastTokenEndForComments = A.nameEnd(at);
3186
3204
  }
3187
3205
  // Dashed-ident scoping over the prelude (the Ident / Function visitors emit).
3188
3206
  dashed.active = Boolean(
@@ -3219,18 +3237,21 @@ class CssParser extends Parser {
3219
3237
  }
3220
3238
 
3221
3239
  // pure.stack push for block-bearing at-rules.
3222
- const atHasBlock = Boolean(at.declarations || at.childRules);
3223
- if (atHasBlock && at.blockStart !== -1) {
3240
+ const atDecls = A.declarations(at);
3241
+ const atChildRules = A.childRules(at);
3242
+ const atHasBlock = Boolean(atDecls || atChildRules);
3243
+ const atBlockStart = A.blockStart(at);
3244
+ if (atHasBlock && atBlockStart !== -1) {
3224
3245
  const isAtRulePrelude = isPureBodyAtRule(name);
3225
3246
  if (isAtRulePrelude) pure.finalizeSelector();
3226
3247
  pure.enterBlock({
3227
3248
  isRulePrelude: isAtRulePrelude,
3228
3249
  treatAsLeaf: atTreatAsLeaf,
3229
3250
  ownSkip: atSkipChildren,
3230
- declarations: at.declarations,
3231
- childRules: at.childRules,
3232
- preludeStart: at.start,
3233
- preludeEnd: at.blockStart
3251
+ declarations: atDecls,
3252
+ childRules: atChildRules,
3253
+ preludeStart: A.start(at),
3254
+ preludeEnd: atBlockStart
3234
3255
  });
3235
3256
  }
3236
3257
 
@@ -3239,7 +3260,7 @@ class CssParser extends Parser {
3239
3260
  savedLocalIdentifiers,
3240
3261
  name,
3241
3262
  hasBlock: atHasBlock,
3242
- endsWithSemicolon: source.charCodeAt(at.end) === CC_SEMICOLON
3263
+ endsWithSemicolon: source.charCodeAt(A.end(at)) === CC_SEMICOLON
3243
3264
  });
3244
3265
  },
3245
3266
  // At-rule exit: pure-frame finalization, `suppressNextRulePrelude`, scope restore, top-level reset.
@@ -3266,25 +3287,27 @@ class CssParser extends Parser {
3266
3287
  enter: (node, parent, ctx) => {
3267
3288
  const rule = /** @type {QualifiedRule} */ (node);
3268
3289
  const topLevel = parent === null;
3269
- advanceCommentCursor(rule.start);
3290
+ advanceCommentCursor(A.start(rule));
3270
3291
  // `:import(…) { … }` / `:export { … }` ICSS pseudo-rules are processed inline at top level; nested ones bail out.
3271
3292
  if (isModules) {
3272
- const firstIdx = nextNonWhitespace(rule.prelude, 0);
3293
+ const rulePrelude = A.prelude(rule);
3294
+ const firstIdx = nextNonWhitespace(rulePrelude, 0);
3273
3295
  if (
3274
- firstIdx + 1 < rule.prelude.length &&
3275
- rule.prelude[firstIdx].type === NodeType.Colon
3296
+ firstIdx + 1 < rulePrelude.length &&
3297
+ A.type(rulePrelude[firstIdx]) === NodeType.Colon
3276
3298
  ) {
3277
- const second = rule.prelude[firstIdx + 1];
3299
+ const second = rulePrelude[firstIdx + 1];
3300
+ const secondType = A.type(second);
3278
3301
  const rawName =
3279
- second.type === NodeType.Ident
3280
- ? /** @type {Token} */ (second).value
3281
- : second.type === NodeType.Function
3282
- ? /** @type {FunctionNode} */ (second).name
3302
+ secondType === NodeType.Ident
3303
+ ? A.value(second)
3304
+ : secondType === NodeType.Function
3305
+ ? A.name(second)
3283
3306
  : "";
3284
3307
  const isImport = equalsLowerCase(rawName, "import");
3285
3308
  if (isImport || equalsLowerCase(rawName, "export")) {
3286
3309
  if (topLevel) {
3287
- const startColon = rule.prelude[firstIdx].start;
3310
+ const startColon = A.start(rulePrelude[firstIdx]);
3288
3311
  const endAfterBody = processImportOrExport(
3289
3312
  isImport ? 0 : 1,
3290
3313
  second,
@@ -3293,11 +3316,13 @@ class CssParser extends Parser {
3293
3316
  module.addPresentationalDependency(
3294
3317
  new ConstDependency("", [startColon, endAfterBody])
3295
3318
  );
3296
- if (rule.blockStart !== -1) rule.blockEnd = endAfterBody;
3297
- rule.end = endAfterBody;
3298
- } else if (rule.blockStart !== -1) {
3319
+ if (A.blockStart(rule) !== -1) {
3320
+ A.setBlockEnd(rule, endAfterBody);
3321
+ }
3322
+ A.setEnd(rule, endAfterBody);
3323
+ } else if (A.blockStart(rule) !== -1) {
3299
3324
  // Nested `:import` / `:export` — leave the body alone.
3300
- rule.end = rule.blockEnd;
3325
+ A.setEnd(rule, A.blockEnd(rule));
3301
3326
  }
3302
3327
  // Don't recurse into the body — handled inline above.
3303
3328
  if (ctx) ctx.skipChildren();
@@ -3327,9 +3352,10 @@ class CssParser extends Parser {
3327
3352
  savedComposesFiles
3328
3353
  });
3329
3354
  // Selectors are only CSS-Modules-relevant when `isModules` holds.
3355
+ const rulePrelude = A.prelude(rule);
3330
3356
  if (isModules) {
3331
3357
  walkSelectorList(
3332
- rule.prelude,
3358
+ rulePrelude,
3333
3359
  /** @type {"local" | "global"} */ (
3334
3360
  mode === "local" ? "local" : "global"
3335
3361
  )
@@ -3339,20 +3365,20 @@ class CssParser extends Parser {
3339
3365
  currentStructural = rule;
3340
3366
  dashed.active = false;
3341
3367
  dashed.emit = false;
3342
- if (this.options.url && rule.prelude.length > 0) {
3343
- lastTokenEndForComments = rule.prelude[0].start;
3368
+ if (this.options.url && rulePrelude.length > 0) {
3369
+ lastTokenEndForComments = A.start(rulePrelude[0]);
3344
3370
  }
3345
3371
  // Dashed-ident scoping for the deprecated `--foo: { … }` custom-property-set syntax (prelude starts with a dashed-ident).
3346
3372
  if (
3347
3373
  this.options.dashedIdents &&
3348
3374
  isModules &&
3349
- rule.prelude.length > 0
3375
+ rulePrelude.length > 0
3350
3376
  ) {
3351
- const first = rule.prelude[nextNonWhitespace(rule.prelude, 0)];
3377
+ const first = rulePrelude[nextNonWhitespace(rulePrelude, 0)];
3352
3378
  if (
3353
3379
  first &&
3354
- first.type === NodeType.Ident &&
3355
- isDashedIdentifier(/** @type {Token} */ (first).value)
3380
+ A.type(first) === NodeType.Ident &&
3381
+ isDashedIdentifier(A.value(first))
3356
3382
  ) {
3357
3383
  const effectiveLocalMode = isEffectivelyLocal();
3358
3384
  if (effectiveLocalMode) {
@@ -3362,14 +3388,15 @@ class CssParser extends Parser {
3362
3388
  }
3363
3389
  }
3364
3390
  // Pure-mode: report an impure prelude (if leaf-ish) and push the inherited-context frame before walking the body.
3391
+ const ruleBlockStart = A.blockStart(rule);
3365
3392
  pure.enterBlock({
3366
3393
  isRulePrelude: true,
3367
3394
  treatAsLeaf: false,
3368
3395
  ownSkip: false,
3369
- declarations: rule.declarations,
3370
- childRules: rule.childRules,
3371
- preludeStart: rule.start,
3372
- preludeEnd: rule.blockStart !== -1 ? rule.blockStart : rule.end
3396
+ declarations: A.declarations(rule),
3397
+ childRules: A.childRules(rule),
3398
+ preludeStart: A.start(rule),
3399
+ preludeEnd: ruleBlockStart !== -1 ? ruleBlockStart : A.end(rule)
3373
3400
  });
3374
3401
  },
3375
3402
  // Qualified-rule exit: pure-frame finalization, scope restore, top-level reset; no-op for bailed ICSS.
@@ -3391,13 +3418,8 @@ class CssParser extends Parser {
3391
3418
  currentStructural = decl;
3392
3419
  dashed.active = false;
3393
3420
  dashed.emit = false;
3394
- const declPropertyName = decl.name
3395
- .replace(/^(-\w+-)/, "")
3396
- .toLowerCase();
3397
- // Cache the known-property flag so the per-token value visitors don't recompute it.
3398
- currentDeclIsKnownProperty = knownProperties.has(declPropertyName);
3399
- // Position `lastTokenEndForComments` just past the `:` so a magic comment before the url() is found.
3400
- let colonPos = decl.nameEnd;
3421
+ // Position `lastTokenEndForComments` just past the `:` so a magic comment before a url() is found (every mode).
3422
+ let colonPos = A.nameEnd(decl);
3401
3423
  while (
3402
3424
  colonPos < source.length &&
3403
3425
  source.charCodeAt(colonPos) !== CC_COLON
@@ -3405,6 +3427,15 @@ class CssParser extends Parser {
3405
3427
  colonPos++;
3406
3428
  }
3407
3429
  lastTokenEndForComments = colonPos + 1;
3430
+ currentDeclIsKnownProperty = false;
3431
+ currentDeclComposesSkip = false;
3432
+ // Property-name analysis and value exports are CSS-Modules-only; a plain
3433
+ // stylesheet's declarations need no per-decl name slice / known-property lookup.
3434
+ if (!isModules) return;
3435
+ const declName = A.name(decl);
3436
+ const declPropertyName = declName.replace(/^(-\w+-)/, "").toLowerCase();
3437
+ // Cache the known-property flag so the per-token value visitors don't recompute it.
3438
+ currentDeclIsKnownProperty = knownProperties.has(declPropertyName);
3408
3439
  const effectiveLocalMode = isEffectivelyLocal();
3409
3440
  // `composes:` with a local anchor: its strip-dep covers the whole declaration, so suppress the value's local/global/dashed/ICSS rewrites.
3410
3441
  currentDeclComposesSkip =
@@ -3413,31 +3444,29 @@ class CssParser extends Parser {
3413
3444
  if (currentDeclComposesSkip) emitComposesWithAnchor(decl);
3414
3445
  const skipForComposes = currentDeclComposesSkip;
3415
3446
  // Known-property value localization (`animation-name: foo` exports `foo`).
3416
- if (isModules && effectiveLocalMode && currentDeclIsKnownProperty) {
3447
+ if (effectiveLocalMode && currentDeclIsKnownProperty) {
3417
3448
  emitKnownPropertyExports(decl, declPropertyName);
3418
3449
  }
3419
3450
  // Dashed-ident (custom-property) export of the property name; the value's dashed idents are scoped by the Ident / Function visitors (top-level only for unknown properties).
3420
3451
  if (
3421
3452
  this.options.dashedIdents &&
3422
- isModules &&
3423
3453
  effectiveLocalMode &&
3424
3454
  !skipForComposes
3425
3455
  ) {
3426
- if (isDashedIdentifier(decl.name)) {
3427
- emitDashedIdentExport(decl.nameStart, decl.nameEnd);
3456
+ if (isDashedIdentifier(declName)) {
3457
+ emitDashedIdentExport(A.nameStart(decl), A.nameEnd(decl));
3428
3458
  }
3429
3459
  dashed.active = true;
3430
3460
  dashed.emit = !currentDeclIsKnownProperty;
3431
3461
  }
3432
3462
  // ICSS-symbol rewrite (`color: foo` when `foo` is `@value`-defined), skipping known properties, the composes anchor, and dashed idents (handled above).
3433
3463
  if (
3434
- isModules &&
3435
3464
  !skipForComposes &&
3436
3465
  !currentDeclIsKnownProperty &&
3437
- !(dashed.active && isDashedIdentifier(decl.name)) &&
3438
- icssDefinitions.has(decl.name)
3466
+ !(dashed.active && isDashedIdentifier(declName)) &&
3467
+ icssDefinitions.has(declName)
3439
3468
  ) {
3440
- emitICSSSymbol(decl.name, decl.nameStart, decl.nameEnd);
3469
+ emitICSSSymbol(declName, A.nameStart(decl), A.nameEnd(decl));
3441
3470
  }
3442
3471
  },
3443
3472
  // Value-level visitors decide handling from the enclosing node via `urlActive()` / `localGlobalActive()` / `icssActive()`.
@@ -3447,7 +3476,7 @@ class CssParser extends Parser {
3447
3476
  // Skip bare url-tokens for a known property in CSS-Modules local mode.
3448
3477
  if (
3449
3478
  currentStructural &&
3450
- currentStructural.type === NodeType.Declaration &&
3479
+ A.type(currentStructural) === NodeType.Declaration &&
3451
3480
  isModules &&
3452
3481
  currentDeclIsKnownProperty &&
3453
3482
  isEffectivelyLocal()
@@ -3456,15 +3485,15 @@ class CssParser extends Parser {
3456
3485
  }
3457
3486
  if (
3458
3487
  webpackIgnored(
3459
- [lastTokenEndForComments, node.end],
3488
+ [lastTokenEndForComments, A.end(node)],
3460
3489
  lastTokenEndForComments,
3461
- node.end
3490
+ A.end(node)
3462
3491
  )
3463
3492
  ) {
3464
3493
  return;
3465
3494
  }
3466
3495
  let value = normalizeUrl(
3467
- input.slice(url.contentStart, url.contentEnd),
3496
+ input.slice(A.contentStart(url), A.contentEnd(url)),
3468
3497
  false
3469
3498
  );
3470
3499
  // Ignore `url()`, `url('')` and `url("")`, they are valid by spec
@@ -3485,25 +3514,29 @@ class CssParser extends Parser {
3485
3514
  state,
3486
3515
  `'@value' identifier '${value}' was imported from another module and cannot be used inside 'url()' — only locally defined values are supported here`,
3487
3516
  locConverter,
3488
- node.start,
3489
- node.end
3517
+ A.start(node),
3518
+ A.end(node)
3490
3519
  );
3491
3520
  return;
3492
3521
  }
3493
3522
  }
3494
3523
  }
3495
- const dep = new CssUrlDependency(value, [node.start, node.end], "url");
3496
- setDepLoc(dep, node.start, node.end);
3524
+ const dep = new CssUrlDependency(
3525
+ value,
3526
+ [A.start(node), A.end(node)],
3527
+ "url"
3528
+ );
3529
+ setDepLoc(dep, A.start(node), A.end(node));
3497
3530
  module.addDependency(dep);
3498
3531
  module.addCodeGenerationDependency(dep);
3499
3532
  },
3500
3533
  [NodeType.Comma](node) {
3501
- if (urlActive()) lastTokenEndForComments = node.start;
3534
+ if (urlActive()) lastTokenEndForComments = A.start(node);
3502
3535
  },
3503
3536
  [NodeType.Function]: {
3504
3537
  enter: (node) => {
3505
3538
  const fn = /** @type {FunctionNode} */ (node);
3506
- const fnameRaw = fn.unescapedName;
3539
+ const fnameRaw = A.unescapedName(fn);
3507
3540
  const fname = fnameRaw.toLowerCase();
3508
3541
  if (urlActive()) emitUrlFunction(fn, fname);
3509
3542
  if (
@@ -3519,7 +3552,7 @@ class CssParser extends Parser {
3519
3552
  !(dashed.active && isDashedIdentifier(fnameRaw)) &&
3520
3553
  icssDefinitions.has(fnameRaw)
3521
3554
  ) {
3522
- emitICSSSymbol(fnameRaw, fn.nameStart, fn.nameEnd);
3555
+ emitICSSSymbol(fnameRaw, A.nameStart(fn), A.nameEnd(fn));
3523
3556
  }
3524
3557
  // Dashed-ident scoping: handle this function, then set the child nesting level's state for the walk.
3525
3558
  dashed.push();
@@ -3531,9 +3564,9 @@ class CssParser extends Parser {
3531
3564
  // `var(--foo, …)` / `style(--foo, …)`: emit the first ident; the fallback doesn't self-emit.
3532
3565
  processDashedIdentInVarFunction(fn);
3533
3566
  dashed.emit = false;
3534
- } else if (dashed.emit && isDashedIdentifier(fn.name)) {
3567
+ } else if (dashed.emit && isDashedIdentifier(A.name(fn))) {
3535
3568
  // Custom-function call `--my-func(args)` — the name is the exported dashed-ident.
3536
- emitDashedIdentExport(fn.nameStart, fn.nameEnd);
3569
+ emitDashedIdentExport(A.nameStart(fn), A.nameEnd(fn));
3537
3570
  }
3538
3571
  }
3539
3572
  },
@@ -3542,8 +3575,15 @@ class CssParser extends Parser {
3542
3575
  }
3543
3576
  },
3544
3577
  [NodeType.Ident](node, parent) {
3545
- const identValue = /** @type {Token} */ (node).value;
3546
- if (dashed.active && isDashedIdentifier(identValue)) {
3578
+ // Fast exit before slicing the ident value: outside dashed-ident scoping
3579
+ // and ICSS context (any non-CSS-Modules stylesheet) a bare ident carries
3580
+ // no work, and idents are the most common node, so skipping the per-ident
3581
+ // `value` slice matters.
3582
+ const dashedActive = dashed.active;
3583
+ const icss = icssActive();
3584
+ if (!dashedActive && !icss) return;
3585
+ const identValue = A.value(node);
3586
+ if (dashedActive && isDashedIdentifier(identValue)) {
3547
3587
  // Dashed idents are scoped here, never `@value` ICSS-rewritten.
3548
3588
  if (!dashed.emit) return;
3549
3589
  // Resolve the `--foo from "./x.css"` / `--foo from global` import suffix via sibling lookahead.
@@ -3553,37 +3593,37 @@ class CssParser extends Parser {
3553
3593
  const j = nextNonWhitespace(siblings, i + 1);
3554
3594
  if (
3555
3595
  j < siblings.length &&
3556
- siblings[j].type === NodeType.Ident &&
3557
- equalsLowerCase(/** @type {Token} */ (siblings[j]).value, "from")
3596
+ A.type(siblings[j]) === NodeType.Ident &&
3597
+ equalsLowerCase(A.value(siblings[j]), "from")
3558
3598
  ) {
3559
3599
  const fromIdent = siblings[j];
3560
3600
  const sourceNode = siblings[nextNonWhitespace(siblings, j + 1)];
3561
3601
  if (
3562
3602
  sourceNode &&
3563
- sourceNode.type === NodeType.Ident &&
3564
- /** @type {Token} */ (sourceNode).value === "global"
3603
+ A.type(sourceNode) === NodeType.Ident &&
3604
+ A.value(sourceNode) === "global"
3565
3605
  ) {
3566
- emitDashedIdentFromGlobal(node.end, sourceNode.end);
3606
+ emitDashedIdentFromGlobal(A.end(node), A.end(sourceNode));
3567
3607
  return;
3568
3608
  }
3569
- if (sourceNode && sourceNode.type === NodeType.String) {
3609
+ if (sourceNode && A.type(sourceNode) === NodeType.String) {
3570
3610
  emitDashedIdentImport(
3571
- node.start,
3572
- node.end,
3573
- fromIdent.start,
3574
- sourceNode.end,
3575
- input.slice(sourceNode.start + 1, sourceNode.end - 1)
3611
+ A.start(node),
3612
+ A.end(node),
3613
+ A.start(fromIdent),
3614
+ A.end(sourceNode),
3615
+ input.slice(A.start(sourceNode) + 1, A.end(sourceNode) - 1)
3576
3616
  );
3577
3617
  return;
3578
3618
  }
3579
3619
  }
3580
3620
  }
3581
- emitDashedIdentExport(node.start, node.end);
3621
+ emitDashedIdentExport(A.start(node), A.end(node));
3582
3622
  return;
3583
3623
  }
3584
- if (!icssActive()) return;
3624
+ if (!icss) return;
3585
3625
  if (icssDefinitions.has(identValue)) {
3586
- emitICSSSymbol(identValue, node.start, node.end);
3626
+ emitICSSSymbol(identValue, A.start(node), A.end(node));
3587
3627
  }
3588
3628
  }
3589
3629
  };