parseman 0.50.0 → 0.50.1

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.
@@ -5884,6 +5884,22 @@ var Encoder = class {
5884
5884
  choiceRollbackMasks = /* @__PURE__ */ new Map();
5885
5885
  nonCommittingChoiceSites = /* @__PURE__ */ new Set();
5886
5886
  failureRollbackCleanSites = /* @__PURE__ */ new Set();
5887
+ /**
5888
+ * `hasSideWriter` memo for `failureNeedsRollback`, shared across every call
5889
+ * for the lifetime of this `Encoder`. A cached entry is written only when
5890
+ * `complete` is true, which means the answer is a path-independent fact
5891
+ * about that combinator node — it does not depend on which root's traversal
5892
+ * asked, only on the node's own reachable subgraph. Scoping the memo per call
5893
+ * (as a local inside `failureNeedsRollback`) was correct but discarded that
5894
+ * fact after every arm, so a grammar with many ordered-choice arms / optional
5895
+ * / attempt sites re-walked the SAME shared rule graph from scratch for each
5896
+ * site — O(sites × graph size) instead of O(graph size). Measured on the
5897
+ * scss-parser grammar (composed CSS-base superset, the deepest/largest of the
5898
+ * four grammars): 47-50s for one `compileRuleMap` with the per-call memo,
5899
+ * versus the whole macro transform completing in under a second once this
5900
+ * memo is hoisted here.
5901
+ */
5902
+ sideWriterMemo = /* @__PURE__ */ new Map();
5887
5903
  labels = void 0;
5888
5904
  /** Trivia table in scope at the row being encoded — codegen's `ctx.activeTrivia`. */
5889
5905
  activeTrivia = void 0;
@@ -6309,13 +6325,13 @@ var Encoder = class {
6309
6325
  const refName = p._ruleName;
6310
6326
  const winner = refName === void 0 ? void 0 : this.winners?.[refName];
6311
6327
  const root = winner !== void 0 && !winnerWrapsReference2(winner, p) ? winner : p;
6312
- const sideWriterMemo = /* @__PURE__ */ new Map();
6313
- const hasSideWriter = (current, seen = /* @__PURE__ */ new Set()) => {
6328
+ const sideWriterMemo = this.sideWriterMemo;
6329
+ const seen = /* @__PURE__ */ new Set();
6330
+ const hasSideWriter = (current) => {
6314
6331
  const cached = sideWriterMemo.get(current);
6315
6332
  if (cached !== void 0) return { found: cached, complete: true };
6316
6333
  if (seen.has(current)) return { found: false, complete: false };
6317
- const next = new Set(seen);
6318
- next.add(current);
6334
+ seen.add(current);
6319
6335
  const def = current._def;
6320
6336
  let result;
6321
6337
  switch (def.tag) {
@@ -6330,11 +6346,11 @@ var Encoder = class {
6330
6346
  const name = current._ruleName;
6331
6347
  const resolvedWinner = name === void 0 ? void 0 : this.winners?.[name];
6332
6348
  if (resolvedWinner !== void 0 && !winnerWrapsReference2(resolvedWinner, current)) {
6333
- result = hasSideWriter(resolvedWinner, next);
6349
+ result = hasSideWriter(resolvedWinner);
6334
6350
  break;
6335
6351
  }
6336
6352
  try {
6337
- result = hasSideWriter(def.thunk(), next);
6353
+ result = hasSideWriter(def.thunk());
6338
6354
  } catch {
6339
6355
  result = { found: true, complete: true };
6340
6356
  }
@@ -6344,7 +6360,7 @@ var Encoder = class {
6344
6360
  let complete = true;
6345
6361
  result = { found: false, complete: true };
6346
6362
  for (const child of childrenOf(def)) {
6347
- const childResult = hasSideWriter(child, next);
6363
+ const childResult = hasSideWriter(child);
6348
6364
  if (childResult.found) {
6349
6365
  result = { found: true, complete: true };
6350
6366
  break;
@@ -6354,6 +6370,7 @@ var Encoder = class {
6354
6370
  if (!result.found) result = { found: false, complete };
6355
6371
  }
6356
6372
  }
6373
+ seen.delete(current);
6357
6374
  if (result.found || result.complete) sideWriterMemo.set(current, result.found);
6358
6375
  return result;
6359
6376
  };