parseman 0.24.0 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cst/relative-spans.d.ts +32 -0
- package/dist/cst/relative-spans.d.ts.map +1 -1
- package/dist/functional/doc.d.ts +53 -3
- package/dist/functional/doc.d.ts.map +1 -1
- package/dist/index.cjs +319 -100
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +319 -100
- package/dist/index.js.map +4 -4
- package/dist/plugin/index.cjs.map +1 -1
- package/dist/plugin/index.js.map +1 -1
- package/dist/spec/index.cjs +67 -6
- package/dist/spec/index.cjs.map +3 -3
- package/dist/spec/index.d.ts +10 -2
- package/dist/spec/index.d.ts.map +1 -1
- package/dist/spec/index.js +67 -6
- package/dist/spec/index.js.map +3 -3
- package/dist/spec/model.d.ts.map +1 -1
- package/dist/spec/railroad.d.ts +12 -0
- package/dist/spec/railroad.d.ts.map +1 -1
- package/package.json +3 -2
package/dist/index.d.ts
CHANGED
|
@@ -44,6 +44,6 @@ export type { TriviaEntriesView } from './cst/trivia-entries.ts';
|
|
|
44
44
|
export { triviaKindMask } from './cst/trivia-kinds.ts';
|
|
45
45
|
export { OffsetIndex, buildOffsetIndex, collectLeafSlots, gapText, lineBreaksIn, blankLinesIn, lineStartWithin, indentWidth, indentMixed, commentsIn, gapIsSignificant, } from './cst/offset-model.ts';
|
|
46
46
|
export type { Slot, Gap } from './cst/offset-model.ts';
|
|
47
|
-
export { relativize, absolutize, absoluteSpanAt, shiftAbsolute, applyEdit, } from './cst/relative-spans.ts';
|
|
47
|
+
export { relativize, absolutize, absoluteSpanAt, shiftAbsolute, applyEdit, relativizeCST, absolutizeCST, absoluteSpanCST, } from './cst/relative-spans.ts';
|
|
48
48
|
export type { AbsNode, RelNode } from './cst/relative-spans.ts';
|
|
49
49
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -6393,17 +6393,159 @@ function manyRecover(item, until) {
|
|
|
6393
6393
|
return many(tolerantElement(item, until, until));
|
|
6394
6394
|
}
|
|
6395
6395
|
|
|
6396
|
+
// src/cst/relative-spans.ts
|
|
6397
|
+
function relativize(node2, parentBase = 0) {
|
|
6398
|
+
return {
|
|
6399
|
+
start: node2.start - parentBase,
|
|
6400
|
+
end: node2.end - parentBase,
|
|
6401
|
+
children: node2.children.map((c) => relativize(c, node2.start))
|
|
6402
|
+
};
|
|
6403
|
+
}
|
|
6404
|
+
function absolutize(node2, parentBase = 0) {
|
|
6405
|
+
const start = parentBase + node2.start;
|
|
6406
|
+
return {
|
|
6407
|
+
start,
|
|
6408
|
+
end: parentBase + node2.end,
|
|
6409
|
+
children: node2.children.map((c) => absolutize(c, start))
|
|
6410
|
+
};
|
|
6411
|
+
}
|
|
6412
|
+
function absoluteSpanAt(root, path) {
|
|
6413
|
+
let base = 0;
|
|
6414
|
+
let node2 = root;
|
|
6415
|
+
for (const idx of path) {
|
|
6416
|
+
base += node2.start;
|
|
6417
|
+
const child = node2.children[idx];
|
|
6418
|
+
if (!child) throw new RangeError(`absoluteSpanAt: no child ${idx} on path ${path.join(".")}`);
|
|
6419
|
+
node2 = child;
|
|
6420
|
+
}
|
|
6421
|
+
return { start: base + node2.start, end: base + node2.end };
|
|
6422
|
+
}
|
|
6423
|
+
function relativizeCST(node2, parentBase = 0) {
|
|
6424
|
+
const span = { start: node2.span.start - parentBase, end: node2.span.end - parentBase };
|
|
6425
|
+
if (node2.children) {
|
|
6426
|
+
const base = node2.span.start;
|
|
6427
|
+
return { ...node2, span, children: node2.children.map((c) => relativizeCST(c, base)) };
|
|
6428
|
+
}
|
|
6429
|
+
return { ...node2, span };
|
|
6430
|
+
}
|
|
6431
|
+
function absolutizeCST(node2, parentBase = 0) {
|
|
6432
|
+
const start = parentBase + node2.span.start;
|
|
6433
|
+
const span = { start, end: parentBase + node2.span.end };
|
|
6434
|
+
if (node2.children) {
|
|
6435
|
+
return { ...node2, span, children: node2.children.map((c) => absolutizeCST(c, start)) };
|
|
6436
|
+
}
|
|
6437
|
+
return { ...node2, span };
|
|
6438
|
+
}
|
|
6439
|
+
function absoluteSpanCST(root, path) {
|
|
6440
|
+
let base = 0;
|
|
6441
|
+
let node2 = root;
|
|
6442
|
+
for (const idx of path) {
|
|
6443
|
+
base += node2.span.start;
|
|
6444
|
+
const child = node2.children?.[idx];
|
|
6445
|
+
if (!child) throw new RangeError(`absoluteSpanCST: no child ${idx} on path ${path.join(".")}`);
|
|
6446
|
+
node2 = child;
|
|
6447
|
+
}
|
|
6448
|
+
return { start: base + node2.span.start, end: base + node2.span.end };
|
|
6449
|
+
}
|
|
6450
|
+
function shiftAbsolute(node2, at, delta) {
|
|
6451
|
+
const s = node2.start >= at ? node2.start + delta : node2.start;
|
|
6452
|
+
const e = node2.end >= at ? node2.end + delta : node2.end;
|
|
6453
|
+
return {
|
|
6454
|
+
start: s,
|
|
6455
|
+
end: e,
|
|
6456
|
+
children: node2.children.map((c) => shiftAbsolute(c, at, delta))
|
|
6457
|
+
};
|
|
6458
|
+
}
|
|
6459
|
+
function applyEdit(root, at, delta, stats) {
|
|
6460
|
+
return editNode(root, at, delta, 0, 0, stats);
|
|
6461
|
+
}
|
|
6462
|
+
function editNode(node2, at, delta, parentBase, parentShift, stats) {
|
|
6463
|
+
const absStart = parentBase + node2.start;
|
|
6464
|
+
const absEnd = parentBase + node2.end;
|
|
6465
|
+
if (absEnd < at) return node2;
|
|
6466
|
+
const startShifts = absStart >= at;
|
|
6467
|
+
if (startShifts && parentShift === delta) return node2;
|
|
6468
|
+
if (stats) stats.allocated++;
|
|
6469
|
+
const newAbsStart = startShifts ? absStart + delta : absStart;
|
|
6470
|
+
const newAbsEnd = absEnd + delta;
|
|
6471
|
+
const newParentBase = parentBase + parentShift;
|
|
6472
|
+
const newStart = newAbsStart - newParentBase;
|
|
6473
|
+
const newEnd = newAbsEnd - newParentBase;
|
|
6474
|
+
const ownShift = newAbsStart - absStart;
|
|
6475
|
+
let changed = false;
|
|
6476
|
+
const newChildren = [];
|
|
6477
|
+
for (const c of node2.children) {
|
|
6478
|
+
const nc = editNode(c, at, delta, absStart, ownShift, stats);
|
|
6479
|
+
if (nc !== c) changed = true;
|
|
6480
|
+
newChildren.push(nc);
|
|
6481
|
+
}
|
|
6482
|
+
return {
|
|
6483
|
+
start: newStart,
|
|
6484
|
+
end: newEnd,
|
|
6485
|
+
children: changed ? newChildren : node2.children
|
|
6486
|
+
};
|
|
6487
|
+
}
|
|
6488
|
+
|
|
6396
6489
|
// src/functional/doc.ts
|
|
6490
|
+
function asRuleFn(entry) {
|
|
6491
|
+
return typeof entry === "function" ? entry : (input, pos, ctx) => entry.parse(input, pos, ctx);
|
|
6492
|
+
}
|
|
6493
|
+
function defOf(entry) {
|
|
6494
|
+
return typeof entry === "object" && entry !== null && "_def" in entry ? entry._def : void 0;
|
|
6495
|
+
}
|
|
6496
|
+
function producesRepetition(def, depth = 0) {
|
|
6497
|
+
if (!def || depth > 24) return false;
|
|
6498
|
+
const d = def;
|
|
6499
|
+
switch (d.tag) {
|
|
6500
|
+
case "sepBy":
|
|
6501
|
+
case "many":
|
|
6502
|
+
case "oneOrMore":
|
|
6503
|
+
return true;
|
|
6504
|
+
// Rule entries and `ref`s wrap their body in a `lazy` thunk — resolve it. The
|
|
6505
|
+
// `depth` cap bounds any self-referential cycle (a repetition, if present, is
|
|
6506
|
+
// found shallowly before recursion goes deep).
|
|
6507
|
+
case "lazy": {
|
|
6508
|
+
const thunk = d.thunk;
|
|
6509
|
+
let inner;
|
|
6510
|
+
try {
|
|
6511
|
+
inner = typeof thunk === "function" ? thunk() : void 0;
|
|
6512
|
+
} catch {
|
|
6513
|
+
return false;
|
|
6514
|
+
}
|
|
6515
|
+
return producesRepetition(inner?._def, depth + 1);
|
|
6516
|
+
}
|
|
6517
|
+
// Transparent wrappers — look through to the inner parser.
|
|
6518
|
+
case "node":
|
|
6519
|
+
case "transform":
|
|
6520
|
+
case "token":
|
|
6521
|
+
case "label":
|
|
6522
|
+
case "field":
|
|
6523
|
+
case "expect":
|
|
6524
|
+
case "withCtx":
|
|
6525
|
+
case "grammar":
|
|
6526
|
+
case "optional":
|
|
6527
|
+
return producesRepetition(defOf(d.parser), depth + 1);
|
|
6528
|
+
case "skip":
|
|
6529
|
+
return producesRepetition(defOf(d.main), depth + 1);
|
|
6530
|
+
// A bracketed/anchored list is a sequence whose element run is a repetition.
|
|
6531
|
+
case "sequence":
|
|
6532
|
+
return d.parsers.some((p) => producesRepetition(defOf(p), depth + 1));
|
|
6533
|
+
default:
|
|
6534
|
+
return false;
|
|
6535
|
+
}
|
|
6536
|
+
}
|
|
6397
6537
|
var REENTRY_MAX_SPAN_FRACTION = 0.5;
|
|
6398
6538
|
function isNode(x) {
|
|
6399
6539
|
return typeof x === "object" && x !== null && x._tag === "node";
|
|
6400
6540
|
}
|
|
6401
|
-
function findContaining(node2, pos, path = []) {
|
|
6541
|
+
function findContaining(node2, nodeAbsStart, pos, path = []) {
|
|
6402
6542
|
for (let i = 0; i < node2.children.length; i++) {
|
|
6403
6543
|
const child = node2.children[i];
|
|
6404
6544
|
if (!isNode(child)) continue;
|
|
6405
|
-
|
|
6406
|
-
|
|
6545
|
+
const childAbsStart = nodeAbsStart + child.span.start;
|
|
6546
|
+
const childAbsEnd = nodeAbsStart + child.span.end;
|
|
6547
|
+
if (childAbsStart <= pos && pos < childAbsEnd) {
|
|
6548
|
+
const inner = findContaining(child, childAbsStart, pos, [...path, i]);
|
|
6407
6549
|
return inner ?? { node: child, path: [...path, i] };
|
|
6408
6550
|
}
|
|
6409
6551
|
}
|
|
@@ -6430,24 +6572,20 @@ function replaceAtPath(rebuild, root, path, newNode) {
|
|
|
6430
6572
|
function defaultRebuild(node2, children) {
|
|
6431
6573
|
return { ...node2, children };
|
|
6432
6574
|
}
|
|
6433
|
-
function
|
|
6575
|
+
function shiftRelStart(child, delta) {
|
|
6434
6576
|
const c = child;
|
|
6435
|
-
|
|
6436
|
-
if (Array.isArray(c.children)) {
|
|
6437
|
-
return { ...c, span, children: c.children.map((g) => shiftSpans(g, delta)) };
|
|
6438
|
-
}
|
|
6439
|
-
return { ...c, span };
|
|
6577
|
+
return { ...c, span: { start: c.span.start + delta, end: c.span.end + delta } };
|
|
6440
6578
|
}
|
|
6441
|
-
function
|
|
6579
|
+
function graftRelative(root, path, newNode, delta) {
|
|
6442
6580
|
if (path.length === 0) return newNode;
|
|
6443
6581
|
const [idx, ...rest] = path;
|
|
6444
6582
|
const oldChildren = root.children;
|
|
6445
6583
|
const newChildren = oldChildren.map((child, i) => {
|
|
6446
6584
|
if (i < idx) return child;
|
|
6447
6585
|
if (i === idx) {
|
|
6448
|
-
return rest.length === 0 ? newNode :
|
|
6586
|
+
return rest.length === 0 ? newNode : graftRelative(child, rest, newNode, delta);
|
|
6449
6587
|
}
|
|
6450
|
-
return
|
|
6588
|
+
return shiftRelStart(child, delta);
|
|
6451
6589
|
});
|
|
6452
6590
|
return {
|
|
6453
6591
|
...root,
|
|
@@ -6455,6 +6593,96 @@ function graftAndShift(root, path, newNode, delta) {
|
|
|
6455
6593
|
children: newChildren
|
|
6456
6594
|
};
|
|
6457
6595
|
}
|
|
6596
|
+
function parseMiddle(input, reStart, reEnd, cStart, ruleFn, separator, build) {
|
|
6597
|
+
const ctx = { trackLines: false, state: null, build };
|
|
6598
|
+
const out = [];
|
|
6599
|
+
let pos = reStart;
|
|
6600
|
+
let guard2 = 0;
|
|
6601
|
+
while (pos < reEnd) {
|
|
6602
|
+
if (++guard2 > reEnd - reStart + 2) return null;
|
|
6603
|
+
if (separator && out.length > 0 && out[out.length - 1]._tag === "node") {
|
|
6604
|
+
if (pos + separator.length > reEnd || !input.startsWith(separator, pos)) return null;
|
|
6605
|
+
out.push({ _tag: "leaf", value: separator, span: { start: pos - cStart, end: pos + separator.length - cStart } });
|
|
6606
|
+
pos += separator.length;
|
|
6607
|
+
continue;
|
|
6608
|
+
}
|
|
6609
|
+
let r;
|
|
6610
|
+
try {
|
|
6611
|
+
r = ruleFn(input, pos, ctx);
|
|
6612
|
+
} catch {
|
|
6613
|
+
return null;
|
|
6614
|
+
}
|
|
6615
|
+
if (!r.ok || r.span.end <= pos || r.span.end > reEnd) return null;
|
|
6616
|
+
out.push(relativizeCST(r.value, cStart));
|
|
6617
|
+
pos = r.span.end;
|
|
6618
|
+
}
|
|
6619
|
+
return pos === reEnd ? out : null;
|
|
6620
|
+
}
|
|
6621
|
+
function tryListSplice(root, path, C, cStart, newInput, from, to, delta, registry, build) {
|
|
6622
|
+
const kids = C.children;
|
|
6623
|
+
if (kids.length === 0) return null;
|
|
6624
|
+
let h = 0;
|
|
6625
|
+
while (h < kids.length && cStart + kids[h].span.end <= from) h++;
|
|
6626
|
+
while (h > 0 && kids[h - 1]._tag === "node") h--;
|
|
6627
|
+
let t = kids.length;
|
|
6628
|
+
while (t > h && cStart + kids[t - 1].span.start >= to) t--;
|
|
6629
|
+
while (t < kids.length && kids[t]._tag !== "node") t++;
|
|
6630
|
+
if (t >= kids.length) return null;
|
|
6631
|
+
for (let i = t; i < kids.length; i++) {
|
|
6632
|
+
if (kids[i]._tag === "node" && kids[i].state != null) return null;
|
|
6633
|
+
}
|
|
6634
|
+
let elemType;
|
|
6635
|
+
let elemCount = 0;
|
|
6636
|
+
for (const k of kids) {
|
|
6637
|
+
if (k._tag !== "node") continue;
|
|
6638
|
+
elemCount++;
|
|
6639
|
+
if (elemType === void 0) elemType = k.type;
|
|
6640
|
+
else if (k.type !== elemType) return null;
|
|
6641
|
+
}
|
|
6642
|
+
if (elemType === void 0 || elemCount < 2) return null;
|
|
6643
|
+
const ruleFn = registry[elemType];
|
|
6644
|
+
if (!ruleFn) return null;
|
|
6645
|
+
let separator = null;
|
|
6646
|
+
for (let i = 1; i < kids.length - 1; i++) {
|
|
6647
|
+
if (kids[i - 1]._tag === "node" && kids[i + 1]._tag === "node") {
|
|
6648
|
+
if (kids[i]._tag !== "leaf") return null;
|
|
6649
|
+
const sep = kids[i].value ?? null;
|
|
6650
|
+
if (separator === null) separator = sep;
|
|
6651
|
+
else if (sep !== separator) return null;
|
|
6652
|
+
}
|
|
6653
|
+
}
|
|
6654
|
+
if (separator === null) return null;
|
|
6655
|
+
const first = kids[0];
|
|
6656
|
+
const last = kids[kids.length - 1];
|
|
6657
|
+
if (first._tag === "leaf" && first.value !== separator && from < cStart + first.span.end) return null;
|
|
6658
|
+
if (last._tag === "leaf" && last.value !== separator && to > cStart + last.span.start) return null;
|
|
6659
|
+
const reStart = h > 0 ? cStart + kids[h - 1].span.end : cStart;
|
|
6660
|
+
const reEnd = cStart + kids[t].span.start + delta;
|
|
6661
|
+
if (reEnd < reStart) return null;
|
|
6662
|
+
const middle = parseMiddle(newInput, reStart, reEnd, cStart, ruleFn, separator, build);
|
|
6663
|
+
if (!middle) return null;
|
|
6664
|
+
if (middle.length > 0) {
|
|
6665
|
+
const last2 = middle[middle.length - 1];
|
|
6666
|
+
if (!(last2._tag === "leaf" && last2.value === separator)) return null;
|
|
6667
|
+
}
|
|
6668
|
+
if (reEnd < newInput.length) {
|
|
6669
|
+
for (const sentinel of [" ", "\uFFFF"]) {
|
|
6670
|
+
if (newInput[reEnd] === sentinel) continue;
|
|
6671
|
+
const probed = newInput.slice(0, reEnd) + sentinel.repeat(newInput.length - reEnd);
|
|
6672
|
+
const probe = parseMiddle(probed, reStart, reEnd, cStart, ruleFn, separator, build);
|
|
6673
|
+
if (!probe || probe.length !== middle.length) return null;
|
|
6674
|
+
for (let i = 0; i < middle.length; i++) if (!structurallyEqual(probe[i], middle[i])) return null;
|
|
6675
|
+
}
|
|
6676
|
+
}
|
|
6677
|
+
const head = kids.slice(0, h);
|
|
6678
|
+
const tail = kids.slice(t).map((k) => shiftRelStart(k, delta));
|
|
6679
|
+
const newC = {
|
|
6680
|
+
...C,
|
|
6681
|
+
span: { start: C.span.start, end: C.span.end + delta },
|
|
6682
|
+
children: [...head, ...middle, ...tail]
|
|
6683
|
+
};
|
|
6684
|
+
return graftRelative(root, path, newC, delta);
|
|
6685
|
+
}
|
|
6458
6686
|
function structurallyEqual(a, b) {
|
|
6459
6687
|
if (a === b) return true;
|
|
6460
6688
|
if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) return false;
|
|
@@ -6498,27 +6726,68 @@ function boundaryIsSafe(ruleFn, newInput, start, boundary, state, build, produce
|
|
|
6498
6726
|
}
|
|
6499
6727
|
var ParseDocImpl = class _ParseDocImpl {
|
|
6500
6728
|
_registry;
|
|
6729
|
+
/** Registry entries normalized to callable parse functions (memoized once). */
|
|
6730
|
+
_fns;
|
|
6731
|
+
/** Rule names the grammar proves are genuine repetitions — the ONLY splice-safe types. */
|
|
6732
|
+
_reps;
|
|
6501
6733
|
_rootRule;
|
|
6502
6734
|
_opts;
|
|
6503
|
-
|
|
6735
|
+
/**
|
|
6736
|
+
* The tree, held in whichever coordinate system it arrived in. A fresh parse
|
|
6737
|
+
* arrives ABSOLUTE (`_abs` set); an incremental graft arrives PARENT-RELATIVE
|
|
6738
|
+
* (`_rel` set). The public `tree` is always the RELATIVE form (so untouched
|
|
6739
|
+
* subtrees stay shared by identity across edits and reads are O(1)); it's
|
|
6740
|
+
* materialized from `_abs` once, on demand, and memoized. `undefined` = not yet
|
|
6741
|
+
* computed; `null` = failed parse. A fresh parse that's never edited nor
|
|
6742
|
+
* tree-read pays no conversion — important for the full-reparse fallback path.
|
|
6743
|
+
*/
|
|
6744
|
+
_abs;
|
|
6745
|
+
_rel;
|
|
6504
6746
|
errors;
|
|
6505
6747
|
input;
|
|
6506
|
-
constructor(registry, rootRule, opts,
|
|
6748
|
+
constructor(registry, rootRule, opts, trees, errors, input) {
|
|
6507
6749
|
this._registry = registry;
|
|
6750
|
+
this._fns = {};
|
|
6751
|
+
this._reps = /* @__PURE__ */ new Set();
|
|
6752
|
+
for (const [name, entry] of Object.entries(registry)) {
|
|
6753
|
+
this._fns[name] = asRuleFn(entry);
|
|
6754
|
+
if (producesRepetition(defOf(entry))) this._reps.add(name);
|
|
6755
|
+
}
|
|
6508
6756
|
this._rootRule = rootRule;
|
|
6509
6757
|
this._opts = opts;
|
|
6510
|
-
this.
|
|
6758
|
+
this._abs = trees.abs;
|
|
6759
|
+
this._rel = trees.rel;
|
|
6511
6760
|
this.errors = errors;
|
|
6512
6761
|
this.input = input;
|
|
6513
6762
|
}
|
|
6763
|
+
/**
|
|
6764
|
+
* The parse tree with PARENT-RELATIVE spans — a node's `span` is relative to
|
|
6765
|
+
* its parent's start (root base 0). This is the shareable representation:
|
|
6766
|
+
* untouched subtrees keep the same identity across `.edit()`s, and reading the
|
|
6767
|
+
* tree after a length-changing edit is O(1) (no offset rewrite). For absolute
|
|
6768
|
+
* positions use the O(depth) cursor `spanAt(path)`, or `absolutizeCST(tree)` to
|
|
6769
|
+
* materialize the whole absolute tree. (A fresh non-incremental `node().parse()`
|
|
6770
|
+
* result is unchanged — still absolute.)
|
|
6771
|
+
*/
|
|
6772
|
+
get tree() {
|
|
6773
|
+
if (this._rel === void 0) {
|
|
6774
|
+
this._rel = this._abs ? relativizeCST(this._abs, 0) : null;
|
|
6775
|
+
}
|
|
6776
|
+
return this._rel;
|
|
6777
|
+
}
|
|
6778
|
+
spanAt(path) {
|
|
6779
|
+
const rel = this.tree;
|
|
6780
|
+
if (!rel) throw new Error("spanAt on a failed parse (tree is null)");
|
|
6781
|
+
return absoluteSpanCST(rel, path);
|
|
6782
|
+
}
|
|
6514
6783
|
edit(from, to, replacement) {
|
|
6515
6784
|
const newInput = this.input.slice(0, from) + replacement + this.input.slice(to);
|
|
6516
6785
|
const reparse = () => parseDoc(this._registry, this._rootRule, newInput, this._opts);
|
|
6517
|
-
|
|
6786
|
+
const root = this.tree;
|
|
6787
|
+
if (!root) return reparse();
|
|
6518
6788
|
const delta = replacement.length - (to - from);
|
|
6519
|
-
const found = findContaining(
|
|
6520
|
-
|
|
6521
|
-
const ancestors = ancestorsAt(this.tree, found.path);
|
|
6789
|
+
const found = findContaining(root, 0, from) ?? { node: root, path: [] };
|
|
6790
|
+
const ancestors = ancestorsAt(root, found.path);
|
|
6522
6791
|
const candidates = [found];
|
|
6523
6792
|
const pathCopy = [...found.path];
|
|
6524
6793
|
for (let i = ancestors.length - 2; i >= 0; i--) {
|
|
@@ -6527,37 +6796,50 @@ var ParseDocImpl = class _ParseDocImpl {
|
|
|
6527
6796
|
}
|
|
6528
6797
|
const rebuild = this._opts.rebuild ?? defaultRebuild;
|
|
6529
6798
|
for (const { node: node2, path } of candidates) {
|
|
6530
|
-
|
|
6531
|
-
|
|
6799
|
+
const { start: absStart, end: absEnd } = absoluteSpanCST(root, path);
|
|
6800
|
+
if (absEnd - absStart > this.input.length * REENTRY_MAX_SPAN_FRACTION) break;
|
|
6801
|
+
const ruleFn = this._fns[node2.type];
|
|
6532
6802
|
if (!ruleFn) continue;
|
|
6533
|
-
if (!(
|
|
6803
|
+
if (!(absStart <= from && to <= absEnd)) continue;
|
|
6534
6804
|
const ctx = { trackLines: false, state: node2.state, build: this._opts.build };
|
|
6535
|
-
const r = ruleFn(newInput,
|
|
6805
|
+
const r = ruleFn(newInput, absStart, ctx);
|
|
6536
6806
|
if (!r.ok) continue;
|
|
6537
|
-
if (r.span.end !==
|
|
6538
|
-
if (!boundaryIsSafe(ruleFn, newInput,
|
|
6807
|
+
if (r.span.end !== absEnd + delta) continue;
|
|
6808
|
+
if (!boundaryIsSafe(ruleFn, newInput, absStart, absEnd + delta, node2.state, this._opts.build, r)) {
|
|
6539
6809
|
continue;
|
|
6540
6810
|
}
|
|
6811
|
+
const parentBase = absStart - node2.span.start;
|
|
6812
|
+
const newRel = relativizeCST(r.value, parentBase);
|
|
6541
6813
|
if (delta === 0) {
|
|
6542
|
-
const newTree2 = replaceAtPath(rebuild,
|
|
6543
|
-
return new _ParseDocImpl(this._registry, this._rootRule, this._opts, newTree2, [], newInput);
|
|
6814
|
+
const newTree2 = replaceAtPath(rebuild, root, path, newRel);
|
|
6815
|
+
return new _ParseDocImpl(this._registry, this._rootRule, this._opts, { rel: newTree2 }, [], newInput);
|
|
6544
6816
|
}
|
|
6545
6817
|
if (this._opts.rebuild) return reparse();
|
|
6546
|
-
const newTree =
|
|
6547
|
-
return new _ParseDocImpl(this._registry, this._rootRule, this._opts, newTree, [], newInput);
|
|
6818
|
+
const newTree = graftRelative(root, path, newRel, delta);
|
|
6819
|
+
return new _ParseDocImpl(this._registry, this._rootRule, this._opts, { rel: newTree }, [], newInput);
|
|
6820
|
+
}
|
|
6821
|
+
if (this._opts.structuralReuse && delta !== 0 && !this._opts.rebuild) {
|
|
6822
|
+
const spliceCandidates = [...candidates, { node: root, path: [] }];
|
|
6823
|
+
for (const { node: node2, path } of spliceCandidates) {
|
|
6824
|
+
if (!this._reps.has(node2.type)) continue;
|
|
6825
|
+
const { start: cStart, end: cEnd } = absoluteSpanCST(root, path);
|
|
6826
|
+
if (!(cStart <= from && to <= cEnd)) continue;
|
|
6827
|
+
const spliced = tryListSplice(root, path, node2, cStart, newInput, from, to, delta, this._fns, this._opts.build);
|
|
6828
|
+
if (spliced) return new _ParseDocImpl(this._registry, this._rootRule, this._opts, { rel: spliced }, [], newInput);
|
|
6829
|
+
}
|
|
6548
6830
|
}
|
|
6549
6831
|
return reparse();
|
|
6550
6832
|
}
|
|
6551
6833
|
};
|
|
6552
6834
|
function parseDoc(registry, rootRule, input, opts = {}) {
|
|
6553
|
-
const
|
|
6554
|
-
if (!
|
|
6835
|
+
const entry = registry[rootRule];
|
|
6836
|
+
if (!entry) throw new Error(`No rule '${rootRule}' in registry`);
|
|
6555
6837
|
const ctx = { trackLines: false, state: opts.state, build: opts.build };
|
|
6556
|
-
const r =
|
|
6838
|
+
const r = asRuleFn(entry)(input, 0, ctx);
|
|
6557
6839
|
if (r.ok) {
|
|
6558
|
-
return new ParseDocImpl(registry, rootRule, opts, r.value, [], input);
|
|
6840
|
+
return new ParseDocImpl(registry, rootRule, opts, { abs: r.value }, [], input);
|
|
6559
6841
|
}
|
|
6560
|
-
return new ParseDocImpl(registry, rootRule, opts, null, [{ ok: false, expected: r.expected, span: r.span }], input);
|
|
6842
|
+
return new ParseDocImpl(registry, rootRule, opts, { abs: null }, [{ ok: false, expected: r.expected, span: r.span }], input);
|
|
6561
6843
|
}
|
|
6562
6844
|
|
|
6563
6845
|
// src/functional/run.ts
|
|
@@ -6926,78 +7208,14 @@ function buildOffsetIndex(root, input = "") {
|
|
|
6926
7208
|
return new OffsetIndex(collectLeafSlots(root), 0, input.length);
|
|
6927
7209
|
}
|
|
6928
7210
|
|
|
6929
|
-
// src/cst/relative-spans.ts
|
|
6930
|
-
function relativize(node2, parentBase = 0) {
|
|
6931
|
-
return {
|
|
6932
|
-
start: node2.start - parentBase,
|
|
6933
|
-
end: node2.end - parentBase,
|
|
6934
|
-
children: node2.children.map((c) => relativize(c, node2.start))
|
|
6935
|
-
};
|
|
6936
|
-
}
|
|
6937
|
-
function absolutize(node2, parentBase = 0) {
|
|
6938
|
-
const start = parentBase + node2.start;
|
|
6939
|
-
return {
|
|
6940
|
-
start,
|
|
6941
|
-
end: parentBase + node2.end,
|
|
6942
|
-
children: node2.children.map((c) => absolutize(c, start))
|
|
6943
|
-
};
|
|
6944
|
-
}
|
|
6945
|
-
function absoluteSpanAt(root, path) {
|
|
6946
|
-
let base = 0;
|
|
6947
|
-
let node2 = root;
|
|
6948
|
-
for (const idx of path) {
|
|
6949
|
-
base += node2.start;
|
|
6950
|
-
const child = node2.children[idx];
|
|
6951
|
-
if (!child) throw new RangeError(`absoluteSpanAt: no child ${idx} on path ${path.join(".")}`);
|
|
6952
|
-
node2 = child;
|
|
6953
|
-
}
|
|
6954
|
-
return { start: base + node2.start, end: base + node2.end };
|
|
6955
|
-
}
|
|
6956
|
-
function shiftAbsolute(node2, at, delta) {
|
|
6957
|
-
const s = node2.start >= at ? node2.start + delta : node2.start;
|
|
6958
|
-
const e = node2.end >= at ? node2.end + delta : node2.end;
|
|
6959
|
-
return {
|
|
6960
|
-
start: s,
|
|
6961
|
-
end: e,
|
|
6962
|
-
children: node2.children.map((c) => shiftAbsolute(c, at, delta))
|
|
6963
|
-
};
|
|
6964
|
-
}
|
|
6965
|
-
function applyEdit(root, at, delta, stats) {
|
|
6966
|
-
return editNode(root, at, delta, 0, 0, stats);
|
|
6967
|
-
}
|
|
6968
|
-
function editNode(node2, at, delta, parentBase, parentShift, stats) {
|
|
6969
|
-
const absStart = parentBase + node2.start;
|
|
6970
|
-
const absEnd = parentBase + node2.end;
|
|
6971
|
-
if (absEnd < at) return node2;
|
|
6972
|
-
const startShifts = absStart >= at;
|
|
6973
|
-
if (startShifts && parentShift === delta) return node2;
|
|
6974
|
-
if (stats) stats.allocated++;
|
|
6975
|
-
const newAbsStart = startShifts ? absStart + delta : absStart;
|
|
6976
|
-
const newAbsEnd = absEnd + delta;
|
|
6977
|
-
const newParentBase = parentBase + parentShift;
|
|
6978
|
-
const newStart = newAbsStart - newParentBase;
|
|
6979
|
-
const newEnd = newAbsEnd - newParentBase;
|
|
6980
|
-
const ownShift = newAbsStart - absStart;
|
|
6981
|
-
let changed = false;
|
|
6982
|
-
const newChildren = [];
|
|
6983
|
-
for (const c of node2.children) {
|
|
6984
|
-
const nc = editNode(c, at, delta, absStart, ownShift, stats);
|
|
6985
|
-
if (nc !== c) changed = true;
|
|
6986
|
-
newChildren.push(nc);
|
|
6987
|
-
}
|
|
6988
|
-
return {
|
|
6989
|
-
start: newStart,
|
|
6990
|
-
end: newEnd,
|
|
6991
|
-
children: changed ? newChildren : node2.children
|
|
6992
|
-
};
|
|
6993
|
-
}
|
|
6994
|
-
|
|
6995
7211
|
// src/index.ts
|
|
6996
7212
|
registerRegexAnalyzer(firstSetFromRegex);
|
|
6997
7213
|
export {
|
|
6998
7214
|
OffsetIndex,
|
|
6999
7215
|
absoluteSpanAt,
|
|
7216
|
+
absoluteSpanCST,
|
|
7000
7217
|
absolutize,
|
|
7218
|
+
absolutizeCST,
|
|
7001
7219
|
annotateSpan,
|
|
7002
7220
|
applyEdit,
|
|
7003
7221
|
balanced,
|
|
@@ -7042,6 +7260,7 @@ export {
|
|
|
7042
7260
|
ref,
|
|
7043
7261
|
regex,
|
|
7044
7262
|
relativize,
|
|
7263
|
+
relativizeCST,
|
|
7045
7264
|
rules,
|
|
7046
7265
|
run,
|
|
7047
7266
|
scanTo,
|