@lezer/common 0.15.10 → 0.16.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/dist/index.cjs +206 -76
- package/dist/index.d.ts +1 -1
- package/dist/index.js +206 -77
- package/dist/mix.d.ts +3 -3
- package/dist/tree.d.ts +48 -29
- package/package.json +1 -1
- package/dist/composite.d.ts +0 -42
- package/dist/frame.d.ts +0 -25
- package/dist/scaffold.d.ts +0 -25
- package/dist/tree.cjs +0 -1156
- package/dist/tree.cjs.map +0 -1
- package/dist/tree.es.js +0 -1143
- package/dist/tree.es.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -214,6 +214,28 @@ class NodeSet {
|
|
|
214
214
|
}
|
|
215
215
|
}
|
|
216
216
|
const CachedNode = new WeakMap(), CachedInnerNode = new WeakMap();
|
|
217
|
+
/// Options that control iteration. Can be combined with the `|`
|
|
218
|
+
/// operator to enable multiple ones.
|
|
219
|
+
exports.IterMode = void 0;
|
|
220
|
+
(function (IterMode) {
|
|
221
|
+
/// When enabled, iteration will only visit [`Tree`](#common.Tree)
|
|
222
|
+
/// objects, not nodes packed into
|
|
223
|
+
/// [`TreeBuffer`](#common.TreeBuffer)s.
|
|
224
|
+
IterMode[IterMode["ExcludeBuffers"] = 1] = "ExcludeBuffers";
|
|
225
|
+
/// Enable this to make iteration include anonymous nodes (such as
|
|
226
|
+
/// the nodes that wrap repeated grammar constructs into a balanced
|
|
227
|
+
/// tree).
|
|
228
|
+
IterMode[IterMode["IncludeAnonymous"] = 2] = "IncludeAnonymous";
|
|
229
|
+
/// By default, regular [mounted](#common.NodeProp^mounted) nodes
|
|
230
|
+
/// replace their base node in iteration. Enable this to ignore them
|
|
231
|
+
/// instead.
|
|
232
|
+
IterMode[IterMode["IgnoreMounts"] = 4] = "IgnoreMounts";
|
|
233
|
+
/// This option only applies in
|
|
234
|
+
/// [`enter`](#common.SyntaxNode.enter)-style methods. It tells the
|
|
235
|
+
/// library to not enter mounted overlays if one covers the given
|
|
236
|
+
/// position.
|
|
237
|
+
IterMode[IterMode["IgnoreOverlays"] = 8] = "IgnoreOverlays";
|
|
238
|
+
})(exports.IterMode || (exports.IterMode = {}));
|
|
217
239
|
/// A piece of syntax tree. There are two ways to approach these
|
|
218
240
|
/// trees: the way they are actually stored in memory, and the
|
|
219
241
|
/// convenient way.
|
|
@@ -272,25 +294,22 @@ class Tree {
|
|
|
272
294
|
(/\W/.test(this.type.name) && !this.type.isError ? JSON.stringify(this.type.name) : this.type.name) +
|
|
273
295
|
(children.length ? "(" + children + ")" : "");
|
|
274
296
|
}
|
|
275
|
-
/// Get a [tree cursor](#common.TreeCursor)
|
|
276
|
-
///
|
|
277
|
-
///
|
|
278
|
-
cursor(
|
|
279
|
-
|
|
297
|
+
/// Get a [tree cursor](#common.TreeCursor) positioned at the top of
|
|
298
|
+
/// the tree. Mode can be used to [control](#common.IterMode) which
|
|
299
|
+
/// nodes the cursor visits.
|
|
300
|
+
cursor(mode = 0) {
|
|
301
|
+
return new TreeCursor(this.topNode, mode);
|
|
302
|
+
}
|
|
303
|
+
/// Get a [tree cursor](#common.TreeCursor) pointing into this tree
|
|
304
|
+
/// at the given position and side (see
|
|
305
|
+
/// [`moveTo`](#common.TreeCursor.moveTo).
|
|
306
|
+
cursorAt(pos, side = 0, mode = 0) {
|
|
307
|
+
let scope = CachedNode.get(this) || this.topNode;
|
|
280
308
|
let cursor = new TreeCursor(scope);
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
CachedNode.set(this, cursor._tree);
|
|
284
|
-
}
|
|
309
|
+
cursor.moveTo(pos, side);
|
|
310
|
+
CachedNode.set(this, cursor._tree);
|
|
285
311
|
return cursor;
|
|
286
312
|
}
|
|
287
|
-
/// Get a [tree cursor](#common.TreeCursor) that, unlike regular
|
|
288
|
-
/// cursors, doesn't skip through
|
|
289
|
-
/// [anonymous](#common.NodeType.isAnonymous) nodes and doesn't
|
|
290
|
-
/// automatically enter mounted nodes.
|
|
291
|
-
fullCursor() {
|
|
292
|
-
return new TreeCursor(this.topNode, 1 /* Full */);
|
|
293
|
-
}
|
|
294
313
|
/// Get a [syntax node](#common.SyntaxNode) object for the top of the
|
|
295
314
|
/// tree.
|
|
296
315
|
get topNode() {
|
|
@@ -323,23 +342,21 @@ class Tree {
|
|
|
323
342
|
/// not have its children iterated over (or `leave` called).
|
|
324
343
|
iterate(spec) {
|
|
325
344
|
let { enter, leave, from = 0, to = this.length } = spec;
|
|
326
|
-
for (let c = this.cursor(
|
|
327
|
-
let
|
|
328
|
-
if (c.from <= to && c.to >= from && (c.type.isAnonymous || enter(c
|
|
345
|
+
for (let c = this.cursor((spec.mode || 0) | exports.IterMode.IncludeAnonymous);;) {
|
|
346
|
+
let entered = false;
|
|
347
|
+
if (c.from <= to && c.to >= from && (c.type.isAnonymous || enter(c) !== false)) {
|
|
329
348
|
if (c.firstChild())
|
|
330
349
|
continue;
|
|
331
|
-
|
|
332
|
-
mustLeave = true;
|
|
350
|
+
entered = true;
|
|
333
351
|
}
|
|
334
352
|
for (;;) {
|
|
335
|
-
if (
|
|
336
|
-
leave(c
|
|
337
|
-
mustLeave = c.type.isAnonymous;
|
|
353
|
+
if (entered && leave && !c.type.isAnonymous)
|
|
354
|
+
leave(c);
|
|
338
355
|
if (c.nextSibling())
|
|
339
356
|
break;
|
|
340
357
|
if (!c.parent())
|
|
341
358
|
return;
|
|
342
|
-
|
|
359
|
+
entered = true;
|
|
343
360
|
}
|
|
344
361
|
}
|
|
345
362
|
}
|
|
@@ -490,72 +507,73 @@ function resolveNode(node, pos, side, overlays) {
|
|
|
490
507
|
return node;
|
|
491
508
|
node = parent;
|
|
492
509
|
}
|
|
510
|
+
let mode = overlays ? 0 : exports.IterMode.IgnoreOverlays;
|
|
493
511
|
// Must go up out of overlays when those do not overlap with pos
|
|
494
512
|
if (overlays)
|
|
495
513
|
for (let scan = node, parent = scan.parent; parent; scan = parent, parent = scan.parent) {
|
|
496
|
-
if (scan instanceof TreeNode && scan.index < 0 && ((_a = parent.enter(pos, side,
|
|
514
|
+
if (scan instanceof TreeNode && scan.index < 0 && ((_a = parent.enter(pos, side, mode)) === null || _a === void 0 ? void 0 : _a.from) != scan.from)
|
|
497
515
|
node = parent;
|
|
498
516
|
}
|
|
499
517
|
for (;;) {
|
|
500
|
-
let inner = node.enter(pos, side,
|
|
518
|
+
let inner = node.enter(pos, side, mode);
|
|
501
519
|
if (!inner)
|
|
502
520
|
return node;
|
|
503
521
|
node = inner;
|
|
504
522
|
}
|
|
505
523
|
}
|
|
506
524
|
class TreeNode {
|
|
507
|
-
constructor(
|
|
525
|
+
constructor(_tree, from,
|
|
508
526
|
// Index in parent node, set to -1 if the node is not a direct child of _parent.node (overlay)
|
|
509
527
|
index, _parent) {
|
|
510
|
-
this.
|
|
511
|
-
this.
|
|
528
|
+
this._tree = _tree;
|
|
529
|
+
this.from = from;
|
|
512
530
|
this.index = index;
|
|
513
531
|
this._parent = _parent;
|
|
514
532
|
}
|
|
515
|
-
get type() { return this.
|
|
516
|
-
get name() { return this.
|
|
517
|
-
get
|
|
518
|
-
get to() { return this._from + this.node.length; }
|
|
533
|
+
get type() { return this._tree.type; }
|
|
534
|
+
get name() { return this._tree.type.name; }
|
|
535
|
+
get to() { return this.from + this._tree.length; }
|
|
519
536
|
nextChild(i, dir, pos, side, mode = 0) {
|
|
520
537
|
for (let parent = this;;) {
|
|
521
|
-
for (let { children, positions } = parent.
|
|
522
|
-
let next = children[i], start = positions[i] + parent.
|
|
538
|
+
for (let { children, positions } = parent._tree, e = dir > 0 ? children.length : -1; i != e; i += dir) {
|
|
539
|
+
let next = children[i], start = positions[i] + parent.from;
|
|
523
540
|
if (!checkSide(side, pos, start, start + next.length))
|
|
524
541
|
continue;
|
|
525
542
|
if (next instanceof TreeBuffer) {
|
|
526
|
-
if (mode &
|
|
543
|
+
if (mode & exports.IterMode.ExcludeBuffers)
|
|
527
544
|
continue;
|
|
528
545
|
let index = next.findChild(0, next.buffer.length, dir, pos - start, side);
|
|
529
546
|
if (index > -1)
|
|
530
547
|
return new BufferNode(new BufferContext(parent, next, i, start), null, index);
|
|
531
548
|
}
|
|
532
|
-
else if ((mode &
|
|
549
|
+
else if ((mode & exports.IterMode.IncludeAnonymous) || (!next.type.isAnonymous || hasChild(next))) {
|
|
533
550
|
let mounted;
|
|
534
|
-
if (!(mode &
|
|
551
|
+
if (!(mode & exports.IterMode.IgnoreMounts) &&
|
|
552
|
+
next.props && (mounted = next.prop(NodeProp.mounted)) && !mounted.overlay)
|
|
535
553
|
return new TreeNode(mounted.tree, start, i, parent);
|
|
536
554
|
let inner = new TreeNode(next, start, i, parent);
|
|
537
|
-
return (mode &
|
|
555
|
+
return (mode & exports.IterMode.IncludeAnonymous) || !inner.type.isAnonymous ? inner
|
|
538
556
|
: inner.nextChild(dir < 0 ? next.children.length - 1 : 0, dir, pos, side);
|
|
539
557
|
}
|
|
540
558
|
}
|
|
541
|
-
if ((mode &
|
|
559
|
+
if ((mode & exports.IterMode.IncludeAnonymous) || !parent.type.isAnonymous)
|
|
542
560
|
return null;
|
|
543
561
|
if (parent.index >= 0)
|
|
544
562
|
i = parent.index + dir;
|
|
545
563
|
else
|
|
546
|
-
i = dir < 0 ? -1 : parent._parent.
|
|
564
|
+
i = dir < 0 ? -1 : parent._parent._tree.children.length;
|
|
547
565
|
parent = parent._parent;
|
|
548
566
|
if (!parent)
|
|
549
567
|
return null;
|
|
550
568
|
}
|
|
551
569
|
}
|
|
552
570
|
get firstChild() { return this.nextChild(0, 1, 0, 4 /* DontCare */); }
|
|
553
|
-
get lastChild() { return this.nextChild(this.
|
|
571
|
+
get lastChild() { return this.nextChild(this._tree.children.length - 1, -1, 0, 4 /* DontCare */); }
|
|
554
572
|
childAfter(pos) { return this.nextChild(0, 1, pos, 2 /* After */); }
|
|
555
|
-
childBefore(pos) { return this.nextChild(this.
|
|
556
|
-
enter(pos, side,
|
|
573
|
+
childBefore(pos) { return this.nextChild(this._tree.children.length - 1, -1, pos, -2 /* Before */); }
|
|
574
|
+
enter(pos, side, mode = 0) {
|
|
557
575
|
let mounted;
|
|
558
|
-
if (
|
|
576
|
+
if (!(mode & exports.IterMode.IgnoreOverlays) && (mounted = this._tree.prop(NodeProp.mounted)) && mounted.overlay) {
|
|
559
577
|
let rPos = pos - this.from;
|
|
560
578
|
for (let { from, to } of mounted.overlay) {
|
|
561
579
|
if ((side > 0 ? from <= rPos : from < rPos) &&
|
|
@@ -563,7 +581,7 @@ class TreeNode {
|
|
|
563
581
|
return new TreeNode(mounted.tree, mounted.overlay[0].from + this.from, -1, this);
|
|
564
582
|
}
|
|
565
583
|
}
|
|
566
|
-
return this.nextChild(0, 1, pos, side,
|
|
584
|
+
return this.nextChild(0, 1, pos, side, mode);
|
|
567
585
|
}
|
|
568
586
|
nextSignificantParent() {
|
|
569
587
|
let val = this;
|
|
@@ -580,9 +598,9 @@ class TreeNode {
|
|
|
580
598
|
get prevSibling() {
|
|
581
599
|
return this._parent && this.index >= 0 ? this._parent.nextChild(this.index - 1, -1, 0, 4 /* DontCare */) : null;
|
|
582
600
|
}
|
|
583
|
-
|
|
584
|
-
get tree() { return this.
|
|
585
|
-
toTree() { return this.
|
|
601
|
+
cursor(mode = 0) { return new TreeCursor(this, mode); }
|
|
602
|
+
get tree() { return this._tree; }
|
|
603
|
+
toTree() { return this._tree; }
|
|
586
604
|
resolve(pos, side = 0) {
|
|
587
605
|
return resolveNode(this, pos, side, false);
|
|
588
606
|
}
|
|
@@ -598,10 +616,12 @@ class TreeNode {
|
|
|
598
616
|
return getChildren(this, type, before, after);
|
|
599
617
|
}
|
|
600
618
|
/// @internal
|
|
601
|
-
toString() { return this.
|
|
619
|
+
toString() { return this._tree.toString(); }
|
|
620
|
+
get node() { return this; }
|
|
621
|
+
matchContext(context) { return matchNodeContext(this, context); }
|
|
602
622
|
}
|
|
603
623
|
function getChildren(node, type, before, after) {
|
|
604
|
-
let cur = node.cursor, result = [];
|
|
624
|
+
let cur = node.cursor(), result = [];
|
|
605
625
|
if (!cur.firstChild())
|
|
606
626
|
return result;
|
|
607
627
|
if (before != null)
|
|
@@ -617,6 +637,18 @@ function getChildren(node, type, before, after) {
|
|
|
617
637
|
return after == null ? result : [];
|
|
618
638
|
}
|
|
619
639
|
}
|
|
640
|
+
function matchNodeContext(node, context, i = context.length - 1) {
|
|
641
|
+
for (let p = node.parent; i >= 0; p = p.parent) {
|
|
642
|
+
if (!p)
|
|
643
|
+
return false;
|
|
644
|
+
if (!p.type.isAnonymous) {
|
|
645
|
+
if (context[i] && context[i] != p.name)
|
|
646
|
+
return false;
|
|
647
|
+
i--;
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
return true;
|
|
651
|
+
}
|
|
620
652
|
class BufferContext {
|
|
621
653
|
constructor(parent, buffer, index, start) {
|
|
622
654
|
this.parent = parent;
|
|
@@ -644,8 +676,8 @@ class BufferNode {
|
|
|
644
676
|
get lastChild() { return this.child(-1, 0, 4 /* DontCare */); }
|
|
645
677
|
childAfter(pos) { return this.child(1, pos, 2 /* After */); }
|
|
646
678
|
childBefore(pos) { return this.child(-1, pos, -2 /* Before */); }
|
|
647
|
-
enter(pos, side,
|
|
648
|
-
if (
|
|
679
|
+
enter(pos, side, mode = 0) {
|
|
680
|
+
if (mode & exports.IterMode.ExcludeBuffers)
|
|
649
681
|
return null;
|
|
650
682
|
let { buffer } = this.context;
|
|
651
683
|
let index = buffer.findChild(this.index + 4, buffer.buffer[this.index + 3], side > 0 ? 1 : -1, pos - this.context.start, side);
|
|
@@ -671,7 +703,7 @@ class BufferNode {
|
|
|
671
703
|
return this.externalSibling(-1);
|
|
672
704
|
return new BufferNode(this.context, this._parent, buffer.findChild(parentStart, this.index, -1, 0, 4 /* DontCare */));
|
|
673
705
|
}
|
|
674
|
-
|
|
706
|
+
cursor(mode = 0) { return new TreeCursor(this, mode); }
|
|
675
707
|
get tree() { return null; }
|
|
676
708
|
toTree() {
|
|
677
709
|
let children = [], positions = [];
|
|
@@ -700,6 +732,8 @@ class BufferNode {
|
|
|
700
732
|
getChildren(type, before = null, after = null) {
|
|
701
733
|
return getChildren(this, type, before, after);
|
|
702
734
|
}
|
|
735
|
+
get node() { return this; }
|
|
736
|
+
matchContext(context) { return matchNodeContext(this, context); }
|
|
703
737
|
}
|
|
704
738
|
/// A tree cursor object focuses on a given node in a syntax tree, and
|
|
705
739
|
/// allows you to move to adjacent nodes.
|
|
@@ -709,8 +743,10 @@ class TreeCursor {
|
|
|
709
743
|
/// @internal
|
|
710
744
|
mode = 0) {
|
|
711
745
|
this.mode = mode;
|
|
746
|
+
/// @internal
|
|
712
747
|
this.buffer = null;
|
|
713
748
|
this.stack = [];
|
|
749
|
+
/// @internal
|
|
714
750
|
this.index = 0;
|
|
715
751
|
this.bufferNode = null;
|
|
716
752
|
if (node instanceof TreeNode) {
|
|
@@ -761,7 +797,7 @@ class TreeCursor {
|
|
|
761
797
|
/// @internal
|
|
762
798
|
enterChild(dir, pos, side) {
|
|
763
799
|
if (!this.buffer)
|
|
764
|
-
return this.yield(this._tree.nextChild(dir < 0 ? this._tree.
|
|
800
|
+
return this.yield(this._tree.nextChild(dir < 0 ? this._tree._tree.children.length - 1 : 0, dir, pos, side, this.mode));
|
|
765
801
|
let { buffer } = this.buffer;
|
|
766
802
|
let index = buffer.findChild(this.index + 4, buffer.buffer[this.index + 3], dir, pos - this.buffer.start, side);
|
|
767
803
|
if (index < 0)
|
|
@@ -783,18 +819,18 @@ class TreeCursor {
|
|
|
783
819
|
/// will also enter [overlaid](#common.MountedTree.overlay)
|
|
784
820
|
/// [mounted](#common.NodeProp^mounted) trees unless `overlays` is
|
|
785
821
|
/// set to false.
|
|
786
|
-
enter(pos, side,
|
|
822
|
+
enter(pos, side, mode = this.mode) {
|
|
787
823
|
if (!this.buffer)
|
|
788
|
-
return this.yield(this._tree.enter(pos, side,
|
|
789
|
-
return
|
|
824
|
+
return this.yield(this._tree.enter(pos, side, mode));
|
|
825
|
+
return mode & exports.IterMode.ExcludeBuffers ? false : this.enterChild(1, pos, side);
|
|
790
826
|
}
|
|
791
827
|
/// Move to the node's parent node, if this isn't the top node.
|
|
792
828
|
parent() {
|
|
793
829
|
if (!this.buffer)
|
|
794
|
-
return this.yieldNode((this.mode &
|
|
830
|
+
return this.yieldNode((this.mode & exports.IterMode.IncludeAnonymous) ? this._tree._parent : this._tree.parent);
|
|
795
831
|
if (this.stack.length)
|
|
796
832
|
return this.yieldBuf(this.stack.pop());
|
|
797
|
-
let parent = (this.mode &
|
|
833
|
+
let parent = (this.mode & exports.IterMode.IncludeAnonymous) ? this.buffer.parent : this.buffer.parent.nextSignificantParent();
|
|
798
834
|
this.buffer = null;
|
|
799
835
|
return this.yieldNode(parent);
|
|
800
836
|
}
|
|
@@ -840,9 +876,12 @@ class TreeCursor {
|
|
|
840
876
|
}
|
|
841
877
|
for (; parent; { index, _parent: parent } = parent) {
|
|
842
878
|
if (index > -1)
|
|
843
|
-
for (let i = index + dir, e = dir < 0 ? -1 : parent.
|
|
844
|
-
let child = parent.
|
|
845
|
-
if ((this.mode &
|
|
879
|
+
for (let i = index + dir, e = dir < 0 ? -1 : parent._tree.children.length; i != e; i += dir) {
|
|
880
|
+
let child = parent._tree.children[i];
|
|
881
|
+
if ((this.mode & exports.IterMode.IncludeAnonymous) ||
|
|
882
|
+
child instanceof TreeBuffer ||
|
|
883
|
+
!child.type.isAnonymous ||
|
|
884
|
+
hasChild(child))
|
|
846
885
|
return false;
|
|
847
886
|
}
|
|
848
887
|
}
|
|
@@ -910,7 +949,55 @@ class TreeCursor {
|
|
|
910
949
|
/// any. Will return null when the node is in a [tree
|
|
911
950
|
/// buffer](#common.TreeBuffer).
|
|
912
951
|
get tree() {
|
|
913
|
-
return this.buffer ? null : this._tree.
|
|
952
|
+
return this.buffer ? null : this._tree._tree;
|
|
953
|
+
}
|
|
954
|
+
/// Iterate over the current node and all its descendants, calling
|
|
955
|
+
/// `enter` when entering a node and `leave`, if given, when leaving
|
|
956
|
+
/// one. When `enter` returns `false`, any children of that node are
|
|
957
|
+
/// skipped, and `leave` isn't called for it.
|
|
958
|
+
iterate(enter, leave) {
|
|
959
|
+
for (let depth = 0;;) {
|
|
960
|
+
let mustLeave = false;
|
|
961
|
+
if (this.type.isAnonymous || enter(this) !== false) {
|
|
962
|
+
if (this.firstChild()) {
|
|
963
|
+
depth++;
|
|
964
|
+
continue;
|
|
965
|
+
}
|
|
966
|
+
if (!this.type.isAnonymous)
|
|
967
|
+
mustLeave = true;
|
|
968
|
+
}
|
|
969
|
+
for (;;) {
|
|
970
|
+
if (mustLeave && leave)
|
|
971
|
+
leave(this);
|
|
972
|
+
mustLeave = this.type.isAnonymous;
|
|
973
|
+
if (this.nextSibling())
|
|
974
|
+
break;
|
|
975
|
+
if (!depth)
|
|
976
|
+
return;
|
|
977
|
+
this.parent();
|
|
978
|
+
depth--;
|
|
979
|
+
mustLeave = true;
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
/// Test whether the current node matches a given context—a sequence
|
|
984
|
+
/// of direct parent node names. Empty strings in the context array
|
|
985
|
+
/// are treated as wildcards.
|
|
986
|
+
matchContext(context) {
|
|
987
|
+
if (!this.buffer)
|
|
988
|
+
return matchNodeContext(this.node, context);
|
|
989
|
+
let { buffer } = this.buffer, { types } = buffer.set;
|
|
990
|
+
for (let i = context.length - 1, d = this.stack.length - 1; i >= 0; d--) {
|
|
991
|
+
if (d < 0)
|
|
992
|
+
return matchNodeContext(this.node, context, i);
|
|
993
|
+
let type = types[buffer.buffer[this.stack[d]]];
|
|
994
|
+
if (!type.isAnonymous) {
|
|
995
|
+
if (context[i] && context[i] != type.name)
|
|
996
|
+
return false;
|
|
997
|
+
i--;
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
return true;
|
|
914
1001
|
}
|
|
915
1002
|
}
|
|
916
1003
|
function hasChild(tree) {
|
|
@@ -1170,6 +1257,48 @@ mkTree) {
|
|
|
1170
1257
|
divide(children, positions, from, to, 0);
|
|
1171
1258
|
return (mkTop || mkTree)(localChildren, localPositions, length);
|
|
1172
1259
|
}
|
|
1260
|
+
/// Provides a way to associate values with pieces of trees. As long
|
|
1261
|
+
/// as that part of the tree is reused, the associated values can be
|
|
1262
|
+
/// retrieved from an updated tree.
|
|
1263
|
+
class NodeWeakMap {
|
|
1264
|
+
constructor() {
|
|
1265
|
+
this.map = new WeakMap();
|
|
1266
|
+
}
|
|
1267
|
+
setBuffer(buffer, index, value) {
|
|
1268
|
+
let inner = this.map.get(buffer);
|
|
1269
|
+
if (!inner)
|
|
1270
|
+
this.map.set(buffer, inner = new Map);
|
|
1271
|
+
inner.set(index, value);
|
|
1272
|
+
}
|
|
1273
|
+
getBuffer(buffer, index) {
|
|
1274
|
+
let inner = this.map.get(buffer);
|
|
1275
|
+
return inner && inner.get(index);
|
|
1276
|
+
}
|
|
1277
|
+
/// Set the value for this syntax node.
|
|
1278
|
+
set(node, value) {
|
|
1279
|
+
if (node instanceof BufferNode)
|
|
1280
|
+
this.setBuffer(node.context.buffer, node.index, value);
|
|
1281
|
+
else if (node instanceof TreeNode)
|
|
1282
|
+
this.map.set(node.tree, value);
|
|
1283
|
+
}
|
|
1284
|
+
/// Retrieve value for this syntax node, if it exists in the map.
|
|
1285
|
+
get(node) {
|
|
1286
|
+
return node instanceof BufferNode ? this.getBuffer(node.context.buffer, node.index)
|
|
1287
|
+
: node instanceof TreeNode ? this.map.get(node.tree) : undefined;
|
|
1288
|
+
}
|
|
1289
|
+
/// Set the value for the node that a cursor currently points to.
|
|
1290
|
+
cursorSet(cursor, value) {
|
|
1291
|
+
if (cursor.buffer)
|
|
1292
|
+
this.setBuffer(cursor.buffer.buffer, cursor.index, value);
|
|
1293
|
+
else
|
|
1294
|
+
this.map.set(cursor.tree, value);
|
|
1295
|
+
}
|
|
1296
|
+
/// Retrieve the value for the node that a cursor currently points
|
|
1297
|
+
/// to.
|
|
1298
|
+
cursorGet(cursor) {
|
|
1299
|
+
return cursor.buffer ? this.getBuffer(cursor.buffer.buffer, cursor.index) : this.map.get(cursor.tree);
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1173
1302
|
|
|
1174
1303
|
/// Tree fragments are used during [incremental
|
|
1175
1304
|
/// parsing](#common.Parser.startParse) to track parts of old trees
|
|
@@ -1390,7 +1519,7 @@ class MixedParse {
|
|
|
1390
1519
|
let fragmentCursor = new FragmentCursor(this.fragments);
|
|
1391
1520
|
let overlay = null;
|
|
1392
1521
|
let covered = null;
|
|
1393
|
-
let cursor = new TreeCursor(new TreeNode(this.baseTree, this.ranges[0].from, 0, null),
|
|
1522
|
+
let cursor = new TreeCursor(new TreeNode(this.baseTree, this.ranges[0].from, 0, null), exports.IterMode.IncludeAnonymous | exports.IterMode.IgnoreMounts);
|
|
1394
1523
|
scan: for (let nest, isCovered; this.stoppedAt == null || cursor.from < this.stoppedAt;) {
|
|
1395
1524
|
let enter = true, range;
|
|
1396
1525
|
if (fragmentCursor.hasNode(cursor)) {
|
|
@@ -1399,7 +1528,7 @@ class MixedParse {
|
|
|
1399
1528
|
if (match)
|
|
1400
1529
|
for (let r of match.mount.overlay) {
|
|
1401
1530
|
let from = r.from + match.pos, to = r.to + match.pos;
|
|
1402
|
-
if (from >= cursor.from && to <= cursor.to)
|
|
1531
|
+
if (from >= cursor.from && to <= cursor.to && !overlay.ranges.some(r => r.from < to && r.to > from))
|
|
1403
1532
|
overlay.ranges.push({ from, to });
|
|
1404
1533
|
}
|
|
1405
1534
|
}
|
|
@@ -1496,20 +1625,20 @@ function materialize(cursor) {
|
|
|
1496
1625
|
let buf = base.children[i], b = buf.buffer;
|
|
1497
1626
|
// Split a level in the buffer, putting the nodes before and after
|
|
1498
1627
|
// the child that contains `node` into new buffers.
|
|
1499
|
-
function split(startI, endI, type, innerOffset) {
|
|
1628
|
+
function split(startI, endI, type, innerOffset, length) {
|
|
1500
1629
|
let i = startI;
|
|
1501
1630
|
while (b[i + 2] + off <= node.from)
|
|
1502
1631
|
i = b[i + 3];
|
|
1503
1632
|
let children = [], positions = [];
|
|
1504
1633
|
sliceBuf(buf, startI, i, children, positions, innerOffset);
|
|
1505
|
-
let
|
|
1506
|
-
|
|
1507
|
-
|
|
1634
|
+
let from = b[i + 1], to = b[i + 2];
|
|
1635
|
+
let isTarget = from + off == node.from && to + off == node.to && b[i] == node.type.id;
|
|
1636
|
+
children.push(isTarget ? node.toTree() : split(i + 4, b[i + 3], buf.set.types[b[i]], from, to - from));
|
|
1637
|
+
positions.push(from - innerOffset);
|
|
1508
1638
|
sliceBuf(buf, b[i + 3], endI, children, positions, innerOffset);
|
|
1509
|
-
|
|
1510
|
-
return new Tree(type, children, positions, positions[last] + children[last].length);
|
|
1639
|
+
return new Tree(type, children, positions, length);
|
|
1511
1640
|
}
|
|
1512
|
-
base.children[i] = split(0, b.length, NodeType.none, 0);
|
|
1641
|
+
base.children[i] = split(0, b.length, NodeType.none, 0, buf.length);
|
|
1513
1642
|
// Move the cursor back to the target node
|
|
1514
1643
|
for (let d = 0; d <= depth; d++)
|
|
1515
1644
|
cursor.childAfter(node.from);
|
|
@@ -1518,13 +1647,13 @@ class StructureCursor {
|
|
|
1518
1647
|
constructor(root, offset) {
|
|
1519
1648
|
this.offset = offset;
|
|
1520
1649
|
this.done = false;
|
|
1521
|
-
this.cursor = root.
|
|
1650
|
+
this.cursor = root.cursor(exports.IterMode.IncludeAnonymous | exports.IterMode.IgnoreMounts);
|
|
1522
1651
|
}
|
|
1523
1652
|
// Move to the first node (in pre-order) that starts at or after `pos`.
|
|
1524
1653
|
moveTo(pos) {
|
|
1525
1654
|
let { cursor } = this, p = pos - this.offset;
|
|
1526
1655
|
while (!this.done && cursor.from < p) {
|
|
1527
|
-
if (cursor.to >= pos && cursor.enter(p, 1,
|
|
1656
|
+
if (cursor.to >= pos && cursor.enter(p, 1, exports.IterMode.IgnoreOverlays | exports.IterMode.ExcludeBuffers)) ;
|
|
1528
1657
|
else if (!cursor.next(false))
|
|
1529
1658
|
this.done = true;
|
|
1530
1659
|
}
|
|
@@ -1693,6 +1822,7 @@ exports.MountedTree = MountedTree;
|
|
|
1693
1822
|
exports.NodeProp = NodeProp;
|
|
1694
1823
|
exports.NodeSet = NodeSet;
|
|
1695
1824
|
exports.NodeType = NodeType;
|
|
1825
|
+
exports.NodeWeakMap = NodeWeakMap;
|
|
1696
1826
|
exports.Parser = Parser;
|
|
1697
1827
|
exports.Tree = Tree;
|
|
1698
1828
|
exports.TreeBuffer = TreeBuffer;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { DefaultBufferLength, NodeProp, MountedTree, NodePropSource, NodeType, NodeSet, Tree, TreeBuffer, SyntaxNode, TreeCursor, BufferCursor } from "./tree";
|
|
1
|
+
export { DefaultBufferLength, NodeProp, MountedTree, NodePropSource, NodeType, NodeSet, Tree, TreeBuffer, SyntaxNode, SyntaxNodeRef, TreeCursor, BufferCursor, NodeWeakMap, IterMode } from "./tree";
|
|
2
2
|
export { ChangedRange, TreeFragment, PartialParse, Parser, Input, ParseWrapper } from "./parse";
|
|
3
3
|
export { NestedParse, parseMixed } from "./mix";
|