parseman 0.40.0 → 0.42.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 (54) hide show
  1. package/README.md +7 -6
  2. package/dist/combinators/expect.d.ts.map +1 -1
  3. package/dist/combinators/grammar.d.ts.map +1 -1
  4. package/dist/combinators/literal.d.ts.map +1 -1
  5. package/dist/combinators/node.d.ts.map +1 -1
  6. package/dist/combinators/regex.d.ts.map +1 -1
  7. package/dist/combinators/scanTo.d.ts.map +1 -1
  8. package/dist/combinators/trivia-skip.d.ts.map +1 -1
  9. package/dist/compiler/codegen.d.ts +3 -0
  10. package/dist/compiler/codegen.d.ts.map +1 -1
  11. package/dist/compiler/inline-build.d.ts +1 -1
  12. package/dist/compiler/inline-build.d.ts.map +1 -1
  13. package/dist/compiler/inline-callback.d.ts +9 -0
  14. package/dist/compiler/inline-callback.d.ts.map +1 -1
  15. package/dist/compiler/line-index.d.ts +1 -15
  16. package/dist/compiler/line-index.d.ts.map +1 -1
  17. package/dist/compiler/value-usage.d.ts.map +1 -1
  18. package/dist/cst/capture-buffer.d.ts.map +1 -1
  19. package/dist/cst/trivia-entries.d.ts +52 -0
  20. package/dist/cst/trivia-entries.d.ts.map +1 -1
  21. package/dist/functional/run.d.ts +11 -2
  22. package/dist/functional/run.d.ts.map +1 -1
  23. package/dist/index.cjs +634 -169
  24. package/dist/index.cjs.map +4 -4
  25. package/dist/index.d.ts +4 -4
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +634 -169
  28. package/dist/index.js.map +4 -4
  29. package/dist/language-service/index.cjs +203 -4
  30. package/dist/language-service/index.cjs.map +4 -4
  31. package/dist/language-service/index.js +203 -4
  32. package/dist/language-service/index.js.map +4 -4
  33. package/dist/line-index.d.ts +41 -0
  34. package/dist/line-index.d.ts.map +1 -0
  35. package/dist/plugin/index.cjs +454 -126
  36. package/dist/plugin/index.cjs.map +4 -4
  37. package/dist/plugin/index.js +454 -126
  38. package/dist/plugin/index.js.map +4 -4
  39. package/dist/recovery/scan.d.ts.map +1 -1
  40. package/dist/regex/first-set.d.ts.map +1 -1
  41. package/dist/run/index.cjs +202 -2
  42. package/dist/run/index.cjs.map +4 -4
  43. package/dist/run/index.d.ts +8 -4
  44. package/dist/run/index.d.ts.map +1 -1
  45. package/dist/run/index.js +202 -2
  46. package/dist/run/index.js.map +4 -4
  47. package/dist/spec/index.cjs +174 -52
  48. package/dist/spec/index.cjs.map +4 -4
  49. package/dist/spec/index.js +174 -52
  50. package/dist/spec/index.js.map +4 -4
  51. package/dist/types.d.ts +12 -0
  52. package/dist/types.d.ts.map +1 -1
  53. package/dist/version.d.ts +1 -1
  54. package/package.json +1 -1
@@ -24,6 +24,50 @@ __export(language_service_exports, {
24
24
  });
25
25
  module.exports = __toCommonJS(language_service_exports);
26
26
 
