parseman 0.43.0 → 0.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/analysis/diagnose.d.ts +118 -0
  2. package/dist/analysis/diagnose.d.ts.map +1 -0
  3. package/dist/analysis/gating.d.ts +9 -9
  4. package/dist/analysis/gating.d.ts.map +1 -1
  5. package/dist/analysis/grammar.d.ts.map +1 -1
  6. package/dist/combinators/attempt.d.ts.map +1 -1
  7. package/dist/combinators/choice.d.ts.map +1 -1
  8. package/dist/combinators/dispatch.d.ts +19 -1
  9. package/dist/combinators/dispatch.d.ts.map +1 -1
  10. package/dist/combinators/expect.d.ts.map +1 -1
  11. package/dist/combinators/first-set.d.ts.map +1 -1
  12. package/dist/combinators/grammar.d.ts +7 -0
  13. package/dist/combinators/grammar.d.ts.map +1 -1
  14. package/dist/combinators/map.d.ts +11 -0
  15. package/dist/combinators/map.d.ts.map +1 -1
  16. package/dist/combinators/node.d.ts +19 -0
  17. package/dist/combinators/node.d.ts.map +1 -1
  18. package/dist/combinators/token.d.ts +3 -2
  19. package/dist/combinators/token.d.ts.map +1 -1
  20. package/dist/combinators/trivia-skip.d.ts +1 -0
  21. package/dist/combinators/trivia-skip.d.ts.map +1 -1
  22. package/dist/compiler/build-arity.d.ts +28 -0
  23. package/dist/compiler/build-arity.d.ts.map +1 -1
  24. package/dist/compiler/codegen.d.ts +80 -60
  25. package/dist/compiler/codegen.d.ts.map +1 -1
  26. package/dist/compiler/degradation.d.ts +123 -0
  27. package/dist/compiler/degradation.d.ts.map +1 -0
  28. package/dist/compiler/fields.d.ts.map +1 -1
  29. package/dist/compiler/grammar-coverage-ids.d.ts.map +1 -1
  30. package/dist/compiler/inline-build.d.ts.map +1 -1
  31. package/dist/compiler/ir-serialize.d.ts.map +1 -1
  32. package/dist/compiler/linker.d.ts +1 -1
  33. package/dist/compiler/linker.d.ts.map +1 -1
  34. package/dist/compiler/scannable-run.d.ts +1 -1
  35. package/dist/compiler/scannable-run.d.ts.map +1 -1
  36. package/dist/compiler/trivia-fast-path.d.ts +4 -3
  37. package/dist/compiler/trivia-fast-path.d.ts.map +1 -1
  38. package/dist/coverage.d.ts +13 -0
  39. package/dist/coverage.d.ts.map +1 -1
  40. package/dist/cst/reflection.d.ts.map +1 -1
  41. package/dist/cst/trivia-entries.d.ts +15 -9
  42. package/dist/cst/trivia-entries.d.ts.map +1 -1
  43. package/dist/cst/trivia-kinds.d.ts +15 -11
  44. package/dist/cst/trivia-kinds.d.ts.map +1 -1
  45. package/dist/functional/run.d.ts +22 -16
  46. package/dist/functional/run.d.ts.map +1 -1
  47. package/dist/index.cjs +2131 -1594
  48. package/dist/index.cjs.map +4 -4
  49. package/dist/index.d.ts +6 -8
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +2131 -1594
  52. package/dist/index.js.map +4 -4
  53. package/dist/language-service/index.cjs +201 -132
  54. package/dist/language-service/index.cjs.map +4 -4
  55. package/dist/language-service/index.js +201 -132
  56. package/dist/language-service/index.js.map +4 -4
  57. package/dist/oracle/digest.d.ts +132 -6
  58. package/dist/oracle/digest.d.ts.map +1 -1
  59. package/dist/oracle/index.cjs +136 -305
  60. package/dist/oracle/index.cjs.map +4 -4
  61. package/dist/oracle/index.d.ts +43 -31
  62. package/dist/oracle/index.d.ts.map +1 -1
  63. package/dist/oracle/index.js +136 -305
  64. package/dist/oracle/index.js.map +4 -4
  65. package/dist/plugin/evaluator.d.ts +3 -0
  66. package/dist/plugin/evaluator.d.ts.map +1 -1
  67. package/dist/plugin/index.cjs +2333 -1721
  68. package/dist/plugin/index.cjs.map +4 -4
  69. package/dist/plugin/index.d.ts +18 -0
  70. package/dist/plugin/index.d.ts.map +1 -1
  71. package/dist/plugin/index.js +2333 -1721
  72. package/dist/plugin/index.js.map +4 -4
  73. package/dist/plugin/reducer-resolver.d.ts +41 -0
  74. package/dist/plugin/reducer-resolver.d.ts.map +1 -0
  75. package/dist/run/index.cjs +185 -132
  76. package/dist/run/index.cjs.map +3 -3
  77. package/dist/run/index.d.ts +1 -1
  78. package/dist/run/index.d.ts.map +1 -1
  79. package/dist/run/index.js +185 -132
  80. package/dist/run/index.js.map +3 -3
  81. package/dist/spec/index.cjs +1637 -1322
  82. package/dist/spec/index.cjs.map +4 -4
  83. package/dist/spec/index.js +1637 -1322
  84. package/dist/spec/index.js.map +4 -4
  85. package/dist/spec/model.d.ts.map +1 -1
  86. package/dist/types.d.ts +31 -1
  87. package/dist/types.d.ts.map +1 -1
  88. package/dist/version.d.ts +1 -1
  89. package/package.json +7 -3
  90. package/dist/combinators/guard.d.ts +0 -8
  91. package/dist/combinators/guard.d.ts.map +0 -1
  92. package/dist/cst/offset-model.d.ts +0 -119
  93. package/dist/cst/offset-model.d.ts.map +0 -1
  94. package/dist/oracle/corpus.d.ts +0 -32
  95. package/dist/oracle/corpus.d.ts.map +0 -1
  96. package/dist/oracle/identity.d.ts +0 -117
  97. package/dist/oracle/identity.d.ts.map +0 -1
