parseman 0.41.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.
- package/dist/combinators/expect.d.ts.map +1 -1
- package/dist/combinators/grammar.d.ts.map +1 -1
- package/dist/combinators/literal.d.ts.map +1 -1
- package/dist/combinators/node.d.ts.map +1 -1
- package/dist/combinators/regex.d.ts.map +1 -1
- package/dist/combinators/scanTo.d.ts.map +1 -1
- package/dist/combinators/trivia-skip.d.ts.map +1 -1
- package/dist/compiler/codegen.d.ts +3 -0
- package/dist/compiler/codegen.d.ts.map +1 -1
- package/dist/compiler/inline-build.d.ts +1 -1
- package/dist/compiler/inline-build.d.ts.map +1 -1
- package/dist/compiler/line-index.d.ts +1 -15
- package/dist/compiler/line-index.d.ts.map +1 -1
- package/dist/cst/capture-buffer.d.ts.map +1 -1
- package/dist/index.cjs +364 -99
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +364 -99
- package/dist/index.js.map +4 -4
- package/dist/language-service/index.cjs +48 -2
- package/dist/language-service/index.cjs.map +3 -3
- package/dist/language-service/index.js +48 -2
- package/dist/language-service/index.js.map +3 -3
- package/dist/line-index.d.ts +41 -0
- package/dist/line-index.d.ts.map +1 -0
- package/dist/plugin/index.cjs +334 -93
- package/dist/plugin/index.cjs.map +4 -4
- package/dist/plugin/index.js +334 -93
- package/dist/plugin/index.js.map +4 -4
- package/dist/recovery/scan.d.ts.map +1 -1
- package/dist/regex/first-set.d.ts.map +1 -1
- package/dist/run/index.cjs +47 -1
- package/dist/run/index.cjs.map +3 -3
- package/dist/run/index.d.ts +3 -2
- package/dist/run/index.d.ts.map +1 -1
- package/dist/run/index.js +47 -1
- package/dist/run/index.js.map +3 -3
- package/dist/spec/index.cjs +170 -50
- package/dist/spec/index.cjs.map +4 -4
- package/dist/spec/index.js +170 -50
- package/dist/spec/index.js.map +4 -4
- package/dist/types.d.ts +12 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -237,6 +237,87 @@ function failAt(ctx, expected, pos) {
|
|
|
237
237
|
return r;
|
|
238
238
|
}
|
|
239
239
|
|
|
240
|
+
// src/line-index.ts
|
|
241
|
+
function createLineIndex() {
|
|
242
|
+
return { lineStarts: [0] };
|
|
243
|
+
}
|
|
244
|
+
function buildLineIndex(input) {
|
|
245
|
+
const lineStarts = [0];
|
|
246
|
+
for (let i = 0; i < input.length; i++) {
|
|
247
|
+
if (input.charCodeAt(i) === 10) lineStarts.push(i + 1);
|
|
248
|
+
}
|
|
249
|
+
return { lineStarts };
|
|
250
|
+
}
|
|
251
|
+
function recordLineRange(index, input, start, end) {
|
|
252
|
+
const lineStarts = index.lineStarts;
|
|
253
|
+
for (let i = start; i < end; i++) {
|
|
254
|
+
if (input.charCodeAt(i) === 10) lineStarts.push(i + 1);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
function recordLineRangeFromContext(ctx, input, _startHint, end) {
|
|
258
|
+
if (!ctx.trackLines) return;
|
|
259
|
+
const from = ctx._lineScannedTo ?? 0;
|
|
260
|
+
if (end <= from) return;
|
|
261
|
+
const index = ctx._lineIndex ?? (ctx._lineStarts ? { lineStarts: ctx._lineStarts } : void 0);
|
|
262
|
+
if (!index) return;
|
|
263
|
+
recordLineRange(index, input, from, end);
|
|
264
|
+
ctx._lineScannedTo = end;
|
|
265
|
+
}
|
|
266
|
+
function normalizeLineIndex(index) {
|
|
267
|
+
const starts = index.lineStarts;
|
|
268
|
+
starts.sort((a, b) => a - b);
|
|
269
|
+
let write = 0;
|
|
270
|
+
for (let read = 0; read < starts.length; read++) {
|
|
271
|
+
const value = starts[read];
|
|
272
|
+
if (write === 0 || starts[write - 1] !== value) starts[write++] = value;
|
|
273
|
+
}
|
|
274
|
+
starts.length = write;
|
|
275
|
+
if (starts.length === 0 || starts[0] !== 0) starts.unshift(0);
|
|
276
|
+
return index;
|
|
277
|
+
}
|
|
278
|
+
function offsetToLineCol(index, offset) {
|
|
279
|
+
const { lineStarts } = index;
|
|
280
|
+
let lo = 0;
|
|
281
|
+
let hi = lineStarts.length - 1;
|
|
282
|
+
while (lo < hi) {
|
|
283
|
+
const mid = lo + hi + 1 >> 1;
|
|
284
|
+
if (lineStarts[mid] <= offset) lo = mid;
|
|
285
|
+
else hi = mid - 1;
|
|
286
|
+
}
|
|
287
|
+
return { line: lo + 1, col: offset - lineStarts[lo] + 1 };
|
|
288
|
+
}
|
|
289
|
+
function annotateSpan(span, index) {
|
|
290
|
+
const s = offsetToLineCol(index, span.start);
|
|
291
|
+
const e = offsetToLineCol(index, span.end);
|
|
292
|
+
return {
|
|
293
|
+
...span,
|
|
294
|
+
startLine: s.line,
|
|
295
|
+
startColumn: s.col,
|
|
296
|
+
endLine: e.line,
|
|
297
|
+
endColumn: e.col
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
function annotateSpanFromLineContext(span, ctx) {
|
|
301
|
+
if (!ctx.trackLines) return span;
|
|
302
|
+
const index = ctx._lineIndex ?? (ctx._lineStarts ? { lineStarts: ctx._lineStarts } : void 0);
|
|
303
|
+
return index ? annotateSpan(span, index) : span;
|
|
304
|
+
}
|
|
305
|
+
function isSpan(value) {
|
|
306
|
+
return !!value && typeof value === "object" && typeof value.start === "number" && typeof value.end === "number";
|
|
307
|
+
}
|
|
308
|
+
function annotateTreeSpans(value, index, seen = /* @__PURE__ */ new WeakSet()) {
|
|
309
|
+
if (!value || typeof value !== "object") return value;
|
|
310
|
+
if (seen.has(value)) return value;
|
|
311
|
+
seen.add(value);
|
|
312
|
+
const obj = value;
|
|
313
|
+
if (isSpan(obj.span)) obj.span = annotateSpan(obj.span, index);
|
|
314
|
+
for (const key of Object.keys(obj)) {
|
|
315
|
+
const child = obj[key];
|
|
316
|
+
if (child && typeof child === "object") annotateTreeSpans(child, index, seen);
|
|
317
|
+
}
|
|
318
|
+
return value;
|
|
319
|
+
}
|
|
320
|
+
|
|
240
321
|
// src/cst/capture-buffer.ts
|
|
241
322
|
var EMPTY = [];
|
|
242
323
|
var EMPTY_TL = [];
|
|
@@ -278,7 +359,12 @@ function endCstNodeCapture(ctx, saved) {
|
|
|
278
359
|
return materialized;
|
|
279
360
|
}
|
|
280
361
|
function pushCstLeaf(ctx, leaf2) {
|
|
281
|
-
|
|
362
|
+
if (!ctx.trackLines) {
|
|
363
|
+
pushCstChild(ctx, leaf2, leaf2);
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
const annotated = leaf2 && typeof leaf2 === "object" && leaf2.span ? { ...leaf2, span: annotateSpanFromLineContext(leaf2.span, ctx) } : leaf2;
|
|
367
|
+
pushCstChild(ctx, annotated, annotated);
|
|
282
368
|
}
|
|
283
369
|
function pushCstChild(ctx, built, rawEntry) {
|
|
284
370
|
const b = ctx._cstBuf;
|
|
@@ -412,6 +498,7 @@ function literal(value, opts = {}) {
|
|
|
412
498
|
canMatchNewline: value.includes("\n"),
|
|
413
499
|
isTrivia: false
|
|
414
500
|
};
|
|
501
|
+
const canMatchNewline = meta.canMatchNewline;
|
|
415
502
|
if (caseInsensitive) {
|
|
416
503
|
const upper = value.toUpperCase();
|
|
417
504
|
const lower = value.toLowerCase();
|
|
@@ -428,6 +515,7 @@ function literal(value, opts = {}) {
|
|
|
428
515
|
return function parse3(input, pos, ctx) {
|
|
429
516
|
if (input.charCodeAt(pos) === code) {
|
|
430
517
|
const span = { start: pos, end: pos + 1 };
|
|
518
|
+
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, span.end);
|
|
431
519
|
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
432
520
|
return { ok: true, value, span };
|
|
433
521
|
}
|
|
@@ -441,6 +529,7 @@ function literal(value, opts = {}) {
|
|
|
441
529
|
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
442
530
|
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
443
531
|
const span = { start: pos, end };
|
|
532
|
+
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, end);
|
|
444
533
|
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: matchedValue, span });
|
|
445
534
|
return { ok: true, value: matchedValue, span };
|
|
446
535
|
}
|
|
@@ -608,6 +697,7 @@ function regex(pattern, flags = "") {
|
|
|
608
697
|
if (scanEnd === null) return failAt(ctx, [`/${source}/`], pos);
|
|
609
698
|
const value = input.slice(pos, scanEnd);
|
|
610
699
|
const span2 = { start: pos, end: scanEnd };
|
|
700
|
+
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, scanEnd);
|
|
611
701
|
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span: span2 });
|
|
612
702
|
return { ok: true, value, span: span2 };
|
|
613
703
|
}
|
|
@@ -617,6 +707,7 @@ function regex(pattern, flags = "") {
|
|
|
617
707
|
return failAt(ctx, [`/${source}/`], pos);
|
|
618
708
|
}
|
|
619
709
|
const span = { start: pos, end: pos + m[0].length };
|
|
710
|
+
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, span.end);
|
|
620
711
|
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: m[0], span });
|
|
621
712
|
return { ok: true, value: m[0], span };
|
|
622
713
|
}
|
|
@@ -755,8 +846,8 @@ function parseRegex(src) {
|
|
|
755
846
|
}
|
|
756
847
|
if (src[k] !== "]") throw BAIL;
|
|
757
848
|
i = k + 1;
|
|
758
|
-
if (negated) return charNode(any(), true);
|
|
759
849
|
const ranges = parseClassRanges(body);
|
|
850
|
+
if (negated) return charNode(any(), !ranges || !rangesHaveNewline(ranges));
|
|
760
851
|
if (!ranges) return charNode(any(), true);
|
|
761
852
|
return charNode(rangesToSet(ranges), rangesHaveNewline(ranges));
|
|
762
853
|
};
|
|
@@ -852,7 +943,7 @@ function firstSet(n) {
|
|
|
852
943
|
}
|
|
853
944
|
}
|
|
854
945
|
}
|
|
855
|
-
function
|
|
946
|
+
function canConsumeNewline(n) {
|
|
856
947
|
switch (n.t) {
|
|
857
948
|
case "char":
|
|
858
949
|
return n.nl;
|
|
@@ -861,16 +952,11 @@ function firstCanBeNewline(n) {
|
|
|
861
952
|
case "empty":
|
|
862
953
|
return false;
|
|
863
954
|
case "rep":
|
|
864
|
-
return
|
|
955
|
+
return canConsumeNewline(n.node);
|
|
865
956
|
case "alt":
|
|
866
|
-
return n.arms.some(
|
|
867
|
-
case "seq":
|
|
868
|
-
|
|
869
|
-
if (firstCanBeNewline(part)) return true;
|
|
870
|
-
if (!nullable(part)) break;
|
|
871
|
-
}
|
|
872
|
-
return false;
|
|
873
|
-
}
|
|
957
|
+
return n.arms.some(canConsumeNewline);
|
|
958
|
+
case "seq":
|
|
959
|
+
return n.parts.some(canConsumeNewline);
|
|
874
960
|
}
|
|
875
961
|
}
|
|
876
962
|
function firstSetFromRegex(source) {
|
|
@@ -880,8 +966,8 @@ function firstSetFromRegex(source) {
|
|
|
880
966
|
} catch {
|
|
881
967
|
return { firstSet: any(), canMatchNewline: true };
|
|
882
968
|
}
|
|
883
|
-
if (nullable(ast)) return { firstSet: any(), canMatchNewline:
|
|
884
|
-
return { firstSet: firstSet(ast), canMatchNewline:
|
|
969
|
+
if (nullable(ast)) return { firstSet: any(), canMatchNewline: canConsumeNewline(ast) };
|
|
970
|
+
return { firstSet: firstSet(ast), canMatchNewline: canConsumeNewline(ast) };
|
|
885
971
|
}
|
|
886
972
|
|
|
887
973
|
// src/combinators/case-fold.ts
|
|
@@ -1043,7 +1129,9 @@ function firstSetSentinel(fs) {
|
|
|
1043
1129
|
function recoverScan(input, from, ctx, sync, expected) {
|
|
1044
1130
|
let scanPos = from;
|
|
1045
1131
|
while (scanPos < input.length && !probeAt(sync, input, scanPos, ctx)) scanPos++;
|
|
1046
|
-
const
|
|
1132
|
+
const span = { start: from, end: scanPos };
|
|
1133
|
+
if (ctx.trackLines) recordLineRangeFromContext(ctx, input, from, scanPos);
|
|
1134
|
+
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1047
1135
|
ctx._errors?.push(error);
|
|
1048
1136
|
return { error, end: scanPos };
|
|
1049
1137
|
}
|
|
@@ -1146,7 +1234,8 @@ function expect(combinator, label2) {
|
|
|
1146
1234
|
parse(input, pos, ctx) {
|
|
1147
1235
|
const result = combinator.parse(input, pos, ctx);
|
|
1148
1236
|
if (result.ok) return result;
|
|
1149
|
-
const
|
|
1237
|
+
const span = { start: pos, end: pos };
|
|
1238
|
+
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1150
1239
|
ctx._errors?.push(error);
|
|
1151
1240
|
if (ctx._tolerant) captureError(ctx, error);
|
|
1152
1241
|
return { ok: true, value: error, span: { start: pos, end: pos } };
|
|
@@ -1594,6 +1683,18 @@ function rollbackTrivia(ctx, mark) {
|
|
|
1594
1683
|
rollbackCstCapture(ctx, { raw: mark.raw, tlog: mark.tlog, leaves: mark.leaves, fields: mark.fields, errors: mark.errors });
|
|
1595
1684
|
if (ctx._triviaLog && ctx._triviaLog.length !== mark.log) ctx._triviaLog.length = mark.log;
|
|
1596
1685
|
}
|
|
1686
|
+
function parseTriviaNoCapture(triviaP, input, cur, ctx) {
|
|
1687
|
+
const probeCtx = {
|
|
1688
|
+
trackLines: ctx.trackLines,
|
|
1689
|
+
state: ctx.state,
|
|
1690
|
+
...ctx._lineIndex ? { _lineIndex: ctx._lineIndex } : {},
|
|
1691
|
+
...ctx._lineStarts ? { _lineStarts: ctx._lineStarts } : {},
|
|
1692
|
+
...ctx._lineScannedTo !== void 0 ? { _lineScannedTo: ctx._lineScannedTo } : {}
|
|
1693
|
+
};
|
|
1694
|
+
const result = triviaP.parse(input, cur, probeCtx);
|
|
1695
|
+
ctx._lineScannedTo = probeCtx._lineScannedTo;
|
|
1696
|
+
return result;
|
|
1697
|
+
}
|
|
1597
1698
|
function saveLookaheadMark(ctx) {
|
|
1598
1699
|
return { ...saveTriviaMark(ctx), probeBest: ctx._probe ? ctx._probe.best : null };
|
|
1599
1700
|
}
|
|
@@ -1616,13 +1717,29 @@ function scanWithLabels(input, cur, ctx) {
|
|
|
1616
1717
|
function advanceTrivia(input, cur, ctx) {
|
|
1617
1718
|
const triviaP = ctx.trivia;
|
|
1618
1719
|
if (!triviaP) return cur;
|
|
1720
|
+
if (!ctx.trackLines) {
|
|
1721
|
+
const fast2 = fastTriviaScanner(triviaP);
|
|
1722
|
+
if (fast2) return fast2(input, cur);
|
|
1723
|
+
if (ctx.triviaKindLabels) {
|
|
1724
|
+
const scan = scanWithLabels(input, cur, ctx);
|
|
1725
|
+
return scan.end;
|
|
1726
|
+
}
|
|
1727
|
+
const tr2 = triviaP.parse(input, cur, { trackLines: ctx.trackLines, state: ctx.state });
|
|
1728
|
+
return tr2.ok && tr2.span.end > cur ? tr2.span.end : cur;
|
|
1729
|
+
}
|
|
1730
|
+
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1619
1731
|
const fast = fastTriviaScanner(triviaP);
|
|
1620
|
-
if (fast)
|
|
1732
|
+
if (fast) {
|
|
1733
|
+
const end = fast(input, cur);
|
|
1734
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1735
|
+
return end;
|
|
1736
|
+
}
|
|
1621
1737
|
if (ctx.triviaKindLabels) {
|
|
1622
1738
|
const scan = scanWithLabels(input, cur, ctx);
|
|
1739
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
|
|
1623
1740
|
return scan.end;
|
|
1624
1741
|
}
|
|
1625
|
-
const tr = triviaP
|
|
1742
|
+
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1626
1743
|
return tr.ok && tr.span.end > cur ? tr.span.end : cur;
|
|
1627
1744
|
}
|
|
1628
1745
|
function scanTrivia(input, cur, ctx) {
|
|
@@ -1630,18 +1747,46 @@ function scanTrivia(input, cur, ctx) {
|
|
|
1630
1747
|
if (!triviaP) return { end: cur, commit: NOOP_COMMIT };
|
|
1631
1748
|
const log = ctx._triviaLog;
|
|
1632
1749
|
const captureTl = ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0);
|
|
1750
|
+
if (!ctx.trackLines) {
|
|
1751
|
+
const fast2 = !ctx.triviaKindLabels ? fastTriviaScanner(triviaP) : null;
|
|
1752
|
+
if (fast2 && log === void 0 && !captureTl) {
|
|
1753
|
+
return { end: fast2(input, cur), commit: NOOP_COMMIT };
|
|
1754
|
+
}
|
|
1755
|
+
if (ctx.triviaKindLabels && (log !== void 0 || captureTl)) {
|
|
1756
|
+
return scanWithLabels(input, cur, ctx);
|
|
1757
|
+
}
|
|
1758
|
+
if (log !== void 0 || captureTl) {
|
|
1759
|
+
const tr3 = triviaP.parse(input, cur, {
|
|
1760
|
+
trackLines: log !== void 0 ? false : ctx.trackLines,
|
|
1761
|
+
state: ctx.state
|
|
1762
|
+
});
|
|
1763
|
+
if (!tr3.ok || tr3.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1764
|
+
const end = tr3.span.end;
|
|
1765
|
+
return {
|
|
1766
|
+
end,
|
|
1767
|
+
commit: () => {
|
|
1768
|
+
pushTriviaLogEntry(ctx, cur, end);
|
|
1769
|
+
if (captureTl) pushCstTriviaEntry(ctx, cur, end);
|
|
1770
|
+
}
|
|
1771
|
+
};
|
|
1772
|
+
}
|
|
1773
|
+
const tr2 = triviaP.parse(input, cur, { trackLines: ctx.trackLines, state: ctx.state });
|
|
1774
|
+
return { end: tr2.ok ? tr2.span.end : cur, commit: NOOP_COMMIT };
|
|
1775
|
+
}
|
|
1776
|
+
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1633
1777
|
const fast = !ctx.triviaKindLabels ? fastTriviaScanner(triviaP) : null;
|
|
1634
1778
|
if (fast && log === void 0 && !captureTl) {
|
|
1635
|
-
|
|
1779
|
+
const end = fast(input, cur);
|
|
1780
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1781
|
+
return { end, commit: NOOP_COMMIT };
|
|
1636
1782
|
}
|
|
1637
1783
|
if (ctx.triviaKindLabels && (log !== void 0 || captureTl)) {
|
|
1638
|
-
|
|
1784
|
+
const scan = scanWithLabels(input, cur, ctx);
|
|
1785
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
|
|
1786
|
+
return scan;
|
|
1639
1787
|
}
|
|
1640
1788
|
if (log !== void 0 || captureTl) {
|
|
1641
|
-
const tr2 = triviaP
|
|
1642
|
-
trackLines: log !== void 0 ? false : ctx.trackLines,
|
|
1643
|
-
state: ctx.state
|
|
1644
|
-
});
|
|
1789
|
+
const tr2 = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1645
1790
|
if (!tr2.ok || tr2.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1646
1791
|
const end = tr2.span.end;
|
|
1647
1792
|
return {
|
|
@@ -1652,7 +1797,7 @@ function scanTrivia(input, cur, ctx) {
|
|
|
1652
1797
|
}
|
|
1653
1798
|
};
|
|
1654
1799
|
}
|
|
1655
|
-
const tr = triviaP
|
|
1800
|
+
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1656
1801
|
return { end: tr.ok ? tr.span.end : cur, commit: NOOP_COMMIT };
|
|
1657
1802
|
}
|
|
1658
1803
|
function consumeTrivia(input, cur, ctx) {
|
|
@@ -3076,13 +3221,14 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
3076
3221
|
const st = clonesState && ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
3077
3222
|
const nodeType = def.type ?? missingInferredType();
|
|
3078
3223
|
const cstOutput = cstOutputHost(ctx.build);
|
|
3224
|
+
const span = ctx.trackLines ? annotateSpanFromLineContext(r.span, ctx) : r.span;
|
|
3079
3225
|
const hostState = clonesState ? st : ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
3080
|
-
const built = unwrap && children2.length === 1 ? unwrapChild(children2[0]) : collapse && children2.length === 1 ? children2[0] : !build && project === void 0 && ctx.build?._parsemanCstCollapse && children2.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children2[0], children2, rawChildren) ? children2[0] : project !== void 0 ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields,
|
|
3081
|
-
const rawEntry = isCstChild(built) ? built : { _tag: "leaf", value: typeof built === "string" ? built : typeof built === "object" && built !== null ? input.slice(r.span.start, r.span.end) : "", span
|
|
3226
|
+
const built = unwrap && children2.length === 1 ? unwrapChild(children2[0]) : collapse && children2.length === 1 ? children2[0] : !build && project === void 0 && ctx.build?._parsemanCstCollapse && children2.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children2[0], children2, rawChildren) ? children2[0] : project !== void 0 ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState) : projectChild(children2, project, nodeType) : build ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState) : build(children2, fields, span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, st) : { _tag: "node", type: nodeType, span: ctx.trackLines ? { ...span } : { start: r.span.start, end: r.span.end }, state: st ?? null, children: children2 };
|
|
3227
|
+
const rawEntry = isCstChild(built) ? built : { _tag: "leaf", value: typeof built === "string" ? built : typeof built === "object" && built !== null ? input.slice(r.span.start, r.span.end) : "", span };
|
|
3082
3228
|
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
3083
3229
|
pushCstChild(ctx, built, rawEntry);
|
|
3084
3230
|
}
|
|
3085
|
-
return { ok: true, value: built, span
|
|
3231
|
+
return { ok: true, value: built, span };
|
|
3086
3232
|
}
|
|
3087
3233
|
};
|
|
3088
3234
|
}
|
|
@@ -3153,38 +3299,24 @@ function field(name, combinator) {
|
|
|
3153
3299
|
};
|
|
3154
3300
|
}
|
|
3155
3301
|
|
|
3156
|
-
// src/
|
|
3157
|
-
function
|
|
3158
|
-
const
|
|
3159
|
-
|
|
3160
|
-
|
|
3302
|
+
// src/combinators/grammar.ts
|
|
3303
|
+
function annotateResultLines(result, index) {
|
|
3304
|
+
const annotated = { ...result, span: annotateSpan(result.span, index) };
|
|
3305
|
+
const errors = annotated.errors;
|
|
3306
|
+
if (errors) {
|
|
3307
|
+
;
|
|
3308
|
+
annotated.errors = errors.map((error) => ({
|
|
3309
|
+
...error,
|
|
3310
|
+
span: annotateSpan(error.span, index)
|
|
3311
|
+
}));
|
|
3161
3312
|
}
|
|
3162
|
-
return
|
|
3313
|
+
return annotated;
|
|
3163
3314
|
}
|
|
3164
|
-
function
|
|
3165
|
-
const
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
while (lo < hi) {
|
|
3169
|
-
const mid = lo + hi + 1 >> 1;
|
|
3170
|
-
if (lineStarts[mid] <= offset) lo = mid;
|
|
3171
|
-
else hi = mid - 1;
|
|
3172
|
-
}
|
|
3173
|
-
return { line: lo + 1, col: offset - lineStarts[lo] + 1 };
|
|
3315
|
+
function createParseLineContext(input, pos) {
|
|
3316
|
+
const lineIndex = createLineIndex();
|
|
3317
|
+
if (pos > 0) recordLineRange(lineIndex, input, 0, pos);
|
|
3318
|
+
return { lineIndex, lineScannedTo: pos };
|
|
3174
3319
|
}
|
|
3175
|
-
function annotateSpan(span, index) {
|
|
3176
|
-
const s = offsetToLineCol(index, span.start);
|
|
3177
|
-
const e = offsetToLineCol(index, span.end);
|
|
3178
|
-
return {
|
|
3179
|
-
...span,
|
|
3180
|
-
startLine: s.line,
|
|
3181
|
-
startColumn: s.col,
|
|
3182
|
-
endLine: e.line,
|
|
3183
|
-
endColumn: e.col
|
|
3184
|
-
};
|
|
3185
|
-
}
|
|
3186
|
-
|
|
3187
|
-
// src/combinators/grammar.ts
|
|
3188
3320
|
function parser(opts, root) {
|
|
3189
3321
|
const clearTrivia = opts.trivia === null;
|
|
3190
3322
|
return {
|
|
@@ -3200,9 +3332,13 @@ function parser(opts, root) {
|
|
|
3200
3332
|
},
|
|
3201
3333
|
parse(input, pos, _ctx) {
|
|
3202
3334
|
const trackLines = opts.trackLines ?? _ctx?.trackLines ?? false;
|
|
3335
|
+
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
3336
|
+
const lineIndex = trackLines ? _ctx?._lineIndex ?? (_ctx?._lineStarts ? { lineStarts: _ctx._lineStarts } : lineContext.lineIndex) : void 0;
|
|
3203
3337
|
const ctx = {
|
|
3204
3338
|
..._ctx,
|
|
3205
3339
|
trackLines,
|
|
3340
|
+
...lineIndex ? { _lineIndex: lineIndex } : {},
|
|
3341
|
+
...lineContext ? { _lineScannedTo: lineContext.lineScannedTo } : {},
|
|
3206
3342
|
// trivia: null clears (contiguous terms); a Combinator sets; undefined inherits.
|
|
3207
3343
|
...clearTrivia ? {
|
|
3208
3344
|
trivia: void 0,
|
|
@@ -3220,11 +3356,10 @@ function parser(opts, root) {
|
|
|
3220
3356
|
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {}
|
|
3221
3357
|
};
|
|
3222
3358
|
const result = root.parse(input, pos ?? 0, ctx);
|
|
3223
|
-
if (trackLines) {
|
|
3224
|
-
|
|
3225
|
-
return { ...result, span: annotateSpan(result.span, idx) };
|
|
3359
|
+
if (trackLines && _ctx && ctx._lineScannedTo !== void 0) {
|
|
3360
|
+
_ctx._lineScannedTo = Math.max(_ctx._lineScannedTo ?? 0, ctx._lineScannedTo);
|
|
3226
3361
|
}
|
|
3227
|
-
return result;
|
|
3362
|
+
return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
3228
3363
|
}
|
|
3229
3364
|
};
|
|
3230
3365
|
}
|
|
@@ -3238,25 +3373,25 @@ function parse(combinator, input, opts = {}) {
|
|
|
3238
3373
|
markUnusedValues(combinator);
|
|
3239
3374
|
}
|
|
3240
3375
|
const trackLines = opts.trackLines ?? false;
|
|
3376
|
+
const lineContext = trackLines ? createParseLineContext(input, 0) : void 0;
|
|
3377
|
+
const lineIndex = lineContext?.lineIndex;
|
|
3241
3378
|
const _errors = opts.recover ? [] : void 0;
|
|
3242
3379
|
const _probe = opts.recover ? { offset: input.length, best: null } : void 0;
|
|
3243
3380
|
const grammarTrivia = combinator._meta.grammarTrivia;
|
|
3244
3381
|
const grammarScanSkip = combinator._meta.grammarScanSkip;
|
|
3245
3382
|
const ctx = {
|
|
3246
3383
|
trackLines,
|
|
3384
|
+
...lineIndex ? { _lineIndex: lineIndex } : {},
|
|
3385
|
+
...lineContext ? { _lineScannedTo: lineContext.lineScannedTo } : {},
|
|
3247
3386
|
...grammarTrivia !== void 0 ? { trivia: grammarTrivia, ...grammarTrivia._meta.triviaKindLabels ? { triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {} } : {},
|
|
3248
3387
|
...grammarScanSkip !== void 0 ? { scanSkip: grammarScanSkip } : {},
|
|
3249
3388
|
..._errors !== void 0 ? { _errors } : {},
|
|
3250
3389
|
..._probe !== void 0 ? { _probe } : {}
|
|
3251
3390
|
};
|
|
3252
3391
|
const result = combinator.parse(input, 0, ctx);
|
|
3253
|
-
if (!result.ok) return result;
|
|
3392
|
+
if (!result.ok) return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
3254
3393
|
const withErrors = _errors !== void 0 ? { ...result, errors: _errors, furthestFail: _probe?.best ?? null } : result;
|
|
3255
|
-
|
|
3256
|
-
const idx = buildLineIndex(input);
|
|
3257
|
-
return { ...withErrors, span: annotateSpan(withErrors.span, idx) };
|
|
3258
|
-
}
|
|
3259
|
-
return withErrors;
|
|
3394
|
+
return lineIndex ? annotateResultLines(withErrors, normalizeLineIndex(lineIndex)) : withErrors;
|
|
3260
3395
|
}
|
|
3261
3396
|
|
|
3262
3397
|
// src/combinators/token.ts
|
|
@@ -3355,7 +3490,7 @@ function leaf(root, fn) {
|
|
|
3355
3490
|
}
|
|
3356
3491
|
|
|
3357
3492
|
// src/version.ts
|
|
3358
|
-
var PARSEMAN_VERSION = "0.
|
|
3493
|
+
var PARSEMAN_VERSION = "0.42.0";
|
|
3359
3494
|
|
|
3360
3495
|
// src/cst/host-mode.ts
|
|
3361
3496
|
var FUSED_HOST_MODE = /* @__PURE__ */ Symbol.for("parseman.fusedHostMode");
|
|
@@ -5039,7 +5174,7 @@ function scanTo(sentinel, { skip: skip2, raw = false, orEOF = false } = {}) {
|
|
|
5039
5174
|
let cur = pos;
|
|
5040
5175
|
const skip3 = resolveScanSkip(explicitSkip, raw, ctx);
|
|
5041
5176
|
const probeCtx = {
|
|
5042
|
-
trackLines:
|
|
5177
|
+
trackLines: false,
|
|
5043
5178
|
state: ctx.state,
|
|
5044
5179
|
...ctx._errors !== void 0 ? { _errors: ctx._errors } : {}
|
|
5045
5180
|
};
|
|
@@ -5052,6 +5187,7 @@ function scanTo(sentinel, { skip: skip2, raw = false, orEOF = false } = {}) {
|
|
|
5052
5187
|
while (cur < input.length) {
|
|
5053
5188
|
const s = sentinel.parse(input, cur, probeCtx);
|
|
5054
5189
|
if (s.ok) {
|
|
5190
|
+
if (ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, cur);
|
|
5055
5191
|
emit2(cur);
|
|
5056
5192
|
return { ok: true, value: input.slice(pos, cur), span: { start: pos, end: cur } };
|
|
5057
5193
|
}
|
|
@@ -5067,6 +5203,7 @@ function scanTo(sentinel, { skip: skip2, raw = false, orEOF = false } = {}) {
|
|
|
5067
5203
|
if (!advanced) cur++;
|
|
5068
5204
|
}
|
|
5069
5205
|
if (orEOF) {
|
|
5206
|
+
if (ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, cur);
|
|
5070
5207
|
emit2(cur);
|
|
5071
5208
|
return { ok: true, value: input.slice(pos, cur), span: { start: pos, end: cur } };
|
|
5072
5209
|
}
|
|
@@ -6505,8 +6642,8 @@ function analyzeMkInlineBuild(def) {
|
|
|
6505
6642
|
if (looseMkBuildRe(def.type).test(src)) return def.type;
|
|
6506
6643
|
return null;
|
|
6507
6644
|
}
|
|
6508
|
-
function emitInlineMkNodeExpr(type, chV, rawV,
|
|
6509
|
-
return `{ _tag: 'node', type: ${JSON.stringify(type)}, span:
|
|
6645
|
+
function emitInlineMkNodeExpr(type, chV, rawV, spanExpr, tlV) {
|
|
6646
|
+
return `{ _tag: 'node', type: ${JSON.stringify(type)}, span: ${spanExpr}, children: ${chV}, rawCount: ${rawV}.length, localTriviaLen: ${tlV}.length }`;
|
|
6510
6647
|
}
|
|
6511
6648
|
|
|
6512
6649
|
// src/compiler/inline-callback.ts
|
|
@@ -6688,6 +6825,8 @@ function leadingFirstSetRecipe(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
6688
6825
|
}
|
|
6689
6826
|
}
|
|
6690
6827
|
var HOST_READS_DECL = "const _hostReads = (b, n) => { if (b === undefined) return false; let s; try { s = Function.prototype.toString.call(b) } catch (e) { return true } if (/\\barguments\\b/.test(s)) return true; const m = /^[^(]*\\(([\\s\\S]*?)\\)/.exec(s); if (m && /\\.\\.\\.|=/.test(m[1])) return true; return b.length > n }";
|
|
6828
|
+
var LINE_TRACK_DECL = "const _trackLines = (_ctx, input, start, end) => { const from = _ctx._lineScannedTo ?? 0; if (end <= from) return; for (let i = from; i < end; i++) if (input.charCodeAt(i) === 10) _ctx._lineStarts.push(i + 1); _ctx._lineScannedTo = end }";
|
|
6829
|
+
var LINE_SPAN_DECL = "const _lineCol = (_ctx, offset) => { const starts = _ctx._lineStarts; let lo = 0, hi = starts.length - 1; while (lo < hi) { const mid = (lo + hi + 1) >> 1; if (starts[mid] <= offset) lo = mid; else hi = mid - 1 } return [lo + 1, offset - starts[lo] + 1] }\nconst _spanLines = (_ctx, start, end) => { const s = _lineCol(_ctx, start), e = _lineCol(_ctx, end); return { start, end, startLine: s[0], startColumn: s[1], endLine: e[0], endColumn: e[1] } }";
|
|
6691
6830
|
var _loweringSink = null;
|
|
6692
6831
|
function v(ctx, prefix = "_v") {
|
|
6693
6832
|
return `${prefix}${ctx.vars++}`;
|
|
@@ -6828,14 +6967,46 @@ function emitLeafCapture(ctx, valExpr, startExpr, endExpr) {
|
|
|
6828
6967
|
if (ctx.capAsTrivia) return [];
|
|
6829
6968
|
const i = ind(ctx);
|
|
6830
6969
|
const lf = v(ctx, "_lf");
|
|
6970
|
+
const spanExpr = emitSpanExpr(ctx, startExpr, endExpr);
|
|
6831
6971
|
return [
|
|
6832
6972
|
`${i}if (_ctx._cstLeaves || _ctx._cstRawChildren) {`,
|
|
6833
|
-
`${i} const ${lf} = { _tag: 'leaf', value: ${valExpr}, span:
|
|
6973
|
+
`${i} const ${lf} = { _tag: 'leaf', value: ${valExpr}, span: ${spanExpr} }`,
|
|
6834
6974
|
`${i} if (_ctx._cstLeaves) _ctx._cstLeaves.push(${lf})`,
|
|
6835
6975
|
`${i} if (_ctx._cstRawChildren) _ctx._cstRawChildren.push(${lf})`,
|
|
6836
6976
|
`${i}}`
|
|
6837
6977
|
];
|
|
6838
6978
|
}
|
|
6979
|
+
function emitSpanExpr(ctx, startExpr, endExpr) {
|
|
6980
|
+
if (!ctx.lineTracking) return `{ start: ${startExpr}, end: ${endExpr} }`;
|
|
6981
|
+
ctx.needsLineSpan = true;
|
|
6982
|
+
return `_spanLines(_ctx, ${startExpr}, ${endExpr})`;
|
|
6983
|
+
}
|
|
6984
|
+
function emitLineTrack(ctx, startExpr, endExpr) {
|
|
6985
|
+
if (!ctx.lineTracking) return [];
|
|
6986
|
+
ctx.needsLineTrack = true;
|
|
6987
|
+
return [`${ind(ctx)}_trackLines(_ctx, input, ${startExpr}, ${endExpr})`];
|
|
6988
|
+
}
|
|
6989
|
+
function emitLiteralLineTrack(ctx, startExpr, value) {
|
|
6990
|
+
if (!ctx.lineTracking) return [];
|
|
6991
|
+
const lineDeltas = [];
|
|
6992
|
+
for (let i = 0; i < value.length; i++) {
|
|
6993
|
+
if (value.charCodeAt(i) === 10) lineDeltas.push(i + 1);
|
|
6994
|
+
}
|
|
6995
|
+
if (lineDeltas.length === 0) return [];
|
|
6996
|
+
const fromV = v(ctx, "_ltFrom");
|
|
6997
|
+
const endExpr = value.length === 0 ? startExpr : `${startExpr} + ${value.length}`;
|
|
6998
|
+
return [
|
|
6999
|
+
`${ind(ctx)}const ${fromV} = _ctx._lineScannedTo ?? 0`,
|
|
7000
|
+
`${ind(ctx)}if (${endExpr} > ${fromV}) {`,
|
|
7001
|
+
`${ind(ctx)} for (let i = ${fromV}; i < ${startExpr}; i++) if (input.charCodeAt(i) === 10) _ctx._lineStarts.push(i + 1)`,
|
|
7002
|
+
...lineDeltas.map((delta) => {
|
|
7003
|
+
const lineStart = `${startExpr} + ${delta}`;
|
|
7004
|
+
return `${ind(ctx)} if (${lineStart} > ${fromV}) _ctx._lineStarts.push(${lineStart})`;
|
|
7005
|
+
}),
|
|
7006
|
+
`${ind(ctx)} _ctx._lineScannedTo = ${endExpr}`,
|
|
7007
|
+
`${ind(ctx)}}`
|
|
7008
|
+
];
|
|
7009
|
+
}
|
|
6839
7010
|
function ensureRegexDecl(ctx, source, flags) {
|
|
6840
7011
|
const f = "y" + flags.replace(/[gy]/g, "");
|
|
6841
7012
|
const key = `${source}/${f}`;
|
|
@@ -7220,6 +7391,7 @@ function emitLit(def, ctx, pos) {
|
|
|
7220
7391
|
);
|
|
7221
7392
|
}
|
|
7222
7393
|
const endVar = len === 0 ? pos : `${pos} + ${len}`;
|
|
7394
|
+
stmts.push(...emitLiteralLineTrack(ctx, pos, value));
|
|
7223
7395
|
stmts.push(...emitLeafCapture(ctx, vv, pos, endVar));
|
|
7224
7396
|
return { stmts, valueVar: vv, endVar };
|
|
7225
7397
|
}
|
|
@@ -7299,7 +7471,7 @@ function emitKeywords(def, ctx, pos) {
|
|
|
7299
7471
|
stmts.push(...emitLeafCapture(ctx, vv, pos, endVar));
|
|
7300
7472
|
return { stmts, valueVar: vv, endVar };
|
|
7301
7473
|
}
|
|
7302
|
-
function emitRegex(def, ctx, pos) {
|
|
7474
|
+
function emitRegex(def, ctx, pos, canMatchNewline = true) {
|
|
7303
7475
|
const expectedStr = JSON.stringify(`/${def.source}/`);
|
|
7304
7476
|
const shape = scanShapeFromRegex(def.source, def.flags);
|
|
7305
7477
|
if (shape) {
|
|
@@ -7312,7 +7484,11 @@ function emitRegex(def, ctx, pos) {
|
|
|
7312
7484
|
fresh: (prefix) => v(ctx, prefix)
|
|
7313
7485
|
});
|
|
7314
7486
|
if (scanned) {
|
|
7315
|
-
const stmts2 = [
|
|
7487
|
+
const stmts2 = [
|
|
7488
|
+
...scanned.stmts,
|
|
7489
|
+
...canMatchNewline ? emitLineTrack(ctx, pos, scanned.endVar) : [],
|
|
7490
|
+
...emitLeafCapture(ctx, vv2, pos, scanned.endVar)
|
|
7491
|
+
];
|
|
7316
7492
|
return { stmts: stmts2, valueVar: vv2, endVar: scanned.endVar };
|
|
7317
7493
|
}
|
|
7318
7494
|
}
|
|
@@ -7334,6 +7510,7 @@ function emitRegex(def, ctx, pos) {
|
|
|
7334
7510
|
`${ind(ctx)}const ${vv} = ${mv}[0]`
|
|
7335
7511
|
];
|
|
7336
7512
|
const endVar = `${pos} + ${vv}.length`;
|
|
7513
|
+
if (canMatchNewline) stmts.push(...emitLineTrack(ctx, pos, endVar));
|
|
7337
7514
|
stmts.push(...emitLeafCapture(ctx, vv, pos, endVar));
|
|
7338
7515
|
return { stmts, valueVar: vv, endVar };
|
|
7339
7516
|
}
|
|
@@ -7371,7 +7548,8 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7371
7548
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
7372
7549
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
7373
7550
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
7374
|
-
`${ind(ctx)}const ${scanEndV} = ${capFn}(input, ${curV}, _ctx, 1)
|
|
7551
|
+
`${ind(ctx)}const ${scanEndV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
7552
|
+
...emitLineTrack(ctx, curV, scanEndV)
|
|
7375
7553
|
);
|
|
7376
7554
|
const r2 = emit(def.parsers[i], ctx, scanEndV);
|
|
7377
7555
|
stmts.push(...r2.stmts);
|
|
@@ -7389,7 +7567,8 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7389
7567
|
const capArg = ctx.noHoist ? "0" : "_ctx._triviaLog !== undefined ? 2 : 0";
|
|
7390
7568
|
stmts.push(
|
|
7391
7569
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
7392
|
-
`${ind(ctx)}const ${scanEndV} = ${trivFn}(input, ${curV}, _ctx, ${capArg})
|
|
7570
|
+
`${ind(ctx)}const ${scanEndV} = ${trivFn}(input, ${curV}, _ctx, ${capArg})`,
|
|
7571
|
+
...emitLineTrack(ctx, curV, scanEndV)
|
|
7393
7572
|
);
|
|
7394
7573
|
const r2 = emit(def.parsers[i], ctx, scanEndV);
|
|
7395
7574
|
stmts.push(...r2.stmts);
|
|
@@ -8089,14 +8268,15 @@ function emitMany(def, ctx, pos) {
|
|
|
8089
8268
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8090
8269
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8091
8270
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8092
|
-
`${ind(ctx)}const ${npV} = ${capFn}(input, ${curV}, _ctx, 1)
|
|
8271
|
+
`${ind(ctx)}const ${npV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
8272
|
+
...emitLineTrack(ctx, curV, npV)
|
|
8093
8273
|
);
|
|
8094
8274
|
itemPos = npV;
|
|
8095
8275
|
rollback = `if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${markV}) _ctx._cstRawChildren.length = ${markV}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${markTl}) _ctx._cstTriviaLog.length = ${markTl}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${markLog}) _ctx._triviaLog.length = ${markLog}; `;
|
|
8096
8276
|
} else {
|
|
8097
8277
|
const trivFn = ensureTriviaFn(ctx);
|
|
8098
8278
|
const npV = v(ctx, "_np");
|
|
8099
|
-
stmts.push(`${ind(ctx)}const ${npV} = ${trivFn}(input, ${curV}, _ctx)
|
|
8279
|
+
stmts.push(`${ind(ctx)}const ${npV} = ${trivFn}(input, ${curV}, _ctx)`, ...emitLineTrack(ctx, curV, npV));
|
|
8100
8280
|
itemPos = npV;
|
|
8101
8281
|
}
|
|
8102
8282
|
}
|
|
@@ -8273,7 +8453,8 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8273
8453
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8274
8454
|
`${ind(ctx)}const ${markLv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
8275
8455
|
`${ind(ctx)}const ${markFld} = _ctx._fields ? _ctx._fields.length : 0`,
|
|
8276
|
-
`${ind(ctx)}const ${spV} = ${capFn}(input, ${curV}, _ctx, 1)
|
|
8456
|
+
`${ind(ctx)}const ${spV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
8457
|
+
...emitLineTrack(ctx, curV, spV)
|
|
8277
8458
|
);
|
|
8278
8459
|
sepAtPos = spV;
|
|
8279
8460
|
const rollbackToSep = `if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${markLv}) _ctx._cstLeaves.length = ${markLv}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${markV}) _ctx._cstRawChildren.length = ${markV}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${markTl}) _ctx._cstTriviaLog.length = ${markTl}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${markLog}) _ctx._triviaLog.length = ${markLog}; if (_ctx._fields && _ctx._fields.length !== ${markFld}) _ctx._fields.length = ${markFld}; `;
|
|
@@ -8283,7 +8464,7 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8283
8464
|
const post = postSepMarks();
|
|
8284
8465
|
stmts.push(...post.decl);
|
|
8285
8466
|
const npV = v(ctx, "_np");
|
|
8286
|
-
stmts.push(`${ind(ctx)}const ${npV} = ${capFn}(input, ${sepEnd}, _ctx, 1)
|
|
8467
|
+
stmts.push(`${ind(ctx)}const ${npV} = ${capFn}(input, ${sepEnd}, _ctx, 1)`, ...emitLineTrack(ctx, sepEnd, npV));
|
|
8287
8468
|
const next = emitFallible(def.parser, ctx, npV, true);
|
|
8288
8469
|
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = next;
|
|
8289
8470
|
stmts.push(
|
|
@@ -8295,13 +8476,13 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8295
8476
|
} else {
|
|
8296
8477
|
const trivFn = ensureTriviaFn(ctx);
|
|
8297
8478
|
const spV = v(ctx, "_sp");
|
|
8298
|
-
stmts.push(`${ind(ctx)}const ${spV} = ${trivFn}(input, ${curV}, _ctx)
|
|
8479
|
+
stmts.push(`${ind(ctx)}const ${spV} = ${trivFn}(input, ${curV}, _ctx)`, ...emitLineTrack(ctx, curV, spV));
|
|
8299
8480
|
sepAtPos = spV;
|
|
8300
8481
|
const sep = emitFallible(def.separator, ctx, sepAtPos, true);
|
|
8301
8482
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = sep;
|
|
8302
8483
|
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${sep.mayCommit ? `if (_ctx._fc) ${committedFailBody(ctx)}; ` : ""}break }`);
|
|
8303
8484
|
const npV = v(ctx, "_np");
|
|
8304
|
-
stmts.push(`${ind(ctx)}const ${npV} = ${trivFn}(input, ${sepEnd}, _ctx)
|
|
8485
|
+
stmts.push(`${ind(ctx)}const ${npV} = ${trivFn}(input, ${sepEnd}, _ctx)`, ...emitLineTrack(ctx, sepEnd, npV));
|
|
8305
8486
|
const next = emitFallible(def.parser, ctx, npV, true);
|
|
8306
8487
|
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = next;
|
|
8307
8488
|
stmts.push(
|
|
@@ -8388,6 +8569,7 @@ function emitScanTo(def, ctx, pos) {
|
|
|
8388
8569
|
}
|
|
8389
8570
|
const valV = v(ctx);
|
|
8390
8571
|
stmts.push(`${ind(ctx)}const ${valV} = input.slice(${pos}, ${curV})`);
|
|
8572
|
+
stmts.push(...emitLineTrack(ctx, pos, curV));
|
|
8391
8573
|
if (ctx.capturing) {
|
|
8392
8574
|
const cap = reindentStmts(emitLeafCapture(ctx, valV, pos, curV), ctx.indent + 1);
|
|
8393
8575
|
stmts.push(`${ind(ctx)}if (${curV} > ${pos}) {`, ...cap, `${ind(ctx)}}`);
|
|
@@ -8531,7 +8713,7 @@ function tokenNullableRegex(def) {
|
|
|
8531
8713
|
}
|
|
8532
8714
|
function emitToken(def, ctx, pos) {
|
|
8533
8715
|
const lowered = tokenNullableRegex(def);
|
|
8534
|
-
if (lowered) return emitRegex(lowered, ctx, pos);
|
|
8716
|
+
if (lowered) return emitRegex(lowered, ctx, pos, def.parser._meta.canMatchNewline);
|
|
8535
8717
|
const savedTrivia = ctx.activeTrivia;
|
|
8536
8718
|
const savedKindLabels = ctx.triviaKindLabels;
|
|
8537
8719
|
ctx.activeTrivia = void 0;
|
|
@@ -8681,7 +8863,7 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8681
8863
|
stmts.push(...innerStmts);
|
|
8682
8864
|
if (def.trailingTrivia === true && ctx.activeTrivia) {
|
|
8683
8865
|
const triviaFn = ensureTriviaFn(ctx);
|
|
8684
|
-
stmts.push(`${i}const ${endVar} = ${okVar} ? ${triviaFn}(input, ${innerEndVar}, _ctx, 1) : ${innerEndVar}
|
|
8866
|
+
stmts.push(`${i}const ${endVar} = ${okVar} ? ${triviaFn}(input, ${innerEndVar}, _ctx, 1) : ${innerEndVar}`, ...emitLineTrack(ctx, innerEndVar, endVar));
|
|
8685
8867
|
}
|
|
8686
8868
|
if (sf && fArr) {
|
|
8687
8869
|
stmts.push(`${i}const ${fArr} = _ctx._fields`);
|
|
@@ -8721,8 +8903,11 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8721
8903
|
);
|
|
8722
8904
|
}
|
|
8723
8905
|
const ndV = v(ctx, "_nd");
|
|
8724
|
-
const
|
|
8725
|
-
const
|
|
8906
|
+
const nodeSpanExpr = emitSpanExpr(ctx, pos, endVar);
|
|
8907
|
+
const nodeSpanV = ctx.lineTracking ? v(ctx, "_nspan") : nodeSpanExpr;
|
|
8908
|
+
if (ctx.lineTracking) stmts.push(`${i}const ${nodeSpanV} = ${nodeSpanExpr}`);
|
|
8909
|
+
const buildExpr = structural ? `{ _tag: 'node', type: ${JSON.stringify(def.type)}, span: ${nodeSpanV}, state: ${stV} ?? null, children: ${chV} }` : mkType ? emitInlineMkNodeExpr(mkType, chV, rawV, nodeSpanV, tlV) : def.project !== void 0 ? emitNodeProjectExpr(def.type, def.project, chV) : `${buildRef(ctx)}[${buildIdx}](${chV}, ${fObj}, ${nodeSpanV}, ${rawV}, ${tlV}, ${stV})`;
|
|
8910
|
+
const hostBuildExpr = `_ctx._pmProfile?.phase === 'host' && _ctx._pmProfile.hostCalls++, _ctx.build(${JSON.stringify(def.type)}, ${chV}, ${fObj}, ${nodeSpanV}, ${rawV}, ${tlV}, ${stV})`;
|
|
8726
8911
|
const ndExpr = structural ? `_ctx.build !== undefined ? (${hostBuildExpr}) : (${buildExpr})` : cstOut ? hostBuildExpr : buildExpr;
|
|
8727
8912
|
const hostCollapseExpr = structural ? `_ctx.build !== undefined && _ctx.build._parsemanCstCollapse !== undefined && ${chV}.length === 1 && ${rawV}.length === 1 && _ctx.build._parsemanCstCollapse(${JSON.stringify(def.type)}, ${chV}[0], ${chV}, ${rawV}) ? ${chV}[0] : (${ndExpr})` : ndExpr;
|
|
8728
8913
|
const unwrapExpr = `${chV}.length === 1 ? (${chV}[0] !== null && typeof ${chV}[0] === 'object' && ${chV}[0]._tag === 'leaf' ? ${chV}[0].value : ${chV}[0]) : (${ndExpr})`;
|
|
@@ -8732,7 +8917,7 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8732
8917
|
`${i}const ${ndV} = (${profileRecognizer} || ${profileCapture}) ? undefined : (${finalExpr})`,
|
|
8733
8918
|
`${i}if (!(${profileRecognizer})) {`,
|
|
8734
8919
|
`${i} if (${sc}) ${sc}.push(${ndV})`,
|
|
8735
|
-
`${i} if (${sr}) ${sr}.push((typeof ${ndV} === 'object' && ${ndV} !== null && (${ndV}._tag === 'node' || ${ndV}._tag === 'leaf' || ${ndV}._tag === 'parseError')) ? ${ndV} : { _tag: 'leaf', value: typeof ${ndV} === 'string' ? ${ndV} : (typeof ${ndV} === 'object' && ${ndV} !== null ? input.slice(${pos}, ${endVar}) : ''), span:
|
|
8920
|
+
`${i} if (${sr}) ${sr}.push((typeof ${ndV} === 'object' && ${ndV} !== null && (${ndV}._tag === 'node' || ${ndV}._tag === 'leaf' || ${ndV}._tag === 'parseError')) ? ${ndV} : { _tag: 'leaf', value: typeof ${ndV} === 'string' ? ${ndV} : (typeof ${ndV} === 'object' && ${ndV} !== null ? input.slice(${pos}, ${endVar}) : ''), span: ${nodeSpanV} })`,
|
|
8736
8921
|
`${i}}`
|
|
8737
8922
|
);
|
|
8738
8923
|
return { stmts, valueVar: ndV, endVar };
|
|
@@ -8748,7 +8933,8 @@ function emitRuntimeFallback(parser2, ctx, pos) {
|
|
|
8748
8933
|
`${ind(ctx)}const ${rv} = _rp[${idx}].parse(input, ${pos}, _ctx)`,
|
|
8749
8934
|
...emitIfFail(ctx, `!${rv}.ok`, failStmt),
|
|
8750
8935
|
`${ind(ctx)}const ${vv} = ${rv}.value`,
|
|
8751
|
-
`${ind(ctx)}const ${ev} = ${rv}.span.end
|
|
8936
|
+
`${ind(ctx)}const ${ev} = ${rv}.span.end`,
|
|
8937
|
+
...parser2._meta.canMatchNewline ? emitLineTrack(ctx, pos, ev) : []
|
|
8752
8938
|
];
|
|
8753
8939
|
return { stmts, valueVar: vv, endVar: ev };
|
|
8754
8940
|
}
|
|
@@ -8814,7 +9000,8 @@ function emitRecover(def, ctx, pos) {
|
|
|
8814
9000
|
`${ind0} if (${sentOk}) break`,
|
|
8815
9001
|
`${ind0} ${scanV}++`,
|
|
8816
9002
|
`${ind0} }`,
|
|
8817
|
-
|
|
9003
|
+
...emitLineTrack(ctx, pos, scanV).map((s) => `${ind0} ${s.trim()}`),
|
|
9004
|
+
`${ind0} const ${errV} = { _tag: 'parseError', span: ${emitSpanExpr(ctx, pos, scanV)}, expected: ${JSON.stringify(deriveExpected(def.parser))} }`,
|
|
8818
9005
|
`${ind0} if (_ctx._errors) _ctx._errors.push(${errV})`,
|
|
8819
9006
|
`${ind0} ${valVar} = ${errV}`,
|
|
8820
9007
|
`${ind0} ${endVar} = ${scanV}`,
|
|
@@ -8830,7 +9017,7 @@ function emitExpect(def, ctx, pos) {
|
|
|
8830
9017
|
const stmts = [
|
|
8831
9018
|
...innerStmts,
|
|
8832
9019
|
`${ind0}if (!${okVar}) {`,
|
|
8833
|
-
`${ind0} const ${errV} = { _tag: 'parseError', span: {
|
|
9020
|
+
`${ind0} const ${errV} = { _tag: 'parseError', span: ${emitSpanExpr(ctx, pos, pos)}, expected: ${JSON.stringify(def.expected)} }`,
|
|
8834
9021
|
`${ind0} if (_ctx._errors) _ctx._errors.push(${errV})`,
|
|
8835
9022
|
// Embed the missing-token error as a `parseError` CST child, mirroring the
|
|
8836
9023
|
// interpreter (expect.ts) and the list-recovery emit sites — guarded on
|
|
@@ -8920,7 +9107,7 @@ function emitDispatch(p, ctx, pos) {
|
|
|
8920
9107
|
case "literal":
|
|
8921
9108
|
return emitLit(def, ctx, pos);
|
|
8922
9109
|
case "regex":
|
|
8923
|
-
return emitRegex(def, ctx, pos);
|
|
9110
|
+
return emitRegex(def, ctx, pos, p._meta.canMatchNewline);
|
|
8924
9111
|
case "keywords":
|
|
8925
9112
|
return emitKeywords(def, ctx, pos);
|
|
8926
9113
|
case "sequence":
|
|
@@ -9170,6 +9357,20 @@ function hasNodeDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9170
9357
|
return false;
|
|
9171
9358
|
}
|
|
9172
9359
|
}
|
|
9360
|
+
function hasLineTrackingDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
9361
|
+
if (seen.has(p)) return false;
|
|
9362
|
+
seen.add(p);
|
|
9363
|
+
const d = p._def;
|
|
9364
|
+
if (d.tag === "grammar" && d.trackLines) return true;
|
|
9365
|
+
if (d.tag === "lazy") {
|
|
9366
|
+
try {
|
|
9367
|
+
return hasLineTrackingDef(d.thunk(), seen);
|
|
9368
|
+
} catch {
|
|
9369
|
+
return false;
|
|
9370
|
+
}
|
|
9371
|
+
}
|
|
9372
|
+
return childrenOf2(d).some((child) => hasLineTrackingDef(child, seen));
|
|
9373
|
+
}
|
|
9173
9374
|
function parserUsesRouted2(p, seen = /* @__PURE__ */ new Set()) {
|
|
9174
9375
|
if (seen.has(p)) return false;
|
|
9175
9376
|
seen.add(p);
|
|
@@ -9537,6 +9738,7 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9537
9738
|
capturing: hasNodeDef(combinator),
|
|
9538
9739
|
recovery: opts?.recovery ?? false,
|
|
9539
9740
|
hostMode: opts?.hostMode ?? grammarHostMode ?? "ast",
|
|
9741
|
+
lineTracking: opts?.trackLines === true || hasLineTrackingDef(combinator),
|
|
9540
9742
|
...opts?.coverage ? { coverage: { plan: buildGrammarPlan(combinator), entry: combinator } } : {},
|
|
9541
9743
|
lazyUsage: analyzeLazyUsage(combinator),
|
|
9542
9744
|
...grammarTrivia ? { activeTrivia: grammarTrivia, triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {},
|
|
@@ -9560,9 +9762,13 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9560
9762
|
const namedPrelude = ctx.namedFnDecls.length > 0 ? [...namedFnPrelude(), ""] : [];
|
|
9561
9763
|
const emptyTlDecls = ctx.needsEmptyTl ? ["const _EMPTY_TL = Object.freeze([])"] : [];
|
|
9562
9764
|
const hostReadsDecls = ctx.needsHostReads ? [HOST_READS_DECL] : [];
|
|
9765
|
+
const lineTrackDecls = ctx.needsLineTrack ? [LINE_TRACK_DECL] : [];
|
|
9766
|
+
const lineSpanDecls = ctx.needsLineSpan ? [LINE_SPAN_DECL] : [];
|
|
9563
9767
|
const source = [
|
|
9564
9768
|
...emptyTlDecls,
|
|
9565
9769
|
...hostReadsDecls,
|
|
9770
|
+
...lineTrackDecls,
|
|
9771
|
+
...lineSpanDecls,
|
|
9566
9772
|
...ctx.regexDecls,
|
|
9567
9773
|
...ctx.expectedDecls,
|
|
9568
9774
|
"",
|
|
@@ -9575,6 +9781,8 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9575
9781
|
const fn = new Function("input", "_pos", "_rp", "_mf", "_build", "_ctx", [
|
|
9576
9782
|
...emptyTlDecls,
|
|
9577
9783
|
...hostReadsDecls,
|
|
9784
|
+
...lineTrackDecls,
|
|
9785
|
+
...lineSpanDecls,
|
|
9578
9786
|
...ctx.regexDecls,
|
|
9579
9787
|
...ctx.expectedDecls,
|
|
9580
9788
|
...namedPrelude,
|
|
@@ -9593,6 +9801,25 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9593
9801
|
trackLines: false,
|
|
9594
9802
|
...ctx.triviaKindLabels ? { triviaKindLabels: ctx.triviaKindLabels } : {}
|
|
9595
9803
|
};
|
|
9804
|
+
const annotateWithTrackedLines = (result, lineStarts) => {
|
|
9805
|
+
const index = normalizeLineIndex({ lineStarts });
|
|
9806
|
+
const annotated = { ...result, span: annotateSpan(result.span, index) };
|
|
9807
|
+
const errors = annotated.errors;
|
|
9808
|
+
if (errors) {
|
|
9809
|
+
;
|
|
9810
|
+
annotated.errors = errors.map((error) => ({
|
|
9811
|
+
...error,
|
|
9812
|
+
span: annotateSpan(error.span, index)
|
|
9813
|
+
}));
|
|
9814
|
+
}
|
|
9815
|
+
return annotated;
|
|
9816
|
+
};
|
|
9817
|
+
const trackedCtx = (base, input, pos) => {
|
|
9818
|
+
if (!ctx.lineTracking) return base;
|
|
9819
|
+
const lineIndex = { lineStarts: [0] };
|
|
9820
|
+
if (pos > 0) recordLineRange(lineIndex, input, 0, pos);
|
|
9821
|
+
return { ...base, trackLines: true, _lineStarts: lineIndex.lineStarts, _lineScannedTo: pos };
|
|
9822
|
+
};
|
|
9596
9823
|
const derivedSrcs = ctx.mapFnSrcs.length === ctx.mapFns.length && ctx.mapFnSrcs.every((s) => s !== null) ? ctx.mapFnSrcs : void 0;
|
|
9597
9824
|
const effectiveSources = mapFnSources ?? derivedSrcs;
|
|
9598
9825
|
const buildCovered = ctx.buildFns.length === 0 || ctx.buildSrcs.every((s) => s !== null);
|
|
@@ -9600,17 +9827,46 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9600
9827
|
const mfCovered = ctx.mapFns.length === 0 || effectiveSources !== void 0 && effectiveSources.length === ctx.mapFns.length;
|
|
9601
9828
|
const canInline = ctx.runtimeParsers.length === 0 && mfCovered && buildCovered;
|
|
9602
9829
|
const inlineExpression = canInline ? buildInlineExpression(ctx, r, effectiveSources, buildSources, coverageRootRuleId) : null;
|
|
9603
|
-
|
|
9830
|
+
const compiledMeta = {
|
|
9604
9831
|
source,
|
|
9605
9832
|
inlineExpression,
|
|
9606
9833
|
...ctx.coverage === void 0 ? {} : { coverageDefinitions: ctx.coverage.plan.definitions },
|
|
9607
|
-
...gatingReport === void 0 ? {} : { gating: gatingReport }
|
|
9834
|
+
...gatingReport === void 0 ? {} : { gating: gatingReport }
|
|
9835
|
+
};
|
|
9836
|
+
if (!ctx.lineTracking) {
|
|
9837
|
+
return {
|
|
9838
|
+
...compiledMeta,
|
|
9839
|
+
parse(input, pos = 0) {
|
|
9840
|
+
return fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, defaultCtx);
|
|
9841
|
+
},
|
|
9842
|
+
parseWithContext(input, parseCtx, pos = 0) {
|
|
9843
|
+
assertHostModeCompatible(ctx.hostMode ?? "ast", parseCtx.build, !!ctx.hostBranchElided);
|
|
9844
|
+
return fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, parseCtx);
|
|
9845
|
+
},
|
|
9846
|
+
// Note: collects expect() errors via _errors. Unlike interpreter
|
|
9847
|
+
// parse({recover:true}) it does NOT populate furthestFail — the compiled path
|
|
9848
|
+
// inlines failures for throughput and deliberately skips _probe bookkeeping.
|
|
9849
|
+
// Callers wanting a furthest-position diagnostic detect unconsumed input
|
|
9850
|
+
// (span.end < input.length) instead, which is mode-agnostic.
|
|
9851
|
+
parseWithErrors(input, pos = 0) {
|
|
9852
|
+
const errors = [];
|
|
9853
|
+
const result = fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, { ...defaultCtx, _errors: errors });
|
|
9854
|
+
return { ...result, errors };
|
|
9855
|
+
}
|
|
9856
|
+
};
|
|
9857
|
+
}
|
|
9858
|
+
return {
|
|
9859
|
+
...compiledMeta,
|
|
9608
9860
|
parse(input, pos = 0) {
|
|
9609
|
-
|
|
9861
|
+
const parseCtx = trackedCtx(defaultCtx, input, pos);
|
|
9862
|
+
const result = fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, parseCtx);
|
|
9863
|
+
return annotateWithTrackedLines(result, parseCtx._lineStarts);
|
|
9610
9864
|
},
|
|
9611
9865
|
parseWithContext(input, parseCtx, pos = 0) {
|
|
9612
9866
|
assertHostModeCompatible(ctx.hostMode ?? "ast", parseCtx.build, !!ctx.hostBranchElided);
|
|
9613
|
-
|
|
9867
|
+
const activeCtx = trackedCtx(parseCtx, input, pos);
|
|
9868
|
+
const result = fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, activeCtx);
|
|
9869
|
+
return activeCtx.trackLines ? annotateWithTrackedLines(result, activeCtx._lineStarts) : result;
|
|
9614
9870
|
},
|
|
9615
9871
|
// Note: collects expect() errors via _errors. Unlike interpreter
|
|
9616
9872
|
// parse({recover:true}) it does NOT populate furthestFail — the compiled path
|
|
@@ -9619,8 +9875,9 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9619
9875
|
// (span.end < input.length) instead, which is mode-agnostic.
|
|
9620
9876
|
parseWithErrors(input, pos = 0) {
|
|
9621
9877
|
const errors = [];
|
|
9622
|
-
const
|
|
9623
|
-
|
|
9878
|
+
const parseCtx = trackedCtx({ ...defaultCtx, _errors: errors }, input, pos);
|
|
9879
|
+
const result = { ...fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, parseCtx), errors };
|
|
9880
|
+
return annotateWithTrackedLines(result, parseCtx._lineStarts);
|
|
9624
9881
|
}
|
|
9625
9882
|
};
|
|
9626
9883
|
}
|
|
@@ -9907,12 +10164,16 @@ function buildInlineExpression(ctx, r, mapFnSources, buildSources, coverageRootR
|
|
|
9907
10164
|
const buildDecl = buildSources?.length ? ` const _build = [${buildSources.join(", ")}]` : "";
|
|
9908
10165
|
const emptyTlDecl = ctx.needsEmptyTl ? ` const _EMPTY_TL = Object.freeze([])` : "";
|
|
9909
10166
|
const hostReadsDecl = ctx.needsHostReads ? ` ${HOST_READS_DECL}` : "";
|
|
9910
|
-
const
|
|
10167
|
+
const lineTrackDecl = ctx.needsLineTrack ? ` ${LINE_TRACK_DECL}` : "";
|
|
10168
|
+
const lineSpanDecl = ctx.needsLineSpan ? ` ${LINE_SPAN_DECL}` : "";
|
|
10169
|
+
const needsWrapper = ctx.regexDecls.length > 0 || ctx.expectedDecls.length > 0 || ctx.namedFnDecls.length > 0 || !!mfDecl || !!buildDecl || !!emptyTlDecl || !!hostReadsDecl || !!lineTrackDecl || !!lineSpanDecl;
|
|
9911
10170
|
if (!needsWrapper) return innerFn;
|
|
9912
10171
|
const namedPrelude = ctx.namedFnDecls.length > 0 ? namedFnPrelude() : [];
|
|
9913
10172
|
const hoistedDecls = [
|
|
9914
10173
|
emptyTlDecl,
|
|
9915
10174
|
hostReadsDecl,
|
|
10175
|
+
lineTrackDecl,
|
|
10176
|
+
lineSpanDecl,
|
|
9916
10177
|
...ctx.regexDecls.map((d) => ` ${d}`),
|
|
9917
10178
|
...ctx.expectedDecls.map((d) => ` ${d}`),
|
|
9918
10179
|
mfDecl,
|
|
@@ -10461,7 +10722,7 @@ function normalizeCstCollapse(collapse) {
|
|
|
10461
10722
|
return typeof collapse === "function" ? collapse : void 0;
|
|
10462
10723
|
}
|
|
10463
10724
|
function buildCstNode(type, children2, _fields, span, _rawChildren, _triviaLog, state) {
|
|
10464
|
-
return { _tag: "node", type, span: {
|
|
10725
|
+
return { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children2] };
|
|
10465
10726
|
}
|
|
10466
10727
|
function cstBuildHost(typeOrOptions, children2, _fields, span, rawChildren, triviaLog, state) {
|
|
10467
10728
|
if (typeof typeOrOptions === "string") {
|
|
@@ -12185,6 +12446,7 @@ export {
|
|
|
12185
12446
|
analyzeGatingRules,
|
|
12186
12447
|
analyzeGrammarGating,
|
|
12187
12448
|
annotateSpan,
|
|
12449
|
+
annotateTreeSpans,
|
|
12188
12450
|
applyEdit,
|
|
12189
12451
|
attempt,
|
|
12190
12452
|
balanced,
|
|
@@ -12206,6 +12468,7 @@ export {
|
|
|
12206
12468
|
createGrammarCoverageCollector,
|
|
12207
12469
|
createGrammarInstrumentationContext,
|
|
12208
12470
|
createGrammarTraceSink,
|
|
12471
|
+
createLineIndex,
|
|
12209
12472
|
createVisitor,
|
|
12210
12473
|
cstBuildHost,
|
|
12211
12474
|
dispatch,
|
|
@@ -12239,6 +12502,7 @@ export {
|
|
|
12239
12502
|
matches,
|
|
12240
12503
|
noTrivia,
|
|
12241
12504
|
node,
|
|
12505
|
+
normalizeLineIndex,
|
|
12242
12506
|
not,
|
|
12243
12507
|
offsetToLineCol,
|
|
12244
12508
|
oneOrMore,
|
|
@@ -12249,6 +12513,7 @@ export {
|
|
|
12249
12513
|
parseDoc,
|
|
12250
12514
|
parser,
|
|
12251
12515
|
peek,
|
|
12516
|
+
recordLineRange,
|
|
12252
12517
|
ref,
|
|
12253
12518
|
regex,
|
|
12254
12519
|
relativize,
|