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
@@ -1,3 +1,47 @@
1
+ // src/line-index.ts
2
+ function recordLineRange(index, input, start, end) {
3
+ const lineStarts = index.lineStarts;
4
+ for (let i = start; i < end; i++) {
5
+ if (input.charCodeAt(i) === 10) lineStarts.push(i + 1);
6
+ }
7
+ }
8
+ function recordLineRangeFromContext(ctx, input, _startHint, end) {
9
+ if (!ctx.trackLines) return;
10
+ const from = ctx._lineScannedTo ?? 0;
11
+ if (end <= from) return;
12
+ const index = ctx._lineIndex ?? (ctx._lineStarts ? { lineStarts: ctx._lineStarts } : void 0);
13
+ if (!index) return;
14
+ recordLineRange(index, input, from, end);
15
+ ctx._lineScannedTo = end;
16
+ }
17
+ function offsetToLineCol(index, offset) {
18
+ const { lineStarts } = index;
19
+ let lo = 0;
20
+ let hi = lineStarts.length - 1;
21
+ while (lo < hi) {
22
+ const mid = lo + hi + 1 >> 1;
23
+ if (lineStarts[mid] <= offset) lo = mid;
24
+ else hi = mid - 1;
25
+ }
26
+ return { line: lo + 1, col: offset - lineStarts[lo] + 1 };
27
+ }
28
+ function annotateSpan(span, index) {
29
+ const s = offsetToLineCol(index, span.start);
30
+ const e = offsetToLineCol(index, span.end);
31
+ return {
32
+ ...span,
33
+ startLine: s.line,
34
+ startColumn: s.col,
35
+ endLine: e.line,
36
+ endColumn: e.col
37
+ };
38
+ }
39
+ function annotateSpanFromLineContext(span, ctx) {
40
+ if (!ctx.trackLines) return span;
41
+ const index = ctx._lineIndex ?? (ctx._lineStarts ? { lineStarts: ctx._lineStarts } : void 0);
42
+ return index ? annotateSpan(span, index) : span;
43
+ }
44
+
1
45
  // src/cst/capture-buffer.ts