@@ -0,0 +1,41 @@
1
+ type AnyNode = {
2
+ type: string;
3
+ start: number;
4
+ end: number;
5
+ } & Record<string, unknown>;
6
+ /** Why a reducer could not be reduced to a parameter list. `undefined` = it could. */
7
+ export type UnresolvedReason = 'rest-parameter' | 'arguments' | 'reassigned' | 'not-a-function' | 'unresolved-import' | 'not-found' | 'computed' | 'foreign-source';
8
+ export type ResolvedReducer = {
9
+ /** Declared positional arity, or `null` when genuinely undecidable. */
10
+ arity: number | null;
11
+ /** Source text of the resolved function, for shape analysis (inline-`mk`). */
12
+ src: string | null;
13
+ reason?: UnresolvedReason;
14
+ };
15
+ /**
16
+ * Declared positional arity of a function node, or `null` when undecidable.
17
+ *
18
+ * A DEFAULT does not change positional arity (`(c, f = undefined, s, r)` is 4) and a
19
+ * DESTRUCTURED parameter still occupies one position — both were previously rejected by
20
+ * a regex that only accepted plain identifiers. A REST parameter genuinely is undecidable
21
+ * (the declared arity is unbounded), as is a body that reads `arguments`.
22
+ */
23
+ export declare function functionArity(fn: AnyNode): {
24
+ arity: number | null;
25
+ reason?: UnresolvedReason;
26
+ };
27
+ export type ReducerResolver = {
28
+ /**
29
+ * Resolve the reducer expression at `offset` (its source text is `exprSrc`).
30
+ * Returns `null` when the expression is not a name at all (an inline function —
31
+ * the caller already has its source and needs nothing from us).
32
+ *
33
+ * `src` is the module text `offset` indexes. An offset is only meaningful against the
34
+ * source it came from, so the caller must say which one it has; see `resolve`'s
35
+ * implementation for what happens when it is not this resolver's.
36
+ */
37
+ resolve(exprSrc: string, offset: number, src: string): ResolvedReducer | null;
38
+ };
39
+ export declare function createReducerResolver(entryFile: string, body: unknown[], src: string): ReducerResolver;
40
+ export {};
41
+ //# sourceMappingURL=reducer-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reducer-resolver.d.ts","sourceRoot":"","sources":["../../src/plugin/reducer-resolver.ts"],"names":[],"mappings":"AAqCA,KAAK,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAErF,sFAAsF;AACtF,MAAM,MAAM,gBAAgB,GACxB,gBAAgB,GAChB,WAAW,GACX,YAAY,GACZ,gBAAgB,GAChB,mBAAmB,GACnB,WAAW,GACX,UAAU,GACV,gBAAgB,CAAA;AAEpB,MAAM,MAAM,eAAe,GAAG;IAC5B,uEAAuE;IACvE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,8EAA8E;IAC9E,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB,MAAM,CAAC,EAAE,gBAAgB,CAAA;CAC1B,CAAA;AA0MD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,OAAO,GAAG;IAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,CAAC,EAAE,gBAAgB,CAAA;CAAE,CAa9F;AAoKD,MAAM,MAAM,eAAe,GAAG;IAC5B;;;;;;;;OAQG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAAA;CAC9E,CAAA;AAKD,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,eAAe,CAgGtG"}
@@ -28,105 +28,97 @@ module.exports = __toCommonJS(run_exports);
28
28
  // src/cst/trivia-entries.ts
