parseman 0.41.0 → 0.42.1
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/parser.d.ts +6 -0
- package/dist/combinators/parser.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 +5 -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/compiler/linker.d.ts +1 -0
- package/dist/compiler/linker.d.ts.map +1 -1
- package/dist/cst/capture-buffer.d.ts.map +1 -1
- package/dist/index.cjs +483 -181
- 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 +483 -181
- 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 +646 -169
- package/dist/plugin/index.cjs.map +4 -4
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +646 -169
- 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 +462 -327
- package/dist/spec/index.cjs.map +4 -4
- package/dist/spec/index.js +462 -327
- package/dist/spec/index.js.map +4 -4
- package/dist/types.d.ts +18 -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) {
|
|
@@ -2623,6 +2768,101 @@ function markUnusedValues(root) {
|
|
|
2623
2768
|
visit(resolveRoot(root), true);
|
|
2624
2769
|
}
|
|
2625
2770
|
|
|
2771
|
+
// src/combinators/grammar.ts
|
|
2772
|
+
function annotateResultLines(result, index) {
|
|
2773
|
+
const annotated = { ...result, span: annotateSpan(result.span, index) };
|
|
2774
|
+
const errors = annotated.errors;
|
|
2775
|
+
if (errors) {
|
|
2776
|
+
;
|
|
2777
|
+
annotated.errors = errors.map((error) => ({
|
|
2778
|
+
...error,
|
|
2779
|
+
span: annotateSpan(error.span, index)
|
|
2780
|
+
}));
|
|
2781
|
+
}
|
|
2782
|
+
return annotated;
|
|
2783
|
+
}
|
|
2784
|
+
function createParseLineContext(input, pos) {
|
|
2785
|
+
const lineIndex = createLineIndex();
|
|
2786
|
+
if (pos > 0) recordLineRange(lineIndex, input, 0, pos);
|
|
2787
|
+
return { lineIndex, lineScannedTo: pos };
|
|
2788
|
+
}
|
|
2789
|
+
function parser(opts, root) {
|
|
2790
|
+
const clearTrivia = opts.trivia === null;
|
|
2791
|
+
return {
|
|
2792
|
+
_tag: "grammar",
|
|
2793
|
+
_meta: root._meta,
|
|
2794
|
+
_def: {
|
|
2795
|
+
tag: "grammar",
|
|
2796
|
+
parser: root,
|
|
2797
|
+
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
2798
|
+
clearTrivia,
|
|
2799
|
+
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
2800
|
+
trackLines: opts.trackLines ?? false
|
|
2801
|
+
},
|
|
2802
|
+
parse(input, pos, _ctx) {
|
|
2803
|
+
const trackLines = opts.trackLines ?? _ctx?.trackLines ?? false;
|
|
2804
|
+
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
2805
|
+
const lineIndex = trackLines ? _ctx?._lineIndex ?? (_ctx?._lineStarts ? { lineStarts: _ctx._lineStarts } : lineContext.lineIndex) : void 0;
|
|
2806
|
+
const ctx = {
|
|
2807
|
+
..._ctx,
|
|
2808
|
+
trackLines,
|
|
2809
|
+
...lineIndex ? { _lineIndex: lineIndex } : {},
|
|
2810
|
+
...lineContext ? { _lineScannedTo: lineContext.lineScannedTo } : {},
|
|
2811
|
+
// trivia: null clears (contiguous terms); a Combinator sets; undefined inherits.
|
|
2812
|
+
...clearTrivia ? {
|
|
2813
|
+
trivia: void 0,
|
|
2814
|
+
triviaKindLabels: void 0
|
|
2815
|
+
} : opts.trivia != null ? {
|
|
2816
|
+
trivia: opts.trivia,
|
|
2817
|
+
...opts.trivia._meta.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {}
|
|
2818
|
+
} : {},
|
|
2819
|
+
...opts.captureTrivia || _ctx?.captureTrivia ? { captureTrivia: true } : {},
|
|
2820
|
+
// Kind-filter for per-node capture. Resolve against this scope's trivia
|
|
2821
|
+
// labels — this parser's own trivia if it declares one, else the INHERITED
|
|
2822
|
+
// labels (`_ctx.triviaKindLabels`), so captureTriviaKinds still applies when
|
|
2823
|
+
// trivia is inherited rather than re-declared here. No labels → undefined
|
|
2824
|
+
// (capture all).
|
|
2825
|
+
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {}
|
|
2826
|
+
};
|
|
2827
|
+
const result = root.parse(input, pos ?? 0, ctx);
|
|
2828
|
+
if (trackLines && _ctx && ctx._lineScannedTo !== void 0) {
|
|
2829
|
+
_ctx._lineScannedTo = Math.max(_ctx._lineScannedTo ?? 0, ctx._lineScannedTo);
|
|
2830
|
+
}
|
|
2831
|
+
return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
2832
|
+
}
|
|
2833
|
+
};
|
|
2834
|
+
}
|
|
2835
|
+
function noTrivia(root) {
|
|
2836
|
+
return parser({ trivia: null }, root);
|
|
2837
|
+
}
|
|
2838
|
+
var _analyzed = /* @__PURE__ */ new WeakSet();
|
|
2839
|
+
function parse(combinator, input, opts = {}) {
|
|
2840
|
+
if (!_analyzed.has(combinator)) {
|
|
2841
|
+
_analyzed.add(combinator);
|
|
2842
|
+
markUnusedValues(combinator);
|
|
2843
|
+
}
|
|
2844
|
+
const trackLines = opts.trackLines ?? combinator._meta.grammarTrackLines ?? false;
|
|
2845
|
+
const lineContext = trackLines ? createParseLineContext(input, 0) : void 0;
|
|
2846
|
+
const lineIndex = lineContext?.lineIndex;
|
|
2847
|
+
const _errors = opts.recover ? [] : void 0;
|
|
2848
|
+
const _probe = opts.recover ? { offset: input.length, best: null } : void 0;
|
|
2849
|
+
const grammarTrivia = combinator._meta.grammarTrivia;
|
|
2850
|
+
const grammarScanSkip = combinator._meta.grammarScanSkip;
|
|
2851
|
+
const ctx = {
|
|
2852
|
+
trackLines,
|
|
2853
|
+
...lineIndex ? { _lineIndex: lineIndex } : {},
|
|
2854
|
+
...lineContext ? { _lineScannedTo: lineContext.lineScannedTo } : {},
|
|
2855
|
+
...grammarTrivia !== void 0 ? { trivia: grammarTrivia, ...grammarTrivia._meta.triviaKindLabels ? { triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {} } : {},
|
|
2856
|
+
...grammarScanSkip !== void 0 ? { scanSkip: grammarScanSkip } : {},
|
|
2857
|
+
..._errors !== void 0 ? { _errors } : {},
|
|
2858
|
+
..._probe !== void 0 ? { _probe } : {}
|
|
2859
|
+
};
|
|
2860
|
+
const result = combinator.parse(input, 0, ctx);
|
|
2861
|
+
if (!result.ok) return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
2862
|
+
const withErrors = _errors !== void 0 ? { ...result, errors: _errors, furthestFail: _probe?.best ?? null } : result;
|
|
2863
|
+
return lineIndex ? annotateResultLines(withErrors, normalizeLineIndex(lineIndex)) : withErrors;
|
|
2864
|
+
}
|
|
2865
|
+
|
|
2626
2866
|
// src/combinators/parser.ts
|
|
2627
2867
|
var RULE_ORDER = "__parsemanRuleOrder";
|
|
2628
2868
|
function tagRule(r, key) {
|
|
@@ -2698,6 +2938,21 @@ function rules(a, b) {
|
|
|
2698
2938
|
if (rule && !rule._meta.isTrivia) rule._meta.grammarHostMode = "cst";
|
|
2699
2939
|
}
|
|
2700
2940
|
}
|
|
2941
|
+
if (options?.trackLines === true) {
|
|
2942
|
+
for (const key of Object.keys(definitions)) {
|
|
2943
|
+
const rule = cache[key];
|
|
2944
|
+
if (rule && !rule._meta.isTrivia) rule._meta.grammarTrackLines = true;
|
|
2945
|
+
}
|
|
2946
|
+
for (const key of Object.keys(definitions)) {
|
|
2947
|
+
const rule = cache[key];
|
|
2948
|
+
if (rule && !rule._meta.isTrivia && rule._def.tag !== "grammar") {
|
|
2949
|
+
const wrapped = parser({ trackLines: true }, rule);
|
|
2950
|
+
tagRule(wrapped, key);
|
|
2951
|
+
wrapped._meta.grammarTrackLines = true;
|
|
2952
|
+
cache[key] = wrapped;
|
|
2953
|
+
}
|
|
2954
|
+
}
|
|
2955
|
+
}
|
|
2701
2956
|
for (const key of Object.keys(definitions)) {
|
|
2702
2957
|
markUnusedValues(cache[key]);
|
|
2703
2958
|
}
|
|
@@ -3076,13 +3331,14 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
3076
3331
|
const st = clonesState && ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
3077
3332
|
const nodeType = def.type ?? missingInferredType();
|
|
3078
3333
|
const cstOutput = cstOutputHost(ctx.build);
|
|
3334
|
+
const span = ctx.trackLines ? annotateSpanFromLineContext(r.span, ctx) : r.span;
|
|
3079
3335
|
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
|
|
3336
|
+
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 };
|
|
3337
|
+
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
3338
|
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
3083
3339
|
pushCstChild(ctx, built, rawEntry);
|
|
3084
3340
|
}
|
|
3085
|
-
return { ok: true, value: built, span
|
|
3341
|
+
return { ok: true, value: built, span };
|
|
3086
3342
|
}
|
|
3087
3343
|
};
|
|
3088
3344
|
}
|
|
@@ -3153,112 +3409,6 @@ function field(name, combinator) {
|
|
|
3153
3409
|
};
|
|
3154
3410
|
}
|
|
3155
3411
|
|
|
3156
|
-
// src/compiler/line-index.ts
|
|
3157
|
-
function buildLineIndex(input) {
|
|
3158
|
-
const lineStarts = [0];
|
|
3159
|
-
for (let i = 0; i < input.length; i++) {
|
|
3160
|
-
if (input.charCodeAt(i) === 10) lineStarts.push(i + 1);
|
|
3161
|
-
}
|
|
3162
|
-
return { lineStarts };
|
|
3163
|
-
}
|
|
3164
|
-
function offsetToLineCol(index, offset) {
|
|
3165
|
-
const { lineStarts } = index;
|
|
3166
|
-
let lo = 0;
|
|
3167
|
-
let hi = lineStarts.length - 1;
|
|
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 };
|
|
3174
|
-
}
|
|
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
|
-
function parser(opts, root) {
|
|
3189
|
-
const clearTrivia = opts.trivia === null;
|
|
3190
|
-
return {
|
|
3191
|
-
_tag: "grammar",
|
|
3192
|
-
_meta: root._meta,
|
|
3193
|
-
_def: {
|
|
3194
|
-
tag: "grammar",
|
|
3195
|
-
parser: root,
|
|
3196
|
-
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
3197
|
-
clearTrivia,
|
|
3198
|
-
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
3199
|
-
trackLines: opts.trackLines ?? false
|
|
3200
|
-
},
|
|
3201
|
-
parse(input, pos, _ctx) {
|
|
3202
|
-
const trackLines = opts.trackLines ?? _ctx?.trackLines ?? false;
|
|
3203
|
-
const ctx = {
|
|
3204
|
-
..._ctx,
|
|
3205
|
-
trackLines,
|
|
3206
|
-
// trivia: null clears (contiguous terms); a Combinator sets; undefined inherits.
|
|
3207
|
-
...clearTrivia ? {
|
|
3208
|
-
trivia: void 0,
|
|
3209
|
-
triviaKindLabels: void 0
|
|
3210
|
-
} : opts.trivia != null ? {
|
|
3211
|
-
trivia: opts.trivia,
|
|
3212
|
-
...opts.trivia._meta.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {}
|
|
3213
|
-
} : {},
|
|
3214
|
-
...opts.captureTrivia || _ctx?.captureTrivia ? { captureTrivia: true } : {},
|
|
3215
|
-
// Kind-filter for per-node capture. Resolve against this scope's trivia
|
|
3216
|
-
// labels — this parser's own trivia if it declares one, else the INHERITED
|
|
3217
|
-
// labels (`_ctx.triviaKindLabels`), so captureTriviaKinds still applies when
|
|
3218
|
-
// trivia is inherited rather than re-declared here. No labels → undefined
|
|
3219
|
-
// (capture all).
|
|
3220
|
-
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {}
|
|
3221
|
-
};
|
|
3222
|
-
const result = root.parse(input, pos ?? 0, ctx);
|
|
3223
|
-
if (trackLines) {
|
|
3224
|
-
const idx = buildLineIndex(input);
|
|
3225
|
-
return { ...result, span: annotateSpan(result.span, idx) };
|
|
3226
|
-
}
|
|
3227
|
-
return result;
|
|
3228
|
-
}
|
|
3229
|
-
};
|
|
3230
|
-
}
|
|
3231
|
-
function noTrivia(root) {
|
|
3232
|
-
return parser({ trivia: null }, root);
|
|
3233
|
-
}
|
|
3234
|
-
var _analyzed = /* @__PURE__ */ new WeakSet();
|
|
3235
|
-
function parse(combinator, input, opts = {}) {
|
|
3236
|
-
if (!_analyzed.has(combinator)) {
|
|
3237
|
-
_analyzed.add(combinator);
|
|
3238
|
-
markUnusedValues(combinator);
|
|
3239
|
-
}
|
|
3240
|
-
const trackLines = opts.trackLines ?? false;
|
|
3241
|
-
const _errors = opts.recover ? [] : void 0;
|
|
3242
|
-
const _probe = opts.recover ? { offset: input.length, best: null } : void 0;
|
|
3243
|
-
const grammarTrivia = combinator._meta.grammarTrivia;
|
|
3244
|
-
const grammarScanSkip = combinator._meta.grammarScanSkip;
|
|
3245
|
-
const ctx = {
|
|
3246
|
-
trackLines,
|
|
3247
|
-
...grammarTrivia !== void 0 ? { trivia: grammarTrivia, ...grammarTrivia._meta.triviaKindLabels ? { triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {} } : {},
|
|
3248
|
-
...grammarScanSkip !== void 0 ? { scanSkip: grammarScanSkip } : {},
|
|
3249
|
-
..._errors !== void 0 ? { _errors } : {},
|
|
3250
|
-
..._probe !== void 0 ? { _probe } : {}
|
|
3251
|
-
};
|
|
3252
|
-
const result = combinator.parse(input, 0, ctx);
|
|
3253
|
-
if (!result.ok) return result;
|
|
3254
|
-
const withErrors = _errors !== void 0 ? { ...result, errors: _errors, furthestFail: _probe?.best ?? null } : result;
|
|
3255
|
-
if (trackLines) {
|
|
3256
|
-
const idx = buildLineIndex(input);
|
|
3257
|
-
return { ...withErrors, span: annotateSpan(withErrors.span, idx) };
|
|
3258
|
-
}
|
|
3259
|
-
return withErrors;
|
|
3260
|
-
}
|
|
3261
|
-
|
|
3262
3412
|
// src/combinators/token.ts
|
|
3263
3413
|
function token(root) {
|
|
3264
3414
|
const meta = {
|
|
@@ -3355,7 +3505,7 @@ function leaf(root, fn) {
|
|
|
3355
3505
|
}
|
|
3356
3506
|
|
|
3357
3507
|
// src/version.ts
|
|
3358
|
-
var PARSEMAN_VERSION = "0.
|
|
3508
|
+
var PARSEMAN_VERSION = "0.42.1";
|
|
3359
3509
|
|
|
3360
3510
|
// src/cst/host-mode.ts
|
|
3361
3511
|
var FUSED_HOST_MODE = /* @__PURE__ */ Symbol.for("parseman.fusedHostMode");
|
|
@@ -5039,7 +5189,7 @@ function scanTo(sentinel, { skip: skip2, raw = false, orEOF = false } = {}) {
|
|
|
5039
5189
|
let cur = pos;
|
|
5040
5190
|
const skip3 = resolveScanSkip(explicitSkip, raw, ctx);
|
|
5041
5191
|
const probeCtx = {
|
|
5042
|
-
trackLines:
|
|
5192
|
+
trackLines: false,
|
|
5043
5193
|
state: ctx.state,
|
|
5044
5194
|
...ctx._errors !== void 0 ? { _errors: ctx._errors } : {}
|
|
5045
5195
|
};
|
|
@@ -5052,6 +5202,7 @@ function scanTo(sentinel, { skip: skip2, raw = false, orEOF = false } = {}) {
|
|
|
5052
5202
|
while (cur < input.length) {
|
|
5053
5203
|
const s = sentinel.parse(input, cur, probeCtx);
|
|
5054
5204
|
if (s.ok) {
|
|
5205
|
+
if (ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, cur);
|
|
5055
5206
|
emit2(cur);
|
|
5056
5207
|
return { ok: true, value: input.slice(pos, cur), span: { start: pos, end: cur } };
|
|
5057
5208
|
}
|
|
@@ -5067,6 +5218,7 @@ function scanTo(sentinel, { skip: skip2, raw = false, orEOF = false } = {}) {
|
|
|
5067
5218
|
if (!advanced) cur++;
|
|
5068
5219
|
}
|
|
5069
5220
|
if (orEOF) {
|
|
5221
|
+
if (ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, cur);
|
|
5070
5222
|
emit2(cur);
|
|
5071
5223
|
return { ok: true, value: input.slice(pos, cur), span: { start: pos, end: cur } };
|
|
5072
5224
|
}
|
|
@@ -6505,8 +6657,8 @@ function analyzeMkInlineBuild(def) {
|
|
|
6505
6657
|
if (looseMkBuildRe(def.type).test(src)) return def.type;
|
|
6506
6658
|
return null;
|
|
6507
6659
|
}
|
|
6508
|
-
function emitInlineMkNodeExpr(type, chV, rawV,
|
|
6509
|
-
return `{ _tag: 'node', type: ${JSON.stringify(type)}, span:
|
|
6660
|
+
function emitInlineMkNodeExpr(type, chV, rawV, spanExpr, tlV) {
|
|
6661
|
+
return `{ _tag: 'node', type: ${JSON.stringify(type)}, span: ${spanExpr}, children: ${chV}, rawCount: ${rawV}.length, localTriviaLen: ${tlV}.length }`;
|
|
6510
6662
|
}
|
|
6511
6663
|
|
|
6512
6664
|
// src/compiler/inline-callback.ts
|
|
@@ -6688,6 +6840,8 @@ function leadingFirstSetRecipe(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
6688
6840
|
}
|
|
6689
6841
|
}
|
|
6690
6842
|
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 }";
|
|
6843
|
+
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 }";
|
|
6844
|
+
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
6845
|
var _loweringSink = null;
|
|
6692
6846
|
function v(ctx, prefix = "_v") {
|
|
6693
6847
|
return `${prefix}${ctx.vars++}`;
|
|
@@ -6711,13 +6865,16 @@ function reindentStmts(stmts, targetLevels) {
|
|
|
6711
6865
|
const targetPrefix = " ".repeat(targetLevels);
|
|
6712
6866
|
return stmts.map((s) => s.trim().length === 0 ? "" : targetPrefix + s.slice(minLeading));
|
|
6713
6867
|
}
|
|
6714
|
-
function failReturn(expected, posExpr) {
|
|
6868
|
+
function failReturn(ctx, expected, posExpr) {
|
|
6869
|
+
if (ctx.lineTracking) return `return { ok: false, expected: [${expected}], span: ${emitSpanExpr(ctx, posExpr, posExpr)} }`;
|
|
6715
6870
|
return `return { ok: false, expected: [${expected}], span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
6716
6871
|
}
|
|
6717
|
-
function failReturnArr(expectedArr, posExpr) {
|
|
6872
|
+
function failReturnArr(ctx, expectedArr, posExpr) {
|
|
6873
|
+
if (ctx.lineTracking) return `return { ok: false, expected: ${expectedArr}, span: ${emitSpanExpr(ctx, posExpr, posExpr)} }`;
|
|
6718
6874
|
return `return { ok: false, expected: ${expectedArr}, span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
6719
6875
|
}
|
|
6720
|
-
function committedReturnArr(expectedArr, posExpr) {
|
|
6876
|
+
function committedReturnArr(ctx, expectedArr, posExpr) {
|
|
6877
|
+
if (ctx.lineTracking) return `return { ok: false, expected: [...${expectedArr}], span: ${emitSpanExpr(ctx, posExpr, posExpr)}, committed: true }`;
|
|
6721
6878
|
return `return { ok: false, expected: [...${expectedArr}], span: { start: ${posExpr}, end: ${posExpr} }, committed: true }`;
|
|
6722
6879
|
}
|
|
6723
6880
|
function hoistExpected(ctx, constArrSource) {
|
|
@@ -6742,7 +6899,7 @@ function failBody(ctx, expected, posExpr) {
|
|
|
6742
6899
|
if (!ctx.recordFail) return probe ? `{ ${probe}${trace}break ${ctx.failLabel} }` : trace ? `{ ${trace}break ${ctx.failLabel} }` : `break ${ctx.failLabel}`;
|
|
6743
6900
|
return `{ ${probe}_ctx._fe = ${posExpr}; _ctx._fx = ${hoistExpected(ctx, `[${expected}]`)}; ${trace}break ${ctx.failLabel} }`;
|
|
6744
6901
|
}
|
|
6745
|
-
return probe + trace + failReturn(expected, posExpr);
|
|
6902
|
+
return probe + trace + failReturn(ctx, expected, posExpr);
|
|
6746
6903
|
}
|
|
6747
6904
|
function failArrBody(ctx, expectedArr, posExpr, constant = true) {
|
|
6748
6905
|
const probe = probeUpdate(ctx, expectedArr, posExpr, constant);
|
|
@@ -6752,18 +6909,19 @@ function failArrBody(ctx, expectedArr, posExpr, constant = true) {
|
|
|
6752
6909
|
const fx = constant ? hoistExpected(ctx, expectedArr) : expectedArr;
|
|
6753
6910
|
return `{ ${probe}_ctx._fe = ${posExpr}; _ctx._fx = ${fx}; ${trace}break ${ctx.failLabel} }`;
|
|
6754
6911
|
}
|
|
6755
|
-
if (!constant) return `${probe}${trace}return { ok: false, expected: [...${expectedArr}], span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
6756
|
-
return probe + trace + failReturnArr(expectedArr, posExpr);
|
|
6912
|
+
if (!constant) return `${probe}${trace}return { ok: false, expected: [...${expectedArr}], span: ${ctx.lineTracking ? emitSpanExpr(ctx, posExpr, posExpr) : `{ start: ${posExpr}, end: ${posExpr} }`} }`;
|
|
6913
|
+
return probe + trace + failReturnArr(ctx, expectedArr, posExpr);
|
|
6757
6914
|
}
|
|
6758
|
-
function resultFromRecorded(feExpr = "_ctx._fe", fxExpr = "_ctx._fx") {
|
|
6759
|
-
|
|
6915
|
+
function resultFromRecorded(ctx, feExpr = "_ctx._fe", fxExpr = "_ctx._fx") {
|
|
6916
|
+
const spanExpr = ctx.lineTracking ? emitSpanExpr(ctx, feExpr, feExpr) : `{ start: ${feExpr}, end: ${feExpr} }`;
|
|
6917
|
+
return `return { ok: false, expected: [...${fxExpr}], span: ${spanExpr}, ...(_ctx._fc ? { committed: true } : {}) }`;
|
|
6760
6918
|
}
|
|
6761
6919
|
function committedFailBody(ctx, expectedArr = "_ctx._fx", posExpr = "_ctx._fe") {
|
|
6762
6920
|
if (ctx.failLabel) {
|
|
6763
6921
|
if (!ctx.recordFail) return `{ _ctx._fc = true; break ${ctx.failLabel} }`;
|
|
6764
6922
|
return `{ _ctx._fc = true; _ctx._fe = ${posExpr}; _ctx._fx = ${expectedArr}; break ${ctx.failLabel} }`;
|
|
6765
6923
|
}
|
|
6766
|
-
return committedReturnArr(expectedArr, posExpr);
|
|
6924
|
+
return committedReturnArr(ctx, expectedArr, posExpr);
|
|
6767
6925
|
}
|
|
6768
6926
|
function propagateFailBody(ctx, srcCtx = "_ctx") {
|
|
6769
6927
|
if (srcCtx !== "_ctx") {
|
|
@@ -6771,10 +6929,10 @@ function propagateFailBody(ctx, srcCtx = "_ctx") {
|
|
|
6771
6929
|
if (!ctx.recordFail) return `break ${ctx.failLabel}`;
|
|
6772
6930
|
return `{ _ctx._fe = ${srcCtx}._fe; _ctx._fx = ${srcCtx}._fx; _ctx._fc = ${srcCtx}._fc; break ${ctx.failLabel} }`;
|
|
6773
6931
|
}
|
|
6774
|
-
return `{ _ctx._fe = ${srcCtx}._fe; _ctx._fx = ${srcCtx}._fx; _ctx._fc = ${srcCtx}._fc; ${resultFromRecorded()} }`;
|
|
6932
|
+
return `{ _ctx._fe = ${srcCtx}._fe; _ctx._fx = ${srcCtx}._fx; _ctx._fc = ${srcCtx}._fc; ${resultFromRecorded(ctx)} }`;
|
|
6775
6933
|
}
|
|
6776
6934
|
if (ctx.failLabel) return `break ${ctx.failLabel}`;
|
|
6777
|
-
return resultFromRecorded();
|
|
6935
|
+
return resultFromRecorded(ctx);
|
|
6778
6936
|
}
|
|
6779
6937
|
function emitIfFail(ctx, cond, body) {
|
|
6780
6938
|
return [
|
|
@@ -6828,14 +6986,46 @@ function emitLeafCapture(ctx, valExpr, startExpr, endExpr) {
|
|
|
6828
6986
|
if (ctx.capAsTrivia) return [];
|
|
6829
6987
|
const i = ind(ctx);
|
|
6830
6988
|
const lf = v(ctx, "_lf");
|
|
6989
|
+
const spanExpr = emitSpanExpr(ctx, startExpr, endExpr);
|
|
6831
6990
|
return [
|
|
6832
6991
|
`${i}if (_ctx._cstLeaves || _ctx._cstRawChildren) {`,
|
|
6833
|
-
`${i} const ${lf} = { _tag: 'leaf', value: ${valExpr}, span:
|
|
6992
|
+
`${i} const ${lf} = { _tag: 'leaf', value: ${valExpr}, span: ${spanExpr} }`,
|
|
6834
6993
|
`${i} if (_ctx._cstLeaves) _ctx._cstLeaves.push(${lf})`,
|
|
6835
6994
|
`${i} if (_ctx._cstRawChildren) _ctx._cstRawChildren.push(${lf})`,
|
|
6836
6995
|
`${i}}`
|
|
6837
6996
|
];
|
|
6838
6997
|
}
|
|
6998
|
+
function emitSpanExpr(ctx, startExpr, endExpr) {
|
|
6999
|
+
if (!ctx.lineTracking) return `{ start: ${startExpr}, end: ${endExpr} }`;
|
|
7000
|
+
ctx.needsLineSpan = true;
|
|
7001
|
+
return `_spanLines(_ctx, ${startExpr}, ${endExpr})`;
|
|
7002
|
+
}
|
|
7003
|
+
function emitLineTrack(ctx, startExpr, endExpr) {
|
|
7004
|
+
if (!ctx.lineTracking) return [];
|
|
7005
|
+
ctx.needsLineTrack = true;
|
|
7006
|
+
return [`${ind(ctx)}_trackLines(_ctx, input, ${startExpr}, ${endExpr})`];
|
|
7007
|
+
}
|
|
7008
|
+
function emitLiteralLineTrack(ctx, startExpr, value) {
|
|
7009
|
+
if (!ctx.lineTracking) return [];
|
|
7010
|
+
const lineDeltas = [];
|
|
7011
|
+
for (let i = 0; i < value.length; i++) {
|
|
7012
|
+
if (value.charCodeAt(i) === 10) lineDeltas.push(i + 1);
|
|
7013
|
+
}
|
|
7014
|
+
if (lineDeltas.length === 0) return [];
|
|
7015
|
+
const fromV = v(ctx, "_ltFrom");
|
|
7016
|
+
const endExpr = value.length === 0 ? startExpr : `${startExpr} + ${value.length}`;
|
|
7017
|
+
return [
|
|
7018
|
+
`${ind(ctx)}const ${fromV} = _ctx._lineScannedTo ?? 0`,
|
|
7019
|
+
`${ind(ctx)}if (${endExpr} > ${fromV}) {`,
|
|
7020
|
+
`${ind(ctx)} for (let i = ${fromV}; i < ${startExpr}; i++) if (input.charCodeAt(i) === 10) _ctx._lineStarts.push(i + 1)`,
|
|
7021
|
+
...lineDeltas.map((delta) => {
|
|
7022
|
+
const lineStart = `${startExpr} + ${delta}`;
|
|
7023
|
+
return `${ind(ctx)} if (${lineStart} > ${fromV}) _ctx._lineStarts.push(${lineStart})`;
|
|
7024
|
+
}),
|
|
7025
|
+
`${ind(ctx)} _ctx._lineScannedTo = ${endExpr}`,
|
|
7026
|
+
`${ind(ctx)}}`
|
|
7027
|
+
];
|
|
7028
|
+
}
|
|
6839
7029
|
function ensureRegexDecl(ctx, source, flags) {
|
|
6840
7030
|
const f = "y" + flags.replace(/[gy]/g, "");
|
|
6841
7031
|
const key = `${source}/${f}`;
|
|
@@ -7220,6 +7410,7 @@ function emitLit(def, ctx, pos) {
|
|
|
7220
7410
|
);
|
|
7221
7411
|
}
|
|
7222
7412
|
const endVar = len === 0 ? pos : `${pos} + ${len}`;
|
|
7413
|
+
stmts.push(...emitLiteralLineTrack(ctx, pos, value));
|
|
7223
7414
|
stmts.push(...emitLeafCapture(ctx, vv, pos, endVar));
|
|
7224
7415
|
return { stmts, valueVar: vv, endVar };
|
|
7225
7416
|
}
|
|
@@ -7299,7 +7490,7 @@ function emitKeywords(def, ctx, pos) {
|
|
|
7299
7490
|
stmts.push(...emitLeafCapture(ctx, vv, pos, endVar));
|
|
7300
7491
|
return { stmts, valueVar: vv, endVar };
|
|
7301
7492
|
}
|
|
7302
|
-
function emitRegex(def, ctx, pos) {
|
|
7493
|
+
function emitRegex(def, ctx, pos, canMatchNewline = true) {
|
|
7303
7494
|
const expectedStr = JSON.stringify(`/${def.source}/`);
|
|
7304
7495
|
const shape = scanShapeFromRegex(def.source, def.flags);
|
|
7305
7496
|
if (shape) {
|
|
@@ -7312,7 +7503,11 @@ function emitRegex(def, ctx, pos) {
|
|
|
7312
7503
|
fresh: (prefix) => v(ctx, prefix)
|
|
7313
7504
|
});
|
|
7314
7505
|
if (scanned) {
|
|
7315
|
-
const stmts2 = [
|
|
7506
|
+
const stmts2 = [
|
|
7507
|
+
...scanned.stmts,
|
|
7508
|
+
...canMatchNewline ? emitLineTrack(ctx, pos, scanned.endVar) : [],
|
|
7509
|
+
...emitLeafCapture(ctx, vv2, pos, scanned.endVar)
|
|
7510
|
+
];
|
|
7316
7511
|
return { stmts: stmts2, valueVar: vv2, endVar: scanned.endVar };
|
|
7317
7512
|
}
|
|
7318
7513
|
}
|
|
@@ -7334,6 +7529,7 @@ function emitRegex(def, ctx, pos) {
|
|
|
7334
7529
|
`${ind(ctx)}const ${vv} = ${mv}[0]`
|
|
7335
7530
|
];
|
|
7336
7531
|
const endVar = `${pos} + ${vv}.length`;
|
|
7532
|
+
if (canMatchNewline) stmts.push(...emitLineTrack(ctx, pos, endVar));
|
|
7337
7533
|
stmts.push(...emitLeafCapture(ctx, vv, pos, endVar));
|
|
7338
7534
|
return { stmts, valueVar: vv, endVar };
|
|
7339
7535
|
}
|
|
@@ -7371,7 +7567,8 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7371
7567
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
7372
7568
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
7373
7569
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
7374
|
-
`${ind(ctx)}const ${scanEndV} = ${capFn}(input, ${curV}, _ctx, 1)
|
|
7570
|
+
`${ind(ctx)}const ${scanEndV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
7571
|
+
...emitLineTrack(ctx, curV, scanEndV)
|
|
7375
7572
|
);
|
|
7376
7573
|
const r2 = emit(def.parsers[i], ctx, scanEndV);
|
|
7377
7574
|
stmts.push(...r2.stmts);
|
|
@@ -7389,7 +7586,8 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7389
7586
|
const capArg = ctx.noHoist ? "0" : "_ctx._triviaLog !== undefined ? 2 : 0";
|
|
7390
7587
|
stmts.push(
|
|
7391
7588
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
7392
|
-
`${ind(ctx)}const ${scanEndV} = ${trivFn}(input, ${curV}, _ctx, ${capArg})
|
|
7589
|
+
`${ind(ctx)}const ${scanEndV} = ${trivFn}(input, ${curV}, _ctx, ${capArg})`,
|
|
7590
|
+
...emitLineTrack(ctx, curV, scanEndV)
|
|
7393
7591
|
);
|
|
7394
7592
|
const r2 = emit(def.parsers[i], ctx, scanEndV);
|
|
7395
7593
|
stmts.push(...r2.stmts);
|
|
@@ -8089,14 +8287,15 @@ function emitMany(def, ctx, pos) {
|
|
|
8089
8287
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8090
8288
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8091
8289
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8092
|
-
`${ind(ctx)}const ${npV} = ${capFn}(input, ${curV}, _ctx, 1)
|
|
8290
|
+
`${ind(ctx)}const ${npV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
8291
|
+
...emitLineTrack(ctx, curV, npV)
|
|
8093
8292
|
);
|
|
8094
8293
|
itemPos = npV;
|
|
8095
8294
|
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
8295
|
} else {
|
|
8097
8296
|
const trivFn = ensureTriviaFn(ctx);
|
|
8098
8297
|
const npV = v(ctx, "_np");
|
|
8099
|
-
stmts.push(`${ind(ctx)}const ${npV} = ${trivFn}(input, ${curV}, _ctx)
|
|
8298
|
+
stmts.push(`${ind(ctx)}const ${npV} = ${trivFn}(input, ${curV}, _ctx)`, ...emitLineTrack(ctx, curV, npV));
|
|
8100
8299
|
itemPos = npV;
|
|
8101
8300
|
}
|
|
8102
8301
|
}
|
|
@@ -8166,7 +8365,7 @@ function emitAttempt(p, def, ctx, pos) {
|
|
|
8166
8365
|
if (!ctx.recovery && !ctx.coverage && needsFirstSetGuard(def.parser)) {
|
|
8167
8366
|
const gcV = v(ctx, "_agc");
|
|
8168
8367
|
const gExp = armStaticExpected(ctx, def.parser);
|
|
8169
|
-
const gFail = ctx.failLabel ? `{ _ctx._fe = ${pos};${ctx.recordFail ? ` _ctx._fx = ${gExp};` : ""} break ${ctx.failLabel} }` : `{ _ctx._fe = ${pos}; ${failReturnArr(gExp, pos)} }`;
|
|
8368
|
+
const gFail = ctx.failLabel ? `{ _ctx._fe = ${pos};${ctx.recordFail ? ` _ctx._fx = ${gExp};` : ""} break ${ctx.failLabel} }` : `{ _ctx._fe = ${pos}; ${failReturnArr(ctx, gExp, pos)} }`;
|
|
8170
8369
|
preGuard.push(
|
|
8171
8370
|
`${ind(ctx)}const ${gcV} = ${pos} < input.length ? (input.codePointAt(${pos}) ?? -1) : -1`,
|
|
8172
8371
|
`${ind(ctx)}if (!(${firstSetCond(gcV, def.parser._meta.firstSet)})) ${gFail}`
|
|
@@ -8273,7 +8472,8 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8273
8472
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8274
8473
|
`${ind(ctx)}const ${markLv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
8275
8474
|
`${ind(ctx)}const ${markFld} = _ctx._fields ? _ctx._fields.length : 0`,
|
|
8276
|
-
`${ind(ctx)}const ${spV} = ${capFn}(input, ${curV}, _ctx, 1)
|
|
8475
|
+
`${ind(ctx)}const ${spV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
8476
|
+
...emitLineTrack(ctx, curV, spV)
|
|
8277
8477
|
);
|
|
8278
8478
|
sepAtPos = spV;
|
|
8279
8479
|
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 +8483,7 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8283
8483
|
const post = postSepMarks();
|
|
8284
8484
|
stmts.push(...post.decl);
|
|
8285
8485
|
const npV = v(ctx, "_np");
|
|
8286
|
-
stmts.push(`${ind(ctx)}const ${npV} = ${capFn}(input, ${sepEnd}, _ctx, 1)
|
|
8486
|
+
stmts.push(`${ind(ctx)}const ${npV} = ${capFn}(input, ${sepEnd}, _ctx, 1)`, ...emitLineTrack(ctx, sepEnd, npV));
|
|
8287
8487
|
const next = emitFallible(def.parser, ctx, npV, true);
|
|
8288
8488
|
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = next;
|
|
8289
8489
|
stmts.push(
|
|
@@ -8295,13 +8495,13 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8295
8495
|
} else {
|
|
8296
8496
|
const trivFn = ensureTriviaFn(ctx);
|
|
8297
8497
|
const spV = v(ctx, "_sp");
|
|
8298
|
-
stmts.push(`${ind(ctx)}const ${spV} = ${trivFn}(input, ${curV}, _ctx)
|
|
8498
|
+
stmts.push(`${ind(ctx)}const ${spV} = ${trivFn}(input, ${curV}, _ctx)`, ...emitLineTrack(ctx, curV, spV));
|
|
8299
8499
|
sepAtPos = spV;
|
|
8300
8500
|
const sep = emitFallible(def.separator, ctx, sepAtPos, true);
|
|
8301
8501
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = sep;
|
|
8302
8502
|
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${sep.mayCommit ? `if (_ctx._fc) ${committedFailBody(ctx)}; ` : ""}break }`);
|
|
8303
8503
|
const npV = v(ctx, "_np");
|
|
8304
|
-
stmts.push(`${ind(ctx)}const ${npV} = ${trivFn}(input, ${sepEnd}, _ctx)
|
|
8504
|
+
stmts.push(`${ind(ctx)}const ${npV} = ${trivFn}(input, ${sepEnd}, _ctx)`, ...emitLineTrack(ctx, sepEnd, npV));
|
|
8305
8505
|
const next = emitFallible(def.parser, ctx, npV, true);
|
|
8306
8506
|
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = next;
|
|
8307
8507
|
stmts.push(
|
|
@@ -8388,6 +8588,7 @@ function emitScanTo(def, ctx, pos) {
|
|
|
8388
8588
|
}
|
|
8389
8589
|
const valV = v(ctx);
|
|
8390
8590
|
stmts.push(`${ind(ctx)}const ${valV} = input.slice(${pos}, ${curV})`);
|
|
8591
|
+
stmts.push(...emitLineTrack(ctx, pos, curV));
|
|
8391
8592
|
if (ctx.capturing) {
|
|
8392
8593
|
const cap = reindentStmts(emitLeafCapture(ctx, valV, pos, curV), ctx.indent + 1);
|
|
8393
8594
|
stmts.push(`${ind(ctx)}if (${curV} > ${pos}) {`, ...cap, `${ind(ctx)}}`);
|
|
@@ -8531,7 +8732,7 @@ function tokenNullableRegex(def) {
|
|
|
8531
8732
|
}
|
|
8532
8733
|
function emitToken(def, ctx, pos) {
|
|
8533
8734
|
const lowered = tokenNullableRegex(def);
|
|
8534
|
-
if (lowered) return emitRegex(lowered, ctx, pos);
|
|
8735
|
+
if (lowered) return emitRegex(lowered, ctx, pos, def.parser._meta.canMatchNewline);
|
|
8535
8736
|
const savedTrivia = ctx.activeTrivia;
|
|
8536
8737
|
const savedKindLabels = ctx.triviaKindLabels;
|
|
8537
8738
|
ctx.activeTrivia = void 0;
|
|
@@ -8663,7 +8864,7 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8663
8864
|
if (!ctx.recovery && !ctx.coverage && (capturesChildren || structural) && needsFirstSetGuard(def.parser)) {
|
|
8664
8865
|
const gcV = v(ctx, "_ngc");
|
|
8665
8866
|
const gExp = armStaticExpected(ctx, def.parser);
|
|
8666
|
-
const gFail = ctx.failLabel ? ctx.recordFail ? `{ _ctx._fe = ${pos}; _ctx._fx = ${gExp}; break ${ctx.failLabel} }` : `break ${ctx.failLabel}` : failReturnArr(gExp, pos);
|
|
8867
|
+
const gFail = ctx.failLabel ? ctx.recordFail ? `{ _ctx._fe = ${pos}; _ctx._fx = ${gExp}; break ${ctx.failLabel} }` : `break ${ctx.failLabel}` : failReturnArr(ctx, gExp, pos);
|
|
8667
8868
|
preGuard.push(
|
|
8668
8869
|
`${i}const ${gcV} = ${pos} < input.length ? (input.codePointAt(${pos}) ?? -1) : -1`,
|
|
8669
8870
|
`${i}if (!(${firstSetCond(gcV, def.parser._meta.firstSet)})) ${gFail}`
|
|
@@ -8681,7 +8882,7 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8681
8882
|
stmts.push(...innerStmts);
|
|
8682
8883
|
if (def.trailingTrivia === true && ctx.activeTrivia) {
|
|
8683
8884
|
const triviaFn = ensureTriviaFn(ctx);
|
|
8684
|
-
stmts.push(`${i}const ${endVar} = ${okVar} ? ${triviaFn}(input, ${innerEndVar}, _ctx, 1) : ${innerEndVar}
|
|
8885
|
+
stmts.push(`${i}const ${endVar} = ${okVar} ? ${triviaFn}(input, ${innerEndVar}, _ctx, 1) : ${innerEndVar}`, ...emitLineTrack(ctx, innerEndVar, endVar));
|
|
8685
8886
|
}
|
|
8686
8887
|
if (sf && fArr) {
|
|
8687
8888
|
stmts.push(`${i}const ${fArr} = _ctx._fields`);
|
|
@@ -8721,8 +8922,11 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8721
8922
|
);
|
|
8722
8923
|
}
|
|
8723
8924
|
const ndV = v(ctx, "_nd");
|
|
8724
|
-
const
|
|
8725
|
-
const
|
|
8925
|
+
const nodeSpanExpr = emitSpanExpr(ctx, pos, endVar);
|
|
8926
|
+
const nodeSpanV = ctx.lineTracking ? v(ctx, "_nspan") : nodeSpanExpr;
|
|
8927
|
+
if (ctx.lineTracking) stmts.push(`${i}const ${nodeSpanV} = ${nodeSpanExpr}`);
|
|
8928
|
+
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})`;
|
|
8929
|
+
const hostBuildExpr = `_ctx._pmProfile?.phase === 'host' && _ctx._pmProfile.hostCalls++, _ctx.build(${JSON.stringify(def.type)}, ${chV}, ${fObj}, ${nodeSpanV}, ${rawV}, ${tlV}, ${stV})`;
|
|
8726
8930
|
const ndExpr = structural ? `_ctx.build !== undefined ? (${hostBuildExpr}) : (${buildExpr})` : cstOut ? hostBuildExpr : buildExpr;
|
|
8727
8931
|
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
8932
|
const unwrapExpr = `${chV}.length === 1 ? (${chV}[0] !== null && typeof ${chV}[0] === 'object' && ${chV}[0]._tag === 'leaf' ? ${chV}[0].value : ${chV}[0]) : (${ndExpr})`;
|
|
@@ -8732,7 +8936,7 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8732
8936
|
`${i}const ${ndV} = (${profileRecognizer} || ${profileCapture}) ? undefined : (${finalExpr})`,
|
|
8733
8937
|
`${i}if (!(${profileRecognizer})) {`,
|
|
8734
8938
|
`${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:
|
|
8939
|
+
`${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
8940
|
`${i}}`
|
|
8737
8941
|
);
|
|
8738
8942
|
return { stmts, valueVar: ndV, endVar };
|
|
@@ -8748,7 +8952,8 @@ function emitRuntimeFallback(parser2, ctx, pos) {
|
|
|
8748
8952
|
`${ind(ctx)}const ${rv} = _rp[${idx}].parse(input, ${pos}, _ctx)`,
|
|
8749
8953
|
...emitIfFail(ctx, `!${rv}.ok`, failStmt),
|
|
8750
8954
|
`${ind(ctx)}const ${vv} = ${rv}.value`,
|
|
8751
|
-
`${ind(ctx)}const ${ev} = ${rv}.span.end
|
|
8955
|
+
`${ind(ctx)}const ${ev} = ${rv}.span.end`,
|
|
8956
|
+
...parser2._meta.canMatchNewline ? emitLineTrack(ctx, pos, ev) : []
|
|
8752
8957
|
];
|
|
8753
8958
|
return { stmts, valueVar: vv, endVar: ev };
|
|
8754
8959
|
}
|
|
@@ -8814,7 +9019,8 @@ function emitRecover(def, ctx, pos) {
|
|
|
8814
9019
|
`${ind0} if (${sentOk}) break`,
|
|
8815
9020
|
`${ind0} ${scanV}++`,
|
|
8816
9021
|
`${ind0} }`,
|
|
8817
|
-
|
|
9022
|
+
...emitLineTrack(ctx, pos, scanV).map((s) => `${ind0} ${s.trim()}`),
|
|
9023
|
+
`${ind0} const ${errV} = { _tag: 'parseError', span: ${emitSpanExpr(ctx, pos, scanV)}, expected: ${JSON.stringify(deriveExpected(def.parser))} }`,
|
|
8818
9024
|
`${ind0} if (_ctx._errors) _ctx._errors.push(${errV})`,
|
|
8819
9025
|
`${ind0} ${valVar} = ${errV}`,
|
|
8820
9026
|
`${ind0} ${endVar} = ${scanV}`,
|
|
@@ -8830,7 +9036,7 @@ function emitExpect(def, ctx, pos) {
|
|
|
8830
9036
|
const stmts = [
|
|
8831
9037
|
...innerStmts,
|
|
8832
9038
|
`${ind0}if (!${okVar}) {`,
|
|
8833
|
-
`${ind0} const ${errV} = { _tag: 'parseError', span: {
|
|
9039
|
+
`${ind0} const ${errV} = { _tag: 'parseError', span: ${emitSpanExpr(ctx, pos, pos)}, expected: ${JSON.stringify(def.expected)} }`,
|
|
8834
9040
|
`${ind0} if (_ctx._errors) _ctx._errors.push(${errV})`,
|
|
8835
9041
|
// Embed the missing-token error as a `parseError` CST child, mirroring the
|
|
8836
9042
|
// interpreter (expect.ts) and the list-recovery emit sites — guarded on
|
|
@@ -8920,7 +9126,7 @@ function emitDispatch(p, ctx, pos) {
|
|
|
8920
9126
|
case "literal":
|
|
8921
9127
|
return emitLit(def, ctx, pos);
|
|
8922
9128
|
case "regex":
|
|
8923
|
-
return emitRegex(def, ctx, pos);
|
|
9129
|
+
return emitRegex(def, ctx, pos, p._meta.canMatchNewline);
|
|
8924
9130
|
case "keywords":
|
|
8925
9131
|
return emitKeywords(def, ctx, pos);
|
|
8926
9132
|
case "sequence":
|
|
@@ -9170,6 +9376,21 @@ function hasNodeDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9170
9376
|
return false;
|
|
9171
9377
|
}
|
|
9172
9378
|
}
|
|
9379
|
+
function hasLineTrackingDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
9380
|
+
if (seen.has(p)) return false;
|
|
9381
|
+
seen.add(p);
|
|
9382
|
+
const d = p._def;
|
|
9383
|
+
if (p._meta.grammarTrackLines) return true;
|
|
9384
|
+
if (d.tag === "grammar" && d.trackLines) return true;
|
|
9385
|
+
if (d.tag === "lazy") {
|
|
9386
|
+
try {
|
|
9387
|
+
return hasLineTrackingDef(d.thunk(), seen);
|
|
9388
|
+
} catch {
|
|
9389
|
+
return false;
|
|
9390
|
+
}
|
|
9391
|
+
}
|
|
9392
|
+
return childrenOf2(d).some((child) => hasLineTrackingDef(child, seen));
|
|
9393
|
+
}
|
|
9173
9394
|
function parserUsesRouted2(p, seen = /* @__PURE__ */ new Set()) {
|
|
9174
9395
|
if (seen.has(p)) return false;
|
|
9175
9396
|
seen.add(p);
|
|
@@ -9517,6 +9738,7 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9517
9738
|
const grammarTrivia = combinator._meta.grammarTrivia;
|
|
9518
9739
|
const grammarScanSkip = combinator._meta.grammarScanSkip;
|
|
9519
9740
|
const grammarHostMode = combinator._meta.grammarHostMode;
|
|
9741
|
+
const grammarTrackLines = combinator._meta.grammarTrackLines;
|
|
9520
9742
|
const ctx = {
|
|
9521
9743
|
vars: 0,
|
|
9522
9744
|
indent: 1,
|
|
@@ -9537,6 +9759,7 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9537
9759
|
capturing: hasNodeDef(combinator),
|
|
9538
9760
|
recovery: opts?.recovery ?? false,
|
|
9539
9761
|
hostMode: opts?.hostMode ?? grammarHostMode ?? "ast",
|
|
9762
|
+
lineTracking: opts?.trackLines === true || grammarTrackLines === true || hasLineTrackingDef(combinator),
|
|
9540
9763
|
...opts?.coverage ? { coverage: { plan: buildGrammarPlan(combinator), entry: combinator } } : {},
|
|
9541
9764
|
lazyUsage: analyzeLazyUsage(combinator),
|
|
9542
9765
|
...grammarTrivia ? { activeTrivia: grammarTrivia, triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {},
|
|
@@ -9560,9 +9783,13 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9560
9783
|
const namedPrelude = ctx.namedFnDecls.length > 0 ? [...namedFnPrelude(), ""] : [];
|
|
9561
9784
|
const emptyTlDecls = ctx.needsEmptyTl ? ["const _EMPTY_TL = Object.freeze([])"] : [];
|
|
9562
9785
|
const hostReadsDecls = ctx.needsHostReads ? [HOST_READS_DECL] : [];
|
|
9786
|
+
const lineTrackDecls = ctx.needsLineTrack ? [LINE_TRACK_DECL] : [];
|
|
9787
|
+
const lineSpanDecls = ctx.needsLineSpan ? [LINE_SPAN_DECL] : [];
|
|
9563
9788
|
const source = [
|
|
9564
9789
|
...emptyTlDecls,
|
|
9565
9790
|
...hostReadsDecls,
|
|
9791
|
+
...lineTrackDecls,
|
|
9792
|
+
...lineSpanDecls,
|
|
9566
9793
|
...ctx.regexDecls,
|
|
9567
9794
|
...ctx.expectedDecls,
|
|
9568
9795
|
"",
|
|
@@ -9575,6 +9802,8 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9575
9802
|
const fn = new Function("input", "_pos", "_rp", "_mf", "_build", "_ctx", [
|
|
9576
9803
|
...emptyTlDecls,
|
|
9577
9804
|
...hostReadsDecls,
|
|
9805
|
+
...lineTrackDecls,
|
|
9806
|
+
...lineSpanDecls,
|
|
9578
9807
|
...ctx.regexDecls,
|
|
9579
9808
|
...ctx.expectedDecls,
|
|
9580
9809
|
...namedPrelude,
|
|
@@ -9593,6 +9822,25 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9593
9822
|
trackLines: false,
|
|
9594
9823
|
...ctx.triviaKindLabels ? { triviaKindLabels: ctx.triviaKindLabels } : {}
|
|
9595
9824
|
};
|
|
9825
|
+
const annotateWithTrackedLines = (result, lineStarts) => {
|
|
9826
|
+
const index = normalizeLineIndex({ lineStarts });
|
|
9827
|
+
const annotated = { ...result, span: annotateSpan(result.span, index) };
|
|
9828
|
+
const errors = annotated.errors;
|
|
9829
|
+
if (errors) {
|
|
9830
|
+
;
|
|
9831
|
+
annotated.errors = errors.map((error) => ({
|
|
9832
|
+
...error,
|
|
9833
|
+
span: annotateSpan(error.span, index)
|
|
9834
|
+
}));
|
|
9835
|
+
}
|
|
9836
|
+
return annotated;
|
|
9837
|
+
};
|
|
9838
|
+
const trackedCtx = (base, input, pos) => {
|
|
9839
|
+
if (!ctx.lineTracking) return base;
|
|
9840
|
+
const lineIndex = { lineStarts: [0] };
|
|
9841
|
+
if (pos > 0) recordLineRange(lineIndex, input, 0, pos);
|
|
9842
|
+
return { ...base, trackLines: true, _lineStarts: lineIndex.lineStarts, _lineScannedTo: pos };
|
|
9843
|
+
};
|
|
9596
9844
|
const derivedSrcs = ctx.mapFnSrcs.length === ctx.mapFns.length && ctx.mapFnSrcs.every((s) => s !== null) ? ctx.mapFnSrcs : void 0;
|
|
9597
9845
|
const effectiveSources = mapFnSources ?? derivedSrcs;
|
|
9598
9846
|
const buildCovered = ctx.buildFns.length === 0 || ctx.buildSrcs.every((s) => s !== null);
|
|
@@ -9600,17 +9848,46 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9600
9848
|
const mfCovered = ctx.mapFns.length === 0 || effectiveSources !== void 0 && effectiveSources.length === ctx.mapFns.length;
|
|
9601
9849
|
const canInline = ctx.runtimeParsers.length === 0 && mfCovered && buildCovered;
|
|
9602
9850
|
const inlineExpression = canInline ? buildInlineExpression(ctx, r, effectiveSources, buildSources, coverageRootRuleId) : null;
|
|
9603
|
-
|
|
9851
|
+
const compiledMeta = {
|
|
9604
9852
|
source,
|
|
9605
9853
|
inlineExpression,
|
|
9606
9854
|
...ctx.coverage === void 0 ? {} : { coverageDefinitions: ctx.coverage.plan.definitions },
|
|
9607
|
-
...gatingReport === void 0 ? {} : { gating: gatingReport }
|
|
9855
|
+
...gatingReport === void 0 ? {} : { gating: gatingReport }
|
|
9856
|
+
};
|
|
9857
|
+
if (!ctx.lineTracking) {
|
|
9858
|
+
return {
|
|
9859
|
+
...compiledMeta,
|
|
9860
|
+
parse(input, pos = 0) {
|
|
9861
|
+
return fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, defaultCtx);
|
|
9862
|
+
},
|
|
9863
|
+
parseWithContext(input, parseCtx, pos = 0) {
|
|
9864
|
+
assertHostModeCompatible(ctx.hostMode ?? "ast", parseCtx.build, !!ctx.hostBranchElided);
|
|
9865
|
+
return fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, parseCtx);
|
|
9866
|
+
},
|
|
9867
|
+
// Note: collects expect() errors via _errors. Unlike interpreter
|
|
9868
|
+
// parse({recover:true}) it does NOT populate furthestFail — the compiled path
|
|
9869
|
+
// inlines failures for throughput and deliberately skips _probe bookkeeping.
|
|
9870
|
+
// Callers wanting a furthest-position diagnostic detect unconsumed input
|
|
9871
|
+
// (span.end < input.length) instead, which is mode-agnostic.
|
|
9872
|
+
parseWithErrors(input, pos = 0) {
|
|
9873
|
+
const errors = [];
|
|
9874
|
+
const result = fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, { ...defaultCtx, _errors: errors });
|
|
9875
|
+
return { ...result, errors };
|
|
9876
|
+
}
|
|
9877
|
+
};
|
|
9878
|
+
}
|
|
9879
|
+
return {
|
|
9880
|
+
...compiledMeta,
|
|
9608
9881
|
parse(input, pos = 0) {
|
|
9609
|
-
|
|
9882
|
+
const parseCtx = trackedCtx(defaultCtx, input, pos);
|
|
9883
|
+
const result = fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, parseCtx);
|
|
9884
|
+
return annotateWithTrackedLines(result, parseCtx._lineStarts);
|
|
9610
9885
|
},
|
|
9611
9886
|
parseWithContext(input, parseCtx, pos = 0) {
|
|
9612
9887
|
assertHostModeCompatible(ctx.hostMode ?? "ast", parseCtx.build, !!ctx.hostBranchElided);
|
|
9613
|
-
|
|
9888
|
+
const activeCtx = trackedCtx(parseCtx, input, pos);
|
|
9889
|
+
const result = fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, activeCtx);
|
|
9890
|
+
return activeCtx.trackLines ? annotateWithTrackedLines(result, activeCtx._lineStarts) : result;
|
|
9614
9891
|
},
|
|
9615
9892
|
// Note: collects expect() errors via _errors. Unlike interpreter
|
|
9616
9893
|
// parse({recover:true}) it does NOT populate furthestFail — the compiled path
|
|
@@ -9619,8 +9896,9 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9619
9896
|
// (span.end < input.length) instead, which is mode-agnostic.
|
|
9620
9897
|
parseWithErrors(input, pos = 0) {
|
|
9621
9898
|
const errors = [];
|
|
9622
|
-
const
|
|
9623
|
-
|
|
9899
|
+
const parseCtx = trackedCtx({ ...defaultCtx, _errors: errors }, input, pos);
|
|
9900
|
+
const result = { ...fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, parseCtx), errors };
|
|
9901
|
+
return annotateWithTrackedLines(result, parseCtx._lineStarts);
|
|
9624
9902
|
}
|
|
9625
9903
|
};
|
|
9626
9904
|
}
|
|
@@ -9645,6 +9923,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
9645
9923
|
const grammarTrivia = opts?.trivia ?? ruleMapArg.map(([, r]) => r._meta.grammarTrivia).find(Boolean);
|
|
9646
9924
|
const grammarScanSkip = opts?.scanSkip ?? ruleMapArg.map(([, r]) => r._meta.grammarScanSkip).find(Boolean);
|
|
9647
9925
|
const grammarHostMode = opts?.hostMode ?? ruleMapArg.map(([, r]) => r._meta.grammarHostMode).find(Boolean);
|
|
9926
|
+
const grammarTrackLines = opts?.trackLines === true || ruleMapArg.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
9648
9927
|
const ruleMap = ruleMapArg.filter(([, val]) => {
|
|
9649
9928
|
const d = val._def;
|
|
9650
9929
|
if (d.tag !== "lazy") return true;
|
|
@@ -9679,6 +9958,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
9679
9958
|
capturing: opts?.captureTerminals === true || ruleMap.some(([, rule]) => hasNodeDef(rule)),
|
|
9680
9959
|
recovery: opts?.recovery ?? false,
|
|
9681
9960
|
hostMode: grammarHostMode ?? "ast",
|
|
9961
|
+
lineTracking: grammarTrackLines,
|
|
9682
9962
|
...opts?.coverage ? { coverage: { plan: opts.coverage } } : {},
|
|
9683
9963
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
9684
9964
|
ns,
|
|
@@ -9775,6 +10055,10 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
9775
10055
|
perEntry.push({ key, rule, r: emitNamedFnCall(ctx, fn, "_pos") });
|
|
9776
10056
|
}
|
|
9777
10057
|
if (ctx.runtimeParsers.length !== 0) return null;
|
|
10058
|
+
if (ctx.lineTracking) {
|
|
10059
|
+
ctx.needsLineTrack = true;
|
|
10060
|
+
ctx.needsLineSpan = true;
|
|
10061
|
+
}
|
|
9778
10062
|
const mfSrcs = ctx.mapFns.length > 0 && ctx.mapFnSrcs.every((s) => s !== null) ? ctx.mapFnSrcs : null;
|
|
9779
10063
|
const buildSrcs = ctx.buildFns.length > 0 && ctx.buildSrcs.every((s) => s !== null) ? ctx.buildSrcs : null;
|
|
9780
10064
|
const ruleFns = /* @__PURE__ */ new Map();
|
|
@@ -9788,6 +10072,8 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
9788
10072
|
const mfDecl = ctx.mapFns.length === 0 ? "" : mfSrcs ? `const ${mfRef(ctx)} = [${mfSrcs.join(", ")}]` : `const ${mfRef(ctx)} = _env[${JSON.stringify(nsp(ctx) + "mf")}]`;
|
|
9789
10073
|
const buildDecl = ctx.buildFns.length === 0 ? "" : buildSrcs ? `const ${buildRef(ctx)} = [${buildSrcs.join(", ")}]` : `const ${buildRef(ctx)} = _env[${JSON.stringify(nsp(ctx) + "build")}]`;
|
|
9790
10074
|
const prelude = [
|
|
10075
|
+
ctx.needsLineTrack ? LINE_TRACK_DECL : "",
|
|
10076
|
+
ctx.needsLineSpan ? LINE_SPAN_DECL : "",
|
|
9791
10077
|
...ctx.regexDecls,
|
|
9792
10078
|
...ctx.expectedDecls,
|
|
9793
10079
|
mfDecl,
|
|
@@ -9796,11 +10082,18 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
9796
10082
|
].filter(Boolean);
|
|
9797
10083
|
const wrappers = /* @__PURE__ */ new Map();
|
|
9798
10084
|
for (const { key, rule, r } of perEntry) {
|
|
10085
|
+
const linePreamble = ctx.lineTracking ? [
|
|
10086
|
+
` if (_ctx._lineStarts === undefined) _ctx = { ..._ctx, trackLines: true, _lineStarts: [0], _lineScannedTo: 0 }`,
|
|
10087
|
+
` else _ctx.trackLines = true`,
|
|
10088
|
+
` if (_pos > (_ctx._lineScannedTo ?? 0)) _trackLines(_ctx, input, 0, _pos)`
|
|
10089
|
+
] : [];
|
|
10090
|
+
const resultSpan = ctx.lineTracking ? `_spanLines(_ctx, _pos, ${r.endVar})` : `{ start: _pos, end: ${r.endVar} }`;
|
|
9799
10091
|
wrappers.set(key, publicRuleWrapperSource(rule, [
|
|
9800
10092
|
`function(input, _pos, _ctx) {`,
|
|
10093
|
+
...linePreamble,
|
|
9801
10094
|
` let pos = _pos`,
|
|
9802
10095
|
...r.stmts,
|
|
9803
|
-
` return { ok: true, value: ${r.valueVar}, span:
|
|
10096
|
+
` return { ok: true, value: ${r.valueVar}, span: ${resultSpan} }`,
|
|
9804
10097
|
`}`
|
|
9805
10098
|
].join("\n"), ctx.triviaKindLabels));
|
|
9806
10099
|
}
|
|
@@ -9907,12 +10200,16 @@ function buildInlineExpression(ctx, r, mapFnSources, buildSources, coverageRootR
|
|
|
9907
10200
|
const buildDecl = buildSources?.length ? ` const _build = [${buildSources.join(", ")}]` : "";
|
|
9908
10201
|
const emptyTlDecl = ctx.needsEmptyTl ? ` const _EMPTY_TL = Object.freeze([])` : "";
|
|
9909
10202
|
const hostReadsDecl = ctx.needsHostReads ? ` ${HOST_READS_DECL}` : "";
|
|
9910
|
-
const
|
|
10203
|
+
const lineTrackDecl = ctx.needsLineTrack ? ` ${LINE_TRACK_DECL}` : "";
|
|
10204
|
+
const lineSpanDecl = ctx.needsLineSpan ? ` ${LINE_SPAN_DECL}` : "";
|
|
10205
|
+
const needsWrapper = ctx.regexDecls.length > 0 || ctx.expectedDecls.length > 0 || ctx.namedFnDecls.length > 0 || !!mfDecl || !!buildDecl || !!emptyTlDecl || !!hostReadsDecl || !!lineTrackDecl || !!lineSpanDecl;
|
|
9911
10206
|
if (!needsWrapper) return innerFn;
|
|
9912
10207
|
const namedPrelude = ctx.namedFnDecls.length > 0 ? namedFnPrelude() : [];
|
|
9913
10208
|
const hoistedDecls = [
|
|
9914
10209
|
emptyTlDecl,
|
|
9915
10210
|
hostReadsDecl,
|
|
10211
|
+
lineTrackDecl,
|
|
10212
|
+
lineSpanDecl,
|
|
9916
10213
|
...ctx.regexDecls.map((d) => ` ${d}`),
|
|
9917
10214
|
...ctx.expectedDecls.map((d) => ` ${d}`),
|
|
9918
10215
|
mfDecl,
|
|
@@ -10461,7 +10758,7 @@ function normalizeCstCollapse(collapse) {
|
|
|
10461
10758
|
return typeof collapse === "function" ? collapse : void 0;
|
|
10462
10759
|
}
|
|
10463
10760
|
function buildCstNode(type, children2, _fields, span, _rawChildren, _triviaLog, state) {
|
|
10464
|
-
return { _tag: "node", type, span: {
|
|
10761
|
+
return { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children2] };
|
|
10465
10762
|
}
|
|
10466
10763
|
function cstBuildHost(typeOrOptions, children2, _fields, span, rawChildren, triviaLog, state) {
|
|
10467
10764
|
if (typeof typeOrOptions === "string") {
|
|
@@ -10684,7 +10981,8 @@ function materializePiece(p, trivia2, captureTerminals = false, hostMode) {
|
|
|
10684
10981
|
const pieces = compileLinkable(evalRuleMapIR(p.ir), p.ns, {
|
|
10685
10982
|
...trivia2 ? { trivia: trivia2 } : {},
|
|
10686
10983
|
...captureTerminals ? { captureTerminals: true } : {},
|
|
10687
|
-
...hostMode ? { hostMode } : {}
|
|
10984
|
+
...hostMode ? { hostMode } : {},
|
|
10985
|
+
...p.trackLines ? { trackLines: true } : {}
|
|
10688
10986
|
});
|
|
10689
10987
|
if (!pieces) throw new Error(`compose: carried IR for ns "${p.ns}" could not be re-lowered`);
|
|
10690
10988
|
return pieces;
|
|
@@ -12185,6 +12483,7 @@ export {
|
|
|
12185
12483
|
analyzeGatingRules,
|
|
12186
12484
|
analyzeGrammarGating,
|
|
12187
12485
|
annotateSpan,
|
|
12486
|
+
annotateTreeSpans,
|
|
12188
12487
|
applyEdit,
|
|
12189
12488
|
attempt,
|
|
12190
12489
|
balanced,
|
|
@@ -12206,6 +12505,7 @@ export {
|
|
|
12206
12505
|
createGrammarCoverageCollector,
|
|
12207
12506
|
createGrammarInstrumentationContext,
|
|
12208
12507
|
createGrammarTraceSink,
|
|
12508
|
+
createLineIndex,
|
|
12209
12509
|
createVisitor,
|
|
12210
12510
|
cstBuildHost,
|
|
12211
12511
|
dispatch,
|
|
@@ -12239,6 +12539,7 @@ export {
|
|
|
12239
12539
|
matches,
|
|
12240
12540
|
noTrivia,
|
|
12241
12541
|
node,
|
|
12542
|
+
normalizeLineIndex,
|
|
12242
12543
|
not,
|
|
12243
12544
|
offsetToLineCol,
|
|
12244
12545
|
oneOrMore,
|
|
@@ -12249,6 +12550,7 @@ export {
|
|
|
12249
12550
|
parseDoc,
|
|
12250
12551
|
parser,
|
|
12251
12552
|
peek,
|
|
12553
|
+
recordLineRange,
|
|
12252
12554
|
ref,
|
|
12253
12555
|
regex,
|
|
12254
12556
|
relativize,
|