2
46
  function cstCaptureActive(ctx) {
3
47
  return ctx._cstBuf !== void 0 || ctx._cstLeaves !== void 0;
@@ -98,7 +142,9 @@ function firstSetSentinel(fs) {
98
142
  function recoverScan(input, from, ctx, sync, expected) {
99
143
  let scanPos = from;
100
144
  while (scanPos < input.length && !probeAt(sync, input, scanPos, ctx)) scanPos++;
101
- const error = { _tag: "parseError", span: { start: from, end: scanPos }, expected };
145
+ const span = { start: from, end: scanPos };
146
+ if (ctx.trackLines) recordLineRangeFromContext(ctx, input, from, scanPos);
147
+ const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
102
148
  ctx._errors?.push(error);
103
149
  return { error, end: scanPos };
104
150
  }
@@ -110,6 +156,150 @@ function captureError(ctx, error) {
110
156
  }
111
157
  var REC = { scan: recoverScan, at: matchesAt, or: orSentinel, sentinel: firstSetSentinel, capture: captureError };
112
158
 
159
+ // src/cst/trivia-entries.ts
160
+ var EMPTY_INDICES = Object.freeze([]);
161
+ var EMPTY_GAPS = Object.freeze([]);
162
+ function entryOffset(i, stride) {
163
+ return i * stride;
164
+ }
165
+ function triviaEntries(log, labels, opts) {
166
+ const baseStride = opts?.nodeLog ? 3 : 2;
167
+ const stride = labels ? baseStride + 1 : baseStride;
168
+ const length = Math.floor(log.length / stride);
169
+ return {
170
+ length,
171
+ labels,
172
+ stride,
173
+ start(i) {
174
+ return log[entryOffset(i, stride)];
175
+ },
176
+ end(i) {
177
+ return log[entryOffset(i, stride) + 1];
178
+ },
179
+ insertIndex(i) {
180
+ return opts?.nodeLog ? log[entryOffset(i, stride) + 2] : void 0;
181
+ },
182
+ kindIndex(i) {
183
+ if (!labels) return void 0;
184
+ return log[entryOffset(i, stride) + baseStride];
185
+ },
186
+ kind(i) {
187
+ const ki = labels ? log[entryOffset(i, stride) + baseStride] : void 0;
188
+ return ki !== void 0 ? labels[ki] : void 0;
189
+ },
190
+ text(i, input) {
191
+ const s = log[entryOffset(i, stride)];
192
+ const e = log[entryOffset(i, stride) + 1];
193
+ return input.slice(s, e);
194
+ }
195
+ };
196
+ }
197
+ function appendEntryRange(map, key, first, last) {
198
+ let indices = map.get(key);
199
+ if (!indices) {
200
+ indices = [];
201
+ map.set(key, indices);
202
+ }
203
+ for (let i = first; i <= last; i++) indices.push(i);
204
+ }
205
+ function buildGap(entries, start, end, first, last) {
206
+ const entryIndices = [];
207
+ for (let i = first; i <= last; i++) entryIndices.push(i);
208
+ return {
209
+ start,
210
+ end,
211
+ entryIndices,
212
+ hasKind(kind) {
213
+ for (const i of entryIndices) {
214
+ if (entries.kind(i) === kind) return true;
215
+ }
216
+ return false;
217
+ },
218
+ text(input) {
219
+ return input.slice(start, end);
220
+ }
221
+ };
222
+ }
223
+ function buildRootMaps(entries) {
224
+ const before = /* @__PURE__ */ new Map();
225
+ const after = /* @__PURE__ */ new Map();
226
+ const beforeGaps = /* @__PURE__ */ new Map();
227
+ const afterGaps = /* @__PURE__ */ new Map();
228
+ const gaps = [];
229
+ if (entries.length === 0) return { before, after, beforeGaps, afterGaps, gaps };
230
+ const appendGap = (first2, last, start2, end2) => {
231
+ const gap = buildGap(entries, start2, end2, first2, last);
232
+ gaps.push(gap);
233
+ afterGaps.set(start2, gap);
234
+ beforeGaps.set(end2, gap);
235
+ appendEntryRange(after, start2, first2, last);
236
+ appendEntryRange(before, end2, first2, last);
237
+ };
238
+ let first = 0;
239
+ let start = entries.start(0);
240
+ let end = entries.end(0);
241
+ for (let i = 1; i < entries.length; i++) {
242
+ const nextStart = entries.start(i);
243
+ const nextEnd = entries.end(i);
244
+ if (nextStart === end) {
245
+ end = nextEnd;
246
+ continue;
247
+ }
248
+ appendGap(first, i - 1, start, end);
249
+ first = i;
250
+ start = nextStart;
251
+ end = nextEnd;
252
+ }
253
+ appendGap(first, entries.length - 1, start, end);
254
+ return { before, after, beforeGaps, afterGaps, gaps };
255
+ }
256
+ function buildRootTriviaIndex(log, labels) {
257
+ const entries = triviaEntries(log, labels);
258
+ let maps;
259
+ const getMaps = () => {
260
+ maps ??= buildRootMaps(entries);
261
+ return maps;
262
+ };
263
+ return {
264
+ entries,
265
+ labels,
266
+ get before() {
267
+ return getMaps().before;
268
+ },
269
+ get after() {
270
+ return getMaps().after;
271
+ },
272
+ entryIndicesBefore(offset) {
273
+ return getMaps().before.get(offset) ?? EMPTY_INDICES;
274
+ },
275
+ entryIndicesAfter(offset) {
276
+ return getMaps().after.get(offset) ?? EMPTY_INDICES;
277
+ },
278
+ gapBefore(offset) {
279
+ return getMaps().beforeGaps.get(offset);
280
+ },
281
+ gapAfter(offset) {
282
+ return getMaps().afterGaps.get(offset);
283
+ },
284
+ gaps() {
285
+ return getMaps().gaps;
286
+ },
287
+ gapsWithKind(kind) {
288
+ const kinds = typeof kind === "string" ? [kind] : kind;
289
+ const matches2 = [];
290
+ for (const gap of getMaps().gaps) {
291
+ for (const k of kinds) {
292
+ if (gap.hasKind(k)) {
293
+ matches2.push(gap);
294
+ break;
295
+ }
296
+ }
297
+ }
298
+ return matches2.length === 0 ? EMPTY_GAPS : matches2;
299
+ }
300
+ };
301
+ }
302
+
113
303
  // src/cst/host-mode.ts
114
304
  var FUSED_HOST_MODE = /* @__PURE__ */ Symbol.for("parseman.fusedHostMode");
115
305
  var FUSED_HOST_ELIDED = /* @__PURE__ */ Symbol.for("parseman.fusedHostElided");
@@ -129,6 +319,12 @@ function assertHostModeCompatible(mode, build, hostBranchElided = true) {
129
319
 
130
320
  // src/functional/run.ts
131
321
  var invoke = (r, input, pos, ctx) => typeof r === "function" ? r(input, pos, ctx) : r.parse(input, pos, ctx);
322
+ function triviaKindLabelsFromRunnable(r) {
323
+ if (!r) return void 0;
324
+ if (typeof r === "function") return r._meta?.triviaKindLabels;
325
+ const grammarTrivia = r._meta.grammarTrivia;
326
+ return r._meta.triviaKindLabels ?? grammarTrivia?._meta.triviaKindLabels ?? (r._def.tag === "grammar" ? r._def.triviaParser?._meta.triviaKindLabels : void 0);
327
+ }
132
328
  function runOnce(entry, input, options, phase, profileState) {
133
329
  if (typeof entry !== "function" && typeof entry?.parse !== "function") {
134
330
  throw new TypeError(
@@ -141,6 +337,7 @@ function runOnce(entry, input, options, phase, profileState) {
141
337
  const skipGlobalSinks = phase === "recognizer" || phase === "capture";
142
338
  const grammarTrivia = typeof entry !== "function" ? entry._meta.grammarTrivia : void 0;
143
339
  const grammarScanSkip = typeof entry !== "function" ? entry._meta.grammarScanSkip : void 0;
340
+ const triviaKindLabels = triviaKindLabelsFromRunnable(entry) ?? triviaKindLabelsFromRunnable(options.trivia);
144
341
  const stamped = entry;
145
342
  assertHostModeCompatible(
146
343
  typeof entry === "function" ? stamped[FUSED_HOST_MODE] ?? "ast" : entry._meta.grammarHostMode ?? "ast",
@@ -152,7 +349,7 @@ function runOnce(entry, input, options, phase, profileState) {
152
349
  ...skipGlobalSinks ? { _pmProfile: profile } : { _triviaLog: triviaLog, _errors: errors, ...profile === void 0 ? {} : { _pmProfile: profile } },
153
350
  build: options.build,
154
351
  state: options.state,
155
- ...grammarTrivia !== void 0 ? { trivia: grammarTrivia, ...grammarTrivia._meta.triviaKindLabels ? { triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {} } : {},
352
+ ...grammarTrivia !== void 0 ? { trivia: grammarTrivia, ...triviaKindLabels ? { triviaKindLabels } : {} } : triviaKindLabels ? { triviaKindLabels } : {},
156
353
  ...grammarScanSkip !== void 0 ? { scanSkip: grammarScanSkip } : {},
157
354
  ...options.triviaCaptureMask !== void 0 ? { _triviaCaptureMask: options.triviaCaptureMask } : {},
158
355
  ...options.tolerant ? { _tolerant: true, _rec: REC } : {},
@@ -175,6 +372,8 @@ function runOnce(entry, input, options, phase, profileState) {
175
372
  expected: r.ok ? [] : r.expected ?? [],
176
373
  errors,
177
374
  triviaLog,
375
+ ...triviaKindLabels === void 0 ? {} : { triviaKindLabels },
376
+ triviaMap: buildRootTriviaIndex(triviaLog, triviaKindLabels),
178
377
  unconsumedFrom
179
378
  };
180
379
  }
@@ -238,7 +437,7 @@ var META = new Set("()[]{}*+?|^$.".split(""));
238
437
  var CAP_RECORD = [
239
438
  ` if (_cap && _e > _pos) {`,
240
439
  ` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_pos, _e)`,
241
- ` if (_ctx._cstTriviaLog !== undefined && _ctx.captureTrivia) _ctx._cstTriviaLog.push(_pos, _e, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0)`,
440
+ ` if (_cap === 1 && _ctx._cstTriviaLog !== undefined && _ctx.captureTrivia) _ctx._cstTriviaLog.push(_pos, _e, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0)`,
242
441
  ` }`
243
442
  ].join("\n");
244
443
 
@@ -252,7 +451,7 @@ function normalizeCstCollapse(collapse) {
252
451
  return typeof collapse === "function" ? collapse : void 0;
253
452
  }
254
453
  function buildCstNode(type, children, _fields, span, _rawChildren, _triviaLog, state) {
255
- return { _tag: "node", type, span: { start: span.start, end: span.end }, state: state ?? null, children: [...children] };
454
+ return { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children] };
256
455
  }
257
456
  function cstBuildHost(typeOrOptions, children, _fields, span, rawChildren, triviaLog, state) {
258
457
  if (typeof typeOrOptions === "string") {