27
+ // src/line-index.ts
28
+ function recordLineRange(index, input, start, end) {
29
+ const lineStarts = index.lineStarts;
30
+ for (let i = start; i < end; i++) {
31
+ if (input.charCodeAt(i) === 10) lineStarts.push(i + 1);
32
+ }
33
+ }
34
+ function recordLineRangeFromContext(ctx, input, _startHint, end) {
35
+ if (!ctx.trackLines) return;
36
+ const from = ctx._lineScannedTo ?? 0;
37
+ if (end <= from) return;
38
+ const index = ctx._lineIndex ?? (ctx._lineStarts ? { lineStarts: ctx._lineStarts } : void 0);
39
+ if (!index) return;
40
+ recordLineRange(index, input, from, end);
41
+ ctx._lineScannedTo = end;
42
+ }
43
+ function offsetToLineCol(index, offset) {
44
+ const { lineStarts } = index;
45
+ let lo = 0;
46
+ let hi = lineStarts.length - 1;
47
+ while (lo < hi) {
48
+ const mid = lo + hi + 1 >> 1;
49
+ if (lineStarts[mid] <= offset) lo = mid;
50
+ else hi = mid - 1;
51
+ }
52
+ return { line: lo + 1, col: offset - lineStarts[lo] + 1 };
53
+ }
54
+ function annotateSpan(span, index) {
55
+ const s = offsetToLineCol(index, span.start);
56
+ const e = offsetToLineCol(index, span.end);
57
+ return {
58
+ ...span,
59
+ startLine: s.line,
60
+ startColumn: s.col,
61
+ endLine: e.line,
62
+ endColumn: e.col
63
+ };
64
+ }
65
+ function annotateSpanFromLineContext(span, ctx) {
66
+ if (!ctx.trackLines) return span;
67
+ const index = ctx._lineIndex ?? (ctx._lineStarts ? { lineStarts: ctx._lineStarts } : void 0);
68
+ return index ? annotateSpan(span, index) : span;
69
+ }
70
+
27
71
  // src/cst/capture-buffer.ts
