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.cjs
CHANGED
|
@@ -317,6 +317,65 @@ function failAt(ctx, expected, pos) {
|
|
|
317
317
|
return r;
|
|
318
318
|
}
|
|
319
319
|
|
|
320
|
+
// src/line-index.ts
|
|
321
|
+
function createLineIndex() {
|
|
322
|
+
return { lineStarts: [0] };
|
|
323
|
+
}
|
|
324
|
+
function recordLineRange(index, input, start, end) {
|
|
325
|
+
const lineStarts = index.lineStarts;
|
|
326
|
+
for (let i = start; i < end; i++) {
|
|
327
|
+
if (input.charCodeAt(i) === 10) lineStarts.push(i + 1);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
function recordLineRangeFromContext(ctx, input, _startHint, end) {
|
|
331
|
+
if (!ctx.trackLines) return;
|
|
332
|
+
const from = ctx._lineScannedTo ?? 0;
|
|
333
|
+
if (end <= from) return;
|
|
334
|
+
const index = ctx._lineIndex ?? (ctx._lineStarts ? { lineStarts: ctx._lineStarts } : void 0);
|
|
335
|
+
if (!index) return;
|
|
336
|
+
recordLineRange(index, input, from, end);
|
|
337
|
+
ctx._lineScannedTo = end;
|
|
338
|
+
}
|
|
339
|
+
function normalizeLineIndex(index) {
|
|
340
|
+
const starts = index.lineStarts;
|
|
341
|
+
starts.sort((a, b) => a - b);
|
|
342
|
+
let write = 0;
|
|
343
|
+
for (let read = 0; read < starts.length; read++) {
|
|
344
|
+
const value = starts[read];
|
|
345
|
+
if (write === 0 || starts[write - 1] !== value) starts[write++] = value;
|
|
346
|
+
}
|
|
347
|
+
starts.length = write;
|
|
348
|
+
if (starts.length === 0 || starts[0] !== 0) starts.unshift(0);
|
|
349
|
+
return index;
|
|
350
|
+
}
|
|
351
|
+
function offsetToLineCol(index, offset) {
|
|
352
|
+
const { lineStarts } = index;
|
|
353
|
+
let lo = 0;
|
|
354
|
+
let hi = lineStarts.length - 1;
|
|
355
|
+
while (lo < hi) {
|
|
356
|
+
const mid = lo + hi + 1 >> 1;
|
|
357
|
+
if (lineStarts[mid] <= offset) lo = mid;
|
|
358
|
+
else hi = mid - 1;
|
|
359
|
+
}
|
|
360
|
+
return { line: lo + 1, col: offset - lineStarts[lo] + 1 };
|
|
361
|
+
}
|
|
362
|
+
function annotateSpan(span, index) {
|
|
363
|
+
const s = offsetToLineCol(index, span.start);
|
|
364
|
+
const e = offsetToLineCol(index, span.end);
|
|
365
|
+
return {
|
|
366
|
+
...span,
|
|
367
|
+
startLine: s.line,
|
|
368
|
+
startColumn: s.col,
|
|
369
|
+
endLine: e.line,
|
|
370
|
+
endColumn: e.col
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
function annotateSpanFromLineContext(span, ctx) {
|
|
374
|
+
if (!ctx.trackLines) return span;
|
|
375
|
+
const index = ctx._lineIndex ?? (ctx._lineStarts ? { lineStarts: ctx._lineStarts } : void 0);
|
|
376
|
+
return index ? annotateSpan(span, index) : span;
|
|
377
|
+
}
|
|
378
|
+
|
|
320
379
|
// src/cst/capture-buffer.ts
|
|
321
380
|
var EMPTY = [];
|
|
322
381
|
var EMPTY_TL = [];
|
|
@@ -358,7 +417,12 @@ function endCstNodeCapture(ctx, saved) {
|
|
|
358
417
|
return materialized;
|
|
359
418
|
}
|
|
360
419
|
function pushCstLeaf(ctx, leaf2) {
|
|
361
|
-
|
|
420
|
+
if (!ctx.trackLines) {
|
|
421
|
+
pushCstChild(ctx, leaf2, leaf2);
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
const annotated = leaf2 && typeof leaf2 === "object" && leaf2.span ? { ...leaf2, span: annotateSpanFromLineContext(leaf2.span, ctx) } : leaf2;
|
|
425
|
+
pushCstChild(ctx, annotated, annotated);
|
|
362
426
|
}
|
|
363
427
|
function pushCstChild(ctx, built, rawEntry) {
|
|
364
428
|
const b = ctx._cstBuf;
|
|
@@ -492,6 +556,7 @@ function literal(value, opts = {}) {
|
|
|
492
556
|
canMatchNewline: value.includes("\n"),
|
|
493
557
|
isTrivia: false
|
|
494
558
|
};
|
|
559
|
+
const canMatchNewline = meta.canMatchNewline;
|
|
495
560
|
if (caseInsensitive) {
|
|
496
561
|
const upper = value.toUpperCase();
|
|
497
562
|
const lower = value.toLowerCase();
|
|
@@ -508,6 +573,7 @@ function literal(value, opts = {}) {
|
|
|
508
573
|
return function parse3(input, pos, ctx) {
|
|
509
574
|
if (input.charCodeAt(pos) === code) {
|
|
510
575
|
const span = { start: pos, end: pos + 1 };
|
|
576
|
+
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, span.end);
|
|
511
577
|
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
512
578
|
return { ok: true, value, span };
|
|
513
579
|
}
|
|
@@ -521,6 +587,7 @@ function literal(value, opts = {}) {
|
|
|
521
587
|
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
522
588
|
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
523
589
|
const span = { start: pos, end };
|
|
590
|
+
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, end);
|
|
524
591
|
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: matchedValue, span });
|
|
525
592
|
return { ok: true, value: matchedValue, span };
|
|
526
593
|
}
|
|
@@ -688,6 +755,7 @@ function regex(pattern, flags = "") {
|
|
|
688
755
|
if (scanEnd === null) return failAt(ctx, [`/${source}/`], pos);
|
|
689
756
|
const value = input.slice(pos, scanEnd);
|
|
690
757
|
const span2 = { start: pos, end: scanEnd };
|
|
758
|
+
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, scanEnd);
|
|
691
759
|
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span: span2 });
|
|
692
760
|
return { ok: true, value, span: span2 };
|
|
693
761
|
}
|
|
@@ -697,6 +765,7 @@ function regex(pattern, flags = "") {
|
|
|
697
765
|
return failAt(ctx, [`/${source}/`], pos);
|
|
698
766
|
}
|
|
699
767
|
const span = { start: pos, end: pos + m[0].length };
|
|
768
|
+
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, span.end);
|
|
700
769
|
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: m[0], span });
|
|
701
770
|
return { ok: true, value: m[0], span };
|
|
702
771
|
}
|
|
@@ -835,8 +904,8 @@ function parseRegex(src) {
|
|
|
835
904
|
}
|
|
836
905
|
if (src[k] !== "]") throw BAIL;
|
|
837
906
|
i = k + 1;
|
|
838
|
-
if (negated) return charNode(any(), true);
|
|
839
907
|
const ranges = parseClassRanges(body);
|
|
908
|
+
if (negated) return charNode(any(), !ranges || !rangesHaveNewline(ranges));
|
|
840
909
|
if (!ranges) return charNode(any(), true);
|
|
841
910
|
return charNode(rangesToSet(ranges), rangesHaveNewline(ranges));
|
|
842
911
|
};
|
|
@@ -932,7 +1001,7 @@ function firstSet(n) {
|
|
|
932
1001
|
}
|
|
933
1002
|
}
|
|
934
1003
|
}
|
|
935
|
-
function
|
|
1004
|
+
function canConsumeNewline(n) {
|
|
936
1005
|
switch (n.t) {
|
|
937
1006
|
case "char":
|
|
938
1007
|
return n.nl;
|
|
@@ -941,16 +1010,11 @@ function firstCanBeNewline(n) {
|
|
|
941
1010
|
case "empty":
|
|
942
1011
|
return false;
|
|
943
1012
|
case "rep":
|
|
944
|
-
return
|
|
1013
|
+
return canConsumeNewline(n.node);
|
|
945
1014
|
case "alt":
|
|
946
|
-
return n.arms.some(
|
|
947
|
-
case "seq":
|
|
948
|
-
|
|
949
|
-
if (firstCanBeNewline(part)) return true;
|
|
950
|
-
if (!nullable(part)) break;
|
|
951
|
-
}
|
|
952
|
-
return false;
|
|
953
|
-
}
|
|
1015
|
+
return n.arms.some(canConsumeNewline);
|
|
1016
|
+
case "seq":
|
|
1017
|
+
return n.parts.some(canConsumeNewline);
|
|
954
1018
|
}
|
|
955
1019
|
}
|
|
956
1020
|
function firstSetFromRegex(source) {
|
|
@@ -960,8 +1024,8 @@ function firstSetFromRegex(source) {
|
|
|
960
1024
|
} catch {
|
|
961
1025
|
return { firstSet: any(), canMatchNewline: true };
|
|
962
1026
|
}
|
|
963
|
-
if (nullable(ast)) return { firstSet: any(), canMatchNewline:
|
|
964
|
-
return { firstSet: firstSet(ast), canMatchNewline:
|
|
1027
|
+
if (nullable(ast)) return { firstSet: any(), canMatchNewline: canConsumeNewline(ast) };
|
|
1028
|
+
return { firstSet: firstSet(ast), canMatchNewline: canConsumeNewline(ast) };
|
|
965
1029
|
}
|
|
966
1030
|
|
|
967
1031
|
// src/combinators/case-fold.ts
|
|
@@ -1118,7 +1182,9 @@ function firstSetSentinel(fs2) {
|
|
|
1118
1182
|
function recoverScan(input, from, ctx, sync, expected) {
|
|
1119
1183
|
let scanPos = from;
|
|
1120
1184
|
while (scanPos < input.length && !probeAt(sync, input, scanPos, ctx)) scanPos++;
|
|
1121
|
-
const
|
|
1185
|
+
const span = { start: from, end: scanPos };
|
|
1186
|
+
if (ctx.trackLines) recordLineRangeFromContext(ctx, input, from, scanPos);
|
|
1187
|
+
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1122
1188
|
ctx._errors?.push(error);
|
|
1123
1189
|
return { error, end: scanPos };
|
|
1124
1190
|
}
|
|
@@ -1220,7 +1286,8 @@ function expect(combinator, label2) {
|
|
|
1220
1286
|
parse(input, pos, ctx) {
|
|
1221
1287
|
const result = combinator.parse(input, pos, ctx);
|
|
1222
1288
|
if (result.ok) return result;
|
|
1223
|
-
const
|
|
1289
|
+
const span = { start: pos, end: pos };
|
|
1290
|
+
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1224
1291
|
ctx._errors?.push(error);
|
|
1225
1292
|
if (ctx._tolerant) captureError(ctx, error);
|
|
1226
1293
|
return { ok: true, value: error, span: { start: pos, end: pos } };
|
|
@@ -1665,6 +1732,18 @@ function rollbackTrivia(ctx, mark) {
|
|
|
1665
1732
|
rollbackCstCapture(ctx, { raw: mark.raw, tlog: mark.tlog, leaves: mark.leaves, fields: mark.fields, errors: mark.errors });
|
|
1666
1733
|
if (ctx._triviaLog && ctx._triviaLog.length !== mark.log) ctx._triviaLog.length = mark.log;
|
|
1667
1734
|
}
|
|
1735
|
+
function parseTriviaNoCapture(triviaP, input, cur, ctx) {
|
|
1736
|
+
const probeCtx = {
|
|
1737
|
+
trackLines: ctx.trackLines,
|
|
1738
|
+
state: ctx.state,
|
|
1739
|
+
...ctx._lineIndex ? { _lineIndex: ctx._lineIndex } : {},
|
|
1740
|
+
...ctx._lineStarts ? { _lineStarts: ctx._lineStarts } : {},
|
|
1741
|
+
...ctx._lineScannedTo !== void 0 ? { _lineScannedTo: ctx._lineScannedTo } : {}
|
|
1742
|
+
};
|
|
1743
|
+
const result = triviaP.parse(input, cur, probeCtx);
|
|
1744
|
+
ctx._lineScannedTo = probeCtx._lineScannedTo;
|
|
1745
|
+
return result;
|
|
1746
|
+
}
|
|
1668
1747
|
function saveLookaheadMark(ctx) {
|
|
1669
1748
|
return { ...saveTriviaMark(ctx), probeBest: ctx._probe ? ctx._probe.best : null };
|
|
1670
1749
|
}
|
|
@@ -1687,13 +1766,29 @@ function scanWithLabels(input, cur, ctx) {
|
|
|
1687
1766
|
function advanceTrivia(input, cur, ctx) {
|
|
1688
1767
|
const triviaP = ctx.trivia;
|
|
1689
1768
|
if (!triviaP) return cur;
|
|
1769
|
+
if (!ctx.trackLines) {
|
|
1770
|
+
const fast2 = fastTriviaScanner(triviaP);
|
|
1771
|
+
if (fast2) return fast2(input, cur);
|
|
1772
|
+
if (ctx.triviaKindLabels) {
|
|
1773
|
+
const scan = scanWithLabels(input, cur, ctx);
|
|
1774
|
+
return scan.end;
|
|
1775
|
+
}
|
|
1776
|
+
const tr2 = triviaP.parse(input, cur, { trackLines: ctx.trackLines, state: ctx.state });
|
|
1777
|
+
return tr2.ok && tr2.span.end > cur ? tr2.span.end : cur;
|
|
1778
|
+
}
|
|
1779
|
+
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1690
1780
|
const fast = fastTriviaScanner(triviaP);
|
|
1691
|
-
if (fast)
|
|
1781
|
+
if (fast) {
|
|
1782
|
+
const end = fast(input, cur);
|
|
1783
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1784
|
+
return end;
|
|
1785
|
+
}
|
|
1692
1786
|
if (ctx.triviaKindLabels) {
|
|
1693
1787
|
const scan = scanWithLabels(input, cur, ctx);
|
|
1788
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
|
|
1694
1789
|
return scan.end;
|
|
1695
1790
|
}
|
|
1696
|
-
const tr = triviaP
|
|
1791
|
+
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1697
1792
|
return tr.ok && tr.span.end > cur ? tr.span.end : cur;
|
|
1698
1793
|
}
|
|
1699
1794
|
function scanTrivia(input, cur, ctx) {
|
|
@@ -1701,18 +1796,46 @@ function scanTrivia(input, cur, ctx) {
|
|
|
1701
1796
|
if (!triviaP) return { end: cur, commit: NOOP_COMMIT };
|
|
1702
1797
|
const log = ctx._triviaLog;
|
|
1703
1798
|
const captureTl = ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0);
|
|
1799
|
+
if (!ctx.trackLines) {
|
|
1800
|
+
const fast2 = !ctx.triviaKindLabels ? fastTriviaScanner(triviaP) : null;
|
|
1801
|
+
if (fast2 && log === void 0 && !captureTl) {
|
|
1802
|
+
return { end: fast2(input, cur), commit: NOOP_COMMIT };
|
|
1803
|
+
}
|
|
1804
|
+
if (ctx.triviaKindLabels && (log !== void 0 || captureTl)) {
|
|
1805
|
+
return scanWithLabels(input, cur, ctx);
|
|
1806
|
+
}
|
|
1807
|
+
if (log !== void 0 || captureTl) {
|
|
1808
|
+
const tr3 = triviaP.parse(input, cur, {
|
|
1809
|
+
trackLines: log !== void 0 ? false : ctx.trackLines,
|
|
1810
|
+
state: ctx.state
|
|
1811
|
+
});
|
|
1812
|
+
if (!tr3.ok || tr3.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1813
|
+
const end = tr3.span.end;
|
|
1814
|
+
return {
|
|
1815
|
+
end,
|
|
1816
|
+
commit: () => {
|
|
1817
|
+
pushTriviaLogEntry(ctx, cur, end);
|
|
1818
|
+
if (captureTl) pushCstTriviaEntry(ctx, cur, end);
|
|
1819
|
+
}
|
|
1820
|
+
};
|
|
1821
|
+
}
|
|
1822
|
+
const tr2 = triviaP.parse(input, cur, { trackLines: ctx.trackLines, state: ctx.state });
|
|
1823
|
+
return { end: tr2.ok ? tr2.span.end : cur, commit: NOOP_COMMIT };
|
|
1824
|
+
}
|
|
1825
|
+
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1704
1826
|
const fast = !ctx.triviaKindLabels ? fastTriviaScanner(triviaP) : null;
|
|
1705
1827
|
if (fast && log === void 0 && !captureTl) {
|
|
1706
|
-
|
|
1828
|
+
const end = fast(input, cur);
|
|
1829
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1830
|
+
return { end, commit: NOOP_COMMIT };
|
|
1707
1831
|
}
|
|
1708
1832
|
if (ctx.triviaKindLabels && (log !== void 0 || captureTl)) {
|
|
1709
|
-
|
|
1833
|
+
const scan = scanWithLabels(input, cur, ctx);
|
|
1834
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
|
|
1835
|
+
return scan;
|
|
1710
1836
|
}
|
|
1711
1837
|
if (log !== void 0 || captureTl) {
|
|
1712
|
-
const tr2 = triviaP
|
|
1713
|
-
trackLines: log !== void 0 ? false : ctx.trackLines,
|
|
1714
|
-
state: ctx.state
|
|
1715
|
-
});
|
|
1838
|
+
const tr2 = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1716
1839
|
if (!tr2.ok || tr2.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1717
1840
|
const end = tr2.span.end;
|
|
1718
1841
|
return {
|
|
@@ -1723,7 +1846,7 @@ function scanTrivia(input, cur, ctx) {
|
|
|
1723
1846
|
}
|
|
1724
1847
|
};
|
|
1725
1848
|
}
|
|
1726
|
-
const tr = triviaP
|
|
1849
|
+
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1727
1850
|
return { end: tr.ok ? tr.span.end : cur, commit: NOOP_COMMIT };
|
|
1728
1851
|
}
|
|
1729
1852
|
function consumeTrivia(input, cur, ctx) {
|
|
@@ -2654,6 +2777,74 @@ function markUnusedValues(root) {
|
|
|
2654
2777
|
visit(resolveRoot(root), true);
|
|
2655
2778
|
}
|
|
2656
2779
|
|
|
2780
|
+
// src/combinators/grammar.ts
|
|
2781
|
+
function annotateResultLines(result, index) {
|
|
2782
|
+
const annotated = { ...result, span: annotateSpan(result.span, index) };
|
|
2783
|
+
const errors = annotated.errors;
|
|
2784
|
+
if (errors) {
|
|
2785
|
+
;
|
|
2786
|
+
annotated.errors = errors.map((error) => ({
|
|
2787
|
+
...error,
|
|
2788
|
+
span: annotateSpan(error.span, index)
|
|
2789
|
+
}));
|
|
2790
|
+
}
|
|
2791
|
+
return annotated;
|
|
2792
|
+
}
|
|
2793
|
+
function createParseLineContext(input, pos) {
|
|
2794
|
+
const lineIndex = createLineIndex();
|
|
2795
|
+
if (pos > 0) recordLineRange(lineIndex, input, 0, pos);
|
|
2796
|
+
return { lineIndex, lineScannedTo: pos };
|
|
2797
|
+
}
|
|
2798
|
+
function parser(opts, root) {
|
|
2799
|
+
const clearTrivia = opts.trivia === null;
|
|
2800
|
+
return {
|
|
2801
|
+
_tag: "grammar",
|
|
2802
|
+
_meta: root._meta,
|
|
2803
|
+
_def: {
|
|
2804
|
+
tag: "grammar",
|
|
2805
|
+
parser: root,
|
|
2806
|
+
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
2807
|
+
clearTrivia,
|
|
2808
|
+
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
2809
|
+
trackLines: opts.trackLines ?? false
|
|
2810
|
+
},
|
|
2811
|
+
parse(input, pos, _ctx) {
|
|
2812
|
+
const trackLines = opts.trackLines ?? _ctx?.trackLines ?? false;
|
|
2813
|
+
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
2814
|
+
const lineIndex = trackLines ? _ctx?._lineIndex ?? (_ctx?._lineStarts ? { lineStarts: _ctx._lineStarts } : lineContext.lineIndex) : void 0;
|
|
2815
|
+
const ctx = {
|
|
2816
|
+
..._ctx,
|
|
2817
|
+
trackLines,
|
|
2818
|
+
...lineIndex ? { _lineIndex: lineIndex } : {},
|
|
2819
|
+
...lineContext ? { _lineScannedTo: lineContext.lineScannedTo } : {},
|
|
2820
|
+
// trivia: null clears (contiguous terms); a Combinator sets; undefined inherits.
|
|
2821
|
+
...clearTrivia ? {
|
|
2822
|
+
trivia: void 0,
|
|
2823
|
+
triviaKindLabels: void 0
|
|
2824
|
+
} : opts.trivia != null ? {
|
|
2825
|
+
trivia: opts.trivia,
|
|
2826
|
+
...opts.trivia._meta.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {}
|
|
2827
|
+
} : {},
|
|
2828
|
+
...opts.captureTrivia || _ctx?.captureTrivia ? { captureTrivia: true } : {},
|
|
2829
|
+
// Kind-filter for per-node capture. Resolve against this scope's trivia
|
|
2830
|
+
// labels — this parser's own trivia if it declares one, else the INHERITED
|
|
2831
|
+
// labels (`_ctx.triviaKindLabels`), so captureTriviaKinds still applies when
|
|
2832
|
+
// trivia is inherited rather than re-declared here. No labels → undefined
|
|
2833
|
+
// (capture all).
|
|
2834
|
+
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {}
|
|
2835
|
+
};
|
|
2836
|
+
const result = root.parse(input, pos ?? 0, ctx);
|
|
2837
|
+
if (trackLines && _ctx && ctx._lineScannedTo !== void 0) {
|
|
2838
|
+
_ctx._lineScannedTo = Math.max(_ctx._lineScannedTo ?? 0, ctx._lineScannedTo);
|
|
2839
|
+
}
|
|
2840
|
+
return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
2841
|
+
}
|
|
2842
|
+
};
|
|
2843
|
+
}
|
|
2844
|
+
function noTrivia(root) {
|
|
2845
|
+
return parser({ trivia: null }, root);
|
|
2846
|
+
}
|
|
2847
|
+
|
|
2657
2848
|
// src/combinators/parser.ts
|
|
2658
2849
|
var RULE_ORDER = "__parsemanRuleOrder";
|
|
2659
2850
|
function tagRule(r, key) {
|
|
@@ -2729,6 +2920,21 @@ function rules(a, b) {
|
|
|
2729
2920
|
if (rule && !rule._meta.isTrivia) rule._meta.grammarHostMode = "cst";
|
|
2730
2921
|
}
|
|
2731
2922
|
}
|
|
2923
|
+
if (options?.trackLines === true) {
|
|
2924
|
+
for (const key of Object.keys(definitions)) {
|
|
2925
|
+
const rule = cache[key];
|
|
2926
|
+
if (rule && !rule._meta.isTrivia) rule._meta.grammarTrackLines = true;
|
|
2927
|
+
}
|
|
2928
|
+
for (const key of Object.keys(definitions)) {
|
|
2929
|
+
const rule = cache[key];
|
|
2930
|
+
if (rule && !rule._meta.isTrivia && rule._def.tag !== "grammar") {
|
|
2931
|
+
const wrapped = parser({ trackLines: true }, rule);
|
|
2932
|
+
tagRule(wrapped, key);
|
|
2933
|
+
wrapped._meta.grammarTrackLines = true;
|
|
2934
|
+
cache[key] = wrapped;
|
|
2935
|
+
}
|
|
2936
|
+
}
|
|
2937
|
+
}
|
|
2732
2938
|
for (const key of Object.keys(definitions)) {
|
|
2733
2939
|
markUnusedValues(cache[key]);
|
|
2734
2940
|
}
|
|
@@ -3107,13 +3313,14 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
3107
3313
|
const st = clonesState && ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
3108
3314
|
const nodeType = def.type ?? missingInferredType();
|
|
3109
3315
|
const cstOutput = cstOutputHost(ctx.build);
|
|
3316
|
+
const span = ctx.trackLines ? annotateSpanFromLineContext(r.span, ctx) : r.span;
|
|
3110
3317
|
const hostState = clonesState ? st : ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
3111
|
-
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,
|
|
3112
|
-
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
|
|
3318
|
+
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 };
|
|
3319
|
+
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 };
|
|
3113
3320
|
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
3114
3321
|
pushCstChild(ctx, built, rawEntry);
|
|
3115
3322
|
}
|
|
3116
|
-
return { ok: true, value: built, span
|
|
3323
|
+
return { ok: true, value: built, span };
|
|
3117
3324
|
}
|
|
3118
3325
|
};
|
|
3119
3326
|
}
|
|
@@ -3184,85 +3391,6 @@ function field(name, combinator) {
|
|
|
3184
3391
|
};
|
|
3185
3392
|
}
|
|
3186
3393
|
|
|
3187
|
-
// src/compiler/line-index.ts
|
|
3188
|
-
function buildLineIndex(input) {
|
|
3189
|
-
const lineStarts = [0];
|
|
3190
|
-
for (let i = 0; i < input.length; i++) {
|
|
3191
|
-
if (input.charCodeAt(i) === 10) lineStarts.push(i + 1);
|
|
3192
|
-
}
|
|
3193
|
-
return { lineStarts };
|
|
3194
|
-
}
|
|
3195
|
-
function offsetToLineCol(index, offset) {
|
|
3196
|
-
const { lineStarts } = index;
|
|
3197
|
-
let lo = 0;
|
|
3198
|
-
let hi = lineStarts.length - 1;
|
|
3199
|
-
while (lo < hi) {
|
|
3200
|
-
const mid = lo + hi + 1 >> 1;
|
|
3201
|
-
if (lineStarts[mid] <= offset) lo = mid;
|
|
3202
|
-
else hi = mid - 1;
|
|
3203
|
-
}
|
|
3204
|
-
return { line: lo + 1, col: offset - lineStarts[lo] + 1 };
|
|
3205
|
-
}
|
|
3206
|
-
function annotateSpan(span, index) {
|
|
3207
|
-
const s = offsetToLineCol(index, span.start);
|
|
3208
|
-
const e = offsetToLineCol(index, span.end);
|
|
3209
|
-
return {
|
|
3210
|
-
...span,
|
|
3211
|
-
startLine: s.line,
|
|
3212
|
-
startColumn: s.col,
|
|
3213
|
-
endLine: e.line,
|
|
3214
|
-
endColumn: e.col
|
|
3215
|
-
};
|
|
3216
|
-
}
|
|
3217
|
-
|
|
3218
|
-
// src/combinators/grammar.ts
|
|
3219
|
-
function parser(opts, root) {
|
|
3220
|
-
const clearTrivia = opts.trivia === null;
|
|
3221
|
-
return {
|
|
3222
|
-
_tag: "grammar",
|
|
3223
|
-
_meta: root._meta,
|
|
3224
|
-
_def: {
|
|
3225
|
-
tag: "grammar",
|
|
3226
|
-
parser: root,
|
|
3227
|
-
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
3228
|
-
clearTrivia,
|
|
3229
|
-
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
3230
|
-
trackLines: opts.trackLines ?? false
|
|
3231
|
-
},
|
|
3232
|
-
parse(input, pos, _ctx) {
|
|
3233
|
-
const trackLines = opts.trackLines ?? _ctx?.trackLines ?? false;
|
|
3234
|
-
const ctx = {
|
|
3235
|
-
..._ctx,
|
|
3236
|
-
trackLines,
|
|
3237
|
-
// trivia: null clears (contiguous terms); a Combinator sets; undefined inherits.
|
|
3238
|
-
...clearTrivia ? {
|
|
3239
|
-
trivia: void 0,
|
|
3240
|
-
triviaKindLabels: void 0
|
|
3241
|
-
} : opts.trivia != null ? {
|
|
3242
|
-
trivia: opts.trivia,
|
|
3243
|
-
...opts.trivia._meta.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {}
|
|
3244
|
-
} : {},
|
|
3245
|
-
...opts.captureTrivia || _ctx?.captureTrivia ? { captureTrivia: true } : {},
|
|
3246
|
-
// Kind-filter for per-node capture. Resolve against this scope's trivia
|
|
3247
|
-
// labels — this parser's own trivia if it declares one, else the INHERITED
|
|
3248
|
-
// labels (`_ctx.triviaKindLabels`), so captureTriviaKinds still applies when
|
|
3249
|
-
// trivia is inherited rather than re-declared here. No labels → undefined
|
|
3250
|
-
// (capture all).
|
|
3251
|
-
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {}
|
|
3252
|
-
};
|
|
3253
|
-
const result = root.parse(input, pos ?? 0, ctx);
|
|
3254
|
-
if (trackLines) {
|
|
3255
|
-
const idx = buildLineIndex(input);
|
|
3256
|
-
return { ...result, span: annotateSpan(result.span, idx) };
|
|
3257
|
-
}
|
|
3258
|
-
return result;
|
|
3259
|
-
}
|
|
3260
|
-
};
|
|
3261
|
-
}
|
|
3262
|
-
function noTrivia(root) {
|
|
3263
|
-
return parser({ trivia: null }, root);
|
|
3264
|
-
}
|
|
3265
|
-
|
|
3266
3394
|
// src/combinators/token.ts
|
|
3267
3395
|
function token(root) {
|
|
3268
3396
|
const meta = {
|
|
@@ -3359,7 +3487,7 @@ function leaf(root, fn) {
|
|
|
3359
3487
|
}
|
|
3360
3488
|
|
|
3361
3489
|
// src/version.ts
|
|
3362
|
-
var PARSEMAN_VERSION = "0.
|
|
3490
|
+
var PARSEMAN_VERSION = "0.42.1";
|
|
3363
3491
|
|
|
3364
3492
|
// src/cst/host-mode.ts
|
|
3365
3493
|
var FUSED_HOST_MODE = /* @__PURE__ */ Symbol.for("parseman.fusedHostMode");
|
|
@@ -5043,7 +5171,7 @@ function scanTo(sentinel, { skip: skip2, raw = false, orEOF = false } = {}) {
|
|
|
5043
5171
|
let cur = pos;
|
|
5044
5172
|
const skip3 = resolveScanSkip(explicitSkip, raw, ctx);
|
|
5045
5173
|
const probeCtx = {
|
|
5046
|
-
trackLines:
|
|
5174
|
+
trackLines: false,
|
|
5047
5175
|
state: ctx.state,
|
|
5048
5176
|
...ctx._errors !== void 0 ? { _errors: ctx._errors } : {}
|
|
5049
5177
|
};
|
|
@@ -5056,6 +5184,7 @@ function scanTo(sentinel, { skip: skip2, raw = false, orEOF = false } = {}) {
|
|
|
5056
5184
|
while (cur < input.length) {
|
|
5057
5185
|
const s = sentinel.parse(input, cur, probeCtx);
|
|
5058
5186
|
if (s.ok) {
|
|
5187
|
+
if (ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, cur);
|
|
5059
5188
|
emit2(cur);
|
|
5060
5189
|
return { ok: true, value: input.slice(pos, cur), span: { start: pos, end: cur } };
|
|
5061
5190
|
}
|
|
@@ -5071,6 +5200,7 @@ function scanTo(sentinel, { skip: skip2, raw = false, orEOF = false } = {}) {
|
|
|
5071
5200
|
if (!advanced) cur++;
|
|
5072
5201
|
}
|
|
5073
5202
|
if (orEOF) {
|
|
5203
|
+
if (ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, cur);
|
|
5074
5204
|
emit2(cur);
|
|
5075
5205
|
return { ok: true, value: input.slice(pos, cur), span: { start: pos, end: cur } };
|
|
5076
5206
|
}
|
|
@@ -6509,8 +6639,8 @@ function analyzeMkInlineBuild(def) {
|
|
|
6509
6639
|
if (looseMkBuildRe(def.type).test(src)) return def.type;
|
|
6510
6640
|
return null;
|
|
6511
6641
|
}
|
|
6512
|
-
function emitInlineMkNodeExpr(type, chV, rawV,
|
|
6513
|
-
return `{ _tag: 'node', type: ${JSON.stringify(type)}, span:
|
|
6642
|
+
function emitInlineMkNodeExpr(type, chV, rawV, spanExpr, tlV) {
|
|
6643
|
+
return `{ _tag: 'node', type: ${JSON.stringify(type)}, span: ${spanExpr}, children: ${chV}, rawCount: ${rawV}.length, localTriviaLen: ${tlV}.length }`;
|
|
6514
6644
|
}
|
|
6515
6645
|
|
|
6516
6646
|
// src/compiler/inline-callback.ts
|
|
@@ -6692,6 +6822,8 @@ function leadingFirstSetRecipe(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
6692
6822
|
}
|
|
6693
6823
|
}
|
|
6694
6824
|
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 }";
|
|
6825
|
+
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 }";
|
|
6826
|
+
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] } }";
|
|
6695
6827
|
var _loweringSink = null;
|
|
6696
6828
|
function beginLoweringCapture() {
|
|
6697
6829
|
_loweringSink = /* @__PURE__ */ new Set();
|
|
@@ -6723,13 +6855,16 @@ function reindentStmts(stmts, targetLevels) {
|
|
|
6723
6855
|
const targetPrefix = " ".repeat(targetLevels);
|
|
6724
6856
|
return stmts.map((s) => s.trim().length === 0 ? "" : targetPrefix + s.slice(minLeading));
|
|
6725
6857
|
}
|
|
6726
|
-
function failReturn(expected, posExpr) {
|
|
6858
|
+
function failReturn(ctx, expected, posExpr) {
|
|
6859
|
+
if (ctx.lineTracking) return `return { ok: false, expected: [${expected}], span: ${emitSpanExpr(ctx, posExpr, posExpr)} }`;
|
|
6727
6860
|
return `return { ok: false, expected: [${expected}], span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
6728
6861
|
}
|
|
6729
|
-
function failReturnArr(expectedArr, posExpr) {
|
|
6862
|
+
function failReturnArr(ctx, expectedArr, posExpr) {
|
|
6863
|
+
if (ctx.lineTracking) return `return { ok: false, expected: ${expectedArr}, span: ${emitSpanExpr(ctx, posExpr, posExpr)} }`;
|
|
6730
6864
|
return `return { ok: false, expected: ${expectedArr}, span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
6731
6865
|
}
|
|
6732
|
-
function committedReturnArr(expectedArr, posExpr) {
|
|
6866
|
+
function committedReturnArr(ctx, expectedArr, posExpr) {
|
|
6867
|
+
if (ctx.lineTracking) return `return { ok: false, expected: [...${expectedArr}], span: ${emitSpanExpr(ctx, posExpr, posExpr)}, committed: true }`;
|
|
6733
6868
|
return `return { ok: false, expected: [...${expectedArr}], span: { start: ${posExpr}, end: ${posExpr} }, committed: true }`;
|
|
6734
6869
|
}
|
|
6735
6870
|
function hoistExpected(ctx, constArrSource) {
|
|
@@ -6754,7 +6889,7 @@ function failBody(ctx, expected, posExpr) {
|
|
|
6754
6889
|
if (!ctx.recordFail) return probe ? `{ ${probe}${trace}break ${ctx.failLabel} }` : trace ? `{ ${trace}break ${ctx.failLabel} }` : `break ${ctx.failLabel}`;
|
|
6755
6890
|
return `{ ${probe}_ctx._fe = ${posExpr}; _ctx._fx = ${hoistExpected(ctx, `[${expected}]`)}; ${trace}break ${ctx.failLabel} }`;
|
|
6756
6891
|
}
|
|
6757
|
-
return probe + trace + failReturn(expected, posExpr);
|
|
6892
|
+
return probe + trace + failReturn(ctx, expected, posExpr);
|
|
6758
6893
|
}
|
|
6759
6894
|
function failArrBody(ctx, expectedArr, posExpr, constant = true) {
|
|
6760
6895
|
const probe = probeUpdate(ctx, expectedArr, posExpr, constant);
|
|
@@ -6764,18 +6899,19 @@ function failArrBody(ctx, expectedArr, posExpr, constant = true) {
|
|
|
6764
6899
|
const fx = constant ? hoistExpected(ctx, expectedArr) : expectedArr;
|
|
6765
6900
|
return `{ ${probe}_ctx._fe = ${posExpr}; _ctx._fx = ${fx}; ${trace}break ${ctx.failLabel} }`;
|
|
6766
6901
|
}
|
|
6767
|
-
if (!constant) return `${probe}${trace}return { ok: false, expected: [...${expectedArr}], span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
6768
|
-
return probe + trace + failReturnArr(expectedArr, posExpr);
|
|
6902
|
+
if (!constant) return `${probe}${trace}return { ok: false, expected: [...${expectedArr}], span: ${ctx.lineTracking ? emitSpanExpr(ctx, posExpr, posExpr) : `{ start: ${posExpr}, end: ${posExpr} }`} }`;
|
|
6903
|
+
return probe + trace + failReturnArr(ctx, expectedArr, posExpr);
|
|
6769
6904
|
}
|
|
6770
|
-
function resultFromRecorded(feExpr = "_ctx._fe", fxExpr = "_ctx._fx") {
|
|
6771
|
-
|
|
6905
|
+
function resultFromRecorded(ctx, feExpr = "_ctx._fe", fxExpr = "_ctx._fx") {
|
|
6906
|
+
const spanExpr = ctx.lineTracking ? emitSpanExpr(ctx, feExpr, feExpr) : `{ start: ${feExpr}, end: ${feExpr} }`;
|
|
6907
|
+
return `return { ok: false, expected: [...${fxExpr}], span: ${spanExpr}, ...(_ctx._fc ? { committed: true } : {}) }`;
|
|
6772
6908
|
}
|
|
6773
6909
|
function committedFailBody(ctx, expectedArr = "_ctx._fx", posExpr = "_ctx._fe") {
|
|
6774
6910
|
if (ctx.failLabel) {
|
|
6775
6911
|
if (!ctx.recordFail) return `{ _ctx._fc = true; break ${ctx.failLabel} }`;
|
|
6776
6912
|
return `{ _ctx._fc = true; _ctx._fe = ${posExpr}; _ctx._fx = ${expectedArr}; break ${ctx.failLabel} }`;
|
|
6777
6913
|
}
|
|
6778
|
-
return committedReturnArr(expectedArr, posExpr);
|
|
6914
|
+
return committedReturnArr(ctx, expectedArr, posExpr);
|
|
6779
6915
|
}
|
|
6780
6916
|
function propagateFailBody(ctx, srcCtx = "_ctx") {
|
|
6781
6917
|
if (srcCtx !== "_ctx") {
|
|
@@ -6783,10 +6919,10 @@ function propagateFailBody(ctx, srcCtx = "_ctx") {
|
|
|
6783
6919
|
if (!ctx.recordFail) return `break ${ctx.failLabel}`;
|
|
6784
6920
|
return `{ _ctx._fe = ${srcCtx}._fe; _ctx._fx = ${srcCtx}._fx; _ctx._fc = ${srcCtx}._fc; break ${ctx.failLabel} }`;
|
|
6785
6921
|
}
|
|
6786
|
-
return `{ _ctx._fe = ${srcCtx}._fe; _ctx._fx = ${srcCtx}._fx; _ctx._fc = ${srcCtx}._fc; ${resultFromRecorded()} }`;
|
|
6922
|
+
return `{ _ctx._fe = ${srcCtx}._fe; _ctx._fx = ${srcCtx}._fx; _ctx._fc = ${srcCtx}._fc; ${resultFromRecorded(ctx)} }`;
|
|
6787
6923
|
}
|
|
6788
6924
|
if (ctx.failLabel) return `break ${ctx.failLabel}`;
|
|
6789
|
-
return resultFromRecorded();
|
|
6925
|
+
return resultFromRecorded(ctx);
|
|
6790
6926
|
}
|
|
6791
6927
|
function emitIfFail(ctx, cond, body) {
|
|
6792
6928
|
return [
|
|
@@ -6840,14 +6976,46 @@ function emitLeafCapture(ctx, valExpr, startExpr, endExpr) {
|
|
|
6840
6976
|
if (ctx.capAsTrivia) return [];
|
|
6841
6977
|
const i = ind(ctx);
|
|
6842
6978
|
const lf = v(ctx, "_lf");
|
|
6979
|
+
const spanExpr = emitSpanExpr(ctx, startExpr, endExpr);
|
|
6843
6980
|
return [
|
|
6844
6981
|
`${i}if (_ctx._cstLeaves || _ctx._cstRawChildren) {`,
|
|
6845
|
-
`${i} const ${lf} = { _tag: 'leaf', value: ${valExpr}, span:
|
|
6982
|
+
`${i} const ${lf} = { _tag: 'leaf', value: ${valExpr}, span: ${spanExpr} }`,
|
|
6846
6983
|
`${i} if (_ctx._cstLeaves) _ctx._cstLeaves.push(${lf})`,
|
|
6847
6984
|
`${i} if (_ctx._cstRawChildren) _ctx._cstRawChildren.push(${lf})`,
|
|
6848
6985
|
`${i}}`
|
|
6849
6986
|
];
|
|
6850
6987
|
}
|
|
6988
|
+
function emitSpanExpr(ctx, startExpr, endExpr) {
|
|
6989
|
+
if (!ctx.lineTracking) return `{ start: ${startExpr}, end: ${endExpr} }`;
|
|
6990
|
+
ctx.needsLineSpan = true;
|
|
6991
|
+
return `_spanLines(_ctx, ${startExpr}, ${endExpr})`;
|
|
6992
|
+
}
|
|
6993
|
+
function emitLineTrack(ctx, startExpr, endExpr) {
|
|
6994
|
+
if (!ctx.lineTracking) return [];
|
|
6995
|
+
ctx.needsLineTrack = true;
|
|
6996
|
+
return [`${ind(ctx)}_trackLines(_ctx, input, ${startExpr}, ${endExpr})`];
|
|
6997
|
+
}
|
|
6998
|
+
function emitLiteralLineTrack(ctx, startExpr, value) {
|
|
6999
|
+
if (!ctx.lineTracking) return [];
|
|
7000
|
+
const lineDeltas = [];
|
|
7001
|
+
for (let i = 0; i < value.length; i++) {
|
|
7002
|
+
if (value.charCodeAt(i) === 10) lineDeltas.push(i + 1);
|
|
7003
|
+
}
|
|
7004
|
+
if (lineDeltas.length === 0) return [];
|
|
7005
|
+
const fromV = v(ctx, "_ltFrom");
|
|
7006
|
+
const endExpr = value.length === 0 ? startExpr : `${startExpr} + ${value.length}`;
|
|
7007
|
+
return [
|
|
7008
|
+
`${ind(ctx)}const ${fromV} = _ctx._lineScannedTo ?? 0`,
|
|
7009
|
+
`${ind(ctx)}if (${endExpr} > ${fromV}) {`,
|
|
7010
|
+
`${ind(ctx)} for (let i = ${fromV}; i < ${startExpr}; i++) if (input.charCodeAt(i) === 10) _ctx._lineStarts.push(i + 1)`,
|
|
7011
|
+
...lineDeltas.map((delta) => {
|
|
7012
|
+
const lineStart = `${startExpr} + ${delta}`;
|
|
7013
|
+
return `${ind(ctx)} if (${lineStart} > ${fromV}) _ctx._lineStarts.push(${lineStart})`;
|
|
7014
|
+
}),
|
|
7015
|
+
`${ind(ctx)} _ctx._lineScannedTo = ${endExpr}`,
|
|
7016
|
+
`${ind(ctx)}}`
|
|
7017
|
+
];
|
|
7018
|
+
}
|
|
6851
7019
|
function ensureRegexDecl(ctx, source, flags) {
|
|
6852
7020
|
const f = "y" + flags.replace(/[gy]/g, "");
|
|
6853
7021
|
const key = `${source}/${f}`;
|
|
@@ -7232,6 +7400,7 @@ function emitLit(def, ctx, pos) {
|
|
|
7232
7400
|
);
|
|
7233
7401
|
}
|
|
7234
7402
|
const endVar = len === 0 ? pos : `${pos} + ${len}`;
|
|
7403
|
+
stmts.push(...emitLiteralLineTrack(ctx, pos, value));
|
|
7235
7404
|
stmts.push(...emitLeafCapture(ctx, vv, pos, endVar));
|
|
7236
7405
|
return { stmts, valueVar: vv, endVar };
|
|
7237
7406
|
}
|
|
@@ -7311,7 +7480,7 @@ function emitKeywords(def, ctx, pos) {
|
|
|
7311
7480
|
stmts.push(...emitLeafCapture(ctx, vv, pos, endVar));
|
|
7312
7481
|
return { stmts, valueVar: vv, endVar };
|
|
7313
7482
|
}
|
|
7314
|
-
function emitRegex(def, ctx, pos) {
|
|
7483
|
+
function emitRegex(def, ctx, pos, canMatchNewline = true) {
|
|
7315
7484
|
const expectedStr = JSON.stringify(`/${def.source}/`);
|
|
7316
7485
|
const shape = scanShapeFromRegex(def.source, def.flags);
|
|
7317
7486
|
if (shape) {
|
|
@@ -7324,7 +7493,11 @@ function emitRegex(def, ctx, pos) {
|
|
|
7324
7493
|
fresh: (prefix) => v(ctx, prefix)
|
|
7325
7494
|
});
|
|
7326
7495
|
if (scanned) {
|
|
7327
|
-
const stmts2 = [
|
|
7496
|
+
const stmts2 = [
|
|
7497
|
+
...scanned.stmts,
|
|
7498
|
+
...canMatchNewline ? emitLineTrack(ctx, pos, scanned.endVar) : [],
|
|
7499
|
+
...emitLeafCapture(ctx, vv2, pos, scanned.endVar)
|
|
7500
|
+
];
|
|
7328
7501
|
return { stmts: stmts2, valueVar: vv2, endVar: scanned.endVar };
|
|
7329
7502
|
}
|
|
7330
7503
|
}
|
|
@@ -7346,6 +7519,7 @@ function emitRegex(def, ctx, pos) {
|
|
|
7346
7519
|
`${ind(ctx)}const ${vv} = ${mv}[0]`
|
|
7347
7520
|
];
|
|
7348
7521
|
const endVar = `${pos} + ${vv}.length`;
|
|
7522
|
+
if (canMatchNewline) stmts.push(...emitLineTrack(ctx, pos, endVar));
|
|
7349
7523
|
stmts.push(...emitLeafCapture(ctx, vv, pos, endVar));
|
|
7350
7524
|
return { stmts, valueVar: vv, endVar };
|
|
7351
7525
|
}
|
|
@@ -7383,7 +7557,8 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7383
7557
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
7384
7558
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
7385
7559
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
7386
|
-
`${ind(ctx)}const ${scanEndV} = ${capFn}(input, ${curV}, _ctx, 1)
|
|
7560
|
+
`${ind(ctx)}const ${scanEndV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
7561
|
+
...emitLineTrack(ctx, curV, scanEndV)
|
|
7387
7562
|
);
|
|
7388
7563
|
const r2 = emit(def.parsers[i], ctx, scanEndV);
|
|
7389
7564
|
stmts.push(...r2.stmts);
|
|
@@ -7401,7 +7576,8 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7401
7576
|
const capArg = ctx.noHoist ? "0" : "_ctx._triviaLog !== undefined ? 2 : 0";
|
|
7402
7577
|
stmts.push(
|
|
7403
7578
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
7404
|
-
`${ind(ctx)}const ${scanEndV} = ${trivFn}(input, ${curV}, _ctx, ${capArg})
|
|
7579
|
+
`${ind(ctx)}const ${scanEndV} = ${trivFn}(input, ${curV}, _ctx, ${capArg})`,
|
|
7580
|
+
...emitLineTrack(ctx, curV, scanEndV)
|
|
7405
7581
|
);
|
|
7406
7582
|
const r2 = emit(def.parsers[i], ctx, scanEndV);
|
|
7407
7583
|
stmts.push(...r2.stmts);
|
|
@@ -8101,14 +8277,15 @@ function emitMany(def, ctx, pos) {
|
|
|
8101
8277
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8102
8278
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8103
8279
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8104
|
-
`${ind(ctx)}const ${npV} = ${capFn}(input, ${curV}, _ctx, 1)
|
|
8280
|
+
`${ind(ctx)}const ${npV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
8281
|
+
...emitLineTrack(ctx, curV, npV)
|
|
8105
8282
|
);
|
|
8106
8283
|
itemPos = npV;
|
|
8107
8284
|
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}; `;
|
|
8108
8285
|
} else {
|
|
8109
8286
|
const trivFn = ensureTriviaFn(ctx);
|
|
8110
8287
|
const npV = v(ctx, "_np");
|
|
8111
|
-
stmts.push(`${ind(ctx)}const ${npV} = ${trivFn}(input, ${curV}, _ctx)
|
|
8288
|
+
stmts.push(`${ind(ctx)}const ${npV} = ${trivFn}(input, ${curV}, _ctx)`, ...emitLineTrack(ctx, curV, npV));
|
|
8112
8289
|
itemPos = npV;
|
|
8113
8290
|
}
|
|
8114
8291
|
}
|
|
@@ -8178,7 +8355,7 @@ function emitAttempt(p, def, ctx, pos) {
|
|
|
8178
8355
|
if (!ctx.recovery && !ctx.coverage && needsFirstSetGuard(def.parser)) {
|
|
8179
8356
|
const gcV = v(ctx, "_agc");
|
|
8180
8357
|
const gExp = armStaticExpected(ctx, def.parser);
|
|
8181
|
-
const gFail = ctx.failLabel ? `{ _ctx._fe = ${pos};${ctx.recordFail ? ` _ctx._fx = ${gExp};` : ""} break ${ctx.failLabel} }` : `{ _ctx._fe = ${pos}; ${failReturnArr(gExp, pos)} }`;
|
|
8358
|
+
const gFail = ctx.failLabel ? `{ _ctx._fe = ${pos};${ctx.recordFail ? ` _ctx._fx = ${gExp};` : ""} break ${ctx.failLabel} }` : `{ _ctx._fe = ${pos}; ${failReturnArr(ctx, gExp, pos)} }`;
|
|
8182
8359
|
preGuard.push(
|
|
8183
8360
|
`${ind(ctx)}const ${gcV} = ${pos} < input.length ? (input.codePointAt(${pos}) ?? -1) : -1`,
|
|
8184
8361
|
`${ind(ctx)}if (!(${firstSetCond(gcV, def.parser._meta.firstSet)})) ${gFail}`
|
|
@@ -8285,7 +8462,8 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8285
8462
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8286
8463
|
`${ind(ctx)}const ${markLv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
8287
8464
|
`${ind(ctx)}const ${markFld} = _ctx._fields ? _ctx._fields.length : 0`,
|
|
8288
|
-
`${ind(ctx)}const ${spV} = ${capFn}(input, ${curV}, _ctx, 1)
|
|
8465
|
+
`${ind(ctx)}const ${spV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
8466
|
+
...emitLineTrack(ctx, curV, spV)
|
|
8289
8467
|
);
|
|
8290
8468
|
sepAtPos = spV;
|
|
8291
8469
|
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}; `;
|
|
@@ -8295,7 +8473,7 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8295
8473
|
const post = postSepMarks();
|
|
8296
8474
|
stmts.push(...post.decl);
|
|
8297
8475
|
const npV = v(ctx, "_np");
|
|
8298
|
-
stmts.push(`${ind(ctx)}const ${npV} = ${capFn}(input, ${sepEnd}, _ctx, 1)
|
|
8476
|
+
stmts.push(`${ind(ctx)}const ${npV} = ${capFn}(input, ${sepEnd}, _ctx, 1)`, ...emitLineTrack(ctx, sepEnd, npV));
|
|
8299
8477
|
const next = emitFallible(def.parser, ctx, npV, true);
|
|
8300
8478
|
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = next;
|
|
8301
8479
|
stmts.push(
|
|
@@ -8307,13 +8485,13 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8307
8485
|
} else {
|
|
8308
8486
|
const trivFn = ensureTriviaFn(ctx);
|
|
8309
8487
|
const spV = v(ctx, "_sp");
|
|
8310
|
-
stmts.push(`${ind(ctx)}const ${spV} = ${trivFn}(input, ${curV}, _ctx)
|
|
8488
|
+
stmts.push(`${ind(ctx)}const ${spV} = ${trivFn}(input, ${curV}, _ctx)`, ...emitLineTrack(ctx, curV, spV));
|
|
8311
8489
|
sepAtPos = spV;
|
|
8312
8490
|
const sep2 = emitFallible(def.separator, ctx, sepAtPos, true);
|
|
8313
8491
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = sep2;
|
|
8314
8492
|
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${sep2.mayCommit ? `if (_ctx._fc) ${committedFailBody(ctx)}; ` : ""}break }`);
|
|
8315
8493
|
const npV = v(ctx, "_np");
|
|
8316
|
-
stmts.push(`${ind(ctx)}const ${npV} = ${trivFn}(input, ${sepEnd}, _ctx)
|
|
8494
|
+
stmts.push(`${ind(ctx)}const ${npV} = ${trivFn}(input, ${sepEnd}, _ctx)`, ...emitLineTrack(ctx, sepEnd, npV));
|
|
8317
8495
|
const next = emitFallible(def.parser, ctx, npV, true);
|
|
8318
8496
|
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = next;
|
|
8319
8497
|
stmts.push(
|
|
@@ -8400,6 +8578,7 @@ function emitScanTo(def, ctx, pos) {
|
|
|
8400
8578
|
}
|
|
8401
8579
|
const valV = v(ctx);
|
|
8402
8580
|
stmts.push(`${ind(ctx)}const ${valV} = input.slice(${pos}, ${curV})`);
|
|
8581
|
+
stmts.push(...emitLineTrack(ctx, pos, curV));
|
|
8403
8582
|
if (ctx.capturing) {
|
|
8404
8583
|
const cap = reindentStmts(emitLeafCapture(ctx, valV, pos, curV), ctx.indent + 1);
|
|
8405
8584
|
stmts.push(`${ind(ctx)}if (${curV} > ${pos}) {`, ...cap, `${ind(ctx)}}`);
|
|
@@ -8543,7 +8722,7 @@ function tokenNullableRegex(def) {
|
|
|
8543
8722
|
}
|
|
8544
8723
|
function emitToken(def, ctx, pos) {
|
|
8545
8724
|
const lowered = tokenNullableRegex(def);
|
|
8546
|
-
if (lowered) return emitRegex(lowered, ctx, pos);
|
|
8725
|
+
if (lowered) return emitRegex(lowered, ctx, pos, def.parser._meta.canMatchNewline);
|
|
8547
8726
|
const savedTrivia = ctx.activeTrivia;
|
|
8548
8727
|
const savedKindLabels = ctx.triviaKindLabels;
|
|
8549
8728
|
ctx.activeTrivia = void 0;
|
|
@@ -8675,7 +8854,7 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8675
8854
|
if (!ctx.recovery && !ctx.coverage && (capturesChildren || structural) && needsFirstSetGuard(def.parser)) {
|
|
8676
8855
|
const gcV = v(ctx, "_ngc");
|
|
8677
8856
|
const gExp = armStaticExpected(ctx, def.parser);
|
|
8678
|
-
const gFail = ctx.failLabel ? ctx.recordFail ? `{ _ctx._fe = ${pos}; _ctx._fx = ${gExp}; break ${ctx.failLabel} }` : `break ${ctx.failLabel}` : failReturnArr(gExp, pos);
|
|
8857
|
+
const gFail = ctx.failLabel ? ctx.recordFail ? `{ _ctx._fe = ${pos}; _ctx._fx = ${gExp}; break ${ctx.failLabel} }` : `break ${ctx.failLabel}` : failReturnArr(ctx, gExp, pos);
|
|
8679
8858
|
preGuard.push(
|
|
8680
8859
|
`${i}const ${gcV} = ${pos} < input.length ? (input.codePointAt(${pos}) ?? -1) : -1`,
|
|
8681
8860
|
`${i}if (!(${firstSetCond(gcV, def.parser._meta.firstSet)})) ${gFail}`
|
|
@@ -8693,7 +8872,7 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8693
8872
|
stmts.push(...innerStmts);
|
|
8694
8873
|
if (def.trailingTrivia === true && ctx.activeTrivia) {
|
|
8695
8874
|
const triviaFn = ensureTriviaFn(ctx);
|
|
8696
|
-
stmts.push(`${i}const ${endVar} = ${okVar} ? ${triviaFn}(input, ${innerEndVar}, _ctx, 1) : ${innerEndVar}
|
|
8875
|
+
stmts.push(`${i}const ${endVar} = ${okVar} ? ${triviaFn}(input, ${innerEndVar}, _ctx, 1) : ${innerEndVar}`, ...emitLineTrack(ctx, innerEndVar, endVar));
|
|
8697
8876
|
}
|
|
8698
8877
|
if (sf && fArr) {
|
|
8699
8878
|
stmts.push(`${i}const ${fArr} = _ctx._fields`);
|
|
@@ -8733,8 +8912,11 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8733
8912
|
);
|
|
8734
8913
|
}
|
|
8735
8914
|
const ndV = v(ctx, "_nd");
|
|
8736
|
-
const
|
|
8737
|
-
const
|
|
8915
|
+
const nodeSpanExpr = emitSpanExpr(ctx, pos, endVar);
|
|
8916
|
+
const nodeSpanV = ctx.lineTracking ? v(ctx, "_nspan") : nodeSpanExpr;
|
|
8917
|
+
if (ctx.lineTracking) stmts.push(`${i}const ${nodeSpanV} = ${nodeSpanExpr}`);
|
|
8918
|
+
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})`;
|
|
8919
|
+
const hostBuildExpr = `_ctx._pmProfile?.phase === 'host' && _ctx._pmProfile.hostCalls++, _ctx.build(${JSON.stringify(def.type)}, ${chV}, ${fObj}, ${nodeSpanV}, ${rawV}, ${tlV}, ${stV})`;
|
|
8738
8920
|
const ndExpr = structural ? `_ctx.build !== undefined ? (${hostBuildExpr}) : (${buildExpr})` : cstOut ? hostBuildExpr : buildExpr;
|
|
8739
8921
|
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;
|
|
8740
8922
|
const unwrapExpr = `${chV}.length === 1 ? (${chV}[0] !== null && typeof ${chV}[0] === 'object' && ${chV}[0]._tag === 'leaf' ? ${chV}[0].value : ${chV}[0]) : (${ndExpr})`;
|
|
@@ -8744,7 +8926,7 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8744
8926
|
`${i}const ${ndV} = (${profileRecognizer} || ${profileCapture}) ? undefined : (${finalExpr})`,
|
|
8745
8927
|
`${i}if (!(${profileRecognizer})) {`,
|
|
8746
8928
|
`${i} if (${sc}) ${sc}.push(${ndV})`,
|
|
8747
|
-
`${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:
|
|
8929
|
+
`${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} })`,
|
|
8748
8930
|
`${i}}`
|
|
8749
8931
|
);
|
|
8750
8932
|
return { stmts, valueVar: ndV, endVar };
|
|
@@ -8760,7 +8942,8 @@ function emitRuntimeFallback(parser2, ctx, pos) {
|
|
|
8760
8942
|
`${ind(ctx)}const ${rv} = _rp[${idx}].parse(input, ${pos}, _ctx)`,
|
|
8761
8943
|
...emitIfFail(ctx, `!${rv}.ok`, failStmt),
|
|
8762
8944
|
`${ind(ctx)}const ${vv} = ${rv}.value`,
|
|
8763
|
-
`${ind(ctx)}const ${ev} = ${rv}.span.end
|
|
8945
|
+
`${ind(ctx)}const ${ev} = ${rv}.span.end`,
|
|
8946
|
+
...parser2._meta.canMatchNewline ? emitLineTrack(ctx, pos, ev) : []
|
|
8764
8947
|
];
|
|
8765
8948
|
return { stmts, valueVar: vv, endVar: ev };
|
|
8766
8949
|
}
|
|
@@ -8826,7 +9009,8 @@ function emitRecover(def, ctx, pos) {
|
|
|
8826
9009
|
`${ind0} if (${sentOk}) break`,
|
|
8827
9010
|
`${ind0} ${scanV}++`,
|
|
8828
9011
|
`${ind0} }`,
|
|
8829
|
-
|
|
9012
|
+
...emitLineTrack(ctx, pos, scanV).map((s) => `${ind0} ${s.trim()}`),
|
|
9013
|
+
`${ind0} const ${errV} = { _tag: 'parseError', span: ${emitSpanExpr(ctx, pos, scanV)}, expected: ${JSON.stringify(deriveExpected(def.parser))} }`,
|
|
8830
9014
|
`${ind0} if (_ctx._errors) _ctx._errors.push(${errV})`,
|
|
8831
9015
|
`${ind0} ${valVar} = ${errV}`,
|
|
8832
9016
|
`${ind0} ${endVar} = ${scanV}`,
|
|
@@ -8842,7 +9026,7 @@ function emitExpect(def, ctx, pos) {
|
|
|
8842
9026
|
const stmts = [
|
|
8843
9027
|
...innerStmts,
|
|
8844
9028
|
`${ind0}if (!${okVar}) {`,
|
|
8845
|
-
`${ind0} const ${errV} = { _tag: 'parseError', span: {
|
|
9029
|
+
`${ind0} const ${errV} = { _tag: 'parseError', span: ${emitSpanExpr(ctx, pos, pos)}, expected: ${JSON.stringify(def.expected)} }`,
|
|
8846
9030
|
`${ind0} if (_ctx._errors) _ctx._errors.push(${errV})`,
|
|
8847
9031
|
// Embed the missing-token error as a `parseError` CST child, mirroring the
|
|
8848
9032
|
// interpreter (expect.ts) and the list-recovery emit sites — guarded on
|
|
@@ -8932,7 +9116,7 @@ function emitDispatch(p, ctx, pos) {
|
|
|
8932
9116
|
case "literal":
|
|
8933
9117
|
return emitLit(def, ctx, pos);
|
|
8934
9118
|
case "regex":
|
|
8935
|
-
return emitRegex(def, ctx, pos);
|
|
9119
|
+
return emitRegex(def, ctx, pos, p._meta.canMatchNewline);
|
|
8936
9120
|
case "keywords":
|
|
8937
9121
|
return emitKeywords(def, ctx, pos);
|
|
8938
9122
|
case "sequence":
|
|
@@ -9182,6 +9366,21 @@ function hasNodeDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9182
9366
|
return false;
|
|
9183
9367
|
}
|
|
9184
9368
|
}
|
|
9369
|
+
function hasLineTrackingDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
9370
|
+
if (seen.has(p)) return false;
|
|
9371
|
+
seen.add(p);
|
|
9372
|
+
const d = p._def;
|
|
9373
|
+
if (p._meta.grammarTrackLines) return true;
|
|
9374
|
+
if (d.tag === "grammar" && d.trackLines) return true;
|
|
9375
|
+
if (d.tag === "lazy") {
|
|
9376
|
+
try {
|
|
9377
|
+
return hasLineTrackingDef(d.thunk(), seen);
|
|
9378
|
+
} catch {
|
|
9379
|
+
return false;
|
|
9380
|
+
}
|
|
9381
|
+
}
|
|
9382
|
+
return childrenOf2(d).some((child) => hasLineTrackingDef(child, seen));
|
|
9383
|
+
}
|
|
9185
9384
|
function parserUsesRouted2(p, seen = /* @__PURE__ */ new Set()) {
|
|
9186
9385
|
if (seen.has(p)) return false;
|
|
9187
9386
|
seen.add(p);
|
|
@@ -9529,6 +9728,7 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9529
9728
|
const grammarTrivia = combinator._meta.grammarTrivia;
|
|
9530
9729
|
const grammarScanSkip = combinator._meta.grammarScanSkip;
|
|
9531
9730
|
const grammarHostMode = combinator._meta.grammarHostMode;
|
|
9731
|
+
const grammarTrackLines = combinator._meta.grammarTrackLines;
|
|
9532
9732
|
const ctx = {
|
|
9533
9733
|
vars: 0,
|
|
9534
9734
|
indent: 1,
|
|
@@ -9549,6 +9749,7 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9549
9749
|
capturing: hasNodeDef(combinator),
|
|
9550
9750
|
recovery: opts?.recovery ?? false,
|
|
9551
9751
|
hostMode: opts?.hostMode ?? grammarHostMode ?? "ast",
|
|
9752
|
+
lineTracking: opts?.trackLines === true || grammarTrackLines === true || hasLineTrackingDef(combinator),
|
|
9552
9753
|
...opts?.coverage ? { coverage: { plan: buildGrammarPlan(combinator), entry: combinator } } : {},
|
|
9553
9754
|
lazyUsage: analyzeLazyUsage(combinator),
|
|
9554
9755
|
...grammarTrivia ? { activeTrivia: grammarTrivia, triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {},
|
|
@@ -9572,9 +9773,13 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9572
9773
|
const namedPrelude = ctx.namedFnDecls.length > 0 ? [...namedFnPrelude(), ""] : [];
|
|
9573
9774
|
const emptyTlDecls = ctx.needsEmptyTl ? ["const _EMPTY_TL = Object.freeze([])"] : [];
|
|
9574
9775
|
const hostReadsDecls = ctx.needsHostReads ? [HOST_READS_DECL] : [];
|
|
9776
|
+
const lineTrackDecls = ctx.needsLineTrack ? [LINE_TRACK_DECL] : [];
|
|
9777
|
+
const lineSpanDecls = ctx.needsLineSpan ? [LINE_SPAN_DECL] : [];
|
|
9575
9778
|
const source = [
|
|
9576
9779
|
...emptyTlDecls,
|
|
9577
9780
|
...hostReadsDecls,
|
|
9781
|
+
...lineTrackDecls,
|
|
9782
|
+
...lineSpanDecls,
|
|
9578
9783
|
...ctx.regexDecls,
|
|
9579
9784
|
...ctx.expectedDecls,
|
|
9580
9785
|
"",
|
|
@@ -9587,6 +9792,8 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9587
9792
|
const fn = new Function("input", "_pos", "_rp", "_mf", "_build", "_ctx", [
|
|
9588
9793
|
...emptyTlDecls,
|
|
9589
9794
|
...hostReadsDecls,
|
|
9795
|
+
...lineTrackDecls,
|
|
9796
|
+
...lineSpanDecls,
|
|
9590
9797
|
...ctx.regexDecls,
|
|
9591
9798
|
...ctx.expectedDecls,
|
|
9592
9799
|
...namedPrelude,
|
|
@@ -9605,6 +9812,25 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9605
9812
|
trackLines: false,
|
|
9606
9813
|
...ctx.triviaKindLabels ? { triviaKindLabels: ctx.triviaKindLabels } : {}
|
|
9607
9814
|
};
|
|
9815
|
+
const annotateWithTrackedLines = (result, lineStarts) => {
|
|
9816
|
+
const index = normalizeLineIndex({ lineStarts });
|
|
9817
|
+
const annotated = { ...result, span: annotateSpan(result.span, index) };
|
|
9818
|
+
const errors = annotated.errors;
|
|
9819
|
+
if (errors) {
|
|
9820
|
+
;
|
|
9821
|
+
annotated.errors = errors.map((error) => ({
|
|
9822
|
+
...error,
|
|
9823
|
+
span: annotateSpan(error.span, index)
|
|
9824
|
+
}));
|
|
9825
|
+
}
|
|
9826
|
+
return annotated;
|
|
9827
|
+
};
|
|
9828
|
+
const trackedCtx = (base, input, pos) => {
|
|
9829
|
+
if (!ctx.lineTracking) return base;
|
|
9830
|
+
const lineIndex = { lineStarts: [0] };
|
|
9831
|
+
if (pos > 0) recordLineRange(lineIndex, input, 0, pos);
|
|
9832
|
+
return { ...base, trackLines: true, _lineStarts: lineIndex.lineStarts, _lineScannedTo: pos };
|
|
9833
|
+
};
|
|
9608
9834
|
const derivedSrcs = ctx.mapFnSrcs.length === ctx.mapFns.length && ctx.mapFnSrcs.every((s) => s !== null) ? ctx.mapFnSrcs : void 0;
|
|
9609
9835
|
const effectiveSources = mapFnSources ?? derivedSrcs;
|
|
9610
9836
|
const buildCovered = ctx.buildFns.length === 0 || ctx.buildSrcs.every((s) => s !== null);
|
|
@@ -9612,17 +9838,46 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9612
9838
|
const mfCovered = ctx.mapFns.length === 0 || effectiveSources !== void 0 && effectiveSources.length === ctx.mapFns.length;
|
|
9613
9839
|
const canInline = ctx.runtimeParsers.length === 0 && mfCovered && buildCovered;
|
|
9614
9840
|
const inlineExpression = canInline ? buildInlineExpression(ctx, r, effectiveSources, buildSources, coverageRootRuleId) : null;
|
|
9615
|
-
|
|
9841
|
+
const compiledMeta = {
|
|
9616
9842
|
source,
|
|
9617
9843
|
inlineExpression,
|
|
9618
9844
|
...ctx.coverage === void 0 ? {} : { coverageDefinitions: ctx.coverage.plan.definitions },
|
|
9619
|
-
...gatingReport === void 0 ? {} : { gating: gatingReport }
|
|
9845
|
+
...gatingReport === void 0 ? {} : { gating: gatingReport }
|
|
9846
|
+
};
|
|
9847
|
+
if (!ctx.lineTracking) {
|
|
9848
|
+
return {
|
|
9849
|
+
...compiledMeta,
|
|
9850
|
+
parse(input, pos = 0) {
|
|
9851
|
+
return fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, defaultCtx);
|
|
9852
|
+
},
|
|
9853
|
+
parseWithContext(input, parseCtx, pos = 0) {
|
|
9854
|
+
assertHostModeCompatible(ctx.hostMode ?? "ast", parseCtx.build, !!ctx.hostBranchElided);
|
|
9855
|
+
return fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, parseCtx);
|
|
9856
|
+
},
|
|
9857
|
+
// Note: collects expect() errors via _errors. Unlike interpreter
|
|
9858
|
+
// parse({recover:true}) it does NOT populate furthestFail — the compiled path
|
|
9859
|
+
// inlines failures for throughput and deliberately skips _probe bookkeeping.
|
|
9860
|
+
// Callers wanting a furthest-position diagnostic detect unconsumed input
|
|
9861
|
+
// (span.end < input.length) instead, which is mode-agnostic.
|
|
9862
|
+
parseWithErrors(input, pos = 0) {
|
|
9863
|
+
const errors = [];
|
|
9864
|
+
const result = fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, { ...defaultCtx, _errors: errors });
|
|
9865
|
+
return { ...result, errors };
|
|
9866
|
+
}
|
|
9867
|
+
};
|
|
9868
|
+
}
|
|
9869
|
+
return {
|
|
9870
|
+
...compiledMeta,
|
|
9620
9871
|
parse(input, pos = 0) {
|
|
9621
|
-
|
|
9872
|
+
const parseCtx = trackedCtx(defaultCtx, input, pos);
|
|
9873
|
+
const result = fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, parseCtx);
|
|
9874
|
+
return annotateWithTrackedLines(result, parseCtx._lineStarts);
|
|
9622
9875
|
},
|
|
9623
9876
|
parseWithContext(input, parseCtx, pos = 0) {
|
|
9624
9877
|
assertHostModeCompatible(ctx.hostMode ?? "ast", parseCtx.build, !!ctx.hostBranchElided);
|
|
9625
|
-
|
|
9878
|
+
const activeCtx = trackedCtx(parseCtx, input, pos);
|
|
9879
|
+
const result = fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, activeCtx);
|
|
9880
|
+
return activeCtx.trackLines ? annotateWithTrackedLines(result, activeCtx._lineStarts) : result;
|
|
9626
9881
|
},
|
|
9627
9882
|
// Note: collects expect() errors via _errors. Unlike interpreter
|
|
9628
9883
|
// parse({recover:true}) it does NOT populate furthestFail — the compiled path
|
|
@@ -9631,8 +9886,9 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9631
9886
|
// (span.end < input.length) instead, which is mode-agnostic.
|
|
9632
9887
|
parseWithErrors(input, pos = 0) {
|
|
9633
9888
|
const errors = [];
|
|
9634
|
-
const
|
|
9635
|
-
|
|
9889
|
+
const parseCtx = trackedCtx({ ...defaultCtx, _errors: errors }, input, pos);
|
|
9890
|
+
const result = { ...fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, parseCtx), errors };
|
|
9891
|
+
return annotateWithTrackedLines(result, parseCtx._lineStarts);
|
|
9636
9892
|
}
|
|
9637
9893
|
};
|
|
9638
9894
|
}
|
|
@@ -9657,6 +9913,7 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
9657
9913
|
const grammarTrivia = opts?.trivia;
|
|
9658
9914
|
const grammarScanSkip = opts?.scanSkip ?? ruleMap.map(([, r]) => r._meta.grammarScanSkip).find(Boolean);
|
|
9659
9915
|
const grammarHostMode = opts?.hostMode ?? ruleMap.map(([, r]) => r._meta.grammarHostMode).find(Boolean);
|
|
9916
|
+
const grammarTrackLines = opts?.trackLines === true || ruleMap.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
9660
9917
|
const ctx = {
|
|
9661
9918
|
vars: 0,
|
|
9662
9919
|
indent: 1,
|
|
@@ -9677,6 +9934,7 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
9677
9934
|
capturing: ruleMap.some(([, rule]) => hasNodeDef(rule)),
|
|
9678
9935
|
recovery: opts?.recovery ?? false,
|
|
9679
9936
|
hostMode: grammarHostMode ?? "ast",
|
|
9937
|
+
lineTracking: grammarTrackLines,
|
|
9680
9938
|
...opts?.coverage ? { coverage: { plan: buildGrammarPlan(ruleMap.map(([, rule]) => rule), coverageWinners) } } : {},
|
|
9681
9939
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
9682
9940
|
...grammarTrivia ? { activeTrivia: grammarTrivia, triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {},
|
|
@@ -9710,12 +9968,18 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
9710
9968
|
const mfCovered = ctx.mapFns.length === 0 || derivedSrcs !== void 0;
|
|
9711
9969
|
const canInline = ctx.runtimeParsers.length === 0 && mfCovered && buildCovered;
|
|
9712
9970
|
if (!canInline) return null;
|
|
9971
|
+
if (ctx.lineTracking) {
|
|
9972
|
+
ctx.needsLineTrack = true;
|
|
9973
|
+
ctx.needsLineSpan = true;
|
|
9974
|
+
}
|
|
9713
9975
|
const mfDecl = derivedSrcs?.length ? ` const ${mfRef(ctx)} = [${derivedSrcs.join(", ")}]` : "";
|
|
9714
9976
|
const buildDecl = buildSources?.length ? ` const ${buildRef(ctx)} = [${buildSources.join(", ")}]` : "";
|
|
9715
9977
|
const namedPrelude = ctx.namedFnDecls.length > 0 ? namedFnPrelude() : [];
|
|
9716
9978
|
const hoistedDecls = [
|
|
9717
9979
|
ctx.needsEmptyTl ? ` const _EMPTY_TL = Object.freeze([])` : "",
|
|
9718
9980
|
ctx.needsHostReads ? ` ${HOST_READS_DECL}` : "",
|
|
9981
|
+
ctx.needsLineTrack ? ` ${LINE_TRACK_DECL}` : "",
|
|
9982
|
+
ctx.needsLineSpan ? ` ${LINE_SPAN_DECL}` : "",
|
|
9719
9983
|
...ctx.regexDecls.map((d) => ` ${d}`),
|
|
9720
9984
|
...ctx.expectedDecls.map((d) => ` ${d}`),
|
|
9721
9985
|
mfDecl,
|
|
@@ -9737,15 +10001,23 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
9737
10001
|
};
|
|
9738
10002
|
const entryFnText = (r, rule) => {
|
|
9739
10003
|
const ruleId = entryRuleId(rule);
|
|
10004
|
+
const linePreamble = ctx.lineTracking ? [
|
|
10005
|
+
` if (_ctx._lineStarts === undefined) _ctx = { ..._ctx, trackLines: true, _lineStarts: [0], _lineScannedTo: 0 }`,
|
|
10006
|
+
` else _ctx.trackLines = true`,
|
|
10007
|
+
` if (_pos > (_ctx._lineScannedTo ?? 0)) _trackLines(_ctx, input, 0, _pos)`
|
|
10008
|
+
] : [];
|
|
10009
|
+
const resultSpan = ctx.lineTracking ? `_spanLines(_ctx, _pos, ${r.endVar})` : `{ start: _pos, end: ${r.endVar} }`;
|
|
9740
10010
|
const body = ruleId === void 0 ? [
|
|
10011
|
+
...linePreamble,
|
|
9741
10012
|
` let pos = _pos`,
|
|
9742
10013
|
...r.stmts,
|
|
9743
|
-
` return { ok: true, value: ${r.valueVar}, span:
|
|
10014
|
+
` return { ok: true, value: ${r.valueVar}, span: ${resultSpan} }`
|
|
9744
10015
|
] : [
|
|
10016
|
+
...linePreamble,
|
|
9745
10017
|
` const _coverageResult = (() => {`,
|
|
9746
10018
|
` let pos = _pos`,
|
|
9747
10019
|
...r.stmts,
|
|
9748
|
-
` return { ok: true, value: ${r.valueVar}, span:
|
|
10020
|
+
` return { ok: true, value: ${r.valueVar}, span: ${resultSpan} }`,
|
|
9749
10021
|
` })()`,
|
|
9750
10022
|
` if (!_coverageResult.ok) _ctx._grammarTrace?.write({ id: ${JSON.stringify(ruleId)}, phase: 'failure', offset: _coverageResult.span.start })`,
|
|
9751
10023
|
` return _coverageResult`
|
|
@@ -9783,6 +10055,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
9783
10055
|
const grammarTrivia = opts?.trivia ?? ruleMapArg.map(([, r]) => r._meta.grammarTrivia).find(Boolean);
|
|
9784
10056
|
const grammarScanSkip = opts?.scanSkip ?? ruleMapArg.map(([, r]) => r._meta.grammarScanSkip).find(Boolean);
|
|
9785
10057
|
const grammarHostMode = opts?.hostMode ?? ruleMapArg.map(([, r]) => r._meta.grammarHostMode).find(Boolean);
|
|
10058
|
+
const grammarTrackLines = opts?.trackLines === true || ruleMapArg.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
9786
10059
|
const ruleMap = ruleMapArg.filter(([, val]) => {
|
|
9787
10060
|
const d = val._def;
|
|
9788
10061
|
if (d.tag !== "lazy") return true;
|
|
@@ -9817,6 +10090,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
9817
10090
|
capturing: opts?.captureTerminals === true || ruleMap.some(([, rule]) => hasNodeDef(rule)),
|
|
9818
10091
|
recovery: opts?.recovery ?? false,
|
|
9819
10092
|
hostMode: grammarHostMode ?? "ast",
|
|
10093
|
+
lineTracking: grammarTrackLines,
|
|
9820
10094
|
...opts?.coverage ? { coverage: { plan: opts.coverage } } : {},
|
|
9821
10095
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
9822
10096
|
ns,
|
|
@@ -9913,6 +10187,10 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
9913
10187
|
perEntry.push({ key, rule, r: emitNamedFnCall(ctx, fn, "_pos") });
|
|
9914
10188
|
}
|
|
9915
10189
|
if (ctx.runtimeParsers.length !== 0) return null;
|
|
10190
|
+
if (ctx.lineTracking) {
|
|
10191
|
+
ctx.needsLineTrack = true;
|
|
10192
|
+
ctx.needsLineSpan = true;
|
|
10193
|
+
}
|
|
9916
10194
|
const mfSrcs = ctx.mapFns.length > 0 && ctx.mapFnSrcs.every((s) => s !== null) ? ctx.mapFnSrcs : null;
|
|
9917
10195
|
const buildSrcs = ctx.buildFns.length > 0 && ctx.buildSrcs.every((s) => s !== null) ? ctx.buildSrcs : null;
|
|
9918
10196
|
const ruleFns = /* @__PURE__ */ new Map();
|
|
@@ -9926,6 +10204,8 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
9926
10204
|
const mfDecl = ctx.mapFns.length === 0 ? "" : mfSrcs ? `const ${mfRef(ctx)} = [${mfSrcs.join(", ")}]` : `const ${mfRef(ctx)} = _env[${JSON.stringify(nsp(ctx) + "mf")}]`;
|
|
9927
10205
|
const buildDecl = ctx.buildFns.length === 0 ? "" : buildSrcs ? `const ${buildRef(ctx)} = [${buildSrcs.join(", ")}]` : `const ${buildRef(ctx)} = _env[${JSON.stringify(nsp(ctx) + "build")}]`;
|
|
9928
10206
|
const prelude = [
|
|
10207
|
+
ctx.needsLineTrack ? LINE_TRACK_DECL : "",
|
|
10208
|
+
ctx.needsLineSpan ? LINE_SPAN_DECL : "",
|
|
9929
10209
|
...ctx.regexDecls,
|
|
9930
10210
|
...ctx.expectedDecls,
|
|
9931
10211
|
mfDecl,
|
|
@@ -9934,11 +10214,18 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
9934
10214
|
].filter(Boolean);
|
|
9935
10215
|
const wrappers = /* @__PURE__ */ new Map();
|
|
9936
10216
|
for (const { key, rule, r } of perEntry) {
|
|
10217
|
+
const linePreamble = ctx.lineTracking ? [
|
|
10218
|
+
` if (_ctx._lineStarts === undefined) _ctx = { ..._ctx, trackLines: true, _lineStarts: [0], _lineScannedTo: 0 }`,
|
|
10219
|
+
` else _ctx.trackLines = true`,
|
|
10220
|
+
` if (_pos > (_ctx._lineScannedTo ?? 0)) _trackLines(_ctx, input, 0, _pos)`
|
|
10221
|
+
] : [];
|
|
10222
|
+
const resultSpan = ctx.lineTracking ? `_spanLines(_ctx, _pos, ${r.endVar})` : `{ start: _pos, end: ${r.endVar} }`;
|
|
9937
10223
|
wrappers.set(key, publicRuleWrapperSource(rule, [
|
|
9938
10224
|
`function(input, _pos, _ctx) {`,
|
|
10225
|
+
...linePreamble,
|
|
9939
10226
|
` let pos = _pos`,
|
|
9940
10227
|
...r.stmts,
|
|
9941
|
-
` return { ok: true, value: ${r.valueVar}, span:
|
|
10228
|
+
` return { ok: true, value: ${r.valueVar}, span: ${resultSpan} }`,
|
|
9942
10229
|
`}`
|
|
9943
10230
|
].join("\n"), ctx.triviaKindLabels));
|
|
9944
10231
|
}
|
|
@@ -10045,12 +10332,16 @@ function buildInlineExpression(ctx, r, mapFnSources, buildSources, coverageRootR
|
|
|
10045
10332
|
const buildDecl = buildSources?.length ? ` const _build = [${buildSources.join(", ")}]` : "";
|
|
10046
10333
|
const emptyTlDecl = ctx.needsEmptyTl ? ` const _EMPTY_TL = Object.freeze([])` : "";
|
|
10047
10334
|
const hostReadsDecl = ctx.needsHostReads ? ` ${HOST_READS_DECL}` : "";
|
|
10048
|
-
const
|
|
10335
|
+
const lineTrackDecl = ctx.needsLineTrack ? ` ${LINE_TRACK_DECL}` : "";
|
|
10336
|
+
const lineSpanDecl = ctx.needsLineSpan ? ` ${LINE_SPAN_DECL}` : "";
|
|
10337
|
+
const needsWrapper = ctx.regexDecls.length > 0 || ctx.expectedDecls.length > 0 || ctx.namedFnDecls.length > 0 || !!mfDecl || !!buildDecl || !!emptyTlDecl || !!hostReadsDecl || !!lineTrackDecl || !!lineSpanDecl;
|
|
10049
10338
|
if (!needsWrapper) return innerFn;
|
|
10050
10339
|
const namedPrelude = ctx.namedFnDecls.length > 0 ? namedFnPrelude() : [];
|
|
10051
10340
|
const hoistedDecls = [
|
|
10052
10341
|
emptyTlDecl,
|
|
10053
10342
|
hostReadsDecl,
|
|
10343
|
+
lineTrackDecl,
|
|
10344
|
+
lineSpanDecl,
|
|
10054
10345
|
...ctx.regexDecls.map((d) => ` ${d}`),
|
|
10055
10346
|
...ctx.expectedDecls.map((d) => ` ${d}`),
|
|
10056
10347
|
mfDecl,
|
|
@@ -10589,7 +10880,7 @@ function normalizeCstCollapse(collapse) {
|
|
|
10589
10880
|
return typeof collapse === "function" ? collapse : void 0;
|
|
10590
10881
|
}
|
|
10591
10882
|
function buildCstNode(type, children2, _fields, span, _rawChildren, _triviaLog, state) {
|
|
10592
|
-
return { _tag: "node", type, span: {
|
|
10883
|
+
return { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children2] };
|
|
10593
10884
|
}
|
|
10594
10885
|
function cstBuildHost(typeOrOptions, children2, _fields, span, rawChildren, triviaLog, state) {
|
|
10595
10886
|
if (typeof typeOrOptions === "string") {
|
|
@@ -10768,7 +11059,8 @@ function materializePiece(p, trivia2, captureTerminals = false, hostMode) {
|
|
|
10768
11059
|
const pieces = compileLinkable(evalRuleMapIR(p.ir), p.ns, {
|
|
10769
11060
|
...trivia2 ? { trivia: trivia2 } : {},
|
|
10770
11061
|
...captureTerminals ? { captureTerminals: true } : {},
|
|
10771
|
-
...hostMode ? { hostMode } : {}
|
|
11062
|
+
...hostMode ? { hostMode } : {},
|
|
11063
|
+
...p.trackLines ? { trackLines: true } : {}
|
|
10772
11064
|
});
|
|
10773
11065
|
if (!pieces) throw new Error(`compose: carried IR for ns "${p.ns}" could not be re-lowered`);
|
|
10774
11066
|
return pieces;
|
|
@@ -12015,6 +12307,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12015
12307
|
const macroImports = [];
|
|
12016
12308
|
const allNames = /* @__PURE__ */ new Set();
|
|
12017
12309
|
const importBindings = /* @__PURE__ */ new Map();
|
|
12310
|
+
const ordinaryImports = [];
|
|
12018
12311
|
for (const stmt of body) {
|
|
12019
12312
|
if (stmt.type !== "ImportDeclaration") continue;
|
|
12020
12313
|
const s = stmt;
|
|
@@ -12023,12 +12316,17 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12023
12316
|
return key === "type" && a.value.value === "macro";
|
|
12024
12317
|
});
|
|
12025
12318
|
if (!isMacro) {
|
|
12319
|
+
const specifiers = [];
|
|
12026
12320
|
for (const spec of s.specifiers) {
|
|
12027
12321
|
if (spec.type === "ImportSpecifier") {
|
|
12028
12322
|
const imported = spec.imported.name ?? spec.local.name;
|
|
12029
12323
|
importBindings.set(spec.local.name, { source: s.source.value, imported });
|
|
12324
|
+
specifiers.push({ type: spec.type, local: spec.local.name, start: spec.start, end: spec.end });
|
|
12325
|
+
} else {
|
|
12326
|
+
specifiers.push({ type: spec.type, local: spec.local.name, start: spec.start, end: spec.end });
|
|
12030
12327
|
}
|
|
12031
12328
|
}
|
|
12329
|
+
ordinaryImports.push({ start: s.start, end: s.end, specifiers });
|
|
12032
12330
|
continue;
|
|
12033
12331
|
}
|
|
12034
12332
|
const names = /* @__PURE__ */ new Set();
|
|
@@ -12039,6 +12337,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12039
12337
|
for (const n of names) allNames.add(n);
|
|
12040
12338
|
}
|
|
12041
12339
|
if (macroImports.length === 0) return null;
|
|
12340
|
+
const unwrapVd = (stmt) => stmt.type === "VariableDeclaration" ? stmt : stmt.type === "ExportNamedDeclaration" && stmt.declaration?.type === "VariableDeclaration" ? stmt.declaration : null;
|
|
12042
12341
|
const factoryDecls = /* @__PURE__ */ new Map();
|
|
12043
12342
|
for (const stmt of body) {
|
|
12044
12343
|
const decl = stmt.type === "ExportNamedDeclaration" ? stmt.declaration : stmt;
|
|
@@ -12056,6 +12355,101 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12056
12355
|
}
|
|
12057
12356
|
}
|
|
12058
12357
|
}
|
|
12358
|
+
const topLevelFunction = (moduleBody, name) => {
|
|
12359
|
+
for (const st of moduleBody) {
|
|
12360
|
+
const decl = st.type === "ExportNamedDeclaration" ? st.declaration : st;
|
|
12361
|
+
const idn = decl?.type === "FunctionDeclaration" ? decl.id : void 0;
|
|
12362
|
+
if (idn?.name === name) return decl ?? null;
|
|
12363
|
+
}
|
|
12364
|
+
return null;
|
|
12365
|
+
};
|
|
12366
|
+
const isParsemanMacroImport = (stmt) => {
|
|
12367
|
+
if (stmt.type !== "ImportDeclaration") return false;
|
|
12368
|
+
const s = stmt;
|
|
12369
|
+
return moduleAliases.has(s.source.value) && s.attributes.some((a) => {
|
|
12370
|
+
const key = a.key.type === "Identifier" ? a.key.name : String(a.key.value);
|
|
12371
|
+
return key === "type" && a.value.value === "macro";
|
|
12372
|
+
});
|
|
12373
|
+
};
|
|
12374
|
+
const sourceScopeUntil = (moduleBody, source, until) => {
|
|
12375
|
+
const out = /* @__PURE__ */ new Map();
|
|
12376
|
+
for (const stmt of moduleBody) {
|
|
12377
|
+
if (stmt.type === "ImportDeclaration") {
|
|
12378
|
+
if (!isParsemanMacroImport(stmt)) return null;
|
|
12379
|
+
continue;
|
|
12380
|
+
}
|
|
12381
|
+
if (stmt.type === "FunctionDeclaration") continue;
|
|
12382
|
+
if (stmt.type === "ExportNamedDeclaration" && stmt.declaration?.type === "FunctionDeclaration") continue;
|
|
12383
|
+
if (stmt.type === "ExportNamedDeclaration" && !stmt.declaration) {
|
|
12384
|
+
if (stmt.source) return null;
|
|
12385
|
+
continue;
|
|
12386
|
+
}
|
|
12387
|
+
const vd = unwrapVd(stmt);
|
|
12388
|
+
if (!vd || vd.kind !== "const") return null;
|
|
12389
|
+
for (const decl of vd.declarations) {
|
|
12390
|
+
const d = decl;
|
|
12391
|
+
const idn = d.id;
|
|
12392
|
+
const init = d.init;
|
|
12393
|
+
if (idn.type !== "Identifier" && idn.type !== "BindingIdentifier" || !idn.name || !init) return null;
|
|
12394
|
+
if (init.type === "ArrowFunctionExpression" || init.type === "FunctionExpression") continue;
|
|
12395
|
+
const mapFnSources = [];
|
|
12396
|
+
const combi = evaluateExpr(init, out, source, mapFnSources);
|
|
12397
|
+
if (combi) {
|
|
12398
|
+
if (stmt.start < until) out.set(idn.name, { combi, mfSrcs: mapFnSources });
|
|
12399
|
+
continue;
|
|
12400
|
+
}
|
|
12401
|
+
const wordFactory = evaluateWordFactory(init, out, source);
|
|
12402
|
+
if (wordFactory) {
|
|
12403
|
+
if (stmt.start < until) {
|
|
12404
|
+
;
|
|
12405
|
+
out.set(idn.name, wordFactory);
|
|
12406
|
+
}
|
|
12407
|
+
continue;
|
|
12408
|
+
}
|
|
12409
|
+
const whenFactory = evaluateWhenFactory(init, out, source);
|
|
12410
|
+
if (whenFactory) {
|
|
12411
|
+
if (stmt.start < until) {
|
|
12412
|
+
;
|
|
12413
|
+
out.set(idn.name, whenFactory);
|
|
12414
|
+
}
|
|
12415
|
+
continue;
|
|
12416
|
+
}
|
|
12417
|
+
const combiArray = evaluateCombinatorArray(init, out, source);
|
|
12418
|
+
if (combiArray) {
|
|
12419
|
+
if (stmt.start < until) {
|
|
12420
|
+
;
|
|
12421
|
+
out.set(idn.name, combiArray);
|
|
12422
|
+
}
|
|
12423
|
+
continue;
|
|
12424
|
+
}
|
|
12425
|
+
return null;
|
|
12426
|
+
}
|
|
12427
|
+
continue;
|
|
12428
|
+
}
|
|
12429
|
+
return out;
|
|
12430
|
+
};
|
|
12431
|
+
const usedImportedFactories = /* @__PURE__ */ new Set();
|
|
12432
|
+
const markUsedImportedFactories = (names) => {
|
|
12433
|
+
for (const name of names ?? []) usedImportedFactories.add(name);
|
|
12434
|
+
};
|
|
12435
|
+
for (const [localName, binding] of importBindings) {
|
|
12436
|
+
const file = resolvePrivateSourceModule(id, binding.source);
|
|
12437
|
+
if (!file) continue;
|
|
12438
|
+
const mod = parseModuleCached(file);
|
|
12439
|
+
if (!mod) continue;
|
|
12440
|
+
const localFor = exportLocalName(mod.body, binding.imported);
|
|
12441
|
+
const init = localFor ? topLevelInit(mod.body, localFor) ?? topLevelFunction(mod.body, localFor) : null;
|
|
12442
|
+
if (!init || init.type !== "ArrowFunctionExpression" && init.type !== "FunctionExpression" && init.type !== "FunctionDeclaration") continue;
|
|
12443
|
+
const factoryScope = sourceScopeUntil(mod.body, mod.src, init.start);
|
|
12444
|
+
if (!factoryScope) continue;
|
|
12445
|
+
factoryDecls.set(localName, {
|
|
12446
|
+
fn: init,
|
|
12447
|
+
declaredAt: -1,
|
|
12448
|
+
code: mod.src,
|
|
12449
|
+
scope: factoryScope,
|
|
12450
|
+
imported: true
|
|
12451
|
+
});
|
|
12452
|
+
}
|
|
12059
12453
|
const scope = /* @__PURE__ */ new Map();
|
|
12060
12454
|
const replacements = [];
|
|
12061
12455
|
const warnings = [];
|
|
@@ -12085,6 +12479,9 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12085
12479
|
}
|
|
12086
12480
|
const namedFactory = factoryArgRaw.type === "Identifier" ? factoryDecls.get(factoryArgRaw.name) : void 0;
|
|
12087
12481
|
const factoryArg = namedFactory !== void 0 && namedFactory.declaredAt <= init.start ? namedFactory.fn : factoryArgRaw;
|
|
12482
|
+
const factoryScope = namedFactory?.scope ?? scope;
|
|
12483
|
+
const factoryCode = namedFactory?.code ?? code;
|
|
12484
|
+
const importedFactory = namedFactory?.imported === true && factoryArg === namedFactory.fn ? factoryArgRaw.name : void 0;
|
|
12088
12485
|
const optionsArg = optionsFirst ? arg0 : arg1;
|
|
12089
12486
|
const optionValue = (name) => optionsArg?.type === "ObjectExpression" ? (optionsArg.properties ?? []).find(
|
|
12090
12487
|
(p) => p.key?.name === name
|
|
@@ -12095,7 +12492,13 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12095
12492
|
warn(init.start, `${label2}: rules({ hostMode }) must be the literal 'ast' or 'cst'`);
|
|
12096
12493
|
return null;
|
|
12097
12494
|
}
|
|
12098
|
-
const
|
|
12495
|
+
const trackLinesValue = optionValue("trackLines");
|
|
12496
|
+
const gTrackLines = trackLinesValue?.type === "Literal" ? trackLinesValue.value : void 0;
|
|
12497
|
+
if (trackLinesValue !== void 0 && typeof gTrackLines !== "boolean") {
|
|
12498
|
+
warn(init.start, `${label2}: rules({ trackLines }) must be a boolean literal`);
|
|
12499
|
+
return null;
|
|
12500
|
+
}
|
|
12501
|
+
const ruleMap = evaluateParserFactory(factoryArg, factoryScope, factoryCode, []);
|
|
12099
12502
|
if (!ruleMap) {
|
|
12100
12503
|
warn(init.start, `${label2}: rules(...) factory isn't statically evaluable`);
|
|
12101
12504
|
return null;
|
|
@@ -12120,12 +12523,26 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12120
12523
|
}
|
|
12121
12524
|
}
|
|
12122
12525
|
}
|
|
12123
|
-
|
|
12526
|
+
if (gTrackLines === true) {
|
|
12527
|
+
for (const rule of ruleMap.values()) {
|
|
12528
|
+
if (rule && !rule._meta.isTrivia) {
|
|
12529
|
+
;
|
|
12530
|
+
rule._meta.grammarTrackLines = true;
|
|
12531
|
+
}
|
|
12532
|
+
}
|
|
12533
|
+
}
|
|
12534
|
+
return {
|
|
12535
|
+
ruleMap,
|
|
12536
|
+
...gTrivia ? { trivia: gTrivia } : {},
|
|
12537
|
+
...gScanSkip ? { scanSkip: gScanSkip } : {},
|
|
12538
|
+
...gTrackLines === true ? { trackLines: true } : {},
|
|
12539
|
+
...importedFactory ? { importedFactory } : {}
|
|
12540
|
+
};
|
|
12124
12541
|
};
|
|
12125
12542
|
const compileRulesFactory = (init, label2) => {
|
|
12126
12543
|
const evaluated = evaluateRulesFactory(init, label2);
|
|
12127
12544
|
if (!evaluated) return null;
|
|
12128
|
-
const compiled = compileRuleMap([...evaluated.ruleMap], { ...evaluated.trivia ? { trivia: evaluated.trivia } : {}, ...evaluated.scanSkip ? { scanSkip: evaluated.scanSkip } : {}, recovery, coverage: grammarCoverage });
|
|
12545
|
+
const compiled = compileRuleMap([...evaluated.ruleMap], { ...evaluated.trivia ? { trivia: evaluated.trivia } : {}, ...evaluated.scanSkip ? { scanSkip: evaluated.scanSkip } : {}, ...evaluated.trackLines ? { trackLines: true } : {}, recovery, coverage: grammarCoverage });
|
|
12129
12546
|
return {
|
|
12130
12547
|
replacement: compiled?.replacement ?? null,
|
|
12131
12548
|
ruleMap: evaluated.ruleMap,
|
|
@@ -12133,7 +12550,9 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12133
12550
|
hostBranchElided: compiled?.hostBranchElided ?? false,
|
|
12134
12551
|
...compiled?.coverageDefinitions ? { coverageDefinitions: compiled.coverageDefinitions } : {},
|
|
12135
12552
|
...evaluated.trivia ? { trivia: evaluated.trivia } : {},
|
|
12136
|
-
...evaluated.scanSkip ? { scanSkip: evaluated.scanSkip } : {}
|
|
12553
|
+
...evaluated.scanSkip ? { scanSkip: evaluated.scanSkip } : {},
|
|
12554
|
+
...evaluated.trackLines ? { trackLines: true } : {},
|
|
12555
|
+
...evaluated.importedFactory ? { importedFactory: evaluated.importedFactory } : {}
|
|
12137
12556
|
};
|
|
12138
12557
|
};
|
|
12139
12558
|
const isRulesCall = (init) => init.type === "CallExpression" && init.callee.type === "Identifier" && init.callee.name === "rules";
|
|
@@ -12153,7 +12572,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12153
12572
|
};
|
|
12154
12573
|
const isSpread = (it) => "__spreadLocal" in it;
|
|
12155
12574
|
const isIR = (it) => "ir" in it && !("ruleFns" in it);
|
|
12156
|
-
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);
|
|
12575
|
+
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);
|
|
12157
12576
|
const serializeList = (list) => `[${list.map(serializeItem).join(", ")}]`;
|
|
12158
12577
|
const withCarriedPieces = (grammarExpr, list) => `/* @__PURE__ */ Object.defineProperty(${grammarExpr}, Symbol.for('parseman.composedPieces'), { value: ${serializeList(list)}, enumerable: false })`;
|
|
12159
12578
|
const withLeafMarker = (grammarExpr) => `/* @__PURE__ */ Object.defineProperty(${grammarExpr}, Symbol.for('parseman.leafComposed'), { value: true, enumerable: false })`;
|
|
@@ -12284,10 +12703,11 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12284
12703
|
const localCarried = (rm, label2, composing, scanSkip) => {
|
|
12285
12704
|
const entries = [...rm];
|
|
12286
12705
|
const ns = nsFor(label2);
|
|
12706
|
+
const trackLines = entries.some(([, rule]) => rule?._meta?.grammarTrackLines === true);
|
|
12287
12707
|
const ir = serializeRuleMap(entries, scanSkip);
|
|
12288
|
-
if (ir) return { carried: [{ ns, ir }] };
|
|
12708
|
+
if (ir) return { carried: [{ ns, ir, ...trackLines ? { trackLines: true } : {} }] };
|
|
12289
12709
|
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.`);
|
|
12290
|
-
const p = compileLinkable(entries, ns, { ...composing ? { trivia: composing } : {}, ...scanSkip ? { scanSkip } : {}, recovery });
|
|
12710
|
+
const p = compileLinkable(entries, ns, { ...composing ? { trivia: composing } : {}, ...scanSkip ? { scanSkip } : {}, ...trackLines ? { trackLines: true } : {}, recovery });
|
|
12291
12711
|
return p ? { carried: [p] } : null;
|
|
12292
12712
|
};
|
|
12293
12713
|
const argPieces = (arg, label2, composing) => {
|
|
@@ -12305,7 +12725,10 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12305
12725
|
const innerArg = argPieces(inner, `${label2}_pick`);
|
|
12306
12726
|
if (!innerArg) return null;
|
|
12307
12727
|
try {
|
|
12308
|
-
return {
|
|
12728
|
+
return {
|
|
12729
|
+
carried: pickPieces(materializeCarried(innerArg.carried, ownTrivia(inner)), names),
|
|
12730
|
+
...innerArg.importedFactories ? { importedFactories: innerArg.importedFactories } : {}
|
|
12731
|
+
};
|
|
12309
12732
|
} catch (e) {
|
|
12310
12733
|
warn(arg.start, `pick(): ${e.message}`);
|
|
12311
12734
|
return null;
|
|
@@ -12313,7 +12736,8 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12313
12736
|
}
|
|
12314
12737
|
if (isRulesCall(arg)) {
|
|
12315
12738
|
const evaluated = evaluateRulesFactory(arg, label2);
|
|
12316
|
-
|
|
12739
|
+
const carried = evaluated ? localCarried(evaluated.ruleMap, label2, composing, evaluated.scanSkip) : null;
|
|
12740
|
+
return carried ? { ...carried, ...evaluated?.importedFactory ? { importedFactories: [evaluated.importedFactory] } : {} } : null;
|
|
12317
12741
|
}
|
|
12318
12742
|
if (arg.type === "Identifier") {
|
|
12319
12743
|
const name = arg.name;
|
|
@@ -12385,6 +12809,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12385
12809
|
}
|
|
12386
12810
|
const composing = composingTrivia(elements);
|
|
12387
12811
|
const carried = [];
|
|
12812
|
+
const importedFactories = [];
|
|
12388
12813
|
for (let i = 0; i < elements.length; i++) {
|
|
12389
12814
|
const r = argPieces(elements[i], `compose${init.start}_${i}`, composing);
|
|
12390
12815
|
if (!r) {
|
|
@@ -12392,6 +12817,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12392
12817
|
return null;
|
|
12393
12818
|
}
|
|
12394
12819
|
carried.push(...r.carried);
|
|
12820
|
+
importedFactories.push(...r.importedFactories ?? []);
|
|
12395
12821
|
}
|
|
12396
12822
|
const detailed = once(() => carriedRuleMapsDetailed(carried));
|
|
12397
12823
|
runFusedGatingDiagnostic(
|
|
@@ -12401,7 +12827,12 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12401
12827
|
);
|
|
12402
12828
|
const pieces = materializeCarried(carried, composing, false, cHostMode);
|
|
12403
12829
|
try {
|
|
12404
|
-
return {
|
|
12830
|
+
return {
|
|
12831
|
+
replacement: emitFusedSource(pieces),
|
|
12832
|
+
carried,
|
|
12833
|
+
...composing ? { trivia: composing } : {},
|
|
12834
|
+
...importedFactories.length ? { importedFactories } : {}
|
|
12835
|
+
};
|
|
12405
12836
|
} catch (e) {
|
|
12406
12837
|
warn(init.start, `compose(): ${e.message}; falling back to runtime`);
|
|
12407
12838
|
return null;
|
|
@@ -12422,10 +12853,12 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12422
12853
|
const localArg = elements[elements.length - 1];
|
|
12423
12854
|
let localRules = null;
|
|
12424
12855
|
let localScanSkip;
|
|
12856
|
+
const importedFactories = [];
|
|
12425
12857
|
if (isRulesCall(localArg)) {
|
|
12426
12858
|
const evaluated = evaluateRulesFactory(localArg, `composeLeaf${init.start}`);
|
|
12427
12859
|
localRules = evaluated?.ruleMap ?? null;
|
|
12428
12860
|
localScanSkip = evaluated?.scanSkip;
|
|
12861
|
+
if (evaluated?.importedFactory) importedFactories.push(evaluated.importedFactory);
|
|
12429
12862
|
} else if (localArg.type === "Identifier") {
|
|
12430
12863
|
const name = localArg.name;
|
|
12431
12864
|
localRules = localRuleMaps.get(name) ?? null;
|
|
@@ -12444,6 +12877,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12444
12877
|
return null;
|
|
12445
12878
|
}
|
|
12446
12879
|
carried.push(...r.carried);
|
|
12880
|
+
importedFactories.push(...r.importedFactories ?? []);
|
|
12447
12881
|
}
|
|
12448
12882
|
try {
|
|
12449
12883
|
const localNs = nsFor(`composeLeaf${init.start}`);
|
|
@@ -12469,13 +12903,15 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12469
12903
|
return null;
|
|
12470
12904
|
}
|
|
12471
12905
|
const replacement = withLeafMarker(emitFusedSource(grammarCoverage ? recognitionPieces : [...recognitionPieces, plainLocalPiece]));
|
|
12472
|
-
return {
|
|
12906
|
+
return {
|
|
12907
|
+
replacement: withCoverageDefinitions(replacement, emittedCoverageDefinitions(replacement)),
|
|
12908
|
+
...importedFactories.length ? { importedFactories } : {}
|
|
12909
|
+
};
|
|
12473
12910
|
} catch (e) {
|
|
12474
12911
|
warn(init.start, `composeLeaf(): ${e.message}`);
|
|
12475
12912
|
return null;
|
|
12476
12913
|
}
|
|
12477
12914
|
};
|
|
12478
|
-
const unwrapVd = (stmt) => stmt.type === "VariableDeclaration" ? stmt : stmt.type === "ExportNamedDeclaration" && stmt.declaration?.type === "VariableDeclaration" ? stmt.declaration : null;
|
|
12479
12915
|
const refNames = /* @__PURE__ */ new Set();
|
|
12480
12916
|
for (const stmt of body) {
|
|
12481
12917
|
const innerVd = unwrapVd(stmt);
|
|
@@ -12559,6 +12995,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12559
12995
|
const ns = nsFor(varName);
|
|
12560
12996
|
const pieces = exportPrefix || compiledRules.replacement === null ? compileLinkable([...compiledRules.ruleMap], ns, {
|
|
12561
12997
|
...compiledRules.scanSkip ? { scanSkip: compiledRules.scanSkip } : {},
|
|
12998
|
+
...compiledRules.trackLines ? { trackLines: true } : {},
|
|
12562
12999
|
recovery
|
|
12563
13000
|
}) : null;
|
|
12564
13001
|
if (compiledRules.replacement === null) {
|
|
@@ -12578,9 +13015,12 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12578
13015
|
}
|
|
12579
13016
|
if (exportPrefix && pieces && !pieces.mfFns.length && !pieces.buildFns.length) {
|
|
12580
13017
|
const ir = serializeRuleMap([...compiledRules.ruleMap], compiledRules.scanSkip);
|
|
12581
|
-
replacement = withCarriedPieces(replacement, [ir ? { ns, ir } : pieces]);
|
|
13018
|
+
replacement = withCarriedPieces(replacement, [ir ? { ns, ir, ...compiledRules.trackLines ? { trackLines: true } : {} } : pieces]);
|
|
12582
13019
|
}
|
|
12583
13020
|
replacements.push({ start: init.start, end: init.end, replacement });
|
|
13021
|
+
if (compiledRules.replacement !== null) {
|
|
13022
|
+
markUsedImportedFactories(compiledRules.importedFactory ? [compiledRules.importedFactory] : void 0);
|
|
13023
|
+
}
|
|
12584
13024
|
continue;
|
|
12585
13025
|
}
|
|
12586
13026
|
if (isComposeCall(init)) {
|
|
@@ -12593,6 +13033,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12593
13033
|
if (fused.trivia) localComposedTrivia.set(varName, fused.trivia);
|
|
12594
13034
|
const replacement = exportPrefix ? withCarriedPieces(fused.replacement, fused.carried) : fused.replacement;
|
|
12595
13035
|
replacements.push({ start: init.start, end: init.end, replacement: withCoverageDefinitions(replacement, emittedCoverageDefinitions(replacement)) });
|
|
13036
|
+
markUsedImportedFactories(fused.importedFactories);
|
|
12596
13037
|
continue;
|
|
12597
13038
|
}
|
|
12598
13039
|
if (isComposeLeafCall(init)) {
|
|
@@ -12601,6 +13042,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12601
13042
|
throw new Error(`${id}:${lineOf(init.start)} \u2014 composeLeaf() must macro-fuse; runtime composition is forbidden`);
|
|
12602
13043
|
}
|
|
12603
13044
|
replacements.push({ start: init.start, end: init.end, replacement: fused.replacement });
|
|
13045
|
+
markUsedImportedFactories(fused.importedFactories);
|
|
12604
13046
|
continue;
|
|
12605
13047
|
}
|
|
12606
13048
|
const mapFnSources = [];
|
|
@@ -12689,6 +13131,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12689
13131
|
end: stmtEnd,
|
|
12690
13132
|
replacement: lines.join("\n")
|
|
12691
13133
|
});
|
|
13134
|
+
markUsedImportedFactories(compiledRules.importedFactory ? [compiledRules.importedFactory] : void 0);
|
|
12692
13135
|
}
|
|
12693
13136
|
}
|
|
12694
13137
|
}
|
|
@@ -12697,6 +13140,40 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12697
13140
|
imp.fullyResolved = !anyUnresolved && !keepMacroImport;
|
|
12698
13141
|
}
|
|
12699
13142
|
const ms = new import_magic_string.default(code);
|
|
13143
|
+
const replacementRanges = runtimeComposeFallback ? [] : replacements.map(({ start, end }) => ({ start, end }));
|
|
13144
|
+
const isInsideReplacement = (start, end) => replacementRanges.some((r) => start >= r.start && end <= r.end);
|
|
13145
|
+
const importedBindingStillReferenced = (local) => {
|
|
13146
|
+
const walk2 = (node2, parent, parentKey) => {
|
|
13147
|
+
if (!node2 || typeof node2 !== "object") return false;
|
|
13148
|
+
const rec = node2;
|
|
13149
|
+
if (rec.type === "ImportDeclaration") return false;
|
|
13150
|
+
if (typeof rec.start === "number" && typeof rec.end === "number" && isInsideReplacement(rec.start, rec.end)) return false;
|
|
13151
|
+
if ((rec.type === "Identifier" || rec.type === "BindingIdentifier") && rec.name === local) {
|
|
13152
|
+
if (parentKey === "key" && (parent?.type === "ObjectProperty" || parent?.type === "Property" || parent?.type === "PropertyDefinition") && parent.computed !== true) return false;
|
|
13153
|
+
if (parentKey === "property" && parent?.type === "StaticMemberExpression") return false;
|
|
13154
|
+
if (parentKey === "property" && parent?.type === "MemberExpression" && parent.computed !== true) return false;
|
|
13155
|
+
return true;
|
|
13156
|
+
}
|
|
13157
|
+
for (const key of Object.keys(rec)) {
|
|
13158
|
+
if (key === "type" || key === "start" || key === "end") continue;
|
|
13159
|
+
const value = rec[key];
|
|
13160
|
+
if (Array.isArray(value)) {
|
|
13161
|
+
if (value.some((child) => walk2(child, rec, key))) return true;
|
|
13162
|
+
} else if (walk2(value, rec, key)) {
|
|
13163
|
+
return true;
|
|
13164
|
+
}
|
|
13165
|
+
}
|
|
13166
|
+
return false;
|
|
13167
|
+
};
|
|
13168
|
+
return body.some((stmt) => walk2(stmt));
|
|
13169
|
+
};
|
|
13170
|
+
for (const imp of ordinaryImports) {
|
|
13171
|
+
if (!runtimeComposeFallback && imp.specifiers.length > 0 && imp.specifiers.every(
|
|
13172
|
+
(spec) => spec.type === "ImportSpecifier" && usedImportedFactories.has(spec.local) && !importedBindingStillReferenced(spec.local)
|
|
13173
|
+
)) {
|
|
13174
|
+
ms.remove(imp.start, imp.end);
|
|
13175
|
+
}
|
|
13176
|
+
}
|
|
12700
13177
|
if (!anyUnresolved) {
|
|
12701
13178
|
for (const { start, end } of defineRemovals) ms.remove(start, end);
|
|
12702
13179
|
}
|