29
29
  var EMPTY_INDICES = Object.freeze([]);
30
30
  var EMPTY_GAPS = Object.freeze([]);
31
- function entryOffset(i, stride) {
32
- return i * stride;
33
- }
34
- function triviaEntries(log, labels, opts) {
35
- const baseStride = opts?.nodeLog ? 3 : 2;
36
- const stride = labels ? baseStride + 1 : baseStride;
37
- const length = Math.floor(log.length / stride);
38
- return {
31
+ var SELECTED_ROOT_STRIDE = 5;
32
+ function buildRootTriviaIndex(log, labels) {
33
+ const length = Math.floor(log.length / SELECTED_ROOT_STRIDE);
34
+ const markerOffset = (i) => i * SELECTED_ROOT_STRIDE;
35
+ const ownedRangeStart = (i) => log[markerOffset(i)];
36
+ const ownedRangeEnd = (i) => log[markerOffset(i) + 1];
37
+ const markerStart = (i) => log[markerOffset(i) + 2];
38
+ const markerEnd = (i) => log[markerOffset(i) + 3];
39
+ const markerKind = (i) => log[markerOffset(i) + 4];
40
+ const entries = {
39
41
  length,
40
42
  labels,
41
- stride,
42
- start(i) {
43
- return log[entryOffset(i, stride)];
44
- },
45
- end(i) {
46
- return log[entryOffset(i, stride) + 1];
47
- },
48
- insertIndex(i) {
49
- return opts?.nodeLog ? log[entryOffset(i, stride) + 2] : void 0;
50
- },
51
- kindIndex(i) {
52
- if (!labels) return void 0;
53
- return log[entryOffset(i, stride) + baseStride];
54
- },
43
+ stride: SELECTED_ROOT_STRIDE,
44
+ start: markerStart,
45
+ end: markerEnd,
46
+ insertIndex: () => void 0,
47
+ kindIndex: markerKind,
55
48
  kind(i) {
56
- const ki = labels ? log[entryOffset(i, stride) + baseStride] : void 0;
57
- return ki !== void 0 ? labels[ki] : void 0;
49
+ return labels[markerKind(i)];
58
50
  },
59
51
  text(i, input) {
60
- const s = log[entryOffset(i, stride)];
61
- const e = log[entryOffset(i, stride) + 1];
62
- return input.slice(s, e);
52
+ return input.slice(markerStart(i), markerEnd(i));
63
53
  }
64
54
  };
65
- }
66
- function appendEntryRange(map, key, first, last) {
67
- let indices = map.get(key);
68
- if (!indices) {
69
- indices = [];
70
- map.set(key, indices);
71
- }
72
- for (let i = first; i <= last; i++) indices.push(i);
73
- }
74
- function buildGap(entries, start, end, first, last) {
75
- const entryIndices = [];
76
- for (let i = first; i <= last; i++) entryIndices.push(i);
77
- return {
78
- start,
79
- end,
80
- entryIndices,
81
- hasKind(kind) {
82
- for (const i of entryIndices) {
83
- if (entries.kind(i) === kind) return true;
84
- }
85
- return false;
86
- },
87
- text(input) {
88
- return input.slice(start, end);
55
+ const lowerBound = (offset, by) => {
56
+ let lo = 0;
57
+ let hi = length;
58
+ while (lo < hi) {
59
+ const mid = lo + hi >>> 1;
60
+ if (by(mid) < offset) lo = mid + 1;
61
+ else hi = mid;
89
62
  }
63
+ return lo;
90
64
  };
91
- }
92
- function buildRootMaps(entries) {
93
- const before = /* @__PURE__ */ new Map();
94
- const after = /* @__PURE__ */ new Map();
95
- const beforeGaps = /* @__PURE__ */ new Map();
96
- const afterGaps = /* @__PURE__ */ new Map();
97
- const gaps = [];
98
- if (entries.length === 0) return { before, after, beforeGaps, afterGaps, gaps };
99
- const appendGap = (first2, last, start2, end2) => {
100
- const gap = buildGap(entries, start2, end2, first2, last);
101
- gaps.push(gap);
102
- afterGaps.set(start2, gap);
103
- beforeGaps.set(end2, gap);
104
- appendEntryRange(after, start2, first2, last);
105
- appendEntryRange(before, end2, first2, last);
65
+ const gapRowsAt = (offset, direction) => {
66
+ const edge = direction === "before" ? ownedRangeEnd : ownedRangeStart;
67
+ let first = lowerBound(offset, edge);
68
+ if (first === length || edge(first) !== offset) return void 0;
69
+ const start = ownedRangeStart(first);
70
+ const end = ownedRangeEnd(first);
71
+ while (first > 0 && ownedRangeStart(first - 1) === start && ownedRangeEnd(first - 1) === end) first--;
72
+ let last = first + 1;
73
+ while (last < length && ownedRangeStart(last) === start && ownedRangeEnd(last) === end) last++;
74
+ return [first, last];
75
+ };
76
+ const indices = (first, last) => {
77
+ const out = [];
78
+ for (let i = first; i < last; i++) out.push(i);
79
+ return out;
80
+ };
81
+ const makeGap = (first, last) => {
82
+ const start = ownedRangeStart(first);
83
+ const end = ownedRangeEnd(first);
84
+ let entryIndices;
85
+ return {
86
+ start,
87
+ end,
88
+ get entryIndices() {
89
+ return entryIndices ??= indices(first, last);
90
+ },
91
+ hasKind(kind) {
92
+ for (let i = first; i < last; i++) {
93
+ if (labels[markerKind(i)] === kind) return true;
94
+ }
95
+ return false;
96
+ },
97
+ text(input) {
98
+ return input.slice(start, end);
99
+ }
100
+ };
106
101
  };
107
- let first = 0;
108
- let start = entries.start(0);
109
- let end = entries.end(0);
110
- for (let i = 1; i < entries.length; i++) {
111
- const nextStart = entries.start(i);
112
- const nextEnd = entries.end(i);
113
- if (nextStart === end) {
114
- end = nextEnd;
115
- continue;
116
- }
117
- appendGap(first, i - 1, start, end);
118
- first = i;
119
- start = nextStart;
120
- end = nextEnd;
121
- }
122
- appendGap(first, entries.length - 1, start, end);
123
- return { before, after, beforeGaps, afterGaps, gaps };
124
- }
125
- function buildRootTriviaIndex(log, labels) {
126
- const entries = triviaEntries(log, labels);
127
102
  let maps;
128
103
  const getMaps = () => {
129
- maps ??= buildRootMaps(entries);
104
+ if (maps !== void 0) return maps;
105
+ const before = /* @__PURE__ */ new Map();
106
+ const after = /* @__PURE__ */ new Map();
107
+ const beforeGaps = /* @__PURE__ */ new Map();
108
+ const afterGaps = /* @__PURE__ */ new Map();
109
+ const gaps = [];
110
+ for (let first = 0; first < length; ) {
111
+ let last = first + 1;
112
+ while (last < length && ownedRangeStart(last) === ownedRangeStart(first) && ownedRangeEnd(last) === ownedRangeEnd(first)) last++;
113
+ const gap = makeGap(first, last);
114
+ gaps.push(gap);
115
+ afterGaps.set(gap.start, gap);
116
+ beforeGaps.set(gap.end, gap);
117
+ after.set(gap.start, [...gap.entryIndices]);
118
+ before.set(gap.end, [...gap.entryIndices]);
119
+ first = last;
120
+ }
121
+ maps = { before, after, beforeGaps, afterGaps, gaps };
130
122
  return maps;
131
123
  };
132
124
  return {
@@ -139,16 +131,20 @@ function buildRootTriviaIndex(log, labels) {
139
131
  return getMaps().after;
140
132
  },
141
133
  entryIndicesBefore(offset) {
142
- return getMaps().before.get(offset) ?? EMPTY_INDICES;
134
+ const rows = gapRowsAt(offset, "before");
135
+ return rows ? indices(rows[0], rows[1]) : EMPTY_INDICES;
143
136
  },
144
137
  entryIndicesAfter(offset) {
145
- return getMaps().after.get(offset) ?? EMPTY_INDICES;
138
+ const rows = gapRowsAt(offset, "after");
139
+ return rows ? indices(rows[0], rows[1]) : EMPTY_INDICES;
146
140
  },
147
141
  gapBefore(offset) {
148
- return getMaps().beforeGaps.get(offset);
142
+ const rows = gapRowsAt(offset, "before");
143
+ return rows ? makeGap(rows[0], rows[1]) : void 0;
149
144
  },
150
145
  gapAfter(offset) {
151
- return getMaps().afterGaps.get(offset);
146
+ const rows = gapRowsAt(offset, "after");
147
+ return rows ? makeGap(rows[0], rows[1]) : void 0;
152
148
  },
153
149
  gaps() {
154
150
  return getMaps().gaps;
@@ -156,13 +152,21 @@ function buildRootTriviaIndex(log, labels) {
156
152
  gapsWithKind(kind) {
157
153
  const kinds = typeof kind === "string" ? [kind] : kind;
158
154
  const matches = [];
159
- for (const gap of getMaps().gaps) {
160
- for (const k of kinds) {
161
- if (gap.hasKind(k)) {
162
- matches.push(gap);
163
- break;
155
+ for (let first = 0; first < length; ) {
156
+ let last = first + 1;
157
+ while (last < length && ownedRangeStart(last) === ownedRangeStart(first) && ownedRangeEnd(last) === ownedRangeEnd(first)) last++;
158
+ let matched = false;
159
+ for (let i = first; i < last && !matched; i++) {
160
+ const label = labels[markerKind(i)];
161
+ for (const kind2 of kinds) {
162
+ if (label === kind2) {
163
+ matched = true;
164
+ break;
165
+ }
164
166
  }
165
167
  }
168
+ if (matched) matches.push(makeGap(first, last));
169
+ first = last;
166
170
  }
167
171
  return matches.length === 0 ? EMPTY_GAPS : matches;
168
172
  }
@@ -247,6 +251,7 @@ function probeAt(sentinel, input, pos, ctx) {
247
251
  _cstRawChildren: ctx._cstRawChildren,
248
252
  _cstTriviaLog: ctx._cstTriviaLog,
249
253
  _triviaLog: ctx._triviaLog,
254
+ _rootTriviaLog: ctx._rootTriviaLog,
250
255
  _fields: ctx._fields,
251
256
  _cstBuf: ctx._cstBuf,
252
257
  _tolerant: ctx._tolerant,
@@ -259,6 +264,7 @@ function probeAt(sentinel, input, pos, ctx) {
259
264
  ctx._cstRawChildren = void 0;
260
265
  ctx._cstTriviaLog = void 0;
261
266
  ctx._triviaLog = void 0;
267
+ ctx._rootTriviaLog = void 0;
262
268
  ctx._fields = void 0;
263
269
  ctx._cstBuf = void 0;
264
270
  ctx._tolerant = void 0;
@@ -273,6 +279,7 @@ function probeAt(sentinel, input, pos, ctx) {
273
279
  ctx._cstRawChildren = s._cstRawChildren;
274
280
  ctx._cstTriviaLog = s._cstTriviaLog;
275
281
  ctx._triviaLog = s._triviaLog;
282
+ ctx._rootTriviaLog = s._rootTriviaLog;
276
283
  ctx._fields = s._fields;
277
284
  ctx._cstBuf = s._cstBuf;
278
285
  ctx._tolerant = s._tolerant;
@@ -345,12 +352,54 @@ function assertHostModeCompatible(mode, build, hostBranchElided = true) {
345
352
  }
346
353
 
347
354
  // src/functional/run.ts
355
+ var SELECT_EXAMPLE = "run(entry, input, { rootTrivia: { select: ['blockComment', 'lineComment'] } })";
356
+ var REMOVED_RUN_RESULT_FIELDS = [
357
+ [
358
+ "triviaMap",
359
+ `It was a dense root-trivia index built on every parse; root trivia is now an OPT-IN sparse capture, because most grammars paid for an index they never read. Migration: name the trivia labels your grammar defines \u2014 ${SELECT_EXAMPLE} \u2014 and read \`RunResult.rootTrivia\`, whose \`.index\` carries the labels and gap lookups \`triviaMap\` exposed.`
360
+ ],
361
+ [
362
+ "triviaLog",
363
+ `It was the flat \`start, end[, kindIndex]\` log every other trivia view was derived from, and it is no longer allocated at all \u2014 not empty, absent. Migration: request the labels you need \u2014 ${SELECT_EXAMPLE} \u2014 and read \`RunResult.rootTrivia.rows\`. Do NOT reuse a stride-2/3 reader: rows are a different width and a different unit (one row per SELECTED marker, not one per trivia chunk), so an old loop reads confidently wrong offsets rather than failing.`
364
+ ],
365
+ [
366
+ "triviaKindLabels",
367
+ `It was already optional, so nothing ever flagged its disappearance \u2014 and \`triviaKindMask(undefined, \u2026)\` means "capture everything", so reading it now silently WIDENS capture instead of erroring. Migration: request labels \u2014 ${SELECT_EXAMPLE} \u2014 then the set you asked for is \`RunResult.rootTrivia.select\` and the resolved table is \`RunResult.rootTrivia.index.labels\`.`
368
+ ]
369
+ ];
370
+ function guardRemovedFields(result) {
371
+ for (const [name, detail] of REMOVED_RUN_RESULT_FIELDS) {
372
+ Object.defineProperty(result, name, {
373
+ configurable: true,
374
+ enumerable: false,
375
+ get() {
376
+ throw new TypeError(
377
+ `RunResult.${name} was REMOVED in parseman 0.44.0 and has no default replacement. ${detail}`
378
+ );
379
+ }
380
+ });
381
+ }
382
+ return result;
383
+ }
348
384
  var invoke = (r, input, pos, ctx) => typeof r === "function" ? r(input, pos, ctx) : r.parse(input, pos, ctx);
349
385
  function triviaKindLabelsFromRunnable(r) {
350
386
  if (!r) return void 0;
351
387
  if (typeof r === "function") return r._meta?.triviaKindLabels;
352
388
  const grammarTrivia = r._meta.grammarTrivia;
353
- return r._meta.triviaKindLabels ?? grammarTrivia?._meta.triviaKindLabels ?? (r._def.tag === "grammar" ? r._def.triviaParser?._meta.triviaKindLabels : void 0);
389
+ return grammarTrivia?._meta.triviaKindLabels ?? r._meta.triviaKindLabels ?? (r._def.tag === "grammar" ? r._def.triviaParser?._meta.triviaKindLabels : void 0);
390
+ }
391
+ function rootTriviaClassifiedFromRunnable(r) {
392
+ if (!r) return false;
393
+ if (typeof r === "function") return r._meta?.rootTriviaClassified === true;
394
+ const grammarTrivia = r._meta.grammarTrivia;
395
+ return grammarTrivia?._meta.rootTriviaClassified === true || r._meta.rootTriviaClassified === true;
396
+ }
397
+ function makeSelectedRootLabelIndex(labels) {
398
+ const index = /* @__PURE__ */ Object.create(null);
399
+ for (let i = 0; i < labels.length; i++) {
400
+ if (index[labels[i]] === void 0) index[labels[i]] = i;
401
+ }
402
+ return index;
354
403
  }
355
404
  function runOnce(entry, input, options, phase, profileState) {
356
405
  if (typeof entry !== "function" && typeof entry?.parse !== "function") {
@@ -358,13 +407,31 @@ function runOnce(entry, input, options, phase, profileState) {
358
407
  `run(): start production is ${entry === null ? "null" : typeof entry}, not a rule \u2014 the requested grammar rule does not exist (check the rule name).`
359
408
  );
360
409
  }
361
- const triviaLog = [];
410
+ const rootTriviaSelection = options.rootTrivia?.select;
411
+ const captureRootTrivia = rootTriviaSelection !== void 0 && rootTriviaSelection.length > 0;
412
+ const selectedRootLog = captureRootTrivia ? [] : void 0;
413
+ const selectedRootLabelIndex = captureRootTrivia ? makeSelectedRootLabelIndex(rootTriviaSelection) : void 0;
362
414
  const errors = [];
363
415
  const profile = profileState ?? (phase === void 0 ? void 0 : { phase, nodes: 0, childSlots: 0, rawSlots: 0, triviaSlots: 0, fieldSlots: 0, hostCalls: 0 });
364
416
  const skipGlobalSinks = phase === "recognizer" || phase === "capture";
365
417
  const grammarTrivia = typeof entry !== "function" ? entry._meta.grammarTrivia : void 0;
366
418
  const grammarScanSkip = typeof entry !== "function" ? entry._meta.grammarScanSkip : void 0;
367
419
  const triviaKindLabels = triviaKindLabelsFromRunnable(entry) ?? triviaKindLabelsFromRunnable(options.trivia);
420
+ if (captureRootTrivia && triviaKindLabels === void 0) {
421
+ throw new TypeError("run(): rootTrivia.select requires labeled grammar trivia.");
422
+ }
423
+ if (captureRootTrivia) {
424
+ for (const label of rootTriviaSelection) {
425
+ if (!triviaKindLabels.includes(label)) {
426
+ throw new TypeError(`run(): rootTrivia.select contains unknown trivia label ${JSON.stringify(label)}.`);
427
+ }
428
+ }
429
+ }
430
+ if (captureRootTrivia && !rootTriviaClassifiedFromRunnable(entry) && !rootTriviaClassifiedFromRunnable(options.trivia)) {
431
+ throw new TypeError(
432
+ "run(): rootTrivia.select requires classifiedTrivia() at the root."
433
+ );
434
+ }
368
435
  const stamped = entry;
369
436
  assertHostModeCompatible(
370
437
  typeof entry === "function" ? stamped[FUSED_HOST_MODE] ?? "ast" : entry._meta.grammarHostMode ?? "ast",
@@ -373,7 +440,15 @@ function runOnce(entry, input, options, phase, profileState) {
373
440
  );
374
441
  const ctx = {
375
442
  trackLines: false,
376
- ...skipGlobalSinks ? { _pmProfile: profile } : { _triviaLog: triviaLog, _errors: errors, ...profile === void 0 ? {} : { _pmProfile: profile } },
443
+ ...skipGlobalSinks ? { _pmProfile: profile } : {
444
+ ...captureRootTrivia ? {
445
+ _rootTriviaLog: selectedRootLog,
446
+ _rootTriviaKindIndex: selectedRootLabelIndex,
447
+ _rootTriviaStrictScopes: true
448
+ } : {},
449
+ _errors: errors,
450
+ ...profile === void 0 ? {} : { _pmProfile: profile }
451
+ },
377
452
  build: options.build,
378
453
  state: options.state,
379
454
  ...grammarTrivia !== void 0 ? { trivia: grammarTrivia, ...triviaKindLabels ? { triviaKindLabels } : {} } : triviaKindLabels ? { triviaKindLabels } : {},
@@ -398,42 +473,20 @@ function runOnce(entry, input, options, phase, profileState) {
398
473
  span: r.span ?? { start: 0, end: 0 },
399
474
  expected: r.ok ? [] : r.expected ?? [],
400
475
  errors,
401
- triviaLog,
402
- ...triviaKindLabels === void 0 ? {} : { triviaKindLabels },
403
- triviaMap: buildRootTriviaIndex(triviaLog, triviaKindLabels),
476
+ ...selectedRootLog !== void 0 && selectedRootLog.length > 0 ? {
477
+ rootTrivia: {
478
+ rows: selectedRootLog,
479
+ select: rootTriviaSelection,
480
+ index: buildRootTriviaIndex(selectedRootLog, rootTriviaSelection)
481
+ }
482
+ } : {},
404
483
  unconsumedFrom
405
484
  };
406
485
  }
407
- function clonePassState(state) {
408
- if (state === null || typeof state !== "object") return state;
409
- return Array.isArray(state) ? [...state] : { ...state };
410
- }
411
- function profilePass(entry, input, options, phase) {
412
- const state = { phase, nodes: 0, childSlots: 0, rawSlots: 0, triviaSlots: 0, fieldSlots: 0, hostCalls: 0 };
413
- const passOptions = options.state === void 0 ? options : { ...options, state: clonePassState(options.state) };
414
- const start = performance.now();
415
- const result = runOnce(entry, input, passOptions, phase, state);
416
- const { phase: _phase, ...counts } = state;
417
- return { result, profile: { ms: performance.now() - start, ...counts } };
418
- }
419
486
  function run(entry, input, options = {}) {
420
- if (!options.profile) return runOnce(entry, input, options);
421
- if (typeof entry !== "function") {
422
- throw new TypeError("run({ profile: true }) requires a compiled parser entry");
423
- }
424
- const recognizer = profilePass(entry, input, options, "recognizer");
425
- const capture = profilePass(entry, input, options, "capture");
426
- const host = profilePass(entry, input, options, "host");
427
- if (recognizer.result.ok !== host.result.ok || capture.result.ok !== host.result.ok || recognizer.result.unconsumedFrom !== host.result.unconsumedFrom || capture.result.unconsumedFrom !== host.result.unconsumedFrom) {
428
- throw new Error("run({ profile: true }) changed recognition; the grammar is not profile-safe");
429
- }
430
- return {
431
- ...host.result,
432
- profile: {
433
- recognizer: recognizer.profile,
434
- structuralCapture: capture.profile,
435
- hostConstruction: host.profile
436
- }
437
- };
487
+ if (!options.profile) return guardRemovedFields(runOnce(entry, input, options));
488
+ throw new TypeError(
489
+ "run({ profile: true }) is unavailable: profiling counters are no longer compiled into parser artifacts, and the interpreter does not implement them yet. Profiling is moving to interpreted mode."
490
+ );
438
491
  }
439
492
  //# sourceMappingURL=index.cjs.map