28
72
  function cstCaptureActive(ctx) {
29
73
  return ctx._cstBuf !== void 0 || ctx._cstLeaves !== void 0;
@@ -124,7 +168,9 @@ function firstSetSentinel(fs) {
124
168
  function recoverScan(input, from, ctx, sync, expected) {
125
169
  let scanPos = from;
126
170
  while (scanPos < input.length && !probeAt(sync, input, scanPos, ctx)) scanPos++;
127
- const error = { _tag: "parseError", span: { start: from, end: scanPos }, expected };
171
+ const span = { start: from, end: scanPos };
172
+ if (ctx.trackLines) recordLineRangeFromContext(ctx, input, from, scanPos);
173
+ const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
128
174
  ctx._errors?.push(error);
129
175
  return { error, end: scanPos };
130
176
  }
@@ -136,6 +182,150 @@ function captureError(ctx, error) {
136
182
  }
137
183
  var REC = { scan: recoverScan, at: matchesAt, or: orSentinel, sentinel: firstSetSentinel, capture: captureError };
138
184
 
185
+ // src/cst/trivia-entries.ts
186
+ var EMPTY_INDICES = Object.freeze([]);
187
+ var EMPTY_GAPS = Object.freeze([]);
188
+ function entryOffset(i, stride) {
189
+ return i * stride;
190
+ }
191
+ function triviaEntries(log, labels, opts) {
192
+ const baseStride = opts?.nodeLog ? 3 : 2;
193
+ const stride = labels ? baseStride + 1 : baseStride;
194
+ const length = Math.floor(log.length / stride);
195
+ return {
196
+ length,
197
+ labels,
198
+ stride,
199
+ start(i) {
200
+ return log[entryOffset(i, stride)];
201
+ },
202
+ end(i) {
203
+ return log[entryOffset(i, stride) + 1];
204
+ },
205
+ insertIndex(i) {
206
+ return opts?.nodeLog ? log[entryOffset(i, stride) + 2] : void 0;
207
+ },
208
+ kindIndex(i) {
209
+ if (!labels) return void 0;
210
+ return log[entryOffset(i, stride) + baseStride];
211
+ },
212
+ kind(i) {
213
+ const ki = labels ? log[entryOffset(i, stride) + baseStride] : void 0;
214
+ return ki !== void 0 ? labels[ki] : void 0;
215
+ },
216
+ text(i, input) {
217
+ const s = log[entryOffset(i, stride)];
218
+ const e = log[entryOffset(i, stride) + 1];
219
+ return input.slice(s, e);
220
+ }
221
+ };
222
+ }
223
+ function appendEntryRange(map, key, first, last) {
224
+ let indices = map.get(key);
225
+ if (!indices) {
226
+ indices = [];
227
+ map.set(key, indices);
228
+ }
229
+ for (let i = first; i <= last; i++) indices.push(i);
230
+ }
231
+ function buildGap(entries, start, end, first, last) {
232
+ const entryIndices = [];
233
+ for (let i = first; i <= last; i++) entryIndices.push(i);
234
+ return {
235
+ start,
236
+ end,
237
+ entryIndices,
238
+ hasKind(kind) {
239
+ for (const i of entryIndices) {
240
+ if (entries.kind(i) === kind) return true;
241
+ }
242
+ return false;
243
+ },
244
+ text(input) {
245
+ return input.slice(start, end);
246
+ }
247
+ };
248
+ }
249
+ function buildRootMaps(entries) {
250
+ const before = /* @__PURE__ */ new Map();
251
+ const after = /* @__PURE__ */ new Map();
252
+ const beforeGaps = /* @__PURE__ */ new Map();
253
+ const afterGaps = /* @__PURE__ */ new Map();
254
+ const gaps = [];
255
+ if (entries.length === 0) return { before, after, beforeGaps, afterGaps, gaps };
256
+ const appendGap = (first2, last, start2, end2) => {
257
+ const gap = buildGap(entries, start2, end2, first2, last);
258
+ gaps.push(gap);
259
+ afterGaps.set(start2, gap);
260
+ beforeGaps.set(end2, gap);
261
+ appendEntryRange(after, start2, first2, last);
262
+ appendEntryRange(before, end2, first2, last);
263
+ };
264
+ let first = 0;
265
+ let start = entries.start(0);
266
+ let end = entries.end(0);
267
+ for (let i = 1; i < entries.length; i++) {
268
+ const nextStart = entries.start(i);
269
+ const nextEnd = entries.end(i);
270
+ if (nextStart === end) {
271
+ end = nextEnd;
272
+ continue;
273
+ }
274
+ appendGap(first, i - 1, start, end);
275
+ first = i;
276
+ start = nextStart;
277
+ end = nextEnd;
278
+ }
279
+ appendGap(first, entries.length - 1, start, end);
280
+ return { before, after, beforeGaps, afterGaps, gaps };
281
+ }
282
+ function buildRootTriviaIndex(log, labels) {
283
+ const entries = triviaEntries(log, labels);
284
+ let maps;
285
+ const getMaps = () => {
286
+ maps ??= buildRootMaps(entries);
287
+ return maps;
288
+ };
289
+ return {
290
+ entries,
291
+ labels,
292
+ get before() {
293
+ return getMaps().before;
294
+ },
295
+ get after() {
296
+ return getMaps().after;
297
+ },
298
+ entryIndicesBefore(offset) {
299
+ return getMaps().before.get(offset) ?? EMPTY_INDICES;
300
+ },
301
+ entryIndicesAfter(offset) {
302
+ return getMaps().after.get(offset) ?? EMPTY_INDICES;
303
+ },
304
+ gapBefore(offset) {
305
+ return getMaps().beforeGaps.get(offset);
306
+ },
307
+ gapAfter(offset) {
308
+ return getMaps().afterGaps.get(offset);
309
+ },
310
+ gaps() {
311
+ return getMaps().gaps;
312
+ },
313
+ gapsWithKind(kind) {
314
+ const kinds = typeof kind === "string" ? [kind] : kind;
315
+ const matches2 = [];
316
+ for (const gap of getMaps().gaps) {
317
+ for (const k of kinds) {
318
+ if (gap.hasKind(k)) {
319
+ matches2.push(gap);
320
+ break;
321
+ }
322
+ }
323
+ }
324
+ return matches2.length === 0 ? EMPTY_GAPS : matches2;
325
+ }
326
+ };
327
+ }
328
+
139
329
  // src/cst/host-mode.ts
140
330
  var FUSED_HOST_MODE = /* @__PURE__ */ Symbol.for("parseman.fusedHostMode");
141
331
  var FUSED_HOST_ELIDED = /* @__PURE__ */ Symbol.for("parseman.fusedHostElided");
@@ -155,6 +345,12 @@ function assertHostModeCompatible(mode, build, hostBranchElided = true) {
155
345
 
156
346
  // src/functional/run.ts
157
347
  var invoke = (r, input, pos, ctx) => typeof r === "function" ? r(input, pos, ctx) : r.parse(input, pos, ctx);
348
+ function triviaKindLabelsFromRunnable(r) {
349
+ if (!r) return void 0;
350
+ if (typeof r === "function") return r._meta?.triviaKindLabels;
351
+ const grammarTrivia = r._meta.grammarTrivia;
352
+ return r._meta.triviaKindLabels ?? grammarTrivia?._meta.triviaKindLabels ?? (r._def.tag === "grammar" ? r._def.triviaParser?._meta.triviaKindLabels : void 0);
353
+ }
158
354
  function runOnce(entry, input, options, phase, profileState) {
159
355
  if (typeof entry !== "function" && typeof entry?.parse !== "function") {
160
356
  throw new TypeError(
@@ -167,6 +363,7 @@ function runOnce(entry, input, options, phase, profileState) {
167
363
  const skipGlobalSinks = phase === "recognizer" || phase === "capture";
168
364
  const grammarTrivia = typeof entry !== "function" ? entry._meta.grammarTrivia : void 0;
169
365
  const grammarScanSkip = typeof entry !== "function" ? entry._meta.grammarScanSkip : void 0;
366
+ const triviaKindLabels = triviaKindLabelsFromRunnable(entry) ?? triviaKindLabelsFromRunnable(options.trivia);
170
367
  const stamped = entry;
171
368
  assertHostModeCompatible(
172
369
  typeof entry === "function" ? stamped[FUSED_HOST_MODE] ?? "ast" : entry._meta.grammarHostMode ?? "ast",
@@ -178,7 +375,7 @@ function runOnce(entry, input, options, phase, profileState) {
178
375
  ...skipGlobalSinks ? { _pmProfile: profile } : { _triviaLog: triviaLog, _errors: errors, ...profile === void 0 ? {} : { _pmProfile: profile } },
179
376
  build: options.build,
180
377
  state: options.state,
181
- ...grammarTrivia !== void 0 ? { trivia: grammarTrivia, ...grammarTrivia._meta.triviaKindLabels ? { triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {} } : {},
378
+ ...grammarTrivia !== void 0 ? { trivia: grammarTrivia, ...triviaKindLabels ? { triviaKindLabels } : {} } : triviaKindLabels ? { triviaKindLabels } : {},
182
379
  ...grammarScanSkip !== void 0 ? { scanSkip: grammarScanSkip } : {},
183
380
  ...options.triviaCaptureMask !== void 0 ? { _triviaCaptureMask: options.triviaCaptureMask } : {},
184
381
  ...options.tolerant ? { _tolerant: true, _rec: REC } : {},
@@ -201,6 +398,8 @@ function runOnce(entry, input, options, phase, profileState) {
201
398
  expected: r.ok ? [] : r.expected ?? [],
202
399
  errors,
203
400
  triviaLog,
401
+ ...triviaKindLabels === void 0 ? {} : { triviaKindLabels },
402
+ triviaMap: buildRootTriviaIndex(triviaLog, triviaKindLabels),
204
403
  unconsumedFrom
205
404
  };
206
405
  }
@@ -264,7 +463,7 @@ var META = new Set("()[]{}*+?|^$.".split(""));
264
463
  var CAP_RECORD = [
265
464
  ` if (_cap && _e > _pos) {`,
266
465
  ` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_pos, _e)`,
267
- ` if (_ctx._cstTriviaLog !== undefined && _ctx.captureTrivia) _ctx._cstTriviaLog.push(_pos, _e, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0)`,
466
+ ` if (_cap === 1 && _ctx._cstTriviaLog !== undefined && _ctx.captureTrivia) _ctx._cstTriviaLog.push(_pos, _e, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0)`,
268
467
  ` }`
269
468
  ].join("\n");
270
469
 
@@ -278,7 +477,7 @@ function normalizeCstCollapse(collapse) {
278
477
  return typeof collapse === "function" ? collapse : void 0;
279
478
  }
280
479
  function buildCstNode(type, children, _fields, span, _rawChildren, _triviaLog, state) {
281
- return { _tag: "node", type, span: { start: span.start, end: span.end }, state: state ?? null, children: [...children] };
480
+ return { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children] };
282
481
  }
283
482
  function cstBuildHost(typeOrOptions, children, _fields, span, rawChildren, triviaLog, state) {
284
483
  if (typeof typeOrOptions === "string") {