parseman 0.41.0 → 0.42.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/combinators/expect.d.ts.map +1 -1
- package/dist/combinators/grammar.d.ts.map +1 -1
- package/dist/combinators/literal.d.ts.map +1 -1
- package/dist/combinators/node.d.ts.map +1 -1
- package/dist/combinators/parser.d.ts +6 -0
- package/dist/combinators/parser.d.ts.map +1 -1
- package/dist/combinators/regex.d.ts.map +1 -1
- package/dist/combinators/scanTo.d.ts.map +1 -1
- package/dist/combinators/trivia-skip.d.ts.map +1 -1
- package/dist/compiler/codegen.d.ts +5 -0
- package/dist/compiler/codegen.d.ts.map +1 -1
- package/dist/compiler/inline-build.d.ts +1 -1
- package/dist/compiler/inline-build.d.ts.map +1 -1
- package/dist/compiler/line-index.d.ts +1 -15
- package/dist/compiler/line-index.d.ts.map +1 -1
- package/dist/compiler/linker.d.ts +1 -0
- package/dist/compiler/linker.d.ts.map +1 -1
- package/dist/cst/capture-buffer.d.ts.map +1 -1
- package/dist/index.cjs +483 -181
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +483 -181
- package/dist/index.js.map +4 -4
- package/dist/language-service/index.cjs +48 -2
- package/dist/language-service/index.cjs.map +3 -3
- package/dist/language-service/index.js +48 -2
- package/dist/language-service/index.js.map +3 -3
- package/dist/line-index.d.ts +41 -0
- package/dist/line-index.d.ts.map +1 -0
- package/dist/plugin/index.cjs +646 -169
- package/dist/plugin/index.cjs.map +4 -4
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +646 -169
- package/dist/plugin/index.js.map +4 -4
- package/dist/recovery/scan.d.ts.map +1 -1
- package/dist/regex/first-set.d.ts.map +1 -1
- package/dist/run/index.cjs +47 -1
- package/dist/run/index.cjs.map +3 -3
- package/dist/run/index.d.ts +3 -2
- package/dist/run/index.d.ts.map +1 -1
- package/dist/run/index.js +47 -1
- package/dist/run/index.js.map +3 -3
- package/dist/spec/index.cjs +462 -327
- package/dist/spec/index.cjs.map +4 -4
- package/dist/spec/index.js +462 -327
- package/dist/spec/index.js.map +4 -4
- package/dist/types.d.ts +18 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -33,6 +33,7 @@ __export(index_exports, {
|
|
|
33
33
|
analyzeGatingRules: () => analyzeGatingRules,
|
|
34
34
|
analyzeGrammarGating: () => analyzeGrammarGating,
|
|
35
35
|
annotateSpan: () => annotateSpan,
|
|
36
|
+
annotateTreeSpans: () => annotateTreeSpans,
|
|
36
37
|
applyEdit: () => applyEdit,
|
|
37
38
|
attempt: () => attempt,
|
|
38
39
|
balanced: () => balanced,
|
|
@@ -54,6 +55,7 @@ __export(index_exports, {
|
|
|
54
55
|
createGrammarCoverageCollector: () => createGrammarCoverageCollector,
|
|
55
56
|
createGrammarInstrumentationContext: () => createGrammarInstrumentationContext,
|
|
56
57
|
createGrammarTraceSink: () => createGrammarTraceSink,
|
|
58
|
+
createLineIndex: () => createLineIndex,
|
|
57
59
|
createVisitor: () => createVisitor,
|
|
58
60
|
cstBuildHost: () => cstBuildHost,
|
|
59
61
|
dispatch: () => dispatch,
|
|
@@ -87,6 +89,7 @@ __export(index_exports, {
|
|
|
87
89
|
matches: () => matches,
|
|
88
90
|
noTrivia: () => noTrivia,
|
|
89
91
|
node: () => node,
|
|
92
|
+
normalizeLineIndex: () => normalizeLineIndex,
|
|
90
93
|
not: () => not,
|
|
91
94
|
offsetToLineCol: () => offsetToLineCol,
|
|
92
95
|
oneOrMore: () => oneOrMore,
|
|
@@ -97,6 +100,7 @@ __export(index_exports, {
|
|
|
97
100
|
parseDoc: () => parseDoc,
|
|
98
101
|
parser: () => parser,
|
|
99
102
|
peek: () => peek,
|
|
103
|
+
recordLineRange: () => recordLineRange,
|
|
100
104
|
ref: () => ref,
|
|
101
105
|
regex: () => regex,
|
|
102
106
|
relativize: () => relativize,
|
|
@@ -363,6 +367,87 @@ function failAt(ctx, expected, pos) {
|
|
|
363
367
|
return r;
|
|
364
368
|
}
|
|
365
369
|
|
|
370
|
+
// src/line-index.ts
|
|
371
|
+
function createLineIndex() {
|
|
372
|
+
return { lineStarts: [0] };
|
|
373
|
+
}
|
|
374
|
+
function buildLineIndex(input) {
|
|
375
|
+
const lineStarts = [0];
|
|
376
|
+
for (let i = 0; i < input.length; i++) {
|
|
377
|
+
if (input.charCodeAt(i) === 10) lineStarts.push(i + 1);
|
|
378
|
+
}
|
|
379
|
+
return { lineStarts };
|
|
380
|
+
}
|
|
381
|
+
function recordLineRange(index, input, start, end) {
|
|
382
|
+
const lineStarts = index.lineStarts;
|
|
383
|
+
for (let i = start; i < end; i++) {
|
|
384
|
+
if (input.charCodeAt(i) === 10) lineStarts.push(i + 1);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
function recordLineRangeFromContext(ctx, input, _startHint, end) {
|
|
388
|
+
if (!ctx.trackLines) return;
|
|
389
|
+
const from = ctx._lineScannedTo ?? 0;
|
|
390
|
+
if (end <= from) return;
|
|
391
|
+
const index = ctx._lineIndex ?? (ctx._lineStarts ? { lineStarts: ctx._lineStarts } : void 0);
|
|
392
|
+
if (!index) return;
|
|
393
|
+
recordLineRange(index, input, from, end);
|
|
394
|
+
ctx._lineScannedTo = end;
|
|
395
|
+
}
|
|
396
|
+
function normalizeLineIndex(index) {
|
|
397
|
+
const starts = index.lineStarts;
|
|
398
|
+
starts.sort((a, b) => a - b);
|
|
399
|
+
let write = 0;
|
|
400
|
+
for (let read = 0; read < starts.length; read++) {
|
|
401
|
+
const value = starts[read];
|
|
402
|
+
if (write === 0 || starts[write - 1] !== value) starts[write++] = value;
|
|
403
|
+
}
|
|
404
|
+
starts.length = write;
|
|
405
|
+
if (starts.length === 0 || starts[0] !== 0) starts.unshift(0);
|
|
406
|
+
return index;
|
|
407
|
+
}
|
|
408
|
+
function offsetToLineCol(index, offset) {
|
|
409
|
+
const { lineStarts } = index;
|
|
410
|
+
let lo = 0;
|
|
411
|
+
let hi = lineStarts.length - 1;
|
|
412
|
+
while (lo < hi) {
|
|
413
|
+
const mid = lo + hi + 1 >> 1;
|
|
414
|
+
if (lineStarts[mid] <= offset) lo = mid;
|
|
415
|
+
else hi = mid - 1;
|
|
416
|
+
}
|
|
417
|
+
return { line: lo + 1, col: offset - lineStarts[lo] + 1 };
|
|
418
|
+
}
|
|
419
|
+
function annotateSpan(span, index) {
|
|
420
|
+
const s = offsetToLineCol(index, span.start);
|
|
421
|
+
const e = offsetToLineCol(index, span.end);
|
|
422
|
+
return {
|
|
423
|
+
...span,
|
|
424
|
+
startLine: s.line,
|
|
425
|
+
startColumn: s.col,
|
|
426
|
+
endLine: e.line,
|
|
427
|
+
endColumn: e.col
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
function annotateSpanFromLineContext(span, ctx) {
|
|
431
|
+
if (!ctx.trackLines) return span;
|
|
432
|
+
const index = ctx._lineIndex ?? (ctx._lineStarts ? { lineStarts: ctx._lineStarts } : void 0);
|
|
433
|
+
return index ? annotateSpan(span, index) : span;
|
|
434
|
+
}
|
|
435
|
+
function isSpan(value) {
|
|
436
|
+
return !!value && typeof value === "object" && typeof value.start === "number" && typeof value.end === "number";
|
|
437
|
+
}
|
|
438
|
+
function annotateTreeSpans(value, index, seen = /* @__PURE__ */ new WeakSet()) {
|
|
439
|
+
if (!value || typeof value !== "object") return value;
|
|
440
|
+
if (seen.has(value)) return value;
|
|
441
|
+
seen.add(value);
|
|
442
|
+
const obj = value;
|
|
443
|
+
if (isSpan(obj.span)) obj.span = annotateSpan(obj.span, index);
|
|
444
|
+
for (const key of Object.keys(obj)) {
|
|
445
|
+
const child = obj[key];
|
|
446
|
+
if (child && typeof child === "object") annotateTreeSpans(child, index, seen);
|
|
447
|
+
}
|
|
448
|
+
return value;
|
|
449
|
+
}
|
|
450
|
+
|
|
366
451
|
// src/cst/capture-buffer.ts
|
|
367
452
|
var EMPTY = [];
|
|
368
453
|
var EMPTY_TL = [];
|
|
@@ -404,7 +489,12 @@ function endCstNodeCapture(ctx, saved) {
|
|
|
404
489
|
return materialized;
|
|
405
490
|
}
|
|
406
491
|
function pushCstLeaf(ctx, leaf2) {
|
|
407
|
-
|
|
492
|
+
if (!ctx.trackLines) {
|
|
493
|
+
pushCstChild(ctx, leaf2, leaf2);
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
const annotated = leaf2 && typeof leaf2 === "object" && leaf2.span ? { ...leaf2, span: annotateSpanFromLineContext(leaf2.span, ctx) } : leaf2;
|
|
497
|
+
pushCstChild(ctx, annotated, annotated);
|
|
408
498
|
}
|
|
409
499
|
function pushCstChild(ctx, built, rawEntry) {
|
|
410
500
|
const b = ctx._cstBuf;
|
|
@@ -538,6 +628,7 @@ function literal(value, opts = {}) {
|
|
|
538
628
|
canMatchNewline: value.includes("\n"),
|
|
539
629
|
isTrivia: false
|
|
540
630
|
};
|
|
631
|
+
const canMatchNewline = meta.canMatchNewline;
|
|
541
632
|
if (caseInsensitive) {
|
|
542
633
|
const upper = value.toUpperCase();
|
|
543
634
|
const lower = value.toLowerCase();
|
|
@@ -554,6 +645,7 @@ function literal(value, opts = {}) {
|
|
|
554
645
|
return function parse3(input, pos, ctx) {
|
|
555
646
|
if (input.charCodeAt(pos) === code) {
|
|
556
647
|
const span = { start: pos, end: pos + 1 };
|
|
648
|
+
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, span.end);
|
|
557
649
|
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
558
650
|
return { ok: true, value, span };
|
|
559
651
|
}
|
|
@@ -567,6 +659,7 @@ function literal(value, opts = {}) {
|
|
|
567
659
|
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
568
660
|
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
569
661
|
const span = { start: pos, end };
|
|
662
|
+
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, end);
|
|
570
663
|
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: matchedValue, span });
|
|
571
664
|
return { ok: true, value: matchedValue, span };
|
|
572
665
|
}
|
|
@@ -734,6 +827,7 @@ function regex(pattern, flags = "") {
|
|
|
734
827
|
if (scanEnd === null) return failAt(ctx, [`/${source}/`], pos);
|
|
735
828
|
const value = input.slice(pos, scanEnd);
|
|
736
829
|
const span2 = { start: pos, end: scanEnd };
|
|
830
|
+
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, scanEnd);
|
|
737
831
|
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span: span2 });
|
|
738
832
|
return { ok: true, value, span: span2 };
|
|
739
833
|
}
|
|
@@ -743,6 +837,7 @@ function regex(pattern, flags = "") {
|
|
|
743
837
|
return failAt(ctx, [`/${source}/`], pos);
|
|
744
838
|
}
|
|
745
839
|
const span = { start: pos, end: pos + m[0].length };
|
|
840
|
+
if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, span.end);
|
|
746
841
|
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: m[0], span });
|
|
747
842
|
return { ok: true, value: m[0], span };
|
|
748
843
|
}
|
|
@@ -881,8 +976,8 @@ function parseRegex(src) {
|
|
|
881
976
|
}
|
|
882
977
|
if (src[k] !== "]") throw BAIL;
|
|
883
978
|
i = k + 1;
|
|
884
|
-
if (negated) return charNode(any(), true);
|
|
885
979
|
const ranges = parseClassRanges(body);
|
|
980
|
+
if (negated) return charNode(any(), !ranges || !rangesHaveNewline(ranges));
|
|
886
981
|
if (!ranges) return charNode(any(), true);
|
|
887
982
|
return charNode(rangesToSet(ranges), rangesHaveNewline(ranges));
|
|
888
983
|
};
|
|
@@ -978,7 +1073,7 @@ function firstSet(n) {
|
|
|
978
1073
|
}
|
|
979
1074
|
}
|
|
980
1075
|
}
|
|
981
|
-
function
|
|
1076
|
+
function canConsumeNewline(n) {
|
|
982
1077
|
switch (n.t) {
|
|
983
1078
|
case "char":
|
|
984
1079
|
return n.nl;
|
|
@@ -987,16 +1082,11 @@ function firstCanBeNewline(n) {
|
|
|
987
1082
|
case "empty":
|
|
988
1083
|
return false;
|
|
989
1084
|
case "rep":
|
|
990
|
-
return
|
|
1085
|
+
return canConsumeNewline(n.node);
|
|
991
1086
|
case "alt":
|
|
992
|
-
return n.arms.some(
|
|
993
|
-
case "seq":
|
|
994
|
-
|
|
995
|
-
if (firstCanBeNewline(part)) return true;
|
|
996
|
-
if (!nullable(part)) break;
|
|
997
|
-
}
|
|
998
|
-
return false;
|
|
999
|
-
}
|
|
1087
|
+
return n.arms.some(canConsumeNewline);
|
|
1088
|
+
case "seq":
|
|
1089
|
+
return n.parts.some(canConsumeNewline);
|
|
1000
1090
|
}
|
|
1001
1091
|
}
|
|
1002
1092
|
function firstSetFromRegex(source) {
|
|
@@ -1006,8 +1096,8 @@ function firstSetFromRegex(source) {
|
|
|
1006
1096
|
} catch {
|
|
1007
1097
|
return { firstSet: any(), canMatchNewline: true };
|
|
1008
1098
|
}
|
|
1009
|
-
if (nullable(ast)) return { firstSet: any(), canMatchNewline:
|
|
1010
|
-
return { firstSet: firstSet(ast), canMatchNewline:
|
|
1099
|
+
if (nullable(ast)) return { firstSet: any(), canMatchNewline: canConsumeNewline(ast) };
|
|
1100
|
+
return { firstSet: firstSet(ast), canMatchNewline: canConsumeNewline(ast) };
|
|
1011
1101
|
}
|
|
1012
1102
|
|
|
1013
1103
|
// src/combinators/case-fold.ts
|
|
@@ -1169,7 +1259,9 @@ function firstSetSentinel(fs) {
|
|
|
1169
1259
|
function recoverScan(input, from, ctx, sync, expected) {
|
|
1170
1260
|
let scanPos = from;
|
|
1171
1261
|
while (scanPos < input.length && !probeAt(sync, input, scanPos, ctx)) scanPos++;
|
|
1172
|
-
const
|
|
1262
|
+
const span = { start: from, end: scanPos };
|
|
1263
|
+
if (ctx.trackLines) recordLineRangeFromContext(ctx, input, from, scanPos);
|
|
1264
|
+
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1173
1265
|
ctx._errors?.push(error);
|
|
1174
1266
|
return { error, end: scanPos };
|
|
1175
1267
|
}
|
|
@@ -1272,7 +1364,8 @@ function expect(combinator, label2) {
|
|
|
1272
1364
|
parse(input, pos, ctx) {
|
|
1273
1365
|
const result = combinator.parse(input, pos, ctx);
|
|
1274
1366
|
if (result.ok) return result;
|
|
1275
|
-
const
|
|
1367
|
+
const span = { start: pos, end: pos };
|
|
1368
|
+
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
1276
1369
|
ctx._errors?.push(error);
|
|
1277
1370
|
if (ctx._tolerant) captureError(ctx, error);
|
|
1278
1371
|
return { ok: true, value: error, span: { start: pos, end: pos } };
|
|
@@ -1720,6 +1813,18 @@ function rollbackTrivia(ctx, mark) {
|
|
|
1720
1813
|
rollbackCstCapture(ctx, { raw: mark.raw, tlog: mark.tlog, leaves: mark.leaves, fields: mark.fields, errors: mark.errors });
|
|
1721
1814
|
if (ctx._triviaLog && ctx._triviaLog.length !== mark.log) ctx._triviaLog.length = mark.log;
|
|
1722
1815
|
}
|
|
1816
|
+
function parseTriviaNoCapture(triviaP, input, cur, ctx) {
|
|
1817
|
+
const probeCtx = {
|
|
1818
|
+
trackLines: ctx.trackLines,
|
|
1819
|
+
state: ctx.state,
|
|
1820
|
+
...ctx._lineIndex ? { _lineIndex: ctx._lineIndex } : {},
|
|
1821
|
+
...ctx._lineStarts ? { _lineStarts: ctx._lineStarts } : {},
|
|
1822
|
+
...ctx._lineScannedTo !== void 0 ? { _lineScannedTo: ctx._lineScannedTo } : {}
|
|
1823
|
+
};
|
|
1824
|
+
const result = triviaP.parse(input, cur, probeCtx);
|
|
1825
|
+
ctx._lineScannedTo = probeCtx._lineScannedTo;
|
|
1826
|
+
return result;
|
|
1827
|
+
}
|
|
1723
1828
|
function saveLookaheadMark(ctx) {
|
|
1724
1829
|
return { ...saveTriviaMark(ctx), probeBest: ctx._probe ? ctx._probe.best : null };
|
|
1725
1830
|
}
|
|
@@ -1742,13 +1847,29 @@ function scanWithLabels(input, cur, ctx) {
|
|
|
1742
1847
|
function advanceTrivia(input, cur, ctx) {
|
|
1743
1848
|
const triviaP = ctx.trivia;
|
|
1744
1849
|
if (!triviaP) return cur;
|
|
1850
|
+
if (!ctx.trackLines) {
|
|
1851
|
+
const fast2 = fastTriviaScanner(triviaP);
|
|
1852
|
+
if (fast2) return fast2(input, cur);
|
|
1853
|
+
if (ctx.triviaKindLabels) {
|
|
1854
|
+
const scan = scanWithLabels(input, cur, ctx);
|
|
1855
|
+
return scan.end;
|
|
1856
|
+
}
|
|
1857
|
+
const tr2 = triviaP.parse(input, cur, { trackLines: ctx.trackLines, state: ctx.state });
|
|
1858
|
+
return tr2.ok && tr2.span.end > cur ? tr2.span.end : cur;
|
|
1859
|
+
}
|
|
1860
|
+
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1745
1861
|
const fast = fastTriviaScanner(triviaP);
|
|
1746
|
-
if (fast)
|
|
1862
|
+
if (fast) {
|
|
1863
|
+
const end = fast(input, cur);
|
|
1864
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1865
|
+
return end;
|
|
1866
|
+
}
|
|
1747
1867
|
if (ctx.triviaKindLabels) {
|
|
1748
1868
|
const scan = scanWithLabels(input, cur, ctx);
|
|
1869
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
|
|
1749
1870
|
return scan.end;
|
|
1750
1871
|
}
|
|
1751
|
-
const tr = triviaP
|
|
1872
|
+
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1752
1873
|
return tr.ok && tr.span.end > cur ? tr.span.end : cur;
|
|
1753
1874
|
}
|
|
1754
1875
|
function scanTrivia(input, cur, ctx) {
|
|
@@ -1756,18 +1877,46 @@ function scanTrivia(input, cur, ctx) {
|
|
|
1756
1877
|
if (!triviaP) return { end: cur, commit: NOOP_COMMIT };
|
|
1757
1878
|
const log = ctx._triviaLog;
|
|
1758
1879
|
const captureTl = ctx.captureTrivia && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0);
|
|
1880
|
+
if (!ctx.trackLines) {
|
|
1881
|
+
const fast2 = !ctx.triviaKindLabels ? fastTriviaScanner(triviaP) : null;
|
|
1882
|
+
if (fast2 && log === void 0 && !captureTl) {
|
|
1883
|
+
return { end: fast2(input, cur), commit: NOOP_COMMIT };
|
|
1884
|
+
}
|
|
1885
|
+
if (ctx.triviaKindLabels && (log !== void 0 || captureTl)) {
|
|
1886
|
+
return scanWithLabels(input, cur, ctx);
|
|
1887
|
+
}
|
|
1888
|
+
if (log !== void 0 || captureTl) {
|
|
1889
|
+
const tr3 = triviaP.parse(input, cur, {
|
|
1890
|
+
trackLines: log !== void 0 ? false : ctx.trackLines,
|
|
1891
|
+
state: ctx.state
|
|
1892
|
+
});
|
|
1893
|
+
if (!tr3.ok || tr3.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1894
|
+
const end = tr3.span.end;
|
|
1895
|
+
return {
|
|
1896
|
+
end,
|
|
1897
|
+
commit: () => {
|
|
1898
|
+
pushTriviaLogEntry(ctx, cur, end);
|
|
1899
|
+
if (captureTl) pushCstTriviaEntry(ctx, cur, end);
|
|
1900
|
+
}
|
|
1901
|
+
};
|
|
1902
|
+
}
|
|
1903
|
+
const tr2 = triviaP.parse(input, cur, { trackLines: ctx.trackLines, state: ctx.state });
|
|
1904
|
+
return { end: tr2.ok ? tr2.span.end : cur, commit: NOOP_COMMIT };
|
|
1905
|
+
}
|
|
1906
|
+
const trackTriviaLines = ctx.trackLines && triviaP._meta.canMatchNewline;
|
|
1759
1907
|
const fast = !ctx.triviaKindLabels ? fastTriviaScanner(triviaP) : null;
|
|
1760
1908
|
if (fast && log === void 0 && !captureTl) {
|
|
1761
|
-
|
|
1909
|
+
const end = fast(input, cur);
|
|
1910
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, end);
|
|
1911
|
+
return { end, commit: NOOP_COMMIT };
|
|
1762
1912
|
}
|
|
1763
1913
|
if (ctx.triviaKindLabels && (log !== void 0 || captureTl)) {
|
|
1764
|
-
|
|
1914
|
+
const scan = scanWithLabels(input, cur, ctx);
|
|
1915
|
+
if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
|
|
1916
|
+
return scan;
|
|
1765
1917
|
}
|
|
1766
1918
|
if (log !== void 0 || captureTl) {
|
|
1767
|
-
const tr2 = triviaP
|
|
1768
|
-
trackLines: log !== void 0 ? false : ctx.trackLines,
|
|
1769
|
-
state: ctx.state
|
|
1770
|
-
});
|
|
1919
|
+
const tr2 = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1771
1920
|
if (!tr2.ok || tr2.span.end === cur) return { end: cur, commit: NOOP_COMMIT };
|
|
1772
1921
|
const end = tr2.span.end;
|
|
1773
1922
|
return {
|
|
@@ -1778,7 +1927,7 @@ function scanTrivia(input, cur, ctx) {
|
|
|
1778
1927
|
}
|
|
1779
1928
|
};
|
|
1780
1929
|
}
|
|
1781
|
-
const tr = triviaP
|
|
1930
|
+
const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
|
|
1782
1931
|
return { end: tr.ok ? tr.span.end : cur, commit: NOOP_COMMIT };
|
|
1783
1932
|
}
|
|
1784
1933
|
function consumeTrivia(input, cur, ctx) {
|
|
@@ -2749,6 +2898,101 @@ function markUnusedValues(root) {
|
|
|
2749
2898
|
visit(resolveRoot(root), true);
|
|
2750
2899
|
}
|
|
2751
2900
|
|
|
2901
|
+
// src/combinators/grammar.ts
|
|
2902
|
+
function annotateResultLines(result, index) {
|
|
2903
|
+
const annotated = { ...result, span: annotateSpan(result.span, index) };
|
|
2904
|
+
const errors = annotated.errors;
|
|
2905
|
+
if (errors) {
|
|
2906
|
+
;
|
|
2907
|
+
annotated.errors = errors.map((error) => ({
|
|
2908
|
+
...error,
|
|
2909
|
+
span: annotateSpan(error.span, index)
|
|
2910
|
+
}));
|
|
2911
|
+
}
|
|
2912
|
+
return annotated;
|
|
2913
|
+
}
|
|
2914
|
+
function createParseLineContext(input, pos) {
|
|
2915
|
+
const lineIndex = createLineIndex();
|
|
2916
|
+
if (pos > 0) recordLineRange(lineIndex, input, 0, pos);
|
|
2917
|
+
return { lineIndex, lineScannedTo: pos };
|
|
2918
|
+
}
|
|
2919
|
+
function parser(opts, root) {
|
|
2920
|
+
const clearTrivia = opts.trivia === null;
|
|
2921
|
+
return {
|
|
2922
|
+
_tag: "grammar",
|
|
2923
|
+
_meta: root._meta,
|
|
2924
|
+
_def: {
|
|
2925
|
+
tag: "grammar",
|
|
2926
|
+
parser: root,
|
|
2927
|
+
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
2928
|
+
clearTrivia,
|
|
2929
|
+
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
2930
|
+
trackLines: opts.trackLines ?? false
|
|
2931
|
+
},
|
|
2932
|
+
parse(input, pos, _ctx) {
|
|
2933
|
+
const trackLines = opts.trackLines ?? _ctx?.trackLines ?? false;
|
|
2934
|
+
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
2935
|
+
const lineIndex = trackLines ? _ctx?._lineIndex ?? (_ctx?._lineStarts ? { lineStarts: _ctx._lineStarts } : lineContext.lineIndex) : void 0;
|
|
2936
|
+
const ctx = {
|
|
2937
|
+
..._ctx,
|
|
2938
|
+
trackLines,
|
|
2939
|
+
...lineIndex ? { _lineIndex: lineIndex } : {},
|
|
2940
|
+
...lineContext ? { _lineScannedTo: lineContext.lineScannedTo } : {},
|
|
2941
|
+
// trivia: null clears (contiguous terms); a Combinator sets; undefined inherits.
|
|
2942
|
+
...clearTrivia ? {
|
|
2943
|
+
trivia: void 0,
|
|
2944
|
+
triviaKindLabels: void 0
|
|
2945
|
+
} : opts.trivia != null ? {
|
|
2946
|
+
trivia: opts.trivia,
|
|
2947
|
+
...opts.trivia._meta.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {}
|
|
2948
|
+
} : {},
|
|
2949
|
+
...opts.captureTrivia || _ctx?.captureTrivia ? { captureTrivia: true } : {},
|
|
2950
|
+
// Kind-filter for per-node capture. Resolve against this scope's trivia
|
|
2951
|
+
// labels — this parser's own trivia if it declares one, else the INHERITED
|
|
2952
|
+
// labels (`_ctx.triviaKindLabels`), so captureTriviaKinds still applies when
|
|
2953
|
+
// trivia is inherited rather than re-declared here. No labels → undefined
|
|
2954
|
+
// (capture all).
|
|
2955
|
+
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {}
|
|
2956
|
+
};
|
|
2957
|
+
const result = root.parse(input, pos ?? 0, ctx);
|
|
2958
|
+
if (trackLines && _ctx && ctx._lineScannedTo !== void 0) {
|
|
2959
|
+
_ctx._lineScannedTo = Math.max(_ctx._lineScannedTo ?? 0, ctx._lineScannedTo);
|
|
2960
|
+
}
|
|
2961
|
+
return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
2962
|
+
}
|
|
2963
|
+
};
|
|
2964
|
+
}
|
|
2965
|
+
function noTrivia(root) {
|
|
2966
|
+
return parser({ trivia: null }, root);
|
|
2967
|
+
}
|
|
2968
|
+
var _analyzed = /* @__PURE__ */ new WeakSet();
|
|
2969
|
+
function parse(combinator, input, opts = {}) {
|
|
2970
|
+
if (!_analyzed.has(combinator)) {
|
|
2971
|
+
_analyzed.add(combinator);
|
|
2972
|
+
markUnusedValues(combinator);
|
|
2973
|
+
}
|
|
2974
|
+
const trackLines = opts.trackLines ?? combinator._meta.grammarTrackLines ?? false;
|
|
2975
|
+
const lineContext = trackLines ? createParseLineContext(input, 0) : void 0;
|
|
2976
|
+
const lineIndex = lineContext?.lineIndex;
|
|
2977
|
+
const _errors = opts.recover ? [] : void 0;
|
|
2978
|
+
const _probe = opts.recover ? { offset: input.length, best: null } : void 0;
|
|
2979
|
+
const grammarTrivia = combinator._meta.grammarTrivia;
|
|
2980
|
+
const grammarScanSkip = combinator._meta.grammarScanSkip;
|
|
2981
|
+
const ctx = {
|
|
2982
|
+
trackLines,
|
|
2983
|
+
...lineIndex ? { _lineIndex: lineIndex } : {},
|
|
2984
|
+
...lineContext ? { _lineScannedTo: lineContext.lineScannedTo } : {},
|
|
2985
|
+
...grammarTrivia !== void 0 ? { trivia: grammarTrivia, ...grammarTrivia._meta.triviaKindLabels ? { triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {} } : {},
|
|
2986
|
+
...grammarScanSkip !== void 0 ? { scanSkip: grammarScanSkip } : {},
|
|
2987
|
+
..._errors !== void 0 ? { _errors } : {},
|
|
2988
|
+
..._probe !== void 0 ? { _probe } : {}
|
|
2989
|
+
};
|
|
2990
|
+
const result = combinator.parse(input, 0, ctx);
|
|
2991
|
+
if (!result.ok) return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
2992
|
+
const withErrors = _errors !== void 0 ? { ...result, errors: _errors, furthestFail: _probe?.best ?? null } : result;
|
|
2993
|
+
return lineIndex ? annotateResultLines(withErrors, normalizeLineIndex(lineIndex)) : withErrors;
|
|
2994
|
+
}
|
|
2995
|
+
|
|
2752
2996
|
// src/combinators/parser.ts
|
|
2753
2997
|
var RULE_ORDER = "__parsemanRuleOrder";
|
|
2754
2998
|
function tagRule(r, key) {
|
|
@@ -2824,6 +3068,21 @@ function rules(a, b) {
|
|
|
2824
3068
|
if (rule && !rule._meta.isTrivia) rule._meta.grammarHostMode = "cst";
|
|
2825
3069
|
}
|
|
2826
3070
|
}
|
|
3071
|
+
if (options?.trackLines === true) {
|
|
3072
|
+
for (const key of Object.keys(definitions)) {
|
|
3073
|
+
const rule = cache[key];
|
|
3074
|
+
if (rule && !rule._meta.isTrivia) rule._meta.grammarTrackLines = true;
|
|
3075
|
+
}
|
|
3076
|
+
for (const key of Object.keys(definitions)) {
|
|
3077
|
+
const rule = cache[key];
|
|
3078
|
+
if (rule && !rule._meta.isTrivia && rule._def.tag !== "grammar") {
|
|
3079
|
+
const wrapped = parser({ trackLines: true }, rule);
|
|
3080
|
+
tagRule(wrapped, key);
|
|
3081
|
+
wrapped._meta.grammarTrackLines = true;
|
|
3082
|
+
cache[key] = wrapped;
|
|
3083
|
+
}
|
|
3084
|
+
}
|
|
3085
|
+
}
|
|
2827
3086
|
for (const key of Object.keys(definitions)) {
|
|
2828
3087
|
markUnusedValues(cache[key]);
|
|
2829
3088
|
}
|
|
@@ -3202,13 +3461,14 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
3202
3461
|
const st = clonesState && ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
3203
3462
|
const nodeType = def.type ?? missingInferredType();
|
|
3204
3463
|
const cstOutput = cstOutputHost(ctx.build);
|
|
3464
|
+
const span = ctx.trackLines ? annotateSpanFromLineContext(r.span, ctx) : r.span;
|
|
3205
3465
|
const hostState = clonesState ? st : ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
3206
|
-
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,
|
|
3207
|
-
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
|
|
3466
|
+
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 };
|
|
3467
|
+
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 };
|
|
3208
3468
|
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
3209
3469
|
pushCstChild(ctx, built, rawEntry);
|
|
3210
3470
|
}
|
|
3211
|
-
return { ok: true, value: built, span
|
|
3471
|
+
return { ok: true, value: built, span };
|
|
3212
3472
|
}
|
|
3213
3473
|
};
|
|
3214
3474
|
}
|
|
@@ -3279,112 +3539,6 @@ function field(name, combinator) {
|
|
|
3279
3539
|
};
|
|
3280
3540
|
}
|
|
3281
3541
|
|
|
3282
|
-
// src/compiler/line-index.ts
|
|
3283
|
-
function buildLineIndex(input) {
|
|
3284
|
-
const lineStarts = [0];
|
|
3285
|
-
for (let i = 0; i < input.length; i++) {
|
|
3286
|
-
if (input.charCodeAt(i) === 10) lineStarts.push(i + 1);
|
|
3287
|
-
}
|
|
3288
|
-
return { lineStarts };
|
|
3289
|
-
}
|
|
3290
|
-
function offsetToLineCol(index, offset) {
|
|
3291
|
-
const { lineStarts } = index;
|
|
3292
|
-
let lo = 0;
|
|
3293
|
-
let hi = lineStarts.length - 1;
|
|
3294
|
-
while (lo < hi) {
|
|
3295
|
-
const mid = lo + hi + 1 >> 1;
|
|
3296
|
-
if (lineStarts[mid] <= offset) lo = mid;
|
|
3297
|
-
else hi = mid - 1;
|
|
3298
|
-
}
|
|
3299
|
-
return { line: lo + 1, col: offset - lineStarts[lo] + 1 };
|
|
3300
|
-
}
|
|
3301
|
-
function annotateSpan(span, index) {
|
|
3302
|
-
const s = offsetToLineCol(index, span.start);
|
|
3303
|
-
const e = offsetToLineCol(index, span.end);
|
|
3304
|
-
return {
|
|
3305
|
-
...span,
|
|
3306
|
-
startLine: s.line,
|
|
3307
|
-
startColumn: s.col,
|
|
3308
|
-
endLine: e.line,
|
|
3309
|
-
endColumn: e.col
|
|
3310
|
-
};
|
|
3311
|
-
}
|
|
3312
|
-
|
|
3313
|
-
// src/combinators/grammar.ts
|
|
3314
|
-
function parser(opts, root) {
|
|
3315
|
-
const clearTrivia = opts.trivia === null;
|
|
3316
|
-
return {
|
|
3317
|
-
_tag: "grammar",
|
|
3318
|
-
_meta: root._meta,
|
|
3319
|
-
_def: {
|
|
3320
|
-
tag: "grammar",
|
|
3321
|
-
parser: root,
|
|
3322
|
-
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
3323
|
-
clearTrivia,
|
|
3324
|
-
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
3325
|
-
trackLines: opts.trackLines ?? false
|
|
3326
|
-
},
|
|
3327
|
-
parse(input, pos, _ctx) {
|
|
3328
|
-
const trackLines = opts.trackLines ?? _ctx?.trackLines ?? false;
|
|
3329
|
-
const ctx = {
|
|
3330
|
-
..._ctx,
|
|
3331
|
-
trackLines,
|
|
3332
|
-
// trivia: null clears (contiguous terms); a Combinator sets; undefined inherits.
|
|
3333
|
-
...clearTrivia ? {
|
|
3334
|
-
trivia: void 0,
|
|
3335
|
-
triviaKindLabels: void 0
|
|
3336
|
-
} : opts.trivia != null ? {
|
|
3337
|
-
trivia: opts.trivia,
|
|
3338
|
-
...opts.trivia._meta.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {}
|
|
3339
|
-
} : {},
|
|
3340
|
-
...opts.captureTrivia || _ctx?.captureTrivia ? { captureTrivia: true } : {},
|
|
3341
|
-
// Kind-filter for per-node capture. Resolve against this scope's trivia
|
|
3342
|
-
// labels — this parser's own trivia if it declares one, else the INHERITED
|
|
3343
|
-
// labels (`_ctx.triviaKindLabels`), so captureTriviaKinds still applies when
|
|
3344
|
-
// trivia is inherited rather than re-declared here. No labels → undefined
|
|
3345
|
-
// (capture all).
|
|
3346
|
-
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {}
|
|
3347
|
-
};
|
|
3348
|
-
const result = root.parse(input, pos ?? 0, ctx);
|
|
3349
|
-
if (trackLines) {
|
|
3350
|
-
const idx = buildLineIndex(input);
|
|
3351
|
-
return { ...result, span: annotateSpan(result.span, idx) };
|
|
3352
|
-
}
|
|
3353
|
-
return result;
|
|
3354
|
-
}
|
|
3355
|
-
};
|
|
3356
|
-
}
|
|
3357
|
-
function noTrivia(root) {
|
|
3358
|
-
return parser({ trivia: null }, root);
|
|
3359
|
-
}
|
|
3360
|
-
var _analyzed = /* @__PURE__ */ new WeakSet();
|
|
3361
|
-
function parse(combinator, input, opts = {}) {
|
|
3362
|
-
if (!_analyzed.has(combinator)) {
|
|
3363
|
-
_analyzed.add(combinator);
|
|
3364
|
-
markUnusedValues(combinator);
|
|
3365
|
-
}
|
|
3366
|
-
const trackLines = opts.trackLines ?? false;
|
|
3367
|
-
const _errors = opts.recover ? [] : void 0;
|
|
3368
|
-
const _probe = opts.recover ? { offset: input.length, best: null } : void 0;
|
|
3369
|
-
const grammarTrivia = combinator._meta.grammarTrivia;
|
|
3370
|
-
const grammarScanSkip = combinator._meta.grammarScanSkip;
|
|
3371
|
-
const ctx = {
|
|
3372
|
-
trackLines,
|
|
3373
|
-
...grammarTrivia !== void 0 ? { trivia: grammarTrivia, ...grammarTrivia._meta.triviaKindLabels ? { triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {} } : {},
|
|
3374
|
-
...grammarScanSkip !== void 0 ? { scanSkip: grammarScanSkip } : {},
|
|
3375
|
-
..._errors !== void 0 ? { _errors } : {},
|
|
3376
|
-
..._probe !== void 0 ? { _probe } : {}
|
|
3377
|
-
};
|
|
3378
|
-
const result = combinator.parse(input, 0, ctx);
|
|
3379
|
-
if (!result.ok) return result;
|
|
3380
|
-
const withErrors = _errors !== void 0 ? { ...result, errors: _errors, furthestFail: _probe?.best ?? null } : result;
|
|
3381
|
-
if (trackLines) {
|
|
3382
|
-
const idx = buildLineIndex(input);
|
|
3383
|
-
return { ...withErrors, span: annotateSpan(withErrors.span, idx) };
|
|
3384
|
-
}
|
|
3385
|
-
return withErrors;
|
|
3386
|
-
}
|
|
3387
|
-
|
|
3388
3542
|
// src/combinators/token.ts
|
|
3389
3543
|
function token(root) {
|
|
3390
3544
|
const meta = {
|
|
@@ -3481,7 +3635,7 @@ function leaf(root, fn) {
|
|
|
3481
3635
|
}
|
|
3482
3636
|
|
|
3483
3637
|
// src/version.ts
|
|
3484
|
-
var PARSEMAN_VERSION = "0.
|
|
3638
|
+
var PARSEMAN_VERSION = "0.42.1";
|
|
3485
3639
|
|
|
3486
3640
|
// src/cst/host-mode.ts
|
|
3487
3641
|
var FUSED_HOST_MODE = /* @__PURE__ */ Symbol.for("parseman.fusedHostMode");
|
|
@@ -5165,7 +5319,7 @@ function scanTo(sentinel, { skip: skip2, raw = false, orEOF = false } = {}) {
|
|
|
5165
5319
|
let cur = pos;
|
|
5166
5320
|
const skip3 = resolveScanSkip(explicitSkip, raw, ctx);
|
|
5167
5321
|
const probeCtx = {
|
|
5168
|
-
trackLines:
|
|
5322
|
+
trackLines: false,
|
|
5169
5323
|
state: ctx.state,
|
|
5170
5324
|
...ctx._errors !== void 0 ? { _errors: ctx._errors } : {}
|
|
5171
5325
|
};
|
|
@@ -5178,6 +5332,7 @@ function scanTo(sentinel, { skip: skip2, raw = false, orEOF = false } = {}) {
|
|
|
5178
5332
|
while (cur < input.length) {
|
|
5179
5333
|
const s = sentinel.parse(input, cur, probeCtx);
|
|
5180
5334
|
if (s.ok) {
|
|
5335
|
+
if (ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, cur);
|
|
5181
5336
|
emit2(cur);
|
|
5182
5337
|
return { ok: true, value: input.slice(pos, cur), span: { start: pos, end: cur } };
|
|
5183
5338
|
}
|
|
@@ -5193,6 +5348,7 @@ function scanTo(sentinel, { skip: skip2, raw = false, orEOF = false } = {}) {
|
|
|
5193
5348
|
if (!advanced) cur++;
|
|
5194
5349
|
}
|
|
5195
5350
|
if (orEOF) {
|
|
5351
|
+
if (ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, cur);
|
|
5196
5352
|
emit2(cur);
|
|
5197
5353
|
return { ok: true, value: input.slice(pos, cur), span: { start: pos, end: cur } };
|
|
5198
5354
|
}
|
|
@@ -6631,8 +6787,8 @@ function analyzeMkInlineBuild(def) {
|
|
|
6631
6787
|
if (looseMkBuildRe(def.type).test(src)) return def.type;
|
|
6632
6788
|
return null;
|
|
6633
6789
|
}
|
|
6634
|
-
function emitInlineMkNodeExpr(type, chV, rawV,
|
|
6635
|
-
return `{ _tag: 'node', type: ${JSON.stringify(type)}, span:
|
|
6790
|
+
function emitInlineMkNodeExpr(type, chV, rawV, spanExpr, tlV) {
|
|
6791
|
+
return `{ _tag: 'node', type: ${JSON.stringify(type)}, span: ${spanExpr}, children: ${chV}, rawCount: ${rawV}.length, localTriviaLen: ${tlV}.length }`;
|
|
6636
6792
|
}
|
|
6637
6793
|
|
|
6638
6794
|
// src/compiler/inline-callback.ts
|
|
@@ -6814,6 +6970,8 @@ function leadingFirstSetRecipe(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
6814
6970
|
}
|
|
6815
6971
|
}
|
|
6816
6972
|
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 }";
|
|
6973
|
+
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 }";
|
|
6974
|
+
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] } }";
|
|
6817
6975
|
var _loweringSink = null;
|
|
6818
6976
|
function v(ctx, prefix = "_v") {
|
|
6819
6977
|
return `${prefix}${ctx.vars++}`;
|
|
@@ -6837,13 +6995,16 @@ function reindentStmts(stmts, targetLevels) {
|
|
|
6837
6995
|
const targetPrefix = " ".repeat(targetLevels);
|
|
6838
6996
|
return stmts.map((s) => s.trim().length === 0 ? "" : targetPrefix + s.slice(minLeading));
|
|
6839
6997
|
}
|
|
6840
|
-
function failReturn(expected, posExpr) {
|
|
6998
|
+
function failReturn(ctx, expected, posExpr) {
|
|
6999
|
+
if (ctx.lineTracking) return `return { ok: false, expected: [${expected}], span: ${emitSpanExpr(ctx, posExpr, posExpr)} }`;
|
|
6841
7000
|
return `return { ok: false, expected: [${expected}], span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
6842
7001
|
}
|
|
6843
|
-
function failReturnArr(expectedArr, posExpr) {
|
|
7002
|
+
function failReturnArr(ctx, expectedArr, posExpr) {
|
|
7003
|
+
if (ctx.lineTracking) return `return { ok: false, expected: ${expectedArr}, span: ${emitSpanExpr(ctx, posExpr, posExpr)} }`;
|
|
6844
7004
|
return `return { ok: false, expected: ${expectedArr}, span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
6845
7005
|
}
|
|
6846
|
-
function committedReturnArr(expectedArr, posExpr) {
|
|
7006
|
+
function committedReturnArr(ctx, expectedArr, posExpr) {
|
|
7007
|
+
if (ctx.lineTracking) return `return { ok: false, expected: [...${expectedArr}], span: ${emitSpanExpr(ctx, posExpr, posExpr)}, committed: true }`;
|
|
6847
7008
|
return `return { ok: false, expected: [...${expectedArr}], span: { start: ${posExpr}, end: ${posExpr} }, committed: true }`;
|
|
6848
7009
|
}
|
|
6849
7010
|
function hoistExpected(ctx, constArrSource) {
|
|
@@ -6868,7 +7029,7 @@ function failBody(ctx, expected, posExpr) {
|
|
|
6868
7029
|
if (!ctx.recordFail) return probe ? `{ ${probe}${trace}break ${ctx.failLabel} }` : trace ? `{ ${trace}break ${ctx.failLabel} }` : `break ${ctx.failLabel}`;
|
|
6869
7030
|
return `{ ${probe}_ctx._fe = ${posExpr}; _ctx._fx = ${hoistExpected(ctx, `[${expected}]`)}; ${trace}break ${ctx.failLabel} }`;
|
|
6870
7031
|
}
|
|
6871
|
-
return probe + trace + failReturn(expected, posExpr);
|
|
7032
|
+
return probe + trace + failReturn(ctx, expected, posExpr);
|
|
6872
7033
|
}
|
|
6873
7034
|
function failArrBody(ctx, expectedArr, posExpr, constant = true) {
|
|
6874
7035
|
const probe = probeUpdate(ctx, expectedArr, posExpr, constant);
|
|
@@ -6878,18 +7039,19 @@ function failArrBody(ctx, expectedArr, posExpr, constant = true) {
|
|
|
6878
7039
|
const fx = constant ? hoistExpected(ctx, expectedArr) : expectedArr;
|
|
6879
7040
|
return `{ ${probe}_ctx._fe = ${posExpr}; _ctx._fx = ${fx}; ${trace}break ${ctx.failLabel} }`;
|
|
6880
7041
|
}
|
|
6881
|
-
if (!constant) return `${probe}${trace}return { ok: false, expected: [...${expectedArr}], span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
6882
|
-
return probe + trace + failReturnArr(expectedArr, posExpr);
|
|
7042
|
+
if (!constant) return `${probe}${trace}return { ok: false, expected: [...${expectedArr}], span: ${ctx.lineTracking ? emitSpanExpr(ctx, posExpr, posExpr) : `{ start: ${posExpr}, end: ${posExpr} }`} }`;
|
|
7043
|
+
return probe + trace + failReturnArr(ctx, expectedArr, posExpr);
|
|
6883
7044
|
}
|
|
6884
|
-
function resultFromRecorded(feExpr = "_ctx._fe", fxExpr = "_ctx._fx") {
|
|
6885
|
-
|
|
7045
|
+
function resultFromRecorded(ctx, feExpr = "_ctx._fe", fxExpr = "_ctx._fx") {
|
|
7046
|
+
const spanExpr = ctx.lineTracking ? emitSpanExpr(ctx, feExpr, feExpr) : `{ start: ${feExpr}, end: ${feExpr} }`;
|
|
7047
|
+
return `return { ok: false, expected: [...${fxExpr}], span: ${spanExpr}, ...(_ctx._fc ? { committed: true } : {}) }`;
|
|
6886
7048
|
}
|
|
6887
7049
|
function committedFailBody(ctx, expectedArr = "_ctx._fx", posExpr = "_ctx._fe") {
|
|
6888
7050
|
if (ctx.failLabel) {
|
|
6889
7051
|
if (!ctx.recordFail) return `{ _ctx._fc = true; break ${ctx.failLabel} }`;
|
|
6890
7052
|
return `{ _ctx._fc = true; _ctx._fe = ${posExpr}; _ctx._fx = ${expectedArr}; break ${ctx.failLabel} }`;
|
|
6891
7053
|
}
|
|
6892
|
-
return committedReturnArr(expectedArr, posExpr);
|
|
7054
|
+
return committedReturnArr(ctx, expectedArr, posExpr);
|
|
6893
7055
|
}
|
|
6894
7056
|
function propagateFailBody(ctx, srcCtx = "_ctx") {
|
|
6895
7057
|
if (srcCtx !== "_ctx") {
|
|
@@ -6897,10 +7059,10 @@ function propagateFailBody(ctx, srcCtx = "_ctx") {
|
|
|
6897
7059
|
if (!ctx.recordFail) return `break ${ctx.failLabel}`;
|
|
6898
7060
|
return `{ _ctx._fe = ${srcCtx}._fe; _ctx._fx = ${srcCtx}._fx; _ctx._fc = ${srcCtx}._fc; break ${ctx.failLabel} }`;
|
|
6899
7061
|
}
|
|
6900
|
-
return `{ _ctx._fe = ${srcCtx}._fe; _ctx._fx = ${srcCtx}._fx; _ctx._fc = ${srcCtx}._fc; ${resultFromRecorded()} }`;
|
|
7062
|
+
return `{ _ctx._fe = ${srcCtx}._fe; _ctx._fx = ${srcCtx}._fx; _ctx._fc = ${srcCtx}._fc; ${resultFromRecorded(ctx)} }`;
|
|
6901
7063
|
}
|
|
6902
7064
|
if (ctx.failLabel) return `break ${ctx.failLabel}`;
|
|
6903
|
-
return resultFromRecorded();
|
|
7065
|
+
return resultFromRecorded(ctx);
|
|
6904
7066
|
}
|
|
6905
7067
|
function emitIfFail(ctx, cond, body) {
|
|
6906
7068
|
return [
|
|
@@ -6954,14 +7116,46 @@ function emitLeafCapture(ctx, valExpr, startExpr, endExpr) {
|
|
|
6954
7116
|
if (ctx.capAsTrivia) return [];
|
|
6955
7117
|
const i = ind(ctx);
|
|
6956
7118
|
const lf = v(ctx, "_lf");
|
|
7119
|
+
const spanExpr = emitSpanExpr(ctx, startExpr, endExpr);
|
|
6957
7120
|
return [
|
|
6958
7121
|
`${i}if (_ctx._cstLeaves || _ctx._cstRawChildren) {`,
|
|
6959
|
-
`${i} const ${lf} = { _tag: 'leaf', value: ${valExpr}, span:
|
|
7122
|
+
`${i} const ${lf} = { _tag: 'leaf', value: ${valExpr}, span: ${spanExpr} }`,
|
|
6960
7123
|
`${i} if (_ctx._cstLeaves) _ctx._cstLeaves.push(${lf})`,
|
|
6961
7124
|
`${i} if (_ctx._cstRawChildren) _ctx._cstRawChildren.push(${lf})`,
|
|
6962
7125
|
`${i}}`
|
|
6963
7126
|
];
|
|
6964
7127
|
}
|
|
7128
|
+
function emitSpanExpr(ctx, startExpr, endExpr) {
|
|
7129
|
+
if (!ctx.lineTracking) return `{ start: ${startExpr}, end: ${endExpr} }`;
|
|
7130
|
+
ctx.needsLineSpan = true;
|
|
7131
|
+
return `_spanLines(_ctx, ${startExpr}, ${endExpr})`;
|
|
7132
|
+
}
|
|
7133
|
+
function emitLineTrack(ctx, startExpr, endExpr) {
|
|
7134
|
+
if (!ctx.lineTracking) return [];
|
|
7135
|
+
ctx.needsLineTrack = true;
|
|
7136
|
+
return [`${ind(ctx)}_trackLines(_ctx, input, ${startExpr}, ${endExpr})`];
|
|
7137
|
+
}
|
|
7138
|
+
function emitLiteralLineTrack(ctx, startExpr, value) {
|
|
7139
|
+
if (!ctx.lineTracking) return [];
|
|
7140
|
+
const lineDeltas = [];
|
|
7141
|
+
for (let i = 0; i < value.length; i++) {
|
|
7142
|
+
if (value.charCodeAt(i) === 10) lineDeltas.push(i + 1);
|
|
7143
|
+
}
|
|
7144
|
+
if (lineDeltas.length === 0) return [];
|
|
7145
|
+
const fromV = v(ctx, "_ltFrom");
|
|
7146
|
+
const endExpr = value.length === 0 ? startExpr : `${startExpr} + ${value.length}`;
|
|
7147
|
+
return [
|
|
7148
|
+
`${ind(ctx)}const ${fromV} = _ctx._lineScannedTo ?? 0`,
|
|
7149
|
+
`${ind(ctx)}if (${endExpr} > ${fromV}) {`,
|
|
7150
|
+
`${ind(ctx)} for (let i = ${fromV}; i < ${startExpr}; i++) if (input.charCodeAt(i) === 10) _ctx._lineStarts.push(i + 1)`,
|
|
7151
|
+
...lineDeltas.map((delta) => {
|
|
7152
|
+
const lineStart = `${startExpr} + ${delta}`;
|
|
7153
|
+
return `${ind(ctx)} if (${lineStart} > ${fromV}) _ctx._lineStarts.push(${lineStart})`;
|
|
7154
|
+
}),
|
|
7155
|
+
`${ind(ctx)} _ctx._lineScannedTo = ${endExpr}`,
|
|
7156
|
+
`${ind(ctx)}}`
|
|
7157
|
+
];
|
|
7158
|
+
}
|
|
6965
7159
|
function ensureRegexDecl(ctx, source, flags) {
|
|
6966
7160
|
const f = "y" + flags.replace(/[gy]/g, "");
|
|
6967
7161
|
const key = `${source}/${f}`;
|
|
@@ -7346,6 +7540,7 @@ function emitLit(def, ctx, pos) {
|
|
|
7346
7540
|
);
|
|
7347
7541
|
}
|
|
7348
7542
|
const endVar = len === 0 ? pos : `${pos} + ${len}`;
|
|
7543
|
+
stmts.push(...emitLiteralLineTrack(ctx, pos, value));
|
|
7349
7544
|
stmts.push(...emitLeafCapture(ctx, vv, pos, endVar));
|
|
7350
7545
|
return { stmts, valueVar: vv, endVar };
|
|
7351
7546
|
}
|
|
@@ -7425,7 +7620,7 @@ function emitKeywords(def, ctx, pos) {
|
|
|
7425
7620
|
stmts.push(...emitLeafCapture(ctx, vv, pos, endVar));
|
|
7426
7621
|
return { stmts, valueVar: vv, endVar };
|
|
7427
7622
|
}
|
|
7428
|
-
function emitRegex(def, ctx, pos) {
|
|
7623
|
+
function emitRegex(def, ctx, pos, canMatchNewline = true) {
|
|
7429
7624
|
const expectedStr = JSON.stringify(`/${def.source}/`);
|
|
7430
7625
|
const shape = scanShapeFromRegex(def.source, def.flags);
|
|
7431
7626
|
if (shape) {
|
|
@@ -7438,7 +7633,11 @@ function emitRegex(def, ctx, pos) {
|
|
|
7438
7633
|
fresh: (prefix) => v(ctx, prefix)
|
|
7439
7634
|
});
|
|
7440
7635
|
if (scanned) {
|
|
7441
|
-
const stmts2 = [
|
|
7636
|
+
const stmts2 = [
|
|
7637
|
+
...scanned.stmts,
|
|
7638
|
+
...canMatchNewline ? emitLineTrack(ctx, pos, scanned.endVar) : [],
|
|
7639
|
+
...emitLeafCapture(ctx, vv2, pos, scanned.endVar)
|
|
7640
|
+
];
|
|
7442
7641
|
return { stmts: stmts2, valueVar: vv2, endVar: scanned.endVar };
|
|
7443
7642
|
}
|
|
7444
7643
|
}
|
|
@@ -7460,6 +7659,7 @@ function emitRegex(def, ctx, pos) {
|
|
|
7460
7659
|
`${ind(ctx)}const ${vv} = ${mv}[0]`
|
|
7461
7660
|
];
|
|
7462
7661
|
const endVar = `${pos} + ${vv}.length`;
|
|
7662
|
+
if (canMatchNewline) stmts.push(...emitLineTrack(ctx, pos, endVar));
|
|
7463
7663
|
stmts.push(...emitLeafCapture(ctx, vv, pos, endVar));
|
|
7464
7664
|
return { stmts, valueVar: vv, endVar };
|
|
7465
7665
|
}
|
|
@@ -7497,7 +7697,8 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7497
7697
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
7498
7698
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
7499
7699
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
7500
|
-
`${ind(ctx)}const ${scanEndV} = ${capFn}(input, ${curV}, _ctx, 1)
|
|
7700
|
+
`${ind(ctx)}const ${scanEndV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
7701
|
+
...emitLineTrack(ctx, curV, scanEndV)
|
|
7501
7702
|
);
|
|
7502
7703
|
const r2 = emit(def.parsers[i], ctx, scanEndV);
|
|
7503
7704
|
stmts.push(...r2.stmts);
|
|
@@ -7515,7 +7716,8 @@ function emitSeqValues(def, ctx, pos) {
|
|
|
7515
7716
|
const capArg = ctx.noHoist ? "0" : "_ctx._triviaLog !== undefined ? 2 : 0";
|
|
7516
7717
|
stmts.push(
|
|
7517
7718
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
7518
|
-
`${ind(ctx)}const ${scanEndV} = ${trivFn}(input, ${curV}, _ctx, ${capArg})
|
|
7719
|
+
`${ind(ctx)}const ${scanEndV} = ${trivFn}(input, ${curV}, _ctx, ${capArg})`,
|
|
7720
|
+
...emitLineTrack(ctx, curV, scanEndV)
|
|
7519
7721
|
);
|
|
7520
7722
|
const r2 = emit(def.parsers[i], ctx, scanEndV);
|
|
7521
7723
|
stmts.push(...r2.stmts);
|
|
@@ -8215,14 +8417,15 @@ function emitMany(def, ctx, pos) {
|
|
|
8215
8417
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
8216
8418
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
8217
8419
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8218
|
-
`${ind(ctx)}const ${npV} = ${capFn}(input, ${curV}, _ctx, 1)
|
|
8420
|
+
`${ind(ctx)}const ${npV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
8421
|
+
...emitLineTrack(ctx, curV, npV)
|
|
8219
8422
|
);
|
|
8220
8423
|
itemPos = npV;
|
|
8221
8424
|
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}; `;
|
|
8222
8425
|
} else {
|
|
8223
8426
|
const trivFn = ensureTriviaFn(ctx);
|
|
8224
8427
|
const npV = v(ctx, "_np");
|
|
8225
|
-
stmts.push(`${ind(ctx)}const ${npV} = ${trivFn}(input, ${curV}, _ctx)
|
|
8428
|
+
stmts.push(`${ind(ctx)}const ${npV} = ${trivFn}(input, ${curV}, _ctx)`, ...emitLineTrack(ctx, curV, npV));
|
|
8226
8429
|
itemPos = npV;
|
|
8227
8430
|
}
|
|
8228
8431
|
}
|
|
@@ -8292,7 +8495,7 @@ function emitAttempt(p, def, ctx, pos) {
|
|
|
8292
8495
|
if (!ctx.recovery && !ctx.coverage && needsFirstSetGuard(def.parser)) {
|
|
8293
8496
|
const gcV = v(ctx, "_agc");
|
|
8294
8497
|
const gExp = armStaticExpected(ctx, def.parser);
|
|
8295
|
-
const gFail = ctx.failLabel ? `{ _ctx._fe = ${pos};${ctx.recordFail ? ` _ctx._fx = ${gExp};` : ""} break ${ctx.failLabel} }` : `{ _ctx._fe = ${pos}; ${failReturnArr(gExp, pos)} }`;
|
|
8498
|
+
const gFail = ctx.failLabel ? `{ _ctx._fe = ${pos};${ctx.recordFail ? ` _ctx._fx = ${gExp};` : ""} break ${ctx.failLabel} }` : `{ _ctx._fe = ${pos}; ${failReturnArr(ctx, gExp, pos)} }`;
|
|
8296
8499
|
preGuard.push(
|
|
8297
8500
|
`${ind(ctx)}const ${gcV} = ${pos} < input.length ? (input.codePointAt(${pos}) ?? -1) : -1`,
|
|
8298
8501
|
`${ind(ctx)}if (!(${firstSetCond(gcV, def.parser._meta.firstSet)})) ${gFail}`
|
|
@@ -8399,7 +8602,8 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8399
8602
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
8400
8603
|
`${ind(ctx)}const ${markLv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
8401
8604
|
`${ind(ctx)}const ${markFld} = _ctx._fields ? _ctx._fields.length : 0`,
|
|
8402
|
-
`${ind(ctx)}const ${spV} = ${capFn}(input, ${curV}, _ctx, 1)
|
|
8605
|
+
`${ind(ctx)}const ${spV} = ${capFn}(input, ${curV}, _ctx, 1)`,
|
|
8606
|
+
...emitLineTrack(ctx, curV, spV)
|
|
8403
8607
|
);
|
|
8404
8608
|
sepAtPos = spV;
|
|
8405
8609
|
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}; `;
|
|
@@ -8409,7 +8613,7 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8409
8613
|
const post = postSepMarks();
|
|
8410
8614
|
stmts.push(...post.decl);
|
|
8411
8615
|
const npV = v(ctx, "_np");
|
|
8412
|
-
stmts.push(`${ind(ctx)}const ${npV} = ${capFn}(input, ${sepEnd}, _ctx, 1)
|
|
8616
|
+
stmts.push(`${ind(ctx)}const ${npV} = ${capFn}(input, ${sepEnd}, _ctx, 1)`, ...emitLineTrack(ctx, sepEnd, npV));
|
|
8413
8617
|
const next = emitFallible(def.parser, ctx, npV, true);
|
|
8414
8618
|
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = next;
|
|
8415
8619
|
stmts.push(
|
|
@@ -8421,13 +8625,13 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
8421
8625
|
} else {
|
|
8422
8626
|
const trivFn = ensureTriviaFn(ctx);
|
|
8423
8627
|
const spV = v(ctx, "_sp");
|
|
8424
|
-
stmts.push(`${ind(ctx)}const ${spV} = ${trivFn}(input, ${curV}, _ctx)
|
|
8628
|
+
stmts.push(`${ind(ctx)}const ${spV} = ${trivFn}(input, ${curV}, _ctx)`, ...emitLineTrack(ctx, curV, spV));
|
|
8425
8629
|
sepAtPos = spV;
|
|
8426
8630
|
const sep = emitFallible(def.separator, ctx, sepAtPos, true);
|
|
8427
8631
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = sep;
|
|
8428
8632
|
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${sep.mayCommit ? `if (_ctx._fc) ${committedFailBody(ctx)}; ` : ""}break }`);
|
|
8429
8633
|
const npV = v(ctx, "_np");
|
|
8430
|
-
stmts.push(`${ind(ctx)}const ${npV} = ${trivFn}(input, ${sepEnd}, _ctx)
|
|
8634
|
+
stmts.push(`${ind(ctx)}const ${npV} = ${trivFn}(input, ${sepEnd}, _ctx)`, ...emitLineTrack(ctx, sepEnd, npV));
|
|
8431
8635
|
const next = emitFallible(def.parser, ctx, npV, true);
|
|
8432
8636
|
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = next;
|
|
8433
8637
|
stmts.push(
|
|
@@ -8514,6 +8718,7 @@ function emitScanTo(def, ctx, pos) {
|
|
|
8514
8718
|
}
|
|
8515
8719
|
const valV = v(ctx);
|
|
8516
8720
|
stmts.push(`${ind(ctx)}const ${valV} = input.slice(${pos}, ${curV})`);
|
|
8721
|
+
stmts.push(...emitLineTrack(ctx, pos, curV));
|
|
8517
8722
|
if (ctx.capturing) {
|
|
8518
8723
|
const cap = reindentStmts(emitLeafCapture(ctx, valV, pos, curV), ctx.indent + 1);
|
|
8519
8724
|
stmts.push(`${ind(ctx)}if (${curV} > ${pos}) {`, ...cap, `${ind(ctx)}}`);
|
|
@@ -8657,7 +8862,7 @@ function tokenNullableRegex(def) {
|
|
|
8657
8862
|
}
|
|
8658
8863
|
function emitToken(def, ctx, pos) {
|
|
8659
8864
|
const lowered = tokenNullableRegex(def);
|
|
8660
|
-
if (lowered) return emitRegex(lowered, ctx, pos);
|
|
8865
|
+
if (lowered) return emitRegex(lowered, ctx, pos, def.parser._meta.canMatchNewline);
|
|
8661
8866
|
const savedTrivia = ctx.activeTrivia;
|
|
8662
8867
|
const savedKindLabels = ctx.triviaKindLabels;
|
|
8663
8868
|
ctx.activeTrivia = void 0;
|
|
@@ -8789,7 +8994,7 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8789
8994
|
if (!ctx.recovery && !ctx.coverage && (capturesChildren || structural) && needsFirstSetGuard(def.parser)) {
|
|
8790
8995
|
const gcV = v(ctx, "_ngc");
|
|
8791
8996
|
const gExp = armStaticExpected(ctx, def.parser);
|
|
8792
|
-
const gFail = ctx.failLabel ? ctx.recordFail ? `{ _ctx._fe = ${pos}; _ctx._fx = ${gExp}; break ${ctx.failLabel} }` : `break ${ctx.failLabel}` : failReturnArr(gExp, pos);
|
|
8997
|
+
const gFail = ctx.failLabel ? ctx.recordFail ? `{ _ctx._fe = ${pos}; _ctx._fx = ${gExp}; break ${ctx.failLabel} }` : `break ${ctx.failLabel}` : failReturnArr(ctx, gExp, pos);
|
|
8793
8998
|
preGuard.push(
|
|
8794
8999
|
`${i}const ${gcV} = ${pos} < input.length ? (input.codePointAt(${pos}) ?? -1) : -1`,
|
|
8795
9000
|
`${i}if (!(${firstSetCond(gcV, def.parser._meta.firstSet)})) ${gFail}`
|
|
@@ -8807,7 +9012,7 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8807
9012
|
stmts.push(...innerStmts);
|
|
8808
9013
|
if (def.trailingTrivia === true && ctx.activeTrivia) {
|
|
8809
9014
|
const triviaFn = ensureTriviaFn(ctx);
|
|
8810
|
-
stmts.push(`${i}const ${endVar} = ${okVar} ? ${triviaFn}(input, ${innerEndVar}, _ctx, 1) : ${innerEndVar}
|
|
9015
|
+
stmts.push(`${i}const ${endVar} = ${okVar} ? ${triviaFn}(input, ${innerEndVar}, _ctx, 1) : ${innerEndVar}`, ...emitLineTrack(ctx, innerEndVar, endVar));
|
|
8811
9016
|
}
|
|
8812
9017
|
if (sf && fArr) {
|
|
8813
9018
|
stmts.push(`${i}const ${fArr} = _ctx._fields`);
|
|
@@ -8847,8 +9052,11 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8847
9052
|
);
|
|
8848
9053
|
}
|
|
8849
9054
|
const ndV = v(ctx, "_nd");
|
|
8850
|
-
const
|
|
8851
|
-
const
|
|
9055
|
+
const nodeSpanExpr = emitSpanExpr(ctx, pos, endVar);
|
|
9056
|
+
const nodeSpanV = ctx.lineTracking ? v(ctx, "_nspan") : nodeSpanExpr;
|
|
9057
|
+
if (ctx.lineTracking) stmts.push(`${i}const ${nodeSpanV} = ${nodeSpanExpr}`);
|
|
9058
|
+
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})`;
|
|
9059
|
+
const hostBuildExpr = `_ctx._pmProfile?.phase === 'host' && _ctx._pmProfile.hostCalls++, _ctx.build(${JSON.stringify(def.type)}, ${chV}, ${fObj}, ${nodeSpanV}, ${rawV}, ${tlV}, ${stV})`;
|
|
8852
9060
|
const ndExpr = structural ? `_ctx.build !== undefined ? (${hostBuildExpr}) : (${buildExpr})` : cstOut ? hostBuildExpr : buildExpr;
|
|
8853
9061
|
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;
|
|
8854
9062
|
const unwrapExpr = `${chV}.length === 1 ? (${chV}[0] !== null && typeof ${chV}[0] === 'object' && ${chV}[0]._tag === 'leaf' ? ${chV}[0].value : ${chV}[0]) : (${ndExpr})`;
|
|
@@ -8858,7 +9066,7 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8858
9066
|
`${i}const ${ndV} = (${profileRecognizer} || ${profileCapture}) ? undefined : (${finalExpr})`,
|
|
8859
9067
|
`${i}if (!(${profileRecognizer})) {`,
|
|
8860
9068
|
`${i} if (${sc}) ${sc}.push(${ndV})`,
|
|
8861
|
-
`${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:
|
|
9069
|
+
`${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} })`,
|
|
8862
9070
|
`${i}}`
|
|
8863
9071
|
);
|
|
8864
9072
|
return { stmts, valueVar: ndV, endVar };
|
|
@@ -8874,7 +9082,8 @@ function emitRuntimeFallback(parser2, ctx, pos) {
|
|
|
8874
9082
|
`${ind(ctx)}const ${rv} = _rp[${idx}].parse(input, ${pos}, _ctx)`,
|
|
8875
9083
|
...emitIfFail(ctx, `!${rv}.ok`, failStmt),
|
|
8876
9084
|
`${ind(ctx)}const ${vv} = ${rv}.value`,
|
|
8877
|
-
`${ind(ctx)}const ${ev} = ${rv}.span.end
|
|
9085
|
+
`${ind(ctx)}const ${ev} = ${rv}.span.end`,
|
|
9086
|
+
...parser2._meta.canMatchNewline ? emitLineTrack(ctx, pos, ev) : []
|
|
8878
9087
|
];
|
|
8879
9088
|
return { stmts, valueVar: vv, endVar: ev };
|
|
8880
9089
|
}
|
|
@@ -8940,7 +9149,8 @@ function emitRecover(def, ctx, pos) {
|
|
|
8940
9149
|
`${ind0} if (${sentOk}) break`,
|
|
8941
9150
|
`${ind0} ${scanV}++`,
|
|
8942
9151
|
`${ind0} }`,
|
|
8943
|
-
|
|
9152
|
+
...emitLineTrack(ctx, pos, scanV).map((s) => `${ind0} ${s.trim()}`),
|
|
9153
|
+
`${ind0} const ${errV} = { _tag: 'parseError', span: ${emitSpanExpr(ctx, pos, scanV)}, expected: ${JSON.stringify(deriveExpected(def.parser))} }`,
|
|
8944
9154
|
`${ind0} if (_ctx._errors) _ctx._errors.push(${errV})`,
|
|
8945
9155
|
`${ind0} ${valVar} = ${errV}`,
|
|
8946
9156
|
`${ind0} ${endVar} = ${scanV}`,
|
|
@@ -8956,7 +9166,7 @@ function emitExpect(def, ctx, pos) {
|
|
|
8956
9166
|
const stmts = [
|
|
8957
9167
|
...innerStmts,
|
|
8958
9168
|
`${ind0}if (!${okVar}) {`,
|
|
8959
|
-
`${ind0} const ${errV} = { _tag: 'parseError', span: {
|
|
9169
|
+
`${ind0} const ${errV} = { _tag: 'parseError', span: ${emitSpanExpr(ctx, pos, pos)}, expected: ${JSON.stringify(def.expected)} }`,
|
|
8960
9170
|
`${ind0} if (_ctx._errors) _ctx._errors.push(${errV})`,
|
|
8961
9171
|
// Embed the missing-token error as a `parseError` CST child, mirroring the
|
|
8962
9172
|
// interpreter (expect.ts) and the list-recovery emit sites — guarded on
|
|
@@ -9046,7 +9256,7 @@ function emitDispatch(p, ctx, pos) {
|
|
|
9046
9256
|
case "literal":
|
|
9047
9257
|
return emitLit(def, ctx, pos);
|
|
9048
9258
|
case "regex":
|
|
9049
|
-
return emitRegex(def, ctx, pos);
|
|
9259
|
+
return emitRegex(def, ctx, pos, p._meta.canMatchNewline);
|
|
9050
9260
|
case "keywords":
|
|
9051
9261
|
return emitKeywords(def, ctx, pos);
|
|
9052
9262
|
case "sequence":
|
|
@@ -9296,6 +9506,21 @@ function hasNodeDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9296
9506
|
return false;
|
|
9297
9507
|
}
|
|
9298
9508
|
}
|
|
9509
|
+
function hasLineTrackingDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
9510
|
+
if (seen.has(p)) return false;
|
|
9511
|
+
seen.add(p);
|
|
9512
|
+
const d = p._def;
|
|
9513
|
+
if (p._meta.grammarTrackLines) return true;
|
|
9514
|
+
if (d.tag === "grammar" && d.trackLines) return true;
|
|
9515
|
+
if (d.tag === "lazy") {
|
|
9516
|
+
try {
|
|
9517
|
+
return hasLineTrackingDef(d.thunk(), seen);
|
|
9518
|
+
} catch {
|
|
9519
|
+
return false;
|
|
9520
|
+
}
|
|
9521
|
+
}
|
|
9522
|
+
return childrenOf2(d).some((child) => hasLineTrackingDef(child, seen));
|
|
9523
|
+
}
|
|
9299
9524
|
function parserUsesRouted2(p, seen = /* @__PURE__ */ new Set()) {
|
|
9300
9525
|
if (seen.has(p)) return false;
|
|
9301
9526
|
seen.add(p);
|
|
@@ -9643,6 +9868,7 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9643
9868
|
const grammarTrivia = combinator._meta.grammarTrivia;
|
|
9644
9869
|
const grammarScanSkip = combinator._meta.grammarScanSkip;
|
|
9645
9870
|
const grammarHostMode = combinator._meta.grammarHostMode;
|
|
9871
|
+
const grammarTrackLines = combinator._meta.grammarTrackLines;
|
|
9646
9872
|
const ctx = {
|
|
9647
9873
|
vars: 0,
|
|
9648
9874
|
indent: 1,
|
|
@@ -9663,6 +9889,7 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9663
9889
|
capturing: hasNodeDef(combinator),
|
|
9664
9890
|
recovery: opts?.recovery ?? false,
|
|
9665
9891
|
hostMode: opts?.hostMode ?? grammarHostMode ?? "ast",
|
|
9892
|
+
lineTracking: opts?.trackLines === true || grammarTrackLines === true || hasLineTrackingDef(combinator),
|
|
9666
9893
|
...opts?.coverage ? { coverage: { plan: buildGrammarPlan(combinator), entry: combinator } } : {},
|
|
9667
9894
|
lazyUsage: analyzeLazyUsage(combinator),
|
|
9668
9895
|
...grammarTrivia ? { activeTrivia: grammarTrivia, triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {},
|
|
@@ -9686,9 +9913,13 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9686
9913
|
const namedPrelude = ctx.namedFnDecls.length > 0 ? [...namedFnPrelude(), ""] : [];
|
|
9687
9914
|
const emptyTlDecls = ctx.needsEmptyTl ? ["const _EMPTY_TL = Object.freeze([])"] : [];
|
|
9688
9915
|
const hostReadsDecls = ctx.needsHostReads ? [HOST_READS_DECL] : [];
|
|
9916
|
+
const lineTrackDecls = ctx.needsLineTrack ? [LINE_TRACK_DECL] : [];
|
|
9917
|
+
const lineSpanDecls = ctx.needsLineSpan ? [LINE_SPAN_DECL] : [];
|
|
9689
9918
|
const source = [
|
|
9690
9919
|
...emptyTlDecls,
|
|
9691
9920
|
...hostReadsDecls,
|
|
9921
|
+
...lineTrackDecls,
|
|
9922
|
+
...lineSpanDecls,
|
|
9692
9923
|
...ctx.regexDecls,
|
|
9693
9924
|
...ctx.expectedDecls,
|
|
9694
9925
|
"",
|
|
@@ -9701,6 +9932,8 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9701
9932
|
const fn = new Function("input", "_pos", "_rp", "_mf", "_build", "_ctx", [
|
|
9702
9933
|
...emptyTlDecls,
|
|
9703
9934
|
...hostReadsDecls,
|
|
9935
|
+
...lineTrackDecls,
|
|
9936
|
+
...lineSpanDecls,
|
|
9704
9937
|
...ctx.regexDecls,
|
|
9705
9938
|
...ctx.expectedDecls,
|
|
9706
9939
|
...namedPrelude,
|
|
@@ -9719,6 +9952,25 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9719
9952
|
trackLines: false,
|
|
9720
9953
|
...ctx.triviaKindLabels ? { triviaKindLabels: ctx.triviaKindLabels } : {}
|
|
9721
9954
|
};
|
|
9955
|
+
const annotateWithTrackedLines = (result, lineStarts) => {
|
|
9956
|
+
const index = normalizeLineIndex({ lineStarts });
|
|
9957
|
+
const annotated = { ...result, span: annotateSpan(result.span, index) };
|
|
9958
|
+
const errors = annotated.errors;
|
|
9959
|
+
if (errors) {
|
|
9960
|
+
;
|
|
9961
|
+
annotated.errors = errors.map((error) => ({
|
|
9962
|
+
...error,
|
|
9963
|
+
span: annotateSpan(error.span, index)
|
|
9964
|
+
}));
|
|
9965
|
+
}
|
|
9966
|
+
return annotated;
|
|
9967
|
+
};
|
|
9968
|
+
const trackedCtx = (base, input, pos) => {
|
|
9969
|
+
if (!ctx.lineTracking) return base;
|
|
9970
|
+
const lineIndex = { lineStarts: [0] };
|
|
9971
|
+
if (pos > 0) recordLineRange(lineIndex, input, 0, pos);
|
|
9972
|
+
return { ...base, trackLines: true, _lineStarts: lineIndex.lineStarts, _lineScannedTo: pos };
|
|
9973
|
+
};
|
|
9722
9974
|
const derivedSrcs = ctx.mapFnSrcs.length === ctx.mapFns.length && ctx.mapFnSrcs.every((s) => s !== null) ? ctx.mapFnSrcs : void 0;
|
|
9723
9975
|
const effectiveSources = mapFnSources ?? derivedSrcs;
|
|
9724
9976
|
const buildCovered = ctx.buildFns.length === 0 || ctx.buildSrcs.every((s) => s !== null);
|
|
@@ -9726,17 +9978,46 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9726
9978
|
const mfCovered = ctx.mapFns.length === 0 || effectiveSources !== void 0 && effectiveSources.length === ctx.mapFns.length;
|
|
9727
9979
|
const canInline = ctx.runtimeParsers.length === 0 && mfCovered && buildCovered;
|
|
9728
9980
|
const inlineExpression = canInline ? buildInlineExpression(ctx, r, effectiveSources, buildSources, coverageRootRuleId) : null;
|
|
9729
|
-
|
|
9981
|
+
const compiledMeta = {
|
|
9730
9982
|
source,
|
|
9731
9983
|
inlineExpression,
|
|
9732
9984
|
...ctx.coverage === void 0 ? {} : { coverageDefinitions: ctx.coverage.plan.definitions },
|
|
9733
|
-
...gatingReport === void 0 ? {} : { gating: gatingReport }
|
|
9985
|
+
...gatingReport === void 0 ? {} : { gating: gatingReport }
|
|
9986
|
+
};
|
|
9987
|
+
if (!ctx.lineTracking) {
|
|
9988
|
+
return {
|
|
9989
|
+
...compiledMeta,
|
|
9990
|
+
parse(input, pos = 0) {
|
|
9991
|
+
return fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, defaultCtx);
|
|
9992
|
+
},
|
|
9993
|
+
parseWithContext(input, parseCtx, pos = 0) {
|
|
9994
|
+
assertHostModeCompatible(ctx.hostMode ?? "ast", parseCtx.build, !!ctx.hostBranchElided);
|
|
9995
|
+
return fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, parseCtx);
|
|
9996
|
+
},
|
|
9997
|
+
// Note: collects expect() errors via _errors. Unlike interpreter
|
|
9998
|
+
// parse({recover:true}) it does NOT populate furthestFail — the compiled path
|
|
9999
|
+
// inlines failures for throughput and deliberately skips _probe bookkeeping.
|
|
10000
|
+
// Callers wanting a furthest-position diagnostic detect unconsumed input
|
|
10001
|
+
// (span.end < input.length) instead, which is mode-agnostic.
|
|
10002
|
+
parseWithErrors(input, pos = 0) {
|
|
10003
|
+
const errors = [];
|
|
10004
|
+
const result = fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, { ...defaultCtx, _errors: errors });
|
|
10005
|
+
return { ...result, errors };
|
|
10006
|
+
}
|
|
10007
|
+
};
|
|
10008
|
+
}
|
|
10009
|
+
return {
|
|
10010
|
+
...compiledMeta,
|
|
9734
10011
|
parse(input, pos = 0) {
|
|
9735
|
-
|
|
10012
|
+
const parseCtx = trackedCtx(defaultCtx, input, pos);
|
|
10013
|
+
const result = fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, parseCtx);
|
|
10014
|
+
return annotateWithTrackedLines(result, parseCtx._lineStarts);
|
|
9736
10015
|
},
|
|
9737
10016
|
parseWithContext(input, parseCtx, pos = 0) {
|
|
9738
10017
|
assertHostModeCompatible(ctx.hostMode ?? "ast", parseCtx.build, !!ctx.hostBranchElided);
|
|
9739
|
-
|
|
10018
|
+
const activeCtx = trackedCtx(parseCtx, input, pos);
|
|
10019
|
+
const result = fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, activeCtx);
|
|
10020
|
+
return activeCtx.trackLines ? annotateWithTrackedLines(result, activeCtx._lineStarts) : result;
|
|
9740
10021
|
},
|
|
9741
10022
|
// Note: collects expect() errors via _errors. Unlike interpreter
|
|
9742
10023
|
// parse({recover:true}) it does NOT populate furthestFail — the compiled path
|
|
@@ -9745,8 +10026,9 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9745
10026
|
// (span.end < input.length) instead, which is mode-agnostic.
|
|
9746
10027
|
parseWithErrors(input, pos = 0) {
|
|
9747
10028
|
const errors = [];
|
|
9748
|
-
const
|
|
9749
|
-
|
|
10029
|
+
const parseCtx = trackedCtx({ ...defaultCtx, _errors: errors }, input, pos);
|
|
10030
|
+
const result = { ...fn(input, pos, ctx.runtimeParsers, ctx.mapFns, ctx.buildFns, parseCtx), errors };
|
|
10031
|
+
return annotateWithTrackedLines(result, parseCtx._lineStarts);
|
|
9750
10032
|
}
|
|
9751
10033
|
};
|
|
9752
10034
|
}
|
|
@@ -9771,6 +10053,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
9771
10053
|
const grammarTrivia = opts?.trivia ?? ruleMapArg.map(([, r]) => r._meta.grammarTrivia).find(Boolean);
|
|
9772
10054
|
const grammarScanSkip = opts?.scanSkip ?? ruleMapArg.map(([, r]) => r._meta.grammarScanSkip).find(Boolean);
|
|
9773
10055
|
const grammarHostMode = opts?.hostMode ?? ruleMapArg.map(([, r]) => r._meta.grammarHostMode).find(Boolean);
|
|
10056
|
+
const grammarTrackLines = opts?.trackLines === true || ruleMapArg.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
9774
10057
|
const ruleMap = ruleMapArg.filter(([, val]) => {
|
|
9775
10058
|
const d = val._def;
|
|
9776
10059
|
if (d.tag !== "lazy") return true;
|
|
@@ -9805,6 +10088,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
9805
10088
|
capturing: opts?.captureTerminals === true || ruleMap.some(([, rule]) => hasNodeDef(rule)),
|
|
9806
10089
|
recovery: opts?.recovery ?? false,
|
|
9807
10090
|
hostMode: grammarHostMode ?? "ast",
|
|
10091
|
+
lineTracking: grammarTrackLines,
|
|
9808
10092
|
...opts?.coverage ? { coverage: { plan: opts.coverage } } : {},
|
|
9809
10093
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
9810
10094
|
ns,
|
|
@@ -9901,6 +10185,10 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
9901
10185
|
perEntry.push({ key, rule, r: emitNamedFnCall(ctx, fn, "_pos") });
|
|
9902
10186
|
}
|
|
9903
10187
|
if (ctx.runtimeParsers.length !== 0) return null;
|
|
10188
|
+
if (ctx.lineTracking) {
|
|
10189
|
+
ctx.needsLineTrack = true;
|
|
10190
|
+
ctx.needsLineSpan = true;
|
|
10191
|
+
}
|
|
9904
10192
|
const mfSrcs = ctx.mapFns.length > 0 && ctx.mapFnSrcs.every((s) => s !== null) ? ctx.mapFnSrcs : null;
|
|
9905
10193
|
const buildSrcs = ctx.buildFns.length > 0 && ctx.buildSrcs.every((s) => s !== null) ? ctx.buildSrcs : null;
|
|
9906
10194
|
const ruleFns = /* @__PURE__ */ new Map();
|
|
@@ -9914,6 +10202,8 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
9914
10202
|
const mfDecl = ctx.mapFns.length === 0 ? "" : mfSrcs ? `const ${mfRef(ctx)} = [${mfSrcs.join(", ")}]` : `const ${mfRef(ctx)} = _env[${JSON.stringify(nsp(ctx) + "mf")}]`;
|
|
9915
10203
|
const buildDecl = ctx.buildFns.length === 0 ? "" : buildSrcs ? `const ${buildRef(ctx)} = [${buildSrcs.join(", ")}]` : `const ${buildRef(ctx)} = _env[${JSON.stringify(nsp(ctx) + "build")}]`;
|
|
9916
10204
|
const prelude = [
|
|
10205
|
+
ctx.needsLineTrack ? LINE_TRACK_DECL : "",
|
|
10206
|
+
ctx.needsLineSpan ? LINE_SPAN_DECL : "",
|
|
9917
10207
|
...ctx.regexDecls,
|
|
9918
10208
|
...ctx.expectedDecls,
|
|
9919
10209
|
mfDecl,
|
|
@@ -9922,11 +10212,18 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
9922
10212
|
].filter(Boolean);
|
|
9923
10213
|
const wrappers = /* @__PURE__ */ new Map();
|
|
9924
10214
|
for (const { key, rule, r } of perEntry) {
|
|
10215
|
+
const linePreamble = ctx.lineTracking ? [
|
|
10216
|
+
` if (_ctx._lineStarts === undefined) _ctx = { ..._ctx, trackLines: true, _lineStarts: [0], _lineScannedTo: 0 }`,
|
|
10217
|
+
` else _ctx.trackLines = true`,
|
|
10218
|
+
` if (_pos > (_ctx._lineScannedTo ?? 0)) _trackLines(_ctx, input, 0, _pos)`
|
|
10219
|
+
] : [];
|
|
10220
|
+
const resultSpan = ctx.lineTracking ? `_spanLines(_ctx, _pos, ${r.endVar})` : `{ start: _pos, end: ${r.endVar} }`;
|
|
9925
10221
|
wrappers.set(key, publicRuleWrapperSource(rule, [
|
|
9926
10222
|
`function(input, _pos, _ctx) {`,
|
|
10223
|
+
...linePreamble,
|
|
9927
10224
|
` let pos = _pos`,
|
|
9928
10225
|
...r.stmts,
|
|
9929
|
-
` return { ok: true, value: ${r.valueVar}, span:
|
|
10226
|
+
` return { ok: true, value: ${r.valueVar}, span: ${resultSpan} }`,
|
|
9930
10227
|
`}`
|
|
9931
10228
|
].join("\n"), ctx.triviaKindLabels));
|
|
9932
10229
|
}
|
|
@@ -10033,12 +10330,16 @@ function buildInlineExpression(ctx, r, mapFnSources, buildSources, coverageRootR
|
|
|
10033
10330
|
const buildDecl = buildSources?.length ? ` const _build = [${buildSources.join(", ")}]` : "";
|
|
10034
10331
|
const emptyTlDecl = ctx.needsEmptyTl ? ` const _EMPTY_TL = Object.freeze([])` : "";
|
|
10035
10332
|
const hostReadsDecl = ctx.needsHostReads ? ` ${HOST_READS_DECL}` : "";
|
|
10036
|
-
const
|
|
10333
|
+
const lineTrackDecl = ctx.needsLineTrack ? ` ${LINE_TRACK_DECL}` : "";
|
|
10334
|
+
const lineSpanDecl = ctx.needsLineSpan ? ` ${LINE_SPAN_DECL}` : "";
|
|
10335
|
+
const needsWrapper = ctx.regexDecls.length > 0 || ctx.expectedDecls.length > 0 || ctx.namedFnDecls.length > 0 || !!mfDecl || !!buildDecl || !!emptyTlDecl || !!hostReadsDecl || !!lineTrackDecl || !!lineSpanDecl;
|
|
10037
10336
|
if (!needsWrapper) return innerFn;
|
|
10038
10337
|
const namedPrelude = ctx.namedFnDecls.length > 0 ? namedFnPrelude() : [];
|
|
10039
10338
|
const hoistedDecls = [
|
|
10040
10339
|
emptyTlDecl,
|
|
10041
10340
|
hostReadsDecl,
|
|
10341
|
+
lineTrackDecl,
|
|
10342
|
+
lineSpanDecl,
|
|
10042
10343
|
...ctx.regexDecls.map((d) => ` ${d}`),
|
|
10043
10344
|
...ctx.expectedDecls.map((d) => ` ${d}`),
|
|
10044
10345
|
mfDecl,
|
|
@@ -10587,7 +10888,7 @@ function normalizeCstCollapse(collapse) {
|
|
|
10587
10888
|
return typeof collapse === "function" ? collapse : void 0;
|
|
10588
10889
|
}
|
|
10589
10890
|
function buildCstNode(type, children2, _fields, span, _rawChildren, _triviaLog, state) {
|
|
10590
|
-
return { _tag: "node", type, span: {
|
|
10891
|
+
return { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children2] };
|
|
10591
10892
|
}
|
|
10592
10893
|
function cstBuildHost(typeOrOptions, children2, _fields, span, rawChildren, triviaLog, state) {
|
|
10593
10894
|
if (typeof typeOrOptions === "string") {
|
|
@@ -10810,7 +11111,8 @@ function materializePiece(p, trivia2, captureTerminals = false, hostMode) {
|
|
|
10810
11111
|
const pieces = compileLinkable(evalRuleMapIR(p.ir), p.ns, {
|
|
10811
11112
|
...trivia2 ? { trivia: trivia2 } : {},
|
|
10812
11113
|
...captureTerminals ? { captureTerminals: true } : {},
|
|
10813
|
-
...hostMode ? { hostMode } : {}
|
|
11114
|
+
...hostMode ? { hostMode } : {},
|
|
11115
|
+
...p.trackLines ? { trackLines: true } : {}
|
|
10814
11116
|
});
|
|
10815
11117
|
if (!pieces) throw new Error(`compose: carried IR for ns "${p.ns}" could not be re-lowered`);
|
|
10816
11118
|
return pieces;
|