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/plugin/index.js
CHANGED
|
@@ -282,6 +282,65 @@ function failAt(ctx, expected, pos) {
|
|
|
282
282
|
return r;
|
|
283
283
|
}
|
|
284
284
|
|
|
285
|
+
// src/line-index.ts
|
|
286
|
+
function createLineIndex() {
|
|
287
|
+
return { lineStarts: [0] };
|
|
288
|
+
}
|
|
289
|
+
function recordLineRange(index, input, start, end) {
|
|
290
|
+
const lineStarts = index.lineStarts;
|
|
291
|
+
for (let i = start; i < end; i++) {
|
|
292
|
+
if (input.charCodeAt(i) === 10) lineStarts.push(i + 1);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
function recordLineRangeFromContext(ctx, input, _startHint, end) {
|
|
296
|
+
if (!ctx.trackLines) return;
|
|
297
|
+
const from = ctx._lineScannedTo ?? 0;
|
|
298
|
+
if (end <= from) return;
|
|
299
|
+
const index = ctx._lineIndex ?? (ctx._lineStarts ? { lineStarts: ctx._lineStarts } : void 0);
|
|
300
|
+
if (!index) return;
|
|
301
|
+
recordLineRange(index, input, from, end);
|
|
302
|
+
ctx._lineScannedTo = end;
|
|
303
|
+
}
|
|
304
|
+
function normalizeLineIndex(index) {
|
|
305
|
+
const starts = index.lineStarts;
|
|
306
|
+
starts.sort((a, b) => a - b);
|
|
307
|
+
let write = 0;
|
|
308
|
+
for (let read = 0; read < starts.length; read++) {
|
|
309
|
+
const value = starts[read];
|
|
310
|
+
if (write === 0 || starts[write - 1] !== value) starts[write++] = value;
|
|
311
|
+
}
|
|
312
|
+
starts.length = write;
|
|
313
|
+
if (starts.length === 0 || starts[0] !== 0) starts.unshift(0);
|
|
314
|
+
return index;
|
|
315
|
+
}
|
|
316
|
+
function offsetToLineCol(index, offset) {
|
|
317
|
+
const { lineStarts } = index;
|
|
318
|
+
let lo = 0;
|
|
319
|
+
let hi = lineStarts.length - 1;
|
|
320
|
+
while (lo < hi) {
|
|
321
|
+
const mid = lo + hi + 1 >> 1;
|
|
322
|
+
if (lineStarts[mid] <= offset) lo = mid;
|
|
323
|
+
else hi = mid - 1;
|
|
324
|
+
}
|
|
325
|
+
return { line: lo + 1, col: offset - lineStarts[lo] + 1 };
|
|
326
|
+
}
|
|
327
|
+
function annotateSpan(span, index) {
|
|
328
|
+
const s = offsetToLineCol(index, span.start);
|
|
329
|
+
const e = offsetToLineCol(index, span.end);
|
|
330
|
+
return {
|
|
331
|
+
...span,
|
|
332
|
+
startLine: s.line,
|
|
333
|
+
startColumn: s.col,
|
|
334
|
+
endLine: e.line,
|
|
335
|
+
endColumn: e.col
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
function annotateSpanFromLineContext(span, ctx) {
|
|
339
|
+
if (!ctx.trackLines) return span;
|
|
340
|
+
const index = ctx._lineIndex ?? (ctx._lineStarts ? { lineStarts: ctx._lineStarts } : void 0);
|
|
341
|
+
return index ? annotateSpan(span, index) : span;
|
|
342
|
+
}
|
|
343
|
+
|
|
285
344
|
// src/cst/capture-buffer.ts
|
|
286
345
|
var EMPTY = [];
|
|
287
346
|
var EMPTY_TL = [];
|
|
@@ -323,7 +382,12 @@ function endCstNodeCapture(ctx, saved) {
|
|
|
323
382
|
return materialized;
|
|
324
383
|
}
|
|
325
384
|
function pushCstLeaf(ctx, leaf2) {
|
|
326
|
-
|
|
385
|
+
if (!ctx.trackLines) {
|
|
386
|
+
pushCstChild(ctx, leaf2, leaf2);
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
const annotated = leaf2 && typeof leaf2 === "object" && leaf2.span ? { ...leaf2, span: annotateSpanFromLineContext(leaf2.span, ctx) } : leaf2;
|
|
390
|
+
pushCstChild(ctx, annotated, annotated);
|
|
327
391
|
}
|
|
328
392
|
function pushCstChild(ctx, built, rawEntry) {
|
|
329
393
|
const b = ctx._cstBuf;
|
|
@@ -457,6 +521,7 @@ function literal(value, opts = {}) {
|
|
|
457
521
|
canMatchNewline: value.includes("\n"),
|
|
458
522
|
isTrivia: false
|
|
459
523
|
};
|
|
524
|
+
const canMatchNewline = meta.canMatchNewline;
|
|
460
525
|
if (caseInsensitive) {
|
|
461
526
|
const upper = value.toUpperCase();
|
|
462
527
|
const lower = value.toLowerCase();
|
|
@@ -473,6 +538,7 @@ function literal(value, opts = {}) {
|
|
|
473
538
|
return function parse3(input, pos, ctx) {
|
|
474
539
|
if (input.charCodeAt(pos) === code) {
|
|
475
540
|
const span = { start: pos, end: pos + 1 };
|
|
541
|
+
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, span.end);
|
|
476
542
|
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
477
543
|
return { ok: true, value, span };
|
|
478
544
|
}
|
|
@@ -486,6 +552,7 @@ function literal(value, opts = {}) {
|
|
|
486
552
|
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
487
553
|
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
488
554
|
const span = { start: pos, end };
|
|
555
|
+
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, end);
|
|
489
556
|
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: matchedValue, span });
|
|
490
557
|
return { ok: true, value: matchedValue, span };
|
|
491
558
|
}
|
|
@@ -653,6 +720,7 @@ function regex(pattern, flags = "") {
|
|
|
653
720
|
if (scanEnd === null) return failAt(ctx, [`/${source}/`], pos);
|
|
654
721
|
const value = input.slice(pos, scanEnd);
|
|
655
722
|
const span2 = { start: pos, end: scanEnd };
|
|
723
|
+
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, scanEnd);
|
|
656
724
|
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span: span2 });
|
|
657
725
|
return { ok: true, value, span: span2 };
|
|
658
726
|
}
|
|
@@ -662,6 +730,7 @@ function regex(pattern, flags = "") {
|
|
|
662
730
|
return failAt(ctx, [`/${source}/`], pos);
|
|
663
731
|
}
|
|
664
732
|
const span = { start: pos, end: pos + m[0].length };
|
|
733
|
+
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, span.end);
|
|
665
734
|
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: m[0], span });
|
|
666
735
|
return { ok: true, value: m[0], span };
|
|
667
736
|
}
|
|
@@ -800,8 +869,8 @@ function parseRegex(src) {
|
|
|
800
869
|
}
|
|
801
870
|
if (src[k] !== "]") throw BAIL;
|
|
802
871
|
i = k + 1;
|
|
803
|
-
if (negated) return charNode(any(), true);
|
|
804
872
|
const ranges = parseClassRanges(body);
|
|
873
|
+
if (negated) return charNode(any(), !ranges || !rangesHaveNewline(ranges));
|
|
805
874
|
if (!ranges) return charNode(any(), true);
|
|
806
875
|
return charNode(rangesToSet(ranges), rangesHaveNewline(ranges));
|
|
807
876
|
};
|
|
@@ -897,7 +966,7 @@ function firstSet(n) {
|
|
|
897
966
|
}
|
|
898
967
|
}
|
|
899
968
|
}
|
|
900
|
-
function
|
|
969
|
+
function canConsumeNewline(n) {
|
|
901
970
|
switch (n.t) {
|
|
902
971
|
case "char":
|
|
903
972
|
return n.nl;
|
|
@@ -906,16 +975,11 @@ function firstCanBeNewline(n) {
|
|
|
906
975
|
case "empty":
|
|
907
976
|
return false;
|
|
908
977
|
case "rep":
|
|
909
|
-
return
|
|
978
|
+
return canConsumeNewline(n.node);
|
|
910
979
|
case "alt":
|
|
911
|
-
return n.arms.some(
|
|
912
|
-
case "seq":
|
|
913
|
-
|
|
914
|
-
if (firstCanBeNewline(part)) return true;
|
|
915
|
-
if (!nullable(part)) break;
|
|
916
|
-
}
|
|
917
|
-
return false;
|
|
918
|
-
}
|
|
980
|
+
return n.arms.some(canConsumeNewline);
|
|
981
|
+
case "seq":
|
|
982
|
+
return n.parts.some(canConsumeNewline);
|
|
919
983
|
}
|
|
920
984
|
}
|
|
921
985
|
function firstSetFromRegex(source) {
|
|
@@ -925,8 +989,8 @@ function firstSetFromRegex(source) {
|
|
|
925
989
|
} catch {
|
|
926
990
|
return { firstSet: any(), canMatchNewline: true };
|
|
927
991
|
}
|
|
928
|
-
if (nullable(ast)) return { firstSet: any(), canMatchNewline:
|
|
929
|
-
return { firstSet: firstSet(ast), canMatchNewline:
|
|
992
|
+
if (nullable(ast)) return { firstSet: any(), canMatchNewline: canConsumeNewline(ast) };
|
|
993
|
+
return { firstSet: firstSet(ast), canMatchNewline: canConsumeNewline(ast) };
|
|
930
994
|
}
|
|
931
995
|
|
|
932
996
|
// src/combinators/case-fold.ts
|
|
@@ -1083,7 +1147,9 @@ function firstSetSentinel(fs2) {
|
|
|
1083
1147
|
function recoverScan(input, from, ctx, sync, expected) {
|
|
1084
1148
|
let scanPos = from;
|
|
1085
1149
|
while (scanPos < input.length && !probeAt(sync, input, scanPos, ctx)) scanPos++;
|
|
1086
|
-
const
|
|
1150
|
+
const span = { start: from, end: scanPos };
|
|
1151
|
+
if (ctx.trackLines) recordLineRangeFromContext(ctx, input, from, scanPos);
|
|
1152
|
+
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1087
1153
|
ctx._errors?.push(error);
|
|
1088
1154
|
return { error, end: scanPos };
|
|
1089
1155
|
}
|
|
@@ -1185,7 +1251,8 @@ function expect(combinator, label2) {
|
|
|
1185
1251
|
parse(input, pos, ctx) {
|
|
1186
1252
|
const result = combinator.parse(input, pos, ctx);
|
|
1187
1253
|
if (result.ok) return result;
|
|
1188
|
-
const
|
|
1254
|
+
const span = { start: pos, end: pos };
|
|
1255
|
+
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1189
1256
|
ctx._errors?.push(error);
|
|
1190
1257
|
if (ctx._tolerant) captureError(ctx, error);
|
|
1191
1258
|
return { ok: true, value: error, span: { start: pos, end: pos } };
|
|
@@ -1630,6 +1697,18 @@ function rollbackTrivia(ctx, mark) {
|
|
|
1630
1697
|
rollbackCstCapture(ctx, { raw: mark.raw, tlog: mark.tlog, leaves: mark.leaves, fields: mark.fields, errors: mark.errors });
|
|
1631
1698
|
if (ctx._triviaLog && ctx._triviaLog.length !== mark.log) ctx._triviaLog.length = mark.log;
|
|
1632
1699
|
}
|
|
1700
|
+
function parseTriviaNoCapture(triviaP, input, cur, ctx) {
|
|
1701
|
+
const probeCtx = {
|
|
1702
|
+
trackLines: ctx.trackLines,
|
|
1703
|
+
state: ctx.state,
|
|
1704
|
+
...ctx._lineIndex ? { _lineIndex: ctx._lineIndex } : {},
|
|
1705
|
+
...ctx._lineStarts ? { _lineStarts: ctx._lineStarts } : {},
|
|
1706
|
+
...ctx._lineScannedTo !== void 0 ? { _lineScannedTo: ctx._lineScannedTo } : {}
|
|
1707
|
+
};
|
|
1708
|
+
const result = triviaP.parse(input, cur, probeCtx);
|
|
1709
|
+
ctx._lineScannedTo = probeCtx._lineScannedTo;
|
|
1710
|
+
return result;
|
|
1711
|
+
}
|
|
1633
1712
|
function saveLookaheadMark(ctx) {
|
|
1634
1713
|
return { ...saveTriviaMark(ctx), probeBest: ctx._probe ? ctx._probe.best : null };
|
|
1635
1714
|
}
|
|
@@ -1652,13 +1731,29 @@ function scanWithLabels(input, cur, ctx) {
|
|
|
1652
1731
|
function advanceTrivia(input, cur, ctx) {
|
|
1653
1732
|
const triviaP = ctx.trivia;
|
|
1654
1733
|
if (!triviaP) return cur;
|
|
1734
|
+
if (!ctx.trackLines) {
|
|
1735
|
+
const fast2 = fastTriviaScanner(triviaP);
|
|
1736
|
+
if (fast2) return fast2(input, cur);
|
|
1737
|
+
if (ctx.triviaKindLabels) {
|
|
1738
|
+
const scan = scanWithLabels(input, cur, ctx);
|
|
1739
|
+
return scan.end;
|
|
1740
|
+
}
|
|
1741
|
+
const tr2 = triviaP.parse(input, cur, { trackLines: ctx.trackLines, state: ctx.state });
|
|
1742
|
+
return tr2.ok && tr2.span.end > cur ? tr2.span.end : cur;
|
|
1743
|
+
}
|
|
1744
|
+
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1655
1745
|
const fast = fastTriviaScanner(triviaP);
|
|
1656
|
-
if (fast)
|
|
1746
|
+
if (fast) {
|
|
1747
|
+
const end = fast(input, cur);
|
|
1748
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1749
|
+
return end;
|
|
1750
|
+
}
|
|
1657
1751
|
if (ctx.triviaKindLabels) {
|
|
1658
1752
|
const scan = scanWithLabels(input, cur, ctx);
|
|
1753
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
|
|
1659
1754
|
return scan.end;
|
|
1660
1755
|
}
|
|
1661
|
-
const tr = triviaP
|
|
1756
|
+
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1662
1757
|
return tr.ok && tr.span.end > cur ? tr.span.end : cur;
|
|
1663
1758
|
}
|
|
1664
1759
|
function scanTrivia(input, cur, ctx) {
|
|
@@ -1666,18 +1761,46 @@ function scanTrivia(input, cur, ctx) {
|
|
|
1666
1761
|
if (!triviaP) return { end: cur, commit: NOOP_COMMIT };
|
|
1667
1762
|
const log = ctx._triviaLog;
|
|
1668
1763
|
const captureTl = ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0);
|
|
1764
|
+
if (!ctx.trackLines) {
|
|
1765
|
+
const fast2 = !ctx.triviaKindLabels ? fastTriviaScanner(triviaP) : null;
|
|
1766
|
+
if (fast2 && log === void 0 && !captureTl) {
|
|
1767
|
+
return { end: fast2(input, cur), commit: NOOP_COMMIT };
|
|
1768
|
+
}
|
|
1769
|
+
if (ctx.triviaKindLabels && (log !== void 0 || captureTl)) {
|
|
1770
|
+
return scanWithLabels(input, cur, ctx);
|
|
1771
|
+
}
|
|
1772
|
+
if (log !== void 0 || captureTl) {
|
|
1773
|
+
const tr3 = triviaP.parse(input, cur, {
|
|
1774
|
+
trackLines: log !== void 0 ? false : ctx.trackLines,
|
|
1775
|
+
state: ctx.state
|
|
1776
|
+
});
|
|
1777
|
+
if (!tr3.ok || tr3.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1778
|
+
const end = tr3.span.end;
|
|
1779
|
+
return {
|
|
1780
|
+
end,
|
|
1781
|
+
commit: () => {
|
|
1782
|
+
pushTriviaLogEntry(ctx, cur, end);
|
|
1783
|
+
if (captureTl) pushCstTriviaEntry(ctx, cur, end);
|
|
1784
|
+
}
|
|
1785
|
+
};
|
|
1786
|
+
}
|
|
1787
|
+
const tr2 = triviaP.parse(input, cur, { trackLines: ctx.trackLines, state: ctx.state });
|
|
1788
|
+
return { end: tr2.ok ? tr2.span.end : cur, commit: NOOP_COMMIT };
|
|
1789
|
+
}
|
|
1790
|
+
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1669
1791
|
const fast = !ctx.triviaKindLabels ? fastTriviaScanner(triviaP) : null;
|
|
1670
1792
|
if (fast && log === void 0 && !captureTl) {
|
|
1671
|
-
|
|
1793
|
+
const end = fast(input, cur);
|
|
1794
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1795
|
+
return { end, commit: NOOP_COMMIT };
|
|
1672
1796
|
}
|
|
1673
1797
|
if (ctx.triviaKindLabels && (log !== void 0 || captureTl)) {
|
|
1674
|
-
|
|
1798
|
+
const scan = scanWithLabels(input, cur, ctx);
|
|
1799
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
|
|
1800
|
+
return scan;
|
|
1675
1801
|
}
|
|
1676
1802
|
if (log !== void 0 || captureTl) {
|
|
1677
|
-
const tr2 = triviaP
|
|
1678
|
-
trackLines: log !== void 0 ? false : ctx.trackLines,
|
|
1679
|
-
state: ctx.state
|
|
1680
|
-
});
|
|
1803
|
+
const tr2 = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1681
1804
|
if (!tr2.ok || tr2.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1682
1805
|
const end = tr2.span.end;
|
|
1683
1806
|
return {
|
|
@@ -1688,7 +1811,7 @@ function scanTrivia(input, cur, ctx) {
|
|
|
1688
1811
|
}
|
|
1689
1812
|
};
|
|
1690
1813
|
}
|
|
1691
|
-
const tr = triviaP
|
|
1814
|
+
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1692
1815
|
return { end: tr.ok ? tr.span.end : cur, commit: NOOP_COMMIT };
|
|
1693
1816
|
}
|
|
1694
1817
|
function consumeTrivia(input, cur, ctx) {
|
|
@@ -2619,6 +2742,74 @@ function markUnusedValues(root) {
|
|
|
2619
2742
|
visit(resolveRoot(root), true);
|
|
2620
2743
|
}
|
|
2621
2744
|
|
|
2745
|
+
// src/combinators/grammar.ts
|
|
2746
|
+
function annotateResultLines(result, index) {
|
|
2747
|
+
const annotated = { ...result, span: annotateSpan(result.span, index) };
|
|
2748
|
+
const errors = annotated.errors;
|
|
2749
|
+
if (errors) {
|
|
2750
|
+
;
|
|
2751
|
+
annotated.errors = errors.map((error) => ({
|
|
2752
|
+
...error,
|
|
2753
|
+
span: annotateSpan(error.span, index)
|
|
2754
|
+
}));
|
|
2755
|
+
}
|
|
2756
|
+
return annotated;
|
|
2757
|
+
}
|
|
2758
|
+
function createParseLineContext(input, pos) {
|
|
2759
|
+
const lineIndex = createLineIndex();
|
|
2760
|
+
if (pos > 0) recordLineRange(lineIndex, input, 0, pos);
|
|
2761
|
+
return { lineIndex, lineScannedTo: pos };
|
|
2762
|
+
}
|
|
2763
|
+
function parser(opts, root) {
|
|
2764
|
+
const clearTrivia = opts.trivia === null;
|
|
2765
|
+
return {
|
|
2766
|
+
_tag: "grammar",
|
|
2767
|
+
_meta: root._meta,
|
|
2768
|
+
_def: {
|
|
2769
|
+
tag: "grammar",
|
|
2770
|
+
parser: root,
|
|
2771
|
+
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
2772
|
+
clearTrivia,
|
|
2773
|
+
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
2774
|
+
trackLines: opts.trackLines ?? false
|
|
2775
|
+
},
|
|
2776
|
+
parse(input, pos, _ctx) {
|
|
2777
|
+
const trackLines = opts.trackLines ?? _ctx?.trackLines ?? false;
|
|
2778
|
+
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
2779
|
+
const lineIndex = trackLines ? _ctx?._lineIndex ?? (_ctx?._lineStarts ? { lineStarts: _ctx._lineStarts } : lineContext.lineIndex) : void 0;
|
|
2780
|
+
const ctx = {
|
|
2781
|
+
..._ctx,
|
|
2782
|
+
trackLines,
|
|
2783
|
+
...lineIndex ? { _lineIndex: lineIndex } : {},
|
|
2784
|
+
...lineContext ? { _lineScannedTo: lineContext.lineScannedTo } : {},
|
|
2785
|
+
// trivia: null clears (contiguous terms); a Combinator sets; undefined inherits.
|
|
2786
|
+
...clearTrivia ? {
|
|
2787
|
+
trivia: void 0,
|
|
2788
|
+
triviaKindLabels: void 0
|
|
2789
|
+
} : opts.trivia != null ? {
|
|
2790
|
+
trivia: opts.trivia,
|
|
2791
|
+
...opts.trivia._meta.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {}
|
|
2792
|
+
} : {},
|
|
2793
|
+
...opts.captureTrivia || _ctx?.captureTrivia ? { captureTrivia: true } : {},
|
|
2794
|
+
// Kind-filter for per-node capture. Resolve against this scope's trivia
|
|
2795
|
+
// labels — this parser's own trivia if it declares one, else the INHERITED
|
|
2796
|
+
// labels (`_ctx.triviaKindLabels`), so captureTriviaKinds still applies when
|
|
2797
|
+
// trivia is inherited rather than re-declared here. No labels → undefined
|
|
2798
|
+
// (capture all).
|
|
2799
|
+
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {}
|
|
2800
|
+
};
|
|
2801
|
+
const result = root.parse(input, pos ?? 0, ctx);
|
|
2802
|
+
if (trackLines && _ctx && ctx._lineScannedTo !== void 0) {
|
|
2803
|
+
_ctx._lineScannedTo = Math.max(_ctx._lineScannedTo ?? 0, ctx._lineScannedTo);
|
|
2804
|
+
}
|
|
2805
|
+
return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
2806
|
+
}
|
|
2807
|
+
};
|
|
2808
|
+
}
|
|
2809
|
+
function noTrivia(root) {
|
|
2810
|
+
return parser({ trivia: null }, root);
|
|
2811
|
+
}
|
|
2812
|
+
|
|
2622
2813
|
// src/combinators/parser.ts
|
|
2623
2814
|
var RULE_ORDER = "__parsemanRuleOrder";
|
|
2624
2815
|
function tagRule(r, key) {
|
|
@@ -2694,6 +2885,21 @@ function rules(a, b) {
|
|
|
2694
2885
|
if (rule && !rule._meta.isTrivia) rule._meta.grammarHostMode = "cst";
|
|
2695
2886
|
}
|
|
2696
2887
|
}
|
|
2888
|
+
if (options?.trackLines === true) {
|
|
2889
|
+
for (const key of Object.keys(definitions)) {
|
|
2890
|
+
const rule = cache[key];
|
|
2891
|
+
if (rule && !rule._meta.isTrivia) rule._meta.grammarTrackLines = true;
|
|
2892
|
+
}
|
|
2893
|
+
for (const key of Object.keys(definitions)) {
|
|
2894
|
+
const rule = cache[key];
|
|
2895
|
+
if (rule && !rule._meta.isTrivia && rule._def.tag !== "grammar") {
|
|
2896
|
+
const wrapped = parser({ trackLines: true }, rule);
|
|
2897
|
+
tagRule(wrapped, key);
|
|
2898
|
+
wrapped._meta.grammarTrackLines = true;
|
|
2899
|
+
cache[key] = wrapped;
|
|
2900
|
+
}
|
|
2901
|
+
}
|
|
2902
|
+
}
|
|
2697
2903
|
for (const key of Object.keys(definitions)) {
|
|
2698
2904
|
markUnusedValues(cache[key]);
|
|
2699
2905
|
}
|
|
@@ -3072,13 +3278,14 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
3072
3278
|
const st = clonesState && ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
3073
3279
|
const nodeType = def.type ?? missingInferredType();
|
|
3074
3280
|
const cstOutput = cstOutputHost(ctx.build);
|
|
3281
|
+
const span = ctx.trackLines ? annotateSpanFromLineContext(r.span, ctx) : r.span;
|
|
3075
3282
|
const hostState = clonesState ? st : ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
3076
|
-
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,
|
|
3077
|
-
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
|
|
3283
|
+
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 };
|
|
3284
|
+
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 };
|
|
3078
3285
|
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
3079
3286
|
pushCstChild(ctx, built, rawEntry);
|
|
3080
3287
|
}
|
|
3081
|
-
return { ok: true, value: built, span
|
|
3288
|
+
return { ok: true, value: built, span };
|
|
3082
3289
|
}
|
|
3083
3290
|
};
|
|
3084
3291
|
}
|
|
@@ -3149,85 +3356,6 @@ function field(name, combinator) {
|
|
|
3149
3356
|
};
|
|
3150
3357
|
}
|
|
3151
3358
|
|
|
3152
|
-
// src/compiler/line-index.ts
|
|
3153
|
-
function buildLineIndex(input) {
|
|
3154
|
-
const lineStarts = [0];
|
|
3155
|
-
for (let i = 0; i < input.length; i++) {
|
|
3156
|
-
if (input.charCodeAt(i) === 10) lineStarts.push(i + 1);
|
|
3157
|
-
}
|
|
3158
|
-
return { lineStarts };
|
|
3159
|
-
}
|
|
3160
|
-
function offsetToLineCol(index, offset) {
|
|
3161
|
-
const { lineStarts } = index;
|
|
3162
|
-
let lo = 0;
|
|
3163
|
-
let hi = lineStarts.length - 1;
|
|
3164
|
-
while (lo < hi) {
|
|
3165
|
-
const mid = lo + hi + 1 >> 1;
|
|
3166
|
-
if (lineStarts[mid] <= offset) lo = mid;
|
|
3167
|
-
else hi = mid - 1;
|
|
3168
|
-
}
|
|
3169
|
-
return { line: lo + 1, col: offset - lineStarts[lo] + 1 };
|
|
3170
|
-
}
|
|
3171
|
-
function annotateSpan(span, index) {
|
|
3172
|
-
const s = offsetToLineCol(index, span.start);
|
|
3173
|
-
const e = offsetToLineCol(index, span.end);
|
|
3174
|
-
return {
|
|
3175
|
-
...span,
|
|
3176
|
-
startLine: s.line,
|
|
3177
|
-
startColumn: s.col,
|
|
3178
|
-
endLine: e.line,
|
|
3179
|
-
endColumn: e.col
|
|
3180
|
-
};
|
|
3181
|
-
}
|
|
3182
|
-
|
|
3183
|
-
// src/combinators/grammar.ts
|
|
3184
|
-
function parser(opts, root) {
|
|
3185
|
-
const clearTrivia = opts.trivia === null;
|
|
3186
|
-
return {
|
|
3187
|
-
_tag: "grammar",
|
|
3188
|
-
_meta: root._meta,
|
|
3189
|
-
_def: {
|
|
3190
|
-
tag: "grammar",
|
|
3191
|
-
parser: root,
|
|
3192
|
-
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
3193
|
-
clearTrivia,
|
|
3194
|
-
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
3195
|
-
trackLines: opts.trackLines ?? false
|
|
3196
|
-
},
|
|
3197
|
-
parse(input, pos, _ctx) {
|
|
3198
|
-
const trackLines = opts.trackLines ?? _ctx?.trackLines ?? false;
|
|
3199
|
-
const ctx = {
|
|
3200
|
-
..._ctx,
|
|
3201
|
-
trackLines,
|
|
3202
|
-
// trivia: null clears (contiguous terms); a Combinator sets; undefined inherits.
|
|
3203
|
-
...clearTrivia ? {
|
|
3204
|
-
trivia: void 0,
|
|
3205
|
-
triviaKindLabels: void 0
|
|
3206
|
-
} : opts.trivia != null ? {
|
|
3207
|
-
trivia: opts.trivia,
|
|
3208
|
-
...opts.trivia._meta.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {}
|
|
3209
|
-
} : {},
|
|
3210
|
-
...opts.captureTrivia || _ctx?.captureTrivia ? { captureTrivia: true } : {},
|
|
3211
|
-
// Kind-filter for per-node capture. Resolve against this scope's trivia
|
|
3212
|
-
// labels — this parser's own trivia if it declares one, else the INHERITED
|
|
3213
|
-
// labels (`_ctx.triviaKindLabels`), so captureTriviaKinds still applies when
|
|
3214
|
-
// trivia is inherited rather than re-declared here. No labels → undefined
|
|
3215
|
-
// (capture all).
|
|
3216
|
-
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {}
|
|
3217
|
-
};
|
|
3218
|
-
const result = root.parse(input, pos ?? 0, ctx);
|
|
3219
|
-
if (trackLines) {
|
|
3220
|
-
const idx = buildLineIndex(input);
|
|
3221
|
-
return { ...result, span: annotateSpan(result.span, idx) };
|
|
3222
|
-
}
|
|
3223
|
-
return result;
|
|
3224
|
-
}
|
|
3225
|
-
};
|
|
3226
|
-
}
|
|
3227
|
-
function noTrivia(root) {
|
|
3228
|
-
return parser({ trivia: null }, root);
|
|
3229
|
-
}
|
|
3230
|
-
|
|
3231
3359
|
// src/combinators/token.ts
|
|
3232
3360
|
function token(root) {
|
|
3233
3361
|
const meta = {
|
|
@@ -3324,7 +3452,7 @@ function leaf(root, fn) {
|
|
|
3324
3452
|
}
|
|
3325
3453
|
|
|
3326
3454
|
// src/version.ts
|
|
3327
|
-
var PARSEMAN_VERSION = "0.
|
|
3455
|
+
var PARSEMAN_VERSION = "0.42.1";
|
|
3328
3456
|
|
|
3329
3457
|
// src/cst/host-mode.ts
|
|
3330
3458
|
var FUSED_HOST_MODE = /* @__PURE__ */ Symbol.for("parseman.fusedHostMode");
|
|
@@ -5008,7 +5136,7 @@ function scanTo(sentinel, { skip: skip2, raw = false, orEOF = false } = {}) {
|
|
|
5008
5136
|
let cur = pos;
|
|
5009
5137
|
const skip3 = resolveScanSkip(explicitSkip, raw, ctx);
|
|
5010
5138
|
const probeCtx = {
|
|
5011
|
-
trackLines:
|
|
5139
|
+
trackLines: false,
|
|
5012
5140
|
state: ctx.state,
|
|
5013
5141
|
...ctx._errors !== void 0 ? { _errors: ctx._errors } : {}
|
|
5014
5142
|
};
|
|
@@ -5021,6 +5149,7 @@ function scanTo(sentinel, { skip: skip2, raw = false, orEOF = false } = {}) {
|
|
|
5021
5149
|
while (cur < input.length) {
|
|
5022
5150
|
const s = sentinel.parse(input, cur, probeCtx);
|
|
5023
5151
|
if (s.ok) {
|
|
5152
|
+
if (ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, cur);
|
|
5024
5153
|
emit2(cur);
|
|
5025
5154
|
return { ok: true, value: input.slice(pos, cur), span: { start: pos, end: cur } };
|
|
5026
5155
|
}
|
|
@@ -5036,6 +5165,7 @@ function scanTo(sentinel, { skip: skip2, raw = false, orEOF = false } = {}) {
|
|
|
5036
5165
|
if (!advanced) cur++;
|
|
5037
5166
|
}
|
|
5038
5167
|
if (orEOF) {
|
|
5168
|
+
if (ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, cur);
|
|
5039
5169
|
emit2(cur);
|
|
5040
5170
|
return { ok: true, value: input.slice(pos, cur), span: { start: pos, end: cur } };
|
|
5041
5171
|
}
|
|
@@ -6474,8 +6604,8 @@ function analyzeMkInlineBuild(def) {
|
|
|
6474
6604
|
if (looseMkBuildRe(def.type).test(src)) return def.type;
|
|
6475
6605
|
return null;
|
|
6476
6606
|
}
|
|
6477
|
-
function emitInlineMkNodeExpr(type, chV, rawV,
|
|
6478
|
-
return `{ _tag: 'node', type: ${JSON.stringify(type)}, span:
|
|
6607
|
+
function emitInlineMkNodeExpr(type, chV, rawV, spanExpr, tlV) {
|
|
6608
|
+
return `{ _tag: 'node', type: ${JSON.stringify(type)}, span: ${spanExpr}, children: ${chV}, rawCount: ${rawV}.length, localTriviaLen: ${tlV}.length }`;
|
|
6479
6609
|
}
|
|
6480
6610
|
|
|
6481
6611
|
// src/compiler/inline-callback.ts
|
|
@@ -6657,6 +6787,8 @@ function leadingFirstSetRecipe(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
6657
6787
|
}
|
|
6658
6788
|
}
|
|
6659
6789
|
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 }";
|
|
6790
|
+
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 }";
|
|
6791
|
+
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] } }";
|
|
6660
6792
|
var _loweringSink = null;
|
|
6661
6793
|
function beginLoweringCapture() {
|
|
6662
6794
|
_loweringSink = /* @__PURE__ */ new Set();
|
|
@@ -6688,13 +6820,16 @@ function reindentStmts(stmts, targetLevels) {
|
|
|
6688
6820
|
const targetPrefix = " ".repeat(targetLevels);
|
|
6689
6821
|
return stmts.map((s) => s.trim().length === 0 ? "" : targetPrefix + s.slice(minLeading));
|
|
6690
6822
|
}
|
|
6691
|
-
function failReturn(expected, posExpr) {
|
|
6823
|
+
function failReturn(ctx, expected, posExpr) {
|
|
6824
|
+
if (ctx.lineTracking) return `return { ok: false, expected: [${expected}], span: ${emitSpanExpr(ctx, posExpr, posExpr)} }`;
|
|
6692
6825
|
return `return { ok: false, expected: [${expected}], span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
6693
6826
|
}
|
|
6694
|
-
function failReturnArr(expectedArr, posExpr) {
|
|
6827
|
+
function failReturnArr(ctx, expectedArr, posExpr) {
|
|
6828
|
+
if (ctx.lineTracking) return `return { ok: false, expected: ${expectedArr}, span: ${emitSpanExpr(ctx, posExpr, posExpr)} }`;
|
|
6695
6829
|
return `return { ok: false, expected: ${expectedArr}, span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
6696
6830
|
}
|
|
6697
|
-
function committedReturnArr(expectedArr, posExpr) {
|
|
6831
|
+
function committedReturnArr(ctx, expectedArr, posExpr) {
|
|
6832
|
+
if (ctx.lineTracking) return `return { ok: false, expected: [...${expectedArr}], span: ${emitSpanExpr(ctx, posExpr, posExpr)}, committed: true }`;
|
|
6698
6833
|
return `return { ok: false, expected: [...${expectedArr}], span: { start: ${posExpr}, end: ${posExpr} }, committed: true }`;
|
|
6699
6834
|
}
|
|
6700
6835
|
function hoistExpected(ctx, constArrSource) {
|
|
@@ -6719,7 +6854,7 @@ function failBody(ctx, expected, posExpr) {
|
|
|
6719
6854
|
if (!ctx.recordFail) return probe ? `{ ${probe}${trace}break ${ctx.failLabel} }` : trace ? `{ ${trace}break ${ctx.failLabel} }` : `break ${ctx.failLabel}`;
|
|
6720
6855
|
return `{ ${probe}_ctx._fe = ${posExpr}; _ctx._fx = ${hoistExpected(ctx, `[${expected}]`)}; ${trace}break ${ctx.failLabel} }`;
|
|
6721
6856
|
}
|
|
6722
|
-
return probe + trace + failReturn(expected, posExpr);
|
|
6857
|
+
return probe + trace + failReturn(ctx, expected, posExpr);
|
|
6723
6858
|
}
|
|
6724
6859
|
function failArrBody(ctx, expectedArr, posExpr, constant = true) {
|
|
6725
6860
|
const probe = probeUpdate(ctx, expectedArr, posExpr, constant);
|
|
@@ -6729,18 +6864,19 @@ function failArrBody(ctx, expectedArr, posExpr, constant = true) {
|
|
|
6729
6864
|
const fx = constant ? hoistExpected(ctx, expectedArr) : expectedArr;
|
|
6730
6865
|
return `{ ${probe}_ctx._fe = ${posExpr}; _ctx._fx = ${fx}; ${trace}break ${ctx.failLabel} }`;
|
|
6731
6866
|
}
|
|
6732
|
-
if (!constant) return `${probe}${trace}return { ok: false, expected: [...${expectedArr}], span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
6733
|
-
return probe + trace + failReturnArr(expectedArr, posExpr);
|
|
6867
|
+
if (!constant) return `${probe}${trace}return { ok: false, expected: [...${expectedArr}], span: ${ctx.lineTracking ? emitSpanExpr(ctx, posExpr, posExpr) : `{ start: ${posExpr}, end: ${posExpr} }`} }`;
|
|
6868
|
+
return probe + trace + failReturnArr(ctx, expectedArr, posExpr);
|
|
6734
6869
|
}
|
|
6735
|
-
function resultFromRecorded(feExpr = "_ctx._fe", fxExpr = "_ctx._fx") {
|
|
6736
|
-
|
|
6870
|
+
function resultFromRecorded(ctx, feExpr = "_ctx._fe", fxExpr = "_ctx._fx") {
|
|
6871
|
+
const spanExpr = ctx.lineTracking ? emitSpanExpr(ctx, feExpr, feExpr) : `{ start: ${feExpr}, end: ${feExpr} }`;
|
|
6872
|
+
return `return { ok: false, expected: [...${fxExpr}], span: ${spanExpr}, ...(_ctx._fc ? { committed: true } : {}) }`;
|
|
6737
6873
|
}
|
|
6738
6874
|
function committedFailBody(ctx, expectedArr = "_ctx._fx", posExpr = "_ctx._fe") {
|
|
6739
6875
|
if (ctx.failLabel) {
|
|
6740
6876
|
if (!ctx.recordFail) return `{ _ctx._fc = true; break ${ctx.failLabel} }`;
|
|
6741
6877
|
return `{ _ctx._fc = true; _ctx._fe = ${posExpr}; _ctx._fx = ${expectedArr}; break ${ctx.failLabel} }`;
|
|
6742
6878
|
}
|
|
6743
|
-
return committedReturnArr(expectedArr, posExpr);
|
|
6879
|
+
return committedReturnArr(ctx, expectedArr, posExpr);
|
|
6744
6880
|
}
|
|
6745
6881
|
function propagateFailBody(ctx, srcCtx = "_ctx") {
|
|
6746
6882
|
if (srcCtx !== "_ctx") {
|
|
@@ -6748,10 +6884,10 @@ function propagateFailBody(ctx, srcCtx = "_ctx") {
|
|
|
6748
6884
|
if (!ctx.recordFail) return `break ${ctx.failLabel}`;
|
|
6749
6885
|
return `{ _ctx._fe = ${srcCtx}._fe; _ctx._fx = ${srcCtx}._fx; _ctx._fc = ${srcCtx}._fc; break ${ctx.failLabel} }`;
|
|
6750
6886
|
}
|
|
6751
|
-
return `{ _ctx._fe = ${srcCtx}._fe; _ctx._fx = ${srcCtx}._fx; _ctx._fc = ${srcCtx}._fc; ${resultFromRecorded()} }`;
|
|
6887
|
+
return `{ _ctx._fe = ${srcCtx}._fe; _ctx._fx = ${srcCtx}._fx; _ctx._fc = ${srcCtx}._fc; ${resultFromRecorded(ctx)} }`;
|
|
6752
6888
|
}
|
|
6753
6889
|
if (ctx.failLabel) return `break ${ctx.failLabel}`;
|
|
6754
|
-
return resultFromRecorded();
|
|
6890
|
+
return resultFromRecorded(ctx);
|
|
6755
6891
|
}
|
|
6756
6892
|
function emitIfFail(ctx, cond, body) {
|
|
6757
6893
|
return [
|
|
@@ -6805,14 +6941,46 @@ function emitLeafCapture(ctx, valExpr, startExpr, endExpr) {
|
|
|
6805
6941
|
if (ctx.capAsTrivia) return [];
|
|
6806
6942
|
const i = ind(ctx);
|
|
6807
6943
|
const lf = v(ctx, "_lf");
|
|
6944
|
+
const spanExpr = emitSpanExpr(ctx, startExpr, endExpr);
|
|
6808
6945
|
return [
|
|
6809
6946
|
`${i}if (_ctx._cstLeaves || _ctx._cstRawChildren) {`,
|
|
6810
|
-
`${i} const ${lf} = { _tag: 'leaf', value: ${valExpr}, span:
|
|
6947
|
+
`${i} const ${lf} = { _tag: 'leaf', value: ${valExpr}, span: ${spanExpr} }`,
|
|
6811
6948
|
`${i} if (_ctx._cstLeaves) _ctx._cstLeaves.push(${lf})`,
|
|
6812
6949
|
`${i} if (_ctx._cstRawChildren) _ctx._cstRawChildren.push(${lf})`,
|
|
6813
6950
|
`${i}}`
|
|
6814
6951
|
];
|
|
6815
6952
|
}
|
|
6953
|
+
function emitSpanExpr(ctx, startExpr, endExpr) {
|
|
6954
|
+
if (!ctx.lineTracking) return `{ start: ${startExpr}, end: ${endExpr} }`;
|
|
6955
|
+
ctx.needsLineSpan = true;
|
|
6956
|
+
return `_spanLines(_ctx, ${startExpr}, ${endExpr})`;
|
|
6957
|
+
}
|
|
6958
|
+
function emitLineTrack(ctx, startExpr, endExpr) {
|
|
6959
|
+
if (!ctx.lineTracking) return [];
|
|
6960
|
+
ctx.needsLineTrack = true;
|
|
6961
|
+
return [`${ind(ctx)}_trackLines(_ctx, input, ${startExpr}, ${endExpr})`];
|
|
6962
|
+
}
|
|
6963
|
+
function emitLiteralLineTrack(ctx, startExpr, value) {
|
|
6964
|
+
if (!ctx.lineTracking) return [];
|
|
6965
|
+
const lineDeltas = [];
|
|
6966
|
+
for (let i = 0; i < value.length; i++) {
|
|
6967
|
+
if (value.charCodeAt(i) === 10) lineDeltas.push(i + 1);
|
|
6968
|
+
}
|
|
6969
|
+
if (lineDeltas.length === 0) return [];
|
|
6970
|
+
const fromV = v(ctx, "_ltFrom");
|
|
6971
|
+
const endExpr = value.length === 0 ? startExpr : `${startExpr} + ${value.length}`;
|
|
6972
|
+
return [
|
|
6973
|
+
`${ind(ctx)}const ${fromV} = _ctx._lineScannedTo ?? 0`,
|
|
6974
|
+
`${ind(ctx)}if (${endExpr} > ${fromV}) {`,
|
|
6975
|
+
`${ind(ctx)} for (let i = ${fromV}; i < ${startExpr}; i++) if (input.charCodeAt(i) === 10) _ctx._lineStarts.push(i + 1)`,
|
|
6976
|
+
...lineDeltas.map((delta) => {
|
|
6977
|
+
const lineStart = `${startExpr} + ${delta}`;
|
|
6978
|
+
return `${ind(ctx)} if (${lineStart} > ${fromV}) _ctx._lineStarts.push(${lineStart})`;
|
|
6979
|
+
}),
|
|
6980
|
+
`${ind(ctx)} _ctx._lineScannedTo = ${endExpr}`,
|
|
6981
|
+
`${ind(ctx)}}`
|
|
6982
|
+
];
|
|
6983
|
+
}
|
|
6816
6984
|
function ensureRegexDecl(ctx, source, flags) {
|
|
6817
6985
|
const f = "y" + flags.replace(/[gy]/g, "");
|
|
6818
6986
|
const key = `${source}/${f}`;
|
|
@@ -7197,6 +7365,7 @@ function emitLit(def, ctx, pos) {
|
|
|
7197
7365
|
);
|
|
7198
7366
|
}
|
|
7199
7367
|
const endVar = len === 0 ? pos : `${pos} + ${len}`;
|
|
7368
|
+
stmts.push(...emitLiteralLineTrack(ctx, pos, value));
|
|
7200
7369
|
stmts.push(...emitLeafCapture(ctx, vv, pos, endVar));
|
|
7201
7370
|
return { stmts, valueVar: vv, endVar };
|
|
7202
7371
|
}
|
|
@@ -7276,7 +7445,7 @@ function emitKeywords(def, ctx, pos) {
|
|
|
7276
7445
|
stmts.push(...emitLeafCapture(ctx, vv, pos, endVar));
|
|
7277
7446
|
return { stmts, valueVar: vv, endVar };
|
|
7278
7447
|
}
|
|
7279
|
-
function emitRegex(def, ctx, pos) {
|
|
7448
|
+
function emitRegex(def, ctx, pos, canMatchNewline = true) {
|
|
7280
7449
|
const expectedStr = JSON.stringify(`/${def.source}/`);
|
|
7281
7450
|
const shape = scanShapeFromRegex(def.source, def.flags);
|
|
7282
7451
|
if (shape) {
|
|
@@ -7289,7 +7458,11 @@ function emitRegex(def, ctx, pos) {
|
|
|
7289
7458
|
fresh: (prefix) => v(ctx, prefix)
|
|
7290
7459
|
});
|
|
7291
7460
|
if (scanned) {
|
|
7292
|
-
const stmts2 = [
|
|
7461
|
+
const stmts2 = [
|
|
7462
|
+
...scanned.stmts,
|
|
7463
|
+
...canMatchNewline ? emitLineTrack(ctx, pos, scanned.endVar) : [],
|
|
7464
|
+
...emitLeafCapture(ctx, vv2, pos, scanned.endVar)
|
|
7465
|
+
];
|
|
7293
7466
|
return { stmts: stmts2, valueVar: vv2, endVar: scanned.endVar };
|
|
7294
7467
|
}
|
|
7295
7468
|
}
|
|
@@ -7311,6 +7484,7 @@ function emitRegex(def, ctx, pos) {
|
|
|
7311
7484
|
`${ind(ctx)}const ${vv} = ${mv}[0]`
|
|
7312
7485
|
];
|
|
7313
7486
|
const endVar = `${pos} + ${vv}.length`;
|
|
7487
|
+
if (canMatchNewline) stmts.push(...emitLineTrack(ctx, pos, endVar));
|
|
7314
7488
|
stmts.push(...emitLeafCapture(ctx, vv, pos, endVar));
|
|
7315
7489
|
return { stmts, valueVar: vv, endVar };
|
|
7316
7490
|
}
|
|
@@ -7348,7 +7522,8 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7348
7522
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
7349
7523
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
7350
7524
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
7351
|
-
`${ind(ctx)}const ${scanEndV} = ${capFn}(input, ${curV}, _ctx, 1)
|
|
7525
|
+
`${ind(ctx)}const ${scanEndV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
7526
|
+
...emitLineTrack(ctx, curV, scanEndV)
|
|
7352
7527
|
);
|
|
7353
7528
|
const r2 = emit(def.parsers[i], ctx, scanEndV);
|
|
7354
7529
|
stmts.push(...r2.stmts);
|
|
@@ -7366,7 +7541,8 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7366
7541
|
const capArg = ctx.noHoist ? "0" : "_ctx._triviaLog !== undefined ? 2 : 0";
|
|
7367
7542
|
stmts.push(
|
|
7368
7543
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
7369
|
-
`${ind(ctx)}const ${scanEndV} = ${trivFn}(input, ${curV}, _ctx, ${capArg})
|
|
7544
|
+
`${ind(ctx)}const ${scanEndV} = ${trivFn}(input, ${curV}, _ctx, ${capArg})`,
|
|
7545
|
+
...emitLineTrack(ctx, curV, scanEndV)
|
|
7370
7546
|
);
|
|
7371
7547
|
const r2 = emit(def.parsers[i], ctx, scanEndV);
|
|
7372
7548
|
stmts.push(...r2.stmts);
|
|
@@ -8066,14 +8242,15 @@ function emitMany(def, ctx, pos) {
|
|
|
8066
8242
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8067
8243
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8068
8244
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8069
|
-
`${ind(ctx)}const ${npV} = ${capFn}(input, ${curV}, _ctx, 1)
|
|
8245
|
+
`${ind(ctx)}const ${npV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
8246
|
+
...emitLineTrack(ctx, curV, npV)
|
|
8070
8247
|
);
|
|
8071
8248
|
itemPos = npV;
|
|
8072
8249
|
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}; `;
|
|
8073
8250
|
} else {
|
|
8074
8251
|
const trivFn = ensureTriviaFn(ctx);
|
|
8075
8252
|
const npV = v(ctx, "_np");
|
|
8076
|
-
stmts.push(`${ind(ctx)}const ${npV} = ${trivFn}(input, ${curV}, _ctx)
|
|
8253
|
+
stmts.push(`${ind(ctx)}const ${npV} = ${trivFn}(input, ${curV}, _ctx)`, ...emitLineTrack(ctx, curV, npV));
|
|
8077
8254
|
itemPos = npV;
|
|
8078
8255
|
}
|
|
8079
8256
|
}
|
|
@@ -8143,7 +8320,7 @@ function emitAttempt(p, def, ctx, pos) {
|
|
|
8143
8320
|
if (!ctx.recovery && !ctx.coverage && needsFirstSetGuard(def.parser)) {
|
|
8144
8321
|
const gcV = v(ctx, "_agc");
|
|
8145
8322
|
const gExp = armStaticExpected(ctx, def.parser);
|
|
8146
|
-
const gFail = ctx.failLabel ? `{ _ctx._fe = ${pos};${ctx.recordFail ? ` _ctx._fx = ${gExp};` : ""} break ${ctx.failLabel} }` : `{ _ctx._fe = ${pos}; ${failReturnArr(gExp, pos)} }`;
|
|
8323
|
+
const gFail = ctx.failLabel ? `{ _ctx._fe = ${pos};${ctx.recordFail ? ` _ctx._fx = ${gExp};` : ""} break ${ctx.failLabel} }` : `{ _ctx._fe = ${pos}; ${failReturnArr(ctx, gExp, pos)} }`;
|
|
8147
8324
|
preGuard.push(
|
|
8148
8325
|
`${ind(ctx)}const ${gcV} = ${pos} < input.length ? (input.codePointAt(${pos}) ?? -1) : -1`,
|
|
8149
8326
|
`${ind(ctx)}if (!(${firstSetCond(gcV, def.parser._meta.firstSet)})) ${gFail}`
|
|
@@ -8250,7 +8427,8 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8250
8427
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8251
8428
|
`${ind(ctx)}const ${markLv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
8252
8429
|
`${ind(ctx)}const ${markFld} = _ctx._fields ? _ctx._fields.length : 0`,
|
|
8253
|
-
`${ind(ctx)}const ${spV} = ${capFn}(input, ${curV}, _ctx, 1)
|
|
8430
|
+
`${ind(ctx)}const ${spV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
8431
|
+
...emitLineTrack(ctx, curV, spV)
|
|
8254
8432
|
);
|
|
8255
8433
|
sepAtPos = spV;
|
|
8256
8434
|
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}; `;
|
|
@@ -8260,7 +8438,7 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8260
8438
|
const post = postSepMarks();
|
|
8261
8439
|
stmts.push(...post.decl);
|
|
8262
8440
|
const npV = v(ctx, "_np");
|
|
8263
|
-
stmts.push(`${ind(ctx)}const ${npV} = ${capFn}(input, ${sepEnd}, _ctx, 1)
|
|
8441
|
+
stmts.push(`${ind(ctx)}const ${npV} = ${capFn}(input, ${sepEnd}, _ctx, 1)`, ...emitLineTrack(ctx, sepEnd, npV));
|
|
8264
8442
|
const next = emitFallible(def.parser, ctx, npV, true);
|
|
8265
8443
|
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = next;
|
|
8266
8444
|
stmts.push(
|
|
@@ -8272,13 +8450,13 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8272
8450
|
} else {
|
|
8273
8451
|
const trivFn = ensureTriviaFn(ctx);
|
|
8274
8452
|
const spV = v(ctx, "_sp");
|
|
8275
|
-
stmts.push(`${ind(ctx)}const ${spV} = ${trivFn}(input, ${curV}, _ctx)
|
|
8453
|
+
stmts.push(`${ind(ctx)}const ${spV} = ${trivFn}(input, ${curV}, _ctx)`, ...emitLineTrack(ctx, curV, spV));
|
|
8276
8454
|
sepAtPos = spV;
|
|
8277
8455
|
const sep2 = emitFallible(def.separator, ctx, sepAtPos, true);
|
|
8278
8456
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = sep2;
|
|
8279
8457
|
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${sep2.mayCommit ? `if (_ctx._fc) ${committedFailBody(ctx)}; ` : ""}break }`);
|
|
8280
8458
|
const npV = v(ctx, "_np");
|
|
8281
|
-
stmts.push(`${ind(ctx)}const ${npV} = ${trivFn}(input, ${sepEnd}, _ctx)
|
|
8459
|
+
stmts.push(`${ind(ctx)}const ${npV} = ${trivFn}(input, ${sepEnd}, _ctx)`, ...emitLineTrack(ctx, sepEnd, npV));
|
|
8282
8460
|
const next = emitFallible(def.parser, ctx, npV, true);
|
|
8283
8461
|
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = next;
|
|
8284
8462
|
stmts.push(
|
|
@@ -8365,6 +8543,7 @@ function emitScanTo(def, ctx, pos) {
|
|
|
8365
8543
|
}
|
|
8366
8544
|
const valV = v(ctx);
|
|
8367
8545
|
stmts.push(`${ind(ctx)}const ${valV} = input.slice(${pos}, ${curV})`);
|
|
8546
|
+
stmts.push(...emitLineTrack(ctx, pos, curV));
|
|
8368
8547
|
if (ctx.capturing) {
|
|
8369
8548
|
const cap = reindentStmts(emitLeafCapture(ctx, valV, pos, curV), ctx.indent + 1);
|
|
8370
8549
|
stmts.push(`${ind(ctx)}if (${curV} > ${pos}) {`, ...cap, `${ind(ctx)}}`);
|
|
@@ -8508,7 +8687,7 @@ function tokenNullableRegex(def) {
|
|
|
8508
8687
|
}
|
|
8509
8688
|
function emitToken(def, ctx, pos) {
|
|
8510
8689
|
const lowered = tokenNullableRegex(def);
|
|
8511
|
-
if (lowered) return emitRegex(lowered, ctx, pos);
|
|
8690
|
+
if (lowered) return emitRegex(lowered, ctx, pos, def.parser._meta.canMatchNewline);
|
|
8512
8691
|
const savedTrivia = ctx.activeTrivia;
|
|
8513
8692
|
const savedKindLabels = ctx.triviaKindLabels;
|
|
8514
8693
|
ctx.activeTrivia = void 0;
|
|
@@ -8640,7 +8819,7 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8640
8819
|
if (!ctx.recovery && !ctx.coverage && (capturesChildren || structural) && needsFirstSetGuard(def.parser)) {
|
|
8641
8820
|
const gcV = v(ctx, "_ngc");
|
|
8642
8821
|
const gExp = armStaticExpected(ctx, def.parser);
|
|
8643
|
-
const gFail = ctx.failLabel ? ctx.recordFail ? `{ _ctx._fe = ${pos}; _ctx._fx = ${gExp}; break ${ctx.failLabel} }` : `break ${ctx.failLabel}` : failReturnArr(gExp, pos);
|
|
8822
|
+
const gFail = ctx.failLabel ? ctx.recordFail ? `{ _ctx._fe = ${pos}; _ctx._fx = ${gExp}; break ${ctx.failLabel} }` : `break ${ctx.failLabel}` : failReturnArr(ctx, gExp, pos);
|
|
8644
8823
|
preGuard.push(
|
|
8645
8824
|
`${i}const ${gcV} = ${pos} < input.length ? (input.codePointAt(${pos}) ?? -1) : -1`,
|
|
8646
8825
|
`${i}if (!(${firstSetCond(gcV, def.parser._meta.firstSet)})) ${gFail}`
|
|
@@ -8658,7 +8837,7 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8658
8837
|
stmts.push(...innerStmts);
|
|
8659
8838
|
if (def.trailingTrivia === true && ctx.activeTrivia) {
|
|
8660
8839
|
const triviaFn = ensureTriviaFn(ctx);
|
|
8661
|
-
stmts.push(`${i}const ${endVar} = ${okVar} ? ${triviaFn}(input, ${innerEndVar}, _ctx, 1) : ${innerEndVar}
|
|
8840
|
+
stmts.push(`${i}const ${endVar} = ${okVar} ? ${triviaFn}(input, ${innerEndVar}, _ctx, 1) : ${innerEndVar}`, ...emitLineTrack(ctx, innerEndVar, endVar));
|
|
8662
8841
|
}
|
|
8663
8842
|
if (sf && fArr) {
|
|
8664
8843
|
stmts.push(`${i}const ${fArr} = _ctx._fields`);
|
|
@@ -8698,8 +8877,11 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8698
8877
|
);
|
|
8699
8878
|
}
|
|
8700
8879
|
const ndV = v(ctx, "_nd");
|
|
8701
|
-
const
|
|
8702
|
-
const
|
|
8880
|
+
const nodeSpanExpr = emitSpanExpr(ctx, pos, endVar);
|
|
8881
|
+
const nodeSpanV = ctx.lineTracking ? v(ctx, "_nspan") : nodeSpanExpr;
|
|
8882
|
+
if (ctx.lineTracking) stmts.push(`${i}const ${nodeSpanV} = ${nodeSpanExpr}`);
|
|
8883
|
+
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})`;
|
|
8884
|
+
const hostBuildExpr = `_ctx._pmProfile?.phase === 'host' && _ctx._pmProfile.hostCalls++, _ctx.build(${JSON.stringify(def.type)}, ${chV}, ${fObj}, ${nodeSpanV}, ${rawV}, ${tlV}, ${stV})`;
|
|
8703
8885
|
const ndExpr = structural ? `_ctx.build !== undefined ? (${hostBuildExpr}) : (${buildExpr})` : cstOut ? hostBuildExpr : buildExpr;
|
|
8704
8886
|
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;
|
|
8705
8887
|
const unwrapExpr = `${chV}.length === 1 ? (${chV}[0] !== null && typeof ${chV}[0] === 'object' && ${chV}[0]._tag === 'leaf' ? ${chV}[0].value : ${chV}[0]) : (${ndExpr})`;
|
|
@@ -8709,7 +8891,7 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8709
8891
|
`${i}const ${ndV} = (${profileRecognizer} || ${profileCapture}) ? undefined : (${finalExpr})`,
|
|
8710
8892
|
`${i}if (!(${profileRecognizer})) {`,
|
|
8711
8893
|
`${i} if (${sc}) ${sc}.push(${ndV})`,
|
|
8712
|
-
`${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:
|
|
8894
|
+
`${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} })`,
|
|
8713
8895
|
`${i}}`
|
|
8714
8896
|
);
|
|
8715
8897
|
return { stmts, valueVar: ndV, endVar };
|
|
@@ -8725,7 +8907,8 @@ function emitRuntimeFallback(parser2, ctx, pos) {
|
|
|
8725
8907
|
`${ind(ctx)}const ${rv} = _rp[${idx}].parse(input, ${pos}, _ctx)`,
|
|
8726
8908
|
...emitIfFail(ctx, `!${rv}.ok`, failStmt),
|
|
8727
8909
|
`${ind(ctx)}const ${vv} = ${rv}.value`,
|
|
8728
|
-
`${ind(ctx)}const ${ev} = ${rv}.span.end
|
|
8910
|
+
`${ind(ctx)}const ${ev} = ${rv}.span.end`,
|
|
8911
|
+
...parser2._meta.canMatchNewline ? emitLineTrack(ctx, pos, ev) : []
|
|
8729
8912
|
];
|
|
8730
8913
|
return { stmts, valueVar: vv, endVar: ev };
|
|
8731
8914
|
}
|
|
@@ -8791,7 +8974,8 @@ function emitRecover(def, ctx, pos) {
|
|
|
8791
8974
|
`${ind0} if (${sentOk}) break`,
|
|
8792
8975
|
`${ind0} ${scanV}++`,
|
|
8793
8976
|
`${ind0} }`,
|
|
8794
|
-
|
|
8977
|
+
...emitLineTrack(ctx, pos, scanV).map((s) => `${ind0} ${s.trim()}`),
|
|
8978
|
+
`${ind0} const ${errV} = { _tag: 'parseError', span: ${emitSpanExpr(ctx, pos, scanV)}, expected: ${JSON.stringify(deriveExpected(def.parser))} }`,
|
|
8795
8979
|
`${ind0} if (_ctx._errors) _ctx._errors.push(${errV})`,
|
|
8796
8980
|
`${ind0} ${valVar} = ${errV}`,
|
|
8797
8981
|
`${ind0} ${endVar} = ${scanV}`,
|
|
@@ -8807,7 +8991,7 @@ function emitExpect(def, ctx, pos) {
|
|
|
8807
8991
|
const stmts = [
|
|
8808
8992
|
...innerStmts,
|
|
8809
8993
|
`${ind0}if (!${okVar}) {`,
|
|
8810
|
-
`${ind0} const ${errV} = { _tag: 'parseError', span: {
|
|
8994
|
+
`${ind0} const ${errV} = { _tag: 'parseError', span: ${emitSpanExpr(ctx, pos, pos)}, expected: ${JSON.stringify(def.expected)} }`,
|
|
8811
8995
|
`${ind0} if (_ctx._errors) _ctx._errors.push(${errV})`,
|
|
8812
8996
|
// Embed the missing-token error as a `parseError` CST child, mirroring the
|
|
8813
8997
|
// interpreter (expect.ts) and the list-recovery emit sites — guarded on
|
|
@@ -8897,7 +9081,7 @@ function emitDispatch(p, ctx, pos) {
|
|
|
8897
9081
|
case "literal":
|
|
8898
9082
|
return emitLit(def, ctx, pos);
|
|
8899
9083
|
case "regex":
|
|
8900
|
-
return emitRegex(def, ctx, pos);
|
|
9084
|
+
return emitRegex(def, ctx, pos, p._meta.canMatchNewline);
|
|
8901
9085
|
case "keywords":
|
|
8902
9086
|
return emitKeywords(def, ctx, pos);
|
|
8903
9087
|
case "sequence":
|
|
@@ -9147,6 +9331,21 @@ function hasNodeDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9147
9331
|
return false;
|
|
9148
9332
|
}
|
|
9149
9333
|
}
|
|
9334
|
+
function hasLineTrackingDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
9335
|
+
if (seen.has(p)) return false;
|
|
9336
|
+
seen.add(p);
|
|
9337
|
+
const d = p._def;
|
|
9338
|
+
if (p._meta.grammarTrackLines) return true;
|
|
9339
|
+
if (d.tag === "grammar" && d.trackLines) return true;
|
|
9340
|
+
if (d.tag === "lazy") {
|
|
9341
|
+
try {
|
|
9342
|
+
return hasLineTrackingDef(d.thunk(), seen);
|
|
9343
|
+
} catch {
|
|
9344
|
+
return false;
|
|
9345
|
+
}
|
|
9346
|
+
}
|
|
9347
|
+
return childrenOf2(d).some((child) => hasLineTrackingDef(child, seen));
|
|
9348
|
+
}
|
|
9150
9349
|
function parserUsesRouted2(p, seen = /* @__PURE__ */ new Set()) {
|
|
9151
9350
|
if (seen.has(p)) return false;
|
|
9152
9351
|
seen.add(p);
|
|
@@ -9494,6 +9693,7 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9494
9693
|
const grammarTrivia = combinator._meta.grammarTrivia;
|
|
9495
9694
|
const grammarScanSkip = combinator._meta.grammarScanSkip;
|
|
9496
9695
|
const grammarHostMode = combinator._meta.grammarHostMode;
|
|
9696
|
+
const grammarTrackLines = combinator._meta.grammarTrackLines;
|
|
9497
9697
|
const ctx = {
|
|
9498
9698
|
vars: 0,
|
|
9499
9699
|
indent: 1,
|
|
@@ -9514,6 +9714,7 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9514
9714
|
capturing: hasNodeDef(combinator),
|
|
9515
9715
|
recovery: opts?.recovery ?? false,
|
|
9516
9716
|
hostMode: opts?.hostMode ?? grammarHostMode ?? "ast",
|
|
9717
|
+
lineTracking: opts?.trackLines === true || grammarTrackLines === true || hasLineTrackingDef(combinator),
|
|
9517
9718
|
...opts?.coverage ? { coverage: { plan: buildGrammarPlan(combinator), entry: combinator } } : {},
|
|
9518
9719
|
lazyUsage: analyzeLazyUsage(combinator),
|
|
9519
9720
|
...grammarTrivia ? { activeTrivia: grammarTrivia, triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {},
|
|
@@ -9537,9 +9738,13 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9537
9738
|
const namedPrelude = ctx.namedFnDecls.length > 0 ? [...namedFnPrelude(), ""] : [];
|
|
9538
9739
|
const emptyTlDecls = ctx.needsEmptyTl ? ["const _EMPTY_TL = Object.freeze([])"] : [];
|
|
9539
9740
|
const hostReadsDecls = ctx.needsHostReads ? [HOST_READS_DECL] : [];
|
|
9741
|
+
const lineTrackDecls = ctx.needsLineTrack ? [LINE_TRACK_DECL] : [];
|
|
9742
|
+
const lineSpanDecls = ctx.needsLineSpan ? [LINE_SPAN_DECL] : [];
|
|
9540
9743
|
const source = [
|
|
9541
9744
|
...emptyTlDecls,
|
|
9542
9745
|
...hostReadsDecls,
|
|
9746
|
+
...lineTrackDecls,
|
|
9747
|
+
...lineSpanDecls,
|
|
9543
9748
|
...ctx.regexDecls,
|
|
9544
9749
|
...ctx.expectedDecls,
|
|
9545
9750
|
"",
|
|
@@ -9552,6 +9757,8 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9552
9757
|
const fn = new Function("input", "_pos", "_rp", "_mf", "_build", "_ctx", [
|
|
9553
9758
|
...emptyTlDecls,
|
|
9554
9759
|
...hostReadsDecls,
|
|
9760
|
+
...lineTrackDecls,
|
|
9761
|
+
...lineSpanDecls,
|
|
9555
9762
|
...ctx.regexDecls,
|
|
9556
9763
|
...ctx.expectedDecls,
|
|
9557
9764
|
...namedPrelude,
|
|
@@ -9570,6 +9777,25 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9570
9777
|
trackLines: false,
|
|
9571
9778
|
...ctx.triviaKindLabels ? { triviaKindLabels: ctx.triviaKindLabels } : {}
|
|
9572
9779
|
};
|
|
9780
|
+
const annotateWithTrackedLines = (result, lineStarts) => {
|
|
9781
|
+
const index = normalizeLineIndex({ lineStarts });
|
|
9782
|
+
const annotated = { ...result, span: annotateSpan(result.span, index) };
|
|
9783
|
+
const errors = annotated.errors;
|
|
9784
|
+
if (errors) {
|
|
9785
|
+
;
|
|
9786
|
+
annotated.errors = errors.map((error) => ({
|
|
9787
|
+
...error,
|
|
9788
|
+
span: annotateSpan(error.span, index)
|
|
9789
|
+
}));
|
|
9790
|
+
}
|
|
9791
|
+
return annotated;
|
|
9792
|
+
};
|
|
9793
|
+
const trackedCtx = (base, input, pos) => {
|
|
9794
|
+
if (!ctx.lineTracking) return base;
|
|
9795
|
+
const lineIndex = { lineStarts: [0] };
|
|
9796
|
+
if (pos > 0) recordLineRange(lineIndex, input, 0, pos);
|
|
9797
|
+
return { ...base, trackLines: true, _lineStarts: lineIndex.lineStarts, _lineScannedTo: pos };
|
|
9798
|
+
};
|
|
9573
9799
|
const derivedSrcs = ctx.mapFnSrcs.length === ctx.mapFns.length && ctx.mapFnSrcs.every((s) => s !== null) ? ctx.mapFnSrcs : void 0;
|
|
9574
9800
|
const effectiveSources = mapFnSources ?? derivedSrcs;
|
|
9575
9801
|
const buildCovered = ctx.buildFns.length === 0 || ctx.buildSrcs.every((s) => s !== null);
|
|
@@ -9577,17 +9803,46 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9577
9803
|
const mfCovered = ctx.mapFns.length === 0 || effectiveSources !== void 0 && effectiveSources.length === ctx.mapFns.length;
|
|
9578
9804
|
const canInline = ctx.runtimeParsers.length === 0 && mfCovered && buildCovered;
|
|
9579
9805
|
const inlineExpression = canInline ? buildInlineExpression(ctx, r, effectiveSources, buildSources, coverageRootRuleId) : null;
|
|
9580
|
-
|
|
9806
|
+
const compiledMeta = {
|
|
9581
9807
|
source,
|
|
9582
9808
|
inlineExpression,
|
|
9583
9809
|
...ctx.coverage === void 0 ? {} : { coverageDefinitions: ctx.coverage.plan.definitions },
|
|
9584
|
-
...gatingReport === void 0 ? {} : { gating: gatingReport }
|
|
9810
|
+
...gatingReport === void 0 ? {} : { gating: gatingReport }
|
|
9811
|
+
};
|
|
9812
|
+
if (!ctx.lineTracking) {
|
|
9813
|
+
return {
|
|
9814
|
+
...compiledMeta,
|
|
9815
|
+
parse(input, pos = 0) {
|
|
9816
|
+
return fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, defaultCtx);
|
|
9817
|
+
},
|
|
9818
|
+
parseWithContext(input, parseCtx, pos = 0) {
|
|
9819
|
+
assertHostModeCompatible(ctx.hostMode ?? "ast", parseCtx.build, !!ctx.hostBranchElided);
|
|
9820
|
+
return fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, parseCtx);
|
|
9821
|
+
},
|
|
9822
|
+
// Note: collects expect() errors via _errors. Unlike interpreter
|
|
9823
|
+
// parse({recover:true}) it does NOT populate furthestFail — the compiled path
|
|
9824
|
+
// inlines failures for throughput and deliberately skips _probe bookkeeping.
|
|
9825
|
+
// Callers wanting a furthest-position diagnostic detect unconsumed input
|
|
9826
|
+
// (span.end < input.length) instead, which is mode-agnostic.
|
|
9827
|
+
parseWithErrors(input, pos = 0) {
|
|
9828
|
+
const errors = [];
|
|
9829
|
+
const result = fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, { ...defaultCtx, _errors: errors });
|
|
9830
|
+
return { ...result, errors };
|
|
9831
|
+
}
|
|
9832
|
+
};
|
|
9833
|
+
}
|
|
9834
|
+
return {
|
|
9835
|
+
...compiledMeta,
|
|
9585
9836
|
parse(input, pos = 0) {
|
|
9586
|
-
|
|
9837
|
+
const parseCtx = trackedCtx(defaultCtx, input, pos);
|
|
9838
|
+
const result = fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, parseCtx);
|
|
9839
|
+
return annotateWithTrackedLines(result, parseCtx._lineStarts);
|
|
9587
9840
|
},
|
|
9588
9841
|
parseWithContext(input, parseCtx, pos = 0) {
|
|
9589
9842
|
assertHostModeCompatible(ctx.hostMode ?? "ast", parseCtx.build, !!ctx.hostBranchElided);
|
|
9590
|
-
|
|
9843
|
+
const activeCtx = trackedCtx(parseCtx, input, pos);
|
|
9844
|
+
const result = fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, activeCtx);
|
|
9845
|
+
return activeCtx.trackLines ? annotateWithTrackedLines(result, activeCtx._lineStarts) : result;
|
|
9591
9846
|
},
|
|
9592
9847
|
// Note: collects expect() errors via _errors. Unlike interpreter
|
|
9593
9848
|
// parse({recover:true}) it does NOT populate furthestFail — the compiled path
|
|
@@ -9596,8 +9851,9 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9596
9851
|
// (span.end < input.length) instead, which is mode-agnostic.
|
|
9597
9852
|
parseWithErrors(input, pos = 0) {
|
|
9598
9853
|
const errors = [];
|
|
9599
|
-
const
|
|
9600
|
-
|
|
9854
|
+
const parseCtx = trackedCtx({ ...defaultCtx, _errors: errors }, input, pos);
|
|
9855
|
+
const result = { ...fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, parseCtx), errors };
|
|
9856
|
+
return annotateWithTrackedLines(result, parseCtx._lineStarts);
|
|
9601
9857
|
}
|
|
9602
9858
|
};
|
|
9603
9859
|
}
|
|
@@ -9622,6 +9878,7 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
9622
9878
|
const grammarTrivia = opts?.trivia;
|
|
9623
9879
|
const grammarScanSkip = opts?.scanSkip ?? ruleMap.map(([, r]) => r._meta.grammarScanSkip).find(Boolean);
|
|
9624
9880
|
const grammarHostMode = opts?.hostMode ?? ruleMap.map(([, r]) => r._meta.grammarHostMode).find(Boolean);
|
|
9881
|
+
const grammarTrackLines = opts?.trackLines === true || ruleMap.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
9625
9882
|
const ctx = {
|
|
9626
9883
|
vars: 0,
|
|
9627
9884
|
indent: 1,
|
|
@@ -9642,6 +9899,7 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
9642
9899
|
capturing: ruleMap.some(([, rule]) => hasNodeDef(rule)),
|
|
9643
9900
|
recovery: opts?.recovery ?? false,
|
|
9644
9901
|
hostMode: grammarHostMode ?? "ast",
|
|
9902
|
+
lineTracking: grammarTrackLines,
|
|
9645
9903
|
...opts?.coverage ? { coverage: { plan: buildGrammarPlan(ruleMap.map(([, rule]) => rule), coverageWinners) } } : {},
|
|
9646
9904
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
9647
9905
|
...grammarTrivia ? { activeTrivia: grammarTrivia, triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {},
|
|
@@ -9675,12 +9933,18 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
9675
9933
|
const mfCovered = ctx.mapFns.length === 0 || derivedSrcs !== void 0;
|
|
9676
9934
|
const canInline = ctx.runtimeParsers.length === 0 && mfCovered && buildCovered;
|
|
9677
9935
|
if (!canInline) return null;
|
|
9936
|
+
if (ctx.lineTracking) {
|
|
9937
|
+
ctx.needsLineTrack = true;
|
|
9938
|
+
ctx.needsLineSpan = true;
|
|
9939
|
+
}
|
|
9678
9940
|
const mfDecl = derivedSrcs?.length ? ` const ${mfRef(ctx)} = [${derivedSrcs.join(", ")}]` : "";
|
|
9679
9941
|
const buildDecl = buildSources?.length ? ` const ${buildRef(ctx)} = [${buildSources.join(", ")}]` : "";
|
|
9680
9942
|
const namedPrelude = ctx.namedFnDecls.length > 0 ? namedFnPrelude() : [];
|
|
9681
9943
|
const hoistedDecls = [
|
|
9682
9944
|
ctx.needsEmptyTl ? ` const _EMPTY_TL = Object.freeze([])` : "",
|
|
9683
9945
|
ctx.needsHostReads ? ` ${HOST_READS_DECL}` : "",
|
|
9946
|
+
ctx.needsLineTrack ? ` ${LINE_TRACK_DECL}` : "",
|
|
9947
|
+
ctx.needsLineSpan ? ` ${LINE_SPAN_DECL}` : "",
|
|
9684
9948
|
...ctx.regexDecls.map((d) => ` ${d}`),
|
|
9685
9949
|
...ctx.expectedDecls.map((d) => ` ${d}`),
|
|
9686
9950
|
mfDecl,
|
|
@@ -9702,15 +9966,23 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
9702
9966
|
};
|
|
9703
9967
|
const entryFnText = (r, rule) => {
|
|
9704
9968
|
const ruleId = entryRuleId(rule);
|
|
9969
|
+
const linePreamble = ctx.lineTracking ? [
|
|
9970
|
+
` if (_ctx._lineStarts === undefined) _ctx = { ..._ctx, trackLines: true, _lineStarts: [0], _lineScannedTo: 0 }`,
|
|
9971
|
+
` else _ctx.trackLines = true`,
|
|
9972
|
+
` if (_pos > (_ctx._lineScannedTo ?? 0)) _trackLines(_ctx, input, 0, _pos)`
|
|
9973
|
+
] : [];
|
|
9974
|
+
const resultSpan = ctx.lineTracking ? `_spanLines(_ctx, _pos, ${r.endVar})` : `{ start: _pos, end: ${r.endVar} }`;
|
|
9705
9975
|
const body = ruleId === void 0 ? [
|
|
9976
|
+
...linePreamble,
|
|
9706
9977
|
` let pos = _pos`,
|
|
9707
9978
|
...r.stmts,
|
|
9708
|
-
` return { ok: true, value: ${r.valueVar}, span:
|
|
9979
|
+
` return { ok: true, value: ${r.valueVar}, span: ${resultSpan} }`
|
|
9709
9980
|
] : [
|
|
9981
|
+
...linePreamble,
|
|
9710
9982
|
` const _coverageResult = (() => {`,
|
|
9711
9983
|
` let pos = _pos`,
|
|
9712
9984
|
...r.stmts,
|
|
9713
|
-
` return { ok: true, value: ${r.valueVar}, span:
|
|
9985
|
+
` return { ok: true, value: ${r.valueVar}, span: ${resultSpan} }`,
|
|
9714
9986
|
` })()`,
|
|
9715
9987
|
` if (!_coverageResult.ok) _ctx._grammarTrace?.write({ id: ${JSON.stringify(ruleId)}, phase: 'failure', offset: _coverageResult.span.start })`,
|
|
9716
9988
|
` return _coverageResult`
|
|
@@ -9748,6 +10020,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
9748
10020
|
const grammarTrivia = opts?.trivia ?? ruleMapArg.map(([, r]) => r._meta.grammarTrivia).find(Boolean);
|
|
9749
10021
|
const grammarScanSkip = opts?.scanSkip ?? ruleMapArg.map(([, r]) => r._meta.grammarScanSkip).find(Boolean);
|
|
9750
10022
|
const grammarHostMode = opts?.hostMode ?? ruleMapArg.map(([, r]) => r._meta.grammarHostMode).find(Boolean);
|
|
10023
|
+
const grammarTrackLines = opts?.trackLines === true || ruleMapArg.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
9751
10024
|
const ruleMap = ruleMapArg.filter(([, val]) => {
|
|
9752
10025
|
const d = val._def;
|
|
9753
10026
|
if (d.tag !== "lazy") return true;
|
|
@@ -9782,6 +10055,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
9782
10055
|
capturing: opts?.captureTerminals === true || ruleMap.some(([, rule]) => hasNodeDef(rule)),
|
|
9783
10056
|
recovery: opts?.recovery ?? false,
|
|
9784
10057
|
hostMode: grammarHostMode ?? "ast",
|
|
10058
|
+
lineTracking: grammarTrackLines,
|
|
9785
10059
|
...opts?.coverage ? { coverage: { plan: opts.coverage } } : {},
|
|
9786
10060
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
9787
10061
|
ns,
|
|
@@ -9878,6 +10152,10 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
9878
10152
|
perEntry.push({ key, rule, r: emitNamedFnCall(ctx, fn, "_pos") });
|
|
9879
10153
|
}
|
|
9880
10154
|
if (ctx.runtimeParsers.length !== 0) return null;
|
|
10155
|
+
if (ctx.lineTracking) {
|
|
10156
|
+
ctx.needsLineTrack = true;
|
|
10157
|
+
ctx.needsLineSpan = true;
|
|
10158
|
+
}
|
|
9881
10159
|
const mfSrcs = ctx.mapFns.length > 0 && ctx.mapFnSrcs.every((s) => s !== null) ? ctx.mapFnSrcs : null;
|
|
9882
10160
|
const buildSrcs = ctx.buildFns.length > 0 && ctx.buildSrcs.every((s) => s !== null) ? ctx.buildSrcs : null;
|
|
9883
10161
|
const ruleFns = /* @__PURE__ */ new Map();
|
|
@@ -9891,6 +10169,8 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
9891
10169
|
const mfDecl = ctx.mapFns.length === 0 ? "" : mfSrcs ? `const ${mfRef(ctx)} = [${mfSrcs.join(", ")}]` : `const ${mfRef(ctx)} = _env[${JSON.stringify(nsp(ctx) + "mf")}]`;
|
|
9892
10170
|
const buildDecl = ctx.buildFns.length === 0 ? "" : buildSrcs ? `const ${buildRef(ctx)} = [${buildSrcs.join(", ")}]` : `const ${buildRef(ctx)} = _env[${JSON.stringify(nsp(ctx) + "build")}]`;
|
|
9893
10171
|
const prelude = [
|
|
10172
|
+
ctx.needsLineTrack ? LINE_TRACK_DECL : "",
|
|
10173
|
+
ctx.needsLineSpan ? LINE_SPAN_DECL : "",
|
|
9894
10174
|
...ctx.regexDecls,
|
|
9895
10175
|
...ctx.expectedDecls,
|
|
9896
10176
|
mfDecl,
|
|
@@ -9899,11 +10179,18 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
9899
10179
|
].filter(Boolean);
|
|
9900
10180
|
const wrappers = /* @__PURE__ */ new Map();
|
|
9901
10181
|
for (const { key, rule, r } of perEntry) {
|
|
10182
|
+
const linePreamble = ctx.lineTracking ? [
|
|
10183
|
+
` if (_ctx._lineStarts === undefined) _ctx = { ..._ctx, trackLines: true, _lineStarts: [0], _lineScannedTo: 0 }`,
|
|
10184
|
+
` else _ctx.trackLines = true`,
|
|
10185
|
+
` if (_pos > (_ctx._lineScannedTo ?? 0)) _trackLines(_ctx, input, 0, _pos)`
|
|
10186
|
+
] : [];
|
|
10187
|
+
const resultSpan = ctx.lineTracking ? `_spanLines(_ctx, _pos, ${r.endVar})` : `{ start: _pos, end: ${r.endVar} }`;
|
|
9902
10188
|
wrappers.set(key, publicRuleWrapperSource(rule, [
|
|
9903
10189
|
`function(input, _pos, _ctx) {`,
|
|
10190
|
+
...linePreamble,
|
|
9904
10191
|
` let pos = _pos`,
|
|
9905
10192
|
...r.stmts,
|
|
9906
|
-
` return { ok: true, value: ${r.valueVar}, span:
|
|
10193
|
+
` return { ok: true, value: ${r.valueVar}, span: ${resultSpan} }`,
|
|
9907
10194
|
`}`
|
|
9908
10195
|
].join("\n"), ctx.triviaKindLabels));
|
|
9909
10196
|
}
|
|
@@ -10010,12 +10297,16 @@ function buildInlineExpression(ctx, r, mapFnSources, buildSources, coverageRootR
|
|
|
10010
10297
|
const buildDecl = buildSources?.length ? ` const _build = [${buildSources.join(", ")}]` : "";
|
|
10011
10298
|
const emptyTlDecl = ctx.needsEmptyTl ? ` const _EMPTY_TL = Object.freeze([])` : "";
|
|
10012
10299
|
const hostReadsDecl = ctx.needsHostReads ? ` ${HOST_READS_DECL}` : "";
|
|
10013
|
-
const
|
|
10300
|
+
const lineTrackDecl = ctx.needsLineTrack ? ` ${LINE_TRACK_DECL}` : "";
|
|
10301
|
+
const lineSpanDecl = ctx.needsLineSpan ? ` ${LINE_SPAN_DECL}` : "";
|
|
10302
|
+
const needsWrapper = ctx.regexDecls.length > 0 || ctx.expectedDecls.length > 0 || ctx.namedFnDecls.length > 0 || !!mfDecl || !!buildDecl || !!emptyTlDecl || !!hostReadsDecl || !!lineTrackDecl || !!lineSpanDecl;
|
|
10014
10303
|
if (!needsWrapper) return innerFn;
|
|
10015
10304
|
const namedPrelude = ctx.namedFnDecls.length > 0 ? namedFnPrelude() : [];
|
|
10016
10305
|
const hoistedDecls = [
|
|
10017
10306
|
emptyTlDecl,
|
|
10018
10307
|
hostReadsDecl,
|
|
10308
|
+
lineTrackDecl,
|
|
10309
|
+
lineSpanDecl,
|
|
10019
10310
|
...ctx.regexDecls.map((d) => ` ${d}`),
|
|
10020
10311
|
...ctx.expectedDecls.map((d) => ` ${d}`),
|
|
10021
10312
|
mfDecl,
|
|
@@ -10554,7 +10845,7 @@ function normalizeCstCollapse(collapse) {
|
|
|
10554
10845
|
return typeof collapse === "function" ? collapse : void 0;
|
|
10555
10846
|
}
|
|
10556
10847
|
function buildCstNode(type, children2, _fields, span, _rawChildren, _triviaLog, state) {
|
|
10557
|
-
return { _tag: "node", type, span: {
|
|
10848
|
+
return { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children2] };
|
|
10558
10849
|
}
|
|
10559
10850
|
function cstBuildHost(typeOrOptions, children2, _fields, span, rawChildren, triviaLog, state) {
|
|
10560
10851
|
if (typeof typeOrOptions === "string") {
|
|
@@ -10733,7 +11024,8 @@ function materializePiece(p, trivia2, captureTerminals = false, hostMode) {
|
|
|
10733
11024
|
const pieces = compileLinkable(evalRuleMapIR(p.ir), p.ns, {
|
|
10734
11025
|
...trivia2 ? { trivia: trivia2 } : {},
|
|
10735
11026
|
...captureTerminals ? { captureTerminals: true } : {},
|
|
10736
|
-
...hostMode ? { hostMode } : {}
|
|
11027
|
+
...hostMode ? { hostMode } : {},
|
|
11028
|
+
...p.trackLines ? { trackLines: true } : {}
|
|
10737
11029
|
});
|
|
10738
11030
|
if (!pieces) throw new Error(`compose: carried IR for ns "${p.ns}" could not be re-lowered`);
|
|
10739
11031
|
return pieces;
|
|
@@ -11980,6 +12272,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
11980
12272
|
const macroImports = [];
|
|
11981
12273
|
const allNames = /* @__PURE__ */ new Set();
|
|
11982
12274
|
const importBindings = /* @__PURE__ */ new Map();
|
|
12275
|
+
const ordinaryImports = [];
|
|
11983
12276
|
for (const stmt of body) {
|
|
11984
12277
|
if (stmt.type !== "ImportDeclaration") continue;
|
|
11985
12278
|
const s = stmt;
|
|
@@ -11988,12 +12281,17 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
11988
12281
|
return key === "type" && a.value.value === "macro";
|
|
11989
12282
|
});
|
|
11990
12283
|
if (!isMacro) {
|
|
12284
|
+
const specifiers = [];
|
|
11991
12285
|
for (const spec of s.specifiers) {
|
|
11992
12286
|
if (spec.type === "ImportSpecifier") {
|
|
11993
12287
|
const imported = spec.imported.name ?? spec.local.name;
|
|
11994
12288
|
importBindings.set(spec.local.name, { source: s.source.value, imported });
|
|
12289
|
+
specifiers.push({ type: spec.type, local: spec.local.name, start: spec.start, end: spec.end });
|
|
12290
|
+
} else {
|
|
12291
|
+
specifiers.push({ type: spec.type, local: spec.local.name, start: spec.start, end: spec.end });
|
|
11995
12292
|
}
|
|
11996
12293
|
}
|
|
12294
|
+
ordinaryImports.push({ start: s.start, end: s.end, specifiers });
|
|
11997
12295
|
continue;
|
|
11998
12296
|
}
|
|
11999
12297
|
const names = /* @__PURE__ */ new Set();
|
|
@@ -12004,6 +12302,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12004
12302
|
for (const n of names) allNames.add(n);
|
|
12005
12303
|
}
|
|
12006
12304
|
if (macroImports.length === 0) return null;
|
|
12305
|
+
const unwrapVd = (stmt) => stmt.type === "VariableDeclaration" ? stmt : stmt.type === "ExportNamedDeclaration" && stmt.declaration?.type === "VariableDeclaration" ? stmt.declaration : null;
|
|
12007
12306
|
const factoryDecls = /* @__PURE__ */ new Map();
|
|
12008
12307
|
for (const stmt of body) {
|
|
12009
12308
|
const decl = stmt.type === "ExportNamedDeclaration" ? stmt.declaration : stmt;
|
|
@@ -12021,6 +12320,101 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12021
12320
|
}
|
|
12022
12321
|
}
|
|
12023
12322
|
}
|
|
12323
|
+
const topLevelFunction = (moduleBody, name) => {
|
|
12324
|
+
for (const st of moduleBody) {
|
|
12325
|
+
const decl = st.type === "ExportNamedDeclaration" ? st.declaration : st;
|
|
12326
|
+
const idn = decl?.type === "FunctionDeclaration" ? decl.id : void 0;
|
|
12327
|
+
if (idn?.name === name) return decl ?? null;
|
|
12328
|
+
}
|
|
12329
|
+
return null;
|
|
12330
|
+
};
|
|
12331
|
+
const isParsemanMacroImport = (stmt) => {
|
|
12332
|
+
if (stmt.type !== "ImportDeclaration") return false;
|
|
12333
|
+
const s = stmt;
|
|
12334
|
+
return moduleAliases.has(s.source.value) && s.attributes.some((a) => {
|
|
12335
|
+
const key = a.key.type === "Identifier" ? a.key.name : String(a.key.value);
|
|
12336
|
+
return key === "type" && a.value.value === "macro";
|
|
12337
|
+
});
|
|
12338
|
+
};
|
|
12339
|
+
const sourceScopeUntil = (moduleBody, source, until) => {
|
|
12340
|
+
const out = /* @__PURE__ */ new Map();
|
|
12341
|
+
for (const stmt of moduleBody) {
|
|
12342
|
+
if (stmt.type === "ImportDeclaration") {
|
|
12343
|
+
if (!isParsemanMacroImport(stmt)) return null;
|
|
12344
|
+
continue;
|
|
12345
|
+
}
|
|
12346
|
+
if (stmt.type === "FunctionDeclaration") continue;
|
|
12347
|
+
if (stmt.type === "ExportNamedDeclaration" && stmt.declaration?.type === "FunctionDeclaration") continue;
|
|
12348
|
+
if (stmt.type === "ExportNamedDeclaration" && !stmt.declaration) {
|
|
12349
|
+
if (stmt.source) return null;
|
|
12350
|
+
continue;
|
|
12351
|
+
}
|
|
12352
|
+
const vd = unwrapVd(stmt);
|
|
12353
|
+
if (!vd || vd.kind !== "const") return null;
|
|
12354
|
+
for (const decl of vd.declarations) {
|
|
12355
|
+
const d = decl;
|
|
12356
|
+
const idn = d.id;
|
|
12357
|
+
const init = d.init;
|
|
12358
|
+
if (idn.type !== "Identifier" && idn.type !== "BindingIdentifier" || !idn.name || !init) return null;
|
|
12359
|
+
if (init.type === "ArrowFunctionExpression" || init.type === "FunctionExpression") continue;
|
|
12360
|
+
const mapFnSources = [];
|
|
12361
|
+
const combi = evaluateExpr(init, out, source, mapFnSources);
|
|
12362
|
+
if (combi) {
|
|
12363
|
+
if (stmt.start < until) out.set(idn.name, { combi, mfSrcs: mapFnSources });
|
|
12364
|
+
continue;
|
|
12365
|
+
}
|
|
12366
|
+
const wordFactory = evaluateWordFactory(init, out, source);
|
|
12367
|
+
if (wordFactory) {
|
|
12368
|
+
if (stmt.start < until) {
|
|
12369
|
+
;
|
|
12370
|
+
out.set(idn.name, wordFactory);
|
|
12371
|
+
}
|
|
12372
|
+
continue;
|
|
12373
|
+
}
|
|
12374
|
+
const whenFactory = evaluateWhenFactory(init, out, source);
|
|
12375
|
+
if (whenFactory) {
|
|
12376
|
+
if (stmt.start < until) {
|
|
12377
|
+
;
|
|
12378
|
+
out.set(idn.name, whenFactory);
|
|
12379
|
+
}
|
|
12380
|
+
continue;
|
|
12381
|
+
}
|
|
12382
|
+
const combiArray = evaluateCombinatorArray(init, out, source);
|
|
12383
|
+
if (combiArray) {
|
|
12384
|
+
if (stmt.start < until) {
|
|
12385
|
+
;
|
|
12386
|
+
out.set(idn.name, combiArray);
|
|
12387
|
+
}
|
|
12388
|
+
continue;
|
|
12389
|
+
}
|
|
12390
|
+
return null;
|
|
12391
|
+
}
|
|
12392
|
+
continue;
|
|
12393
|
+
}
|
|
12394
|
+
return out;
|
|
12395
|
+
};
|
|
12396
|
+
const usedImportedFactories = /* @__PURE__ */ new Set();
|
|
12397
|
+
const markUsedImportedFactories = (names) => {
|
|
12398
|
+
for (const name of names ?? []) usedImportedFactories.add(name);
|
|
12399
|
+
};
|
|
12400
|
+
for (const [localName, binding] of importBindings) {
|
|
12401
|
+
const file = resolvePrivateSourceModule(id, binding.source);
|
|
12402
|
+
if (!file) continue;
|
|
12403
|
+
const mod = parseModuleCached(file);
|
|
12404
|
+
if (!mod) continue;
|
|
12405
|
+
const localFor = exportLocalName(mod.body, binding.imported);
|
|
12406
|
+
const init = localFor ? topLevelInit(mod.body, localFor) ?? topLevelFunction(mod.body, localFor) : null;
|
|
12407
|
+
if (!init || init.type !== "ArrowFunctionExpression" && init.type !== "FunctionExpression" && init.type !== "FunctionDeclaration") continue;
|
|
12408
|
+
const factoryScope = sourceScopeUntil(mod.body, mod.src, init.start);
|
|
12409
|
+
if (!factoryScope) continue;
|
|
12410
|
+
factoryDecls.set(localName, {
|
|
12411
|
+
fn: init,
|
|
12412
|
+
declaredAt: -1,
|
|
12413
|
+
code: mod.src,
|
|
12414
|
+
scope: factoryScope,
|
|
12415
|
+
imported: true
|
|
12416
|
+
});
|
|
12417
|
+
}
|
|
12024
12418
|
const scope = /* @__PURE__ */ new Map();
|
|
12025
12419
|
const replacements = [];
|
|
12026
12420
|
const warnings = [];
|
|
@@ -12050,6 +12444,9 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12050
12444
|
}
|
|
12051
12445
|
const namedFactory = factoryArgRaw.type === "Identifier" ? factoryDecls.get(factoryArgRaw.name) : void 0;
|
|
12052
12446
|
const factoryArg = namedFactory !== void 0 && namedFactory.declaredAt <= init.start ? namedFactory.fn : factoryArgRaw;
|
|
12447
|
+
const factoryScope = namedFactory?.scope ?? scope;
|
|
12448
|
+
const factoryCode = namedFactory?.code ?? code;
|
|
12449
|
+
const importedFactory = namedFactory?.imported === true && factoryArg === namedFactory.fn ? factoryArgRaw.name : void 0;
|
|
12053
12450
|
const optionsArg = optionsFirst ? arg0 : arg1;
|
|
12054
12451
|
const optionValue = (name) => optionsArg?.type === "ObjectExpression" ? (optionsArg.properties ?? []).find(
|
|
12055
12452
|
(p) => p.key?.name === name
|
|
@@ -12060,7 +12457,13 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12060
12457
|
warn(init.start, `${label2}: rules({ hostMode }) must be the literal 'ast' or 'cst'`);
|
|
12061
12458
|
return null;
|
|
12062
12459
|
}
|
|
12063
|
-
const
|
|
12460
|
+
const trackLinesValue = optionValue("trackLines");
|
|
12461
|
+
const gTrackLines = trackLinesValue?.type === "Literal" ? trackLinesValue.value : void 0;
|
|
12462
|
+
if (trackLinesValue !== void 0 && typeof gTrackLines !== "boolean") {
|
|
12463
|
+
warn(init.start, `${label2}: rules({ trackLines }) must be a boolean literal`);
|
|
12464
|
+
return null;
|
|
12465
|
+
}
|
|
12466
|
+
const ruleMap = evaluateParserFactory(factoryArg, factoryScope, factoryCode, []);
|
|
12064
12467
|
if (!ruleMap) {
|
|
12065
12468
|
warn(init.start, `${label2}: rules(...) factory isn't statically evaluable`);
|
|
12066
12469
|
return null;
|
|
@@ -12085,12 +12488,26 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12085
12488
|
}
|
|
12086
12489
|
}
|
|
12087
12490
|
}
|
|
12088
|
-
|
|
12491
|
+
if (gTrackLines === true) {
|
|
12492
|
+
for (const rule of ruleMap.values()) {
|
|
12493
|
+
if (rule && !rule._meta.isTrivia) {
|
|
12494
|
+
;
|
|
12495
|
+
rule._meta.grammarTrackLines = true;
|
|
12496
|
+
}
|
|
12497
|
+
}
|
|
12498
|
+
}
|
|
12499
|
+
return {
|
|
12500
|
+
ruleMap,
|
|
12501
|
+
...gTrivia ? { trivia: gTrivia } : {},
|
|
12502
|
+
...gScanSkip ? { scanSkip: gScanSkip } : {},
|
|
12503
|
+
...gTrackLines === true ? { trackLines: true } : {},
|
|
12504
|
+
...importedFactory ? { importedFactory } : {}
|
|
12505
|
+
};
|
|
12089
12506
|
};
|
|
12090
12507
|
const compileRulesFactory = (init, label2) => {
|
|
12091
12508
|
const evaluated = evaluateRulesFactory(init, label2);
|
|
12092
12509
|
if (!evaluated) return null;
|
|
12093
|
-
const compiled = compileRuleMap([...evaluated.ruleMap], { ...evaluated.trivia ? { trivia: evaluated.trivia } : {}, ...evaluated.scanSkip ? { scanSkip: evaluated.scanSkip } : {}, recovery, coverage: grammarCoverage });
|
|
12510
|
+
const compiled = compileRuleMap([...evaluated.ruleMap], { ...evaluated.trivia ? { trivia: evaluated.trivia } : {}, ...evaluated.scanSkip ? { scanSkip: evaluated.scanSkip } : {}, ...evaluated.trackLines ? { trackLines: true } : {}, recovery, coverage: grammarCoverage });
|
|
12094
12511
|
return {
|
|
12095
12512
|
replacement: compiled?.replacement ?? null,
|
|
12096
12513
|
ruleMap: evaluated.ruleMap,
|
|
@@ -12098,7 +12515,9 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12098
12515
|
hostBranchElided: compiled?.hostBranchElided ?? false,
|
|
12099
12516
|
...compiled?.coverageDefinitions ? { coverageDefinitions: compiled.coverageDefinitions } : {},
|
|
12100
12517
|
...evaluated.trivia ? { trivia: evaluated.trivia } : {},
|
|
12101
|
-
...evaluated.scanSkip ? { scanSkip: evaluated.scanSkip } : {}
|
|
12518
|
+
...evaluated.scanSkip ? { scanSkip: evaluated.scanSkip } : {},
|
|
12519
|
+
...evaluated.trackLines ? { trackLines: true } : {},
|
|
12520
|
+
...evaluated.importedFactory ? { importedFactory: evaluated.importedFactory } : {}
|
|
12102
12521
|
};
|
|
12103
12522
|
};
|
|
12104
12523
|
const isRulesCall = (init) => init.type === "CallExpression" && init.callee.type === "Identifier" && init.callee.name === "rules";
|
|
@@ -12118,7 +12537,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12118
12537
|
};
|
|
12119
12538
|
const isSpread = (it) => "__spreadLocal" in it;
|
|
12120
12539
|
const isIR = (it) => "ir" in it && !("ruleFns" in it);
|
|
12121
|
-
const serializeItem = (it) => isSpread(it) ? `...(${it.__spreadLocal}[Symbol.for('parseman.composedPieces')] ?? [])` : isIR(it) ? `{ ns: ${JSON.stringify(it.ns)}, ir: ${JSON.stringify(it.ir)} }` : serializePieces(it);
|
|
12540
|
+
const serializeItem = (it) => isSpread(it) ? `...(${it.__spreadLocal}[Symbol.for('parseman.composedPieces')] ?? [])` : isIR(it) ? `{ ns: ${JSON.stringify(it.ns)}, ir: ${JSON.stringify(it.ir)}${it.trackLines ? ", trackLines: true" : ""} }` : serializePieces(it);
|
|
12122
12541
|
const serializeList = (list) => `[${list.map(serializeItem).join(", ")}]`;
|
|
12123
12542
|
const withCarriedPieces = (grammarExpr, list) => `/* @__PURE__ */ Object.defineProperty(${grammarExpr}, Symbol.for('parseman.composedPieces'), { value: ${serializeList(list)}, enumerable: false })`;
|
|
12124
12543
|
const withLeafMarker = (grammarExpr) => `/* @__PURE__ */ Object.defineProperty(${grammarExpr}, Symbol.for('parseman.leafComposed'), { value: true, enumerable: false })`;
|
|
@@ -12249,10 +12668,11 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12249
12668
|
const localCarried = (rm, label2, composing, scanSkip) => {
|
|
12250
12669
|
const entries = [...rm];
|
|
12251
12670
|
const ns = nsFor(label2);
|
|
12671
|
+
const trackLines = entries.some(([, rule]) => rule?._meta?.grammarTrackLines === true);
|
|
12252
12672
|
const ir = serializeRuleMap(entries, scanSkip);
|
|
12253
|
-
if (ir) return { carried: [{ ns, ir }] };
|
|
12673
|
+
if (ir) return { carried: [{ ns, ir, ...trackLines ? { trackLines: true } : {} }] };
|
|
12254
12674
|
warn(0, `${label2}: rule map could not be serialized to IR; carrying FULL pieces instead. The artifact is correct but larger, and a downstream compose cannot re-lower it. Re-run with PARSEMAN_IR_DEBUG=1 to print the exact combinator that blocked serialization.`);
|
|
12255
|
-
const p = compileLinkable(entries, ns, { ...composing ? { trivia: composing } : {}, ...scanSkip ? { scanSkip } : {}, recovery });
|
|
12675
|
+
const p = compileLinkable(entries, ns, { ...composing ? { trivia: composing } : {}, ...scanSkip ? { scanSkip } : {}, ...trackLines ? { trackLines: true } : {}, recovery });
|
|
12256
12676
|
return p ? { carried: [p] } : null;
|
|
12257
12677
|
};
|
|
12258
12678
|
const argPieces = (arg, label2, composing) => {
|
|
@@ -12270,7 +12690,10 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12270
12690
|
const innerArg = argPieces(inner, `${label2}_pick`);
|
|
12271
12691
|
if (!innerArg) return null;
|
|
12272
12692
|
try {
|
|
12273
|
-
return {
|
|
12693
|
+
return {
|
|
12694
|
+
carried: pickPieces(materializeCarried(innerArg.carried, ownTrivia(inner)), names),
|
|
12695
|
+
...innerArg.importedFactories ? { importedFactories: innerArg.importedFactories } : {}
|
|
12696
|
+
};
|
|
12274
12697
|
} catch (e) {
|
|
12275
12698
|
warn(arg.start, `pick(): ${e.message}`);
|
|
12276
12699
|
return null;
|
|
@@ -12278,7 +12701,8 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12278
12701
|
}
|
|
12279
12702
|
if (isRulesCall(arg)) {
|
|
12280
12703
|
const evaluated = evaluateRulesFactory(arg, label2);
|
|
12281
|
-
|
|
12704
|
+
const carried = evaluated ? localCarried(evaluated.ruleMap, label2, composing, evaluated.scanSkip) : null;
|
|
12705
|
+
return carried ? { ...carried, ...evaluated?.importedFactory ? { importedFactories: [evaluated.importedFactory] } : {} } : null;
|
|
12282
12706
|
}
|
|
12283
12707
|
if (arg.type === "Identifier") {
|
|
12284
12708
|
const name = arg.name;
|
|
@@ -12350,6 +12774,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12350
12774
|
}
|
|
12351
12775
|
const composing = composingTrivia(elements);
|
|
12352
12776
|
const carried = [];
|
|
12777
|
+
const importedFactories = [];
|
|
12353
12778
|
for (let i = 0; i < elements.length; i++) {
|
|
12354
12779
|
const r = argPieces(elements[i], `compose${init.start}_${i}`, composing);
|
|
12355
12780
|
if (!r) {
|
|
@@ -12357,6 +12782,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12357
12782
|
return null;
|
|
12358
12783
|
}
|
|
12359
12784
|
carried.push(...r.carried);
|
|
12785
|
+
importedFactories.push(...r.importedFactories ?? []);
|
|
12360
12786
|
}
|
|
12361
12787
|
const detailed = once(() => carriedRuleMapsDetailed(carried));
|
|
12362
12788
|
runFusedGatingDiagnostic(
|
|
@@ -12366,7 +12792,12 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12366
12792
|
);
|
|
12367
12793
|
const pieces = materializeCarried(carried, composing, false, cHostMode);
|
|
12368
12794
|
try {
|
|
12369
|
-
return {
|
|
12795
|
+
return {
|
|
12796
|
+
replacement: emitFusedSource(pieces),
|
|
12797
|
+
carried,
|
|
12798
|
+
...composing ? { trivia: composing } : {},
|
|
12799
|
+
...importedFactories.length ? { importedFactories } : {}
|
|
12800
|
+
};
|
|
12370
12801
|
} catch (e) {
|
|
12371
12802
|
warn(init.start, `compose(): ${e.message}; falling back to runtime`);
|
|
12372
12803
|
return null;
|
|
@@ -12387,10 +12818,12 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12387
12818
|
const localArg = elements[elements.length - 1];
|
|
12388
12819
|
let localRules = null;
|
|
12389
12820
|
let localScanSkip;
|
|
12821
|
+
const importedFactories = [];
|
|
12390
12822
|
if (isRulesCall(localArg)) {
|
|
12391
12823
|
const evaluated = evaluateRulesFactory(localArg, `composeLeaf${init.start}`);
|
|
12392
12824
|
localRules = evaluated?.ruleMap ?? null;
|
|
12393
12825
|
localScanSkip = evaluated?.scanSkip;
|
|
12826
|
+
if (evaluated?.importedFactory) importedFactories.push(evaluated.importedFactory);
|
|
12394
12827
|
} else if (localArg.type === "Identifier") {
|
|
12395
12828
|
const name = localArg.name;
|
|
12396
12829
|
localRules = localRuleMaps.get(name) ?? null;
|
|
@@ -12409,6 +12842,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12409
12842
|
return null;
|
|
12410
12843
|
}
|
|
12411
12844
|
carried.push(...r.carried);
|
|
12845
|
+
importedFactories.push(...r.importedFactories ?? []);
|
|
12412
12846
|
}
|
|
12413
12847
|
try {
|
|
12414
12848
|
const localNs = nsFor(`composeLeaf${init.start}`);
|
|
@@ -12434,13 +12868,15 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12434
12868
|
return null;
|
|
12435
12869
|
}
|
|
12436
12870
|
const replacement = withLeafMarker(emitFusedSource(grammarCoverage ? recognitionPieces : [...recognitionPieces, plainLocalPiece]));
|
|
12437
|
-
return {
|
|
12871
|
+
return {
|
|
12872
|
+
replacement: withCoverageDefinitions(replacement, emittedCoverageDefinitions(replacement)),
|
|
12873
|
+
...importedFactories.length ? { importedFactories } : {}
|
|
12874
|
+
};
|
|
12438
12875
|
} catch (e) {
|
|
12439
12876
|
warn(init.start, `composeLeaf(): ${e.message}`);
|
|
12440
12877
|
return null;
|
|
12441
12878
|
}
|
|
12442
12879
|
};
|
|
12443
|
-
const unwrapVd = (stmt) => stmt.type === "VariableDeclaration" ? stmt : stmt.type === "ExportNamedDeclaration" && stmt.declaration?.type === "VariableDeclaration" ? stmt.declaration : null;
|
|
12444
12880
|
const refNames = /* @__PURE__ */ new Set();
|
|
12445
12881
|
for (const stmt of body) {
|
|
12446
12882
|
const innerVd = unwrapVd(stmt);
|
|
@@ -12524,6 +12960,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12524
12960
|
const ns = nsFor(varName);
|
|
12525
12961
|
const pieces = exportPrefix || compiledRules.replacement === null ? compileLinkable([...compiledRules.ruleMap], ns, {
|
|
12526
12962
|
...compiledRules.scanSkip ? { scanSkip: compiledRules.scanSkip } : {},
|
|
12963
|
+
...compiledRules.trackLines ? { trackLines: true } : {},
|
|
12527
12964
|
recovery
|
|
12528
12965
|
}) : null;
|
|
12529
12966
|
if (compiledRules.replacement === null) {
|
|
@@ -12543,9 +12980,12 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12543
12980
|
}
|
|
12544
12981
|
if (exportPrefix && pieces && !pieces.mfFns.length && !pieces.buildFns.length) {
|
|
12545
12982
|
const ir = serializeRuleMap([...compiledRules.ruleMap], compiledRules.scanSkip);
|
|
12546
|
-
replacement = withCarriedPieces(replacement, [ir ? { ns, ir } : pieces]);
|
|
12983
|
+
replacement = withCarriedPieces(replacement, [ir ? { ns, ir, ...compiledRules.trackLines ? { trackLines: true } : {} } : pieces]);
|
|
12547
12984
|
}
|
|
12548
12985
|
replacements.push({ start: init.start, end: init.end, replacement });
|
|
12986
|
+
if (compiledRules.replacement !== null) {
|
|
12987
|
+
markUsedImportedFactories(compiledRules.importedFactory ? [compiledRules.importedFactory] : void 0);
|
|
12988
|
+
}
|
|
12549
12989
|
continue;
|
|
12550
12990
|
}
|
|
12551
12991
|
if (isComposeCall(init)) {
|
|
@@ -12558,6 +12998,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12558
12998
|
if (fused.trivia) localComposedTrivia.set(varName, fused.trivia);
|
|
12559
12999
|
const replacement = exportPrefix ? withCarriedPieces(fused.replacement, fused.carried) : fused.replacement;
|
|
12560
13000
|
replacements.push({ start: init.start, end: init.end, replacement: withCoverageDefinitions(replacement, emittedCoverageDefinitions(replacement)) });
|
|
13001
|
+
markUsedImportedFactories(fused.importedFactories);
|
|
12561
13002
|
continue;
|
|
12562
13003
|
}
|
|
12563
13004
|
if (isComposeLeafCall(init)) {
|
|
@@ -12566,6 +13007,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12566
13007
|
throw new Error(`${id}:${lineOf(init.start)} \u2014 composeLeaf() must macro-fuse; runtime composition is forbidden`);
|
|
12567
13008
|
}
|
|
12568
13009
|
replacements.push({ start: init.start, end: init.end, replacement: fused.replacement });
|
|
13010
|
+
markUsedImportedFactories(fused.importedFactories);
|
|
12569
13011
|
continue;
|
|
12570
13012
|
}
|
|
12571
13013
|
const mapFnSources = [];
|
|
@@ -12654,6 +13096,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12654
13096
|
end: stmtEnd,
|
|
12655
13097
|
replacement: lines.join("\n")
|
|
12656
13098
|
});
|
|
13099
|
+
markUsedImportedFactories(compiledRules.importedFactory ? [compiledRules.importedFactory] : void 0);
|
|
12657
13100
|
}
|
|
12658
13101
|
}
|
|
12659
13102
|
}
|
|
@@ -12662,6 +13105,40 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12662
13105
|
imp.fullyResolved = !anyUnresolved && !keepMacroImport;
|
|
12663
13106
|
}
|
|
12664
13107
|
const ms = new MagicString(code);
|
|
13108
|
+
const replacementRanges = runtimeComposeFallback ? [] : replacements.map(({ start, end }) => ({ start, end }));
|
|
13109
|
+
const isInsideReplacement = (start, end) => replacementRanges.some((r) => start >= r.start && end <= r.end);
|
|
13110
|
+
const importedBindingStillReferenced = (local) => {
|
|
13111
|
+
const walk2 = (node2, parent, parentKey) => {
|
|
13112
|
+
if (!node2 || typeof node2 !== "object") return false;
|
|
13113
|
+
const rec = node2;
|
|
13114
|
+
if (rec.type === "ImportDeclaration") return false;
|
|
13115
|
+
if (typeof rec.start === "number" && typeof rec.end === "number" && isInsideReplacement(rec.start, rec.end)) return false;
|
|
13116
|
+
if ((rec.type === "Identifier" || rec.type === "BindingIdentifier") && rec.name === local) {
|
|
13117
|
+
if (parentKey === "key" && (parent?.type === "ObjectProperty" || parent?.type === "Property" || parent?.type === "PropertyDefinition") && parent.computed !== true) return false;
|
|
13118
|
+
if (parentKey === "property" && parent?.type === "StaticMemberExpression") return false;
|
|
13119
|
+
if (parentKey === "property" && parent?.type === "MemberExpression" && parent.computed !== true) return false;
|
|
13120
|
+
return true;
|
|
13121
|
+
}
|
|
13122
|
+
for (const key of Object.keys(rec)) {
|
|
13123
|
+
if (key === "type" || key === "start" || key === "end") continue;
|
|
13124
|
+
const value = rec[key];
|
|
13125
|
+
if (Array.isArray(value)) {
|
|
13126
|
+
if (value.some((child) => walk2(child, rec, key))) return true;
|
|
13127
|
+
} else if (walk2(value, rec, key)) {
|
|
13128
|
+
return true;
|
|
13129
|
+
}
|
|
13130
|
+
}
|
|
13131
|
+
return false;
|
|
13132
|
+
};
|
|
13133
|
+
return body.some((stmt) => walk2(stmt));
|
|
13134
|
+
};
|
|
13135
|
+
for (const imp of ordinaryImports) {
|
|
13136
|
+
if (!runtimeComposeFallback && imp.specifiers.length > 0 && imp.specifiers.every(
|
|
13137
|
+
(spec) => spec.type === "ImportSpecifier" && usedImportedFactories.has(spec.local) && !importedBindingStillReferenced(spec.local)
|
|
13138
|
+
)) {
|
|
13139
|
+
ms.remove(imp.start, imp.end);
|
|
13140
|
+
}
|
|
13141
|
+
}
|
|
12665
13142
|
if (!anyUnresolved) {
|
|
12666
13143
|
for (const { start, end } of defineRemovals) ms.remove(start, end);
|
|
12667
13144
|
}
|