parseman 0.42.1 → 0.44.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 (68) hide show
  1. package/dist/combinators/attempt.d.ts.map +1 -1
  2. package/dist/combinators/choice.d.ts.map +1 -1
  3. package/dist/combinators/grammar.d.ts +7 -0
  4. package/dist/combinators/grammar.d.ts.map +1 -1
  5. package/dist/combinators/map.d.ts +11 -0
  6. package/dist/combinators/map.d.ts.map +1 -1
  7. package/dist/combinators/node.d.ts +21 -7
  8. package/dist/combinators/node.d.ts.map +1 -1
  9. package/dist/combinators/parser.d.ts +17 -2
  10. package/dist/combinators/parser.d.ts.map +1 -1
  11. package/dist/combinators/token.d.ts +3 -2
  12. package/dist/combinators/token.d.ts.map +1 -1
  13. package/dist/combinators/trivia-skip.d.ts +1 -0
  14. package/dist/combinators/trivia-skip.d.ts.map +1 -1
  15. package/dist/compiler/codegen.d.ts +4 -0
  16. package/dist/compiler/codegen.d.ts.map +1 -1
  17. package/dist/compiler/ir-serialize.d.ts.map +1 -1
  18. package/dist/compiler/linker.d.ts +6 -1
  19. package/dist/compiler/linker.d.ts.map +1 -1
  20. package/dist/compiler/scannable-run.d.ts +1 -1
  21. package/dist/compiler/scannable-run.d.ts.map +1 -1
  22. package/dist/compiler/trivia-fast-path.d.ts +4 -3
  23. package/dist/compiler/trivia-fast-path.d.ts.map +1 -1
  24. package/dist/cst/reflection.d.ts +24 -0
  25. package/dist/cst/reflection.d.ts.map +1 -0
  26. package/dist/cst/trivia-entries.d.ts +15 -9
  27. package/dist/cst/trivia-entries.d.ts.map +1 -1
  28. package/dist/cst/trivia-kinds.d.ts +15 -11
  29. package/dist/cst/trivia-kinds.d.ts.map +1 -1
  30. package/dist/cst/types.d.ts +2 -0
  31. package/dist/cst/types.d.ts.map +1 -1
  32. package/dist/cst/walk.d.ts +27 -62
  33. package/dist/cst/walk.d.ts.map +1 -1
  34. package/dist/functional/run.d.ts +22 -16
  35. package/dist/functional/run.d.ts.map +1 -1
  36. package/dist/index.cjs +1651 -1207
  37. package/dist/index.cjs.map +4 -4
  38. package/dist/index.d.ts +6 -5
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +1651 -1207
  41. package/dist/index.js.map +4 -4
  42. package/dist/language-service/index.cjs +186 -135
  43. package/dist/language-service/index.cjs.map +4 -4
  44. package/dist/language-service/index.d.ts +1 -1
  45. package/dist/language-service/index.d.ts.map +1 -1
  46. package/dist/language-service/index.js +186 -135
  47. package/dist/language-service/index.js.map +4 -4
  48. package/dist/plugin/evaluator.d.ts +1 -0
  49. package/dist/plugin/evaluator.d.ts.map +1 -1
  50. package/dist/plugin/index.cjs +1525 -1048
  51. package/dist/plugin/index.cjs.map +4 -4
  52. package/dist/plugin/index.d.ts.map +1 -1
  53. package/dist/plugin/index.js +1525 -1048
  54. package/dist/plugin/index.js.map +4 -4
  55. package/dist/run/index.cjs +152 -102
  56. package/dist/run/index.cjs.map +3 -3
  57. package/dist/run/index.d.ts +1 -1
  58. package/dist/run/index.d.ts.map +1 -1
  59. package/dist/run/index.js +152 -102
  60. package/dist/run/index.js.map +3 -3
  61. package/dist/spec/index.cjs +1381 -1152
  62. package/dist/spec/index.cjs.map +4 -4
  63. package/dist/spec/index.js +1381 -1152
  64. package/dist/spec/index.js.map +4 -4
  65. package/dist/types.d.ts +27 -1
  66. package/dist/types.d.ts.map +1 -1
  67. package/dist/version.d.ts +1 -1
  68. package/package.json +1 -1
package/dist/run/index.js CHANGED
@@ -1,105 +1,97 @@
1
1
  // src/cst/trivia-entries.ts
2
2
  var EMPTY_INDICES = Object.freeze([]);
3
3
  var EMPTY_GAPS = Object.freeze([]);
4
- function entryOffset(i, stride) {
5
- return i * stride;
6
- }
7
- function triviaEntries(log, labels, opts) {
8
- const baseStride = opts?.nodeLog ? 3 : 2;
9
- const stride = labels ? baseStride + 1 : baseStride;
10
- const length = Math.floor(log.length / stride);
11
- return {
4
+ var SELECTED_ROOT_STRIDE = 5;
5
+ function buildRootTriviaIndex(log, labels) {
6
+ const length = Math.floor(log.length / SELECTED_ROOT_STRIDE);
7
+ const markerOffset = (i) => i * SELECTED_ROOT_STRIDE;
8
+ const ownedRangeStart = (i) => log[markerOffset(i)];
9
+ const ownedRangeEnd = (i) => log[markerOffset(i) + 1];
10
+ const markerStart = (i) => log[markerOffset(i) + 2];
11
+ const markerEnd = (i) => log[markerOffset(i) + 3];
12
+ const markerKind = (i) => log[markerOffset(i) + 4];
13
+ const entries = {
12
14
  length,
13
15
  labels,
14
- stride,
15
- start(i) {
16
- return log[entryOffset(i, stride)];
17
- },
18
- end(i) {
19
- return log[entryOffset(i, stride) + 1];
20
- },
21
- insertIndex(i) {
22
- return opts?.nodeLog ? log[entryOffset(i, stride) + 2] : void 0;
23
- },
24
- kindIndex(i) {
25
- if (!labels) return void 0;
26
- return log[entryOffset(i, stride) + baseStride];
27
- },
16
+ stride: SELECTED_ROOT_STRIDE,
17
+ start: markerStart,
18
+ end: markerEnd,
19
+ insertIndex: () => void 0,
20
+ kindIndex: markerKind,
28
21
  kind(i) {
29
- const ki = labels ? log[entryOffset(i, stride) + baseStride] : void 0;
30
- return ki !== void 0 ? labels[ki] : void 0;
22
+ return labels[markerKind(i)];
31
23
  },
32
24
  text(i, input) {
33
- const s = log[entryOffset(i, stride)];
34
- const e = log[entryOffset(i, stride) + 1];
35
- return input.slice(s, e);
25
+ return input.slice(markerStart(i), markerEnd(i));
36
26
  }
37
27
  };
38
- }
39
- function appendEntryRange(map, key, first, last) {
40
- let indices = map.get(key);
41
- if (!indices) {
42
- indices = [];
43
- map.set(key, indices);
44
- }
45
- for (let i = first; i <= last; i++) indices.push(i);
46
- }
47
- function buildGap(entries, start, end, first, last) {
48
- const entryIndices = [];
49
- for (let i = first; i <= last; i++) entryIndices.push(i);
50
- return {
51
- start,
52
- end,
53
- entryIndices,
54
- hasKind(kind) {
55
- for (const i of entryIndices) {
56
- if (entries.kind(i) === kind) return true;
57
- }
58
- return false;
59
- },
60
- text(input) {
61
- return input.slice(start, end);
28
+ const lowerBound = (offset, by) => {
29
+ let lo = 0;
30
+ let hi = length;
31
+ while (lo < hi) {
32
+ const mid = lo + hi >>> 1;
33
+ if (by(mid) < offset) lo = mid + 1;
34
+ else hi = mid;
62
35
  }
36
+ return lo;
63
37
  };
64
- }
65
- function buildRootMaps(entries) {
66
- const before = /* @__PURE__ */ new Map();
67
- const after = /* @__PURE__ */ new Map();
68
- const beforeGaps = /* @__PURE__ */ new Map();
69
- const afterGaps = /* @__PURE__ */ new Map();
70
- const gaps = [];
71
- if (entries.length === 0) return { before, after, beforeGaps, afterGaps, gaps };
72
- const appendGap = (first2, last, start2, end2) => {
73
- const gap = buildGap(entries, start2, end2, first2, last);
74
- gaps.push(gap);
75
- afterGaps.set(start2, gap);
76
- beforeGaps.set(end2, gap);
77
- appendEntryRange(after, start2, first2, last);
78
- appendEntryRange(before, end2, first2, last);
38
+ const gapRowsAt = (offset, direction) => {
39
+ const edge = direction === "before" ? ownedRangeEnd : ownedRangeStart;
40
+ let first = lowerBound(offset, edge);
41
+ if (first === length || edge(first) !== offset) return void 0;
42
+ const start = ownedRangeStart(first);
43
+ const end = ownedRangeEnd(first);
44
+ while (first > 0 && ownedRangeStart(first - 1) === start && ownedRangeEnd(first - 1) === end) first--;
45
+ let last = first + 1;
46
+ while (last < length && ownedRangeStart(last) === start && ownedRangeEnd(last) === end) last++;
47
+ return [first, last];
48
+ };
49
+ const indices = (first, last) => {
50
+ const out = [];
51
+ for (let i = first; i < last; i++) out.push(i);
52
+ return out;
53
+ };
54
+ const makeGap = (first, last) => {
55
+ const start = ownedRangeStart(first);
56
+ const end = ownedRangeEnd(first);
57
+ let entryIndices;
58
+ return {
59
+ start,
60
+ end,
61
+ get entryIndices() {
62
+ return entryIndices ??= indices(first, last);
63
+ },
64
+ hasKind(kind) {
65
+ for (let i = first; i < last; i++) {
66
+ if (labels[markerKind(i)] === kind) return true;
67
+ }
68
+ return false;
69
+ },
70
+ text(input) {
71
+ return input.slice(start, end);
72
+ }
73
+ };
79
74
  };
80
- let first = 0;
81
- let start = entries.start(0);
82
- let end = entries.end(0);
83
- for (let i = 1; i < entries.length; i++) {
84
- const nextStart = entries.start(i);
85
- const nextEnd = entries.end(i);
86
- if (nextStart === end) {
87
- end = nextEnd;
88
- continue;
89
- }
90
- appendGap(first, i - 1, start, end);
91
- first = i;
92
- start = nextStart;
93
- end = nextEnd;
94
- }
95
- appendGap(first, entries.length - 1, start, end);
96
- return { before, after, beforeGaps, afterGaps, gaps };
97
- }
98
- function buildRootTriviaIndex(log, labels) {
99
- const entries = triviaEntries(log, labels);
100
75
  let maps;
101
76
  const getMaps = () => {
102
- maps ??= buildRootMaps(entries);
77
+ if (maps !== void 0) return maps;
78
+ const before = /* @__PURE__ */ new Map();
79
+ const after = /* @__PURE__ */ new Map();
80
+ const beforeGaps = /* @__PURE__ */ new Map();
81
+ const afterGaps = /* @__PURE__ */ new Map();
82
+ const gaps = [];
83
+ for (let first = 0; first < length; ) {
84
+ let last = first + 1;
85
+ while (last < length && ownedRangeStart(last) === ownedRangeStart(first) && ownedRangeEnd(last) === ownedRangeEnd(first)) last++;
86
+ const gap = makeGap(first, last);
87
+ gaps.push(gap);
88
+ afterGaps.set(gap.start, gap);
89
+ beforeGaps.set(gap.end, gap);
90
+ after.set(gap.start, [...gap.entryIndices]);
91
+ before.set(gap.end, [...gap.entryIndices]);
92
+ first = last;
93
+ }
94
+ maps = { before, after, beforeGaps, afterGaps, gaps };
103
95
  return maps;
104
96
  };
105
97
  return {
@@ -112,16 +104,20 @@ function buildRootTriviaIndex(log, labels) {
112
104
  return getMaps().after;
113
105
  },
114
106
  entryIndicesBefore(offset) {
115
- return getMaps().before.get(offset) ?? EMPTY_INDICES;
107
+ const rows = gapRowsAt(offset, "before");
108
+ return rows ? indices(rows[0], rows[1]) : EMPTY_INDICES;
116
109
  },
117
110
  entryIndicesAfter(offset) {
118
- return getMaps().after.get(offset) ?? EMPTY_INDICES;
111
+ const rows = gapRowsAt(offset, "after");
112
+ return rows ? indices(rows[0], rows[1]) : EMPTY_INDICES;
119
113
  },
120
114
  gapBefore(offset) {
121
- return getMaps().beforeGaps.get(offset);
115
+ const rows = gapRowsAt(offset, "before");
116
+ return rows ? makeGap(rows[0], rows[1]) : void 0;
122
117
  },
123
118
  gapAfter(offset) {
124
- return getMaps().afterGaps.get(offset);
119
+ const rows = gapRowsAt(offset, "after");
120
+ return rows ? makeGap(rows[0], rows[1]) : void 0;
125
121
  },
126
122
  gaps() {
127
123
  return getMaps().gaps;
@@ -129,13 +125,21 @@ function buildRootTriviaIndex(log, labels) {
129
125
  gapsWithKind(kind) {
130
126
  const kinds = typeof kind === "string" ? [kind] : kind;
131
127
  const matches = [];
132
- for (const gap of getMaps().gaps) {
133
- for (const k of kinds) {
134
- if (gap.hasKind(k)) {
135
- matches.push(gap);
136
- break;
128
+ for (let first = 0; first < length; ) {
129
+ let last = first + 1;
130
+ while (last < length && ownedRangeStart(last) === ownedRangeStart(first) && ownedRangeEnd(last) === ownedRangeEnd(first)) last++;
131
+ let matched = false;
132
+ for (let i = first; i < last && !matched; i++) {
133
+ const label = labels[markerKind(i)];
134
+ for (const kind2 of kinds) {
135
+ if (label === kind2) {
136
+ matched = true;
137
+ break;
138
+ }
137
139
  }
138
140
  }
141
+ if (matched) matches.push(makeGap(first, last));
142
+ first = last;
139
143
  }
140
144
  return matches.length === 0 ? EMPTY_GAPS : matches;
141
145
  }
@@ -220,6 +224,7 @@ function probeAt(sentinel, input, pos, ctx) {
220
224
  _cstRawChildren: ctx._cstRawChildren,
221
225
  _cstTriviaLog: ctx._cstTriviaLog,
222
226
  _triviaLog: ctx._triviaLog,
227
+ _rootTriviaLog: ctx._rootTriviaLog,
223
228
  _fields: ctx._fields,
224
229
  _cstBuf: ctx._cstBuf,
225
230
  _tolerant: ctx._tolerant,
@@ -232,6 +237,7 @@ function probeAt(sentinel, input, pos, ctx) {
232
237
  ctx._cstRawChildren = void 0;
233
238
  ctx._cstTriviaLog = void 0;
234
239
  ctx._triviaLog = void 0;
240
+ ctx._rootTriviaLog = void 0;
235
241
  ctx._fields = void 0;
236
242
  ctx._cstBuf = void 0;
237
243
  ctx._tolerant = void 0;
@@ -246,6 +252,7 @@ function probeAt(sentinel, input, pos, ctx) {
246
252
  ctx._cstRawChildren = s._cstRawChildren;
247
253
  ctx._cstTriviaLog = s._cstTriviaLog;
248
254
  ctx._triviaLog = s._triviaLog;
255
+ ctx._rootTriviaLog = s._rootTriviaLog;
249
256
  ctx._fields = s._fields;
250
257
  ctx._cstBuf = s._cstBuf;
251
258
  ctx._tolerant = s._tolerant;
@@ -323,7 +330,20 @@ function triviaKindLabelsFromRunnable(r) {
323
330
  if (!r) return void 0;
324
331
  if (typeof r === "function") return r._meta?.triviaKindLabels;
325
332
  const grammarTrivia = r._meta.grammarTrivia;
326
- return r._meta.triviaKindLabels ?? grammarTrivia?._meta.triviaKindLabels ?? (r._def.tag === "grammar" ? r._def.triviaParser?._meta.triviaKindLabels : void 0);
333
+ return grammarTrivia?._meta.triviaKindLabels ?? r._meta.triviaKindLabels ?? (r._def.tag === "grammar" ? r._def.triviaParser?._meta.triviaKindLabels : void 0);
334
+ }
335
+ function rootTriviaClassifiedFromRunnable(r) {
336
+ if (!r) return false;
337
+ if (typeof r === "function") return r._meta?.rootTriviaClassified === true;
338
+ const grammarTrivia = r._meta.grammarTrivia;
339
+ return grammarTrivia?._meta.rootTriviaClassified === true || r._meta.rootTriviaClassified === true;
340
+ }
341
+ function makeSelectedRootLabelIndex(labels) {
342
+ const index = /* @__PURE__ */ Object.create(null);
343
+ for (let i = 0; i < labels.length; i++) {
344
+ if (index[labels[i]] === void 0) index[labels[i]] = i;
345
+ }
346
+ return index;
327
347
  }
328
348
  function runOnce(entry, input, options, phase, profileState) {
329
349
  if (typeof entry !== "function" && typeof entry?.parse !== "function") {
@@ -331,13 +351,31 @@ function runOnce(entry, input, options, phase, profileState) {
331
351
  `run(): start production is ${entry === null ? "null" : typeof entry}, not a rule \u2014 the requested grammar rule does not exist (check the rule name).`
332
352
  );
333
353
  }
334
- const triviaLog = [];
354
+ const rootTriviaSelection = options.rootTrivia?.select;
355
+ const captureRootTrivia = rootTriviaSelection !== void 0 && rootTriviaSelection.length > 0;
356
+ const selectedRootLog = captureRootTrivia ? [] : void 0;
357
+ const selectedRootLabelIndex = captureRootTrivia ? makeSelectedRootLabelIndex(rootTriviaSelection) : void 0;
335
358
  const errors = [];
336
359
  const profile = profileState ?? (phase === void 0 ? void 0 : { phase, nodes: 0, childSlots: 0, rawSlots: 0, triviaSlots: 0, fieldSlots: 0, hostCalls: 0 });
337
360
  const skipGlobalSinks = phase === "recognizer" || phase === "capture";
338
361
  const grammarTrivia = typeof entry !== "function" ? entry._meta.grammarTrivia : void 0;
339
362
  const grammarScanSkip = typeof entry !== "function" ? entry._meta.grammarScanSkip : void 0;
340
363
  const triviaKindLabels = triviaKindLabelsFromRunnable(entry) ?? triviaKindLabelsFromRunnable(options.trivia);
364
+ if (captureRootTrivia && triviaKindLabels === void 0) {
365
+ throw new TypeError("run(): rootTrivia.select requires labeled grammar trivia.");
366
+ }
367
+ if (captureRootTrivia) {
368
+ for (const label of rootTriviaSelection) {
369
+ if (!triviaKindLabels.includes(label)) {
370
+ throw new TypeError(`run(): rootTrivia.select contains unknown trivia label ${JSON.stringify(label)}.`);
371
+ }
372
+ }
373
+ }
374
+ if (captureRootTrivia && !rootTriviaClassifiedFromRunnable(entry) && !rootTriviaClassifiedFromRunnable(options.trivia)) {
375
+ throw new TypeError(
376
+ "run(): rootTrivia.select requires classifiedTrivia() at the root."
377
+ );
378
+ }
341
379
  const stamped = entry;
342
380
  assertHostModeCompatible(
343
381
  typeof entry === "function" ? stamped[FUSED_HOST_MODE] ?? "ast" : entry._meta.grammarHostMode ?? "ast",
@@ -346,7 +384,15 @@ function runOnce(entry, input, options, phase, profileState) {
346
384
  );
347
385
  const ctx = {
348
386
  trackLines: false,
349
- ...skipGlobalSinks ? { _pmProfile: profile } : { _triviaLog: triviaLog, _errors: errors, ...profile === void 0 ? {} : { _pmProfile: profile } },
387
+ ...skipGlobalSinks ? { _pmProfile: profile } : {
388
+ ...captureRootTrivia ? {
389
+ _rootTriviaLog: selectedRootLog,
390
+ _rootTriviaKindIndex: selectedRootLabelIndex,
391
+ _rootTriviaStrictScopes: true
392
+ } : {},
393
+ _errors: errors,
394
+ ...profile === void 0 ? {} : { _pmProfile: profile }
395
+ },
350
396
  build: options.build,
351
397
  state: options.state,
352
398
  ...grammarTrivia !== void 0 ? { trivia: grammarTrivia, ...triviaKindLabels ? { triviaKindLabels } : {} } : triviaKindLabels ? { triviaKindLabels } : {},
@@ -371,9 +417,13 @@ function runOnce(entry, input, options, phase, profileState) {
371
417
  span: r.span ?? { start: 0, end: 0 },
372
418
  expected: r.ok ? [] : r.expected ?? [],
373
419
  errors,
374
- triviaLog,
375
- ...triviaKindLabels === void 0 ? {} : { triviaKindLabels },
376
- triviaMap: buildRootTriviaIndex(triviaLog, triviaKindLabels),
420
+ ...selectedRootLog !== void 0 && selectedRootLog.length > 0 ? {
421
+ rootTrivia: {
422
+ rows: selectedRootLog,
423
+ select: rootTriviaSelection,
424
+ index: buildRootTriviaIndex(selectedRootLog, rootTriviaSelection)
425
+ }
426
+ } : {},
377
427
  unconsumedFrom
378
428
  };
379
429
  }