@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.js CHANGED
@@ -210,6 +210,28 @@ class NodeSet {
210
210
  }
211
211
  }
212
212
  const CachedNode = new WeakMap(), CachedInnerNode = new WeakMap();
213
+ /// Options that control iteration. Can be combined with the `|`
214
+ /// operator to enable multiple ones.
215
+ var IterMode;
216
+ (function (IterMode) {
217
+ /// When enabled, iteration will only visit [`Tree`](#common.Tree)
218
+ /// objects, not nodes packed into
219
+ /// [`TreeBuffer`](#common.TreeBuffer)s.
220
+ IterMode[IterMode["ExcludeBuffers"] = 1] = "ExcludeBuffers";
221
+ /// Enable this to make iteration include anonymous nodes (such as
222
+ /// the nodes that wrap repeated grammar constructs into a balanced
223
+ /// tree).
224
+ IterMode[IterMode["IncludeAnonymous"] = 2] = "IncludeAnonymous";
225
+ /// By default, regular [mounted](#common.NodeProp^mounted) nodes
226
+ /// replace their base node in iteration. Enable this to ignore them
227
+ /// instead.
228
+ IterMode[IterMode["IgnoreMounts"] = 4] = "IgnoreMounts";
229
+ /// This option only applies in
230
+ /// [`enter`](#common.SyntaxNode.enter)-style methods. It tells the
231
+ /// library to not enter mounted overlays if one covers the given
232
+ /// position.
233
+ IterMode[IterMode["IgnoreOverlays"] = 8] = "IgnoreOverlays";
234
+ })(IterMode || (IterMode = {}));
213
235
  /// A piece of syntax tree. There are two ways to approach these
214
236
  /// trees: the way they are actually stored in memory, and the
215
237
  /// convenient way.
@@ -268,25 +290,22 @@ class Tree {
268
290
  (/\W/.test(this.type.name) && !this.type.isError ? JSON.stringify(this.type.name) : this.type.name) +
269
291
  (children.length ? "(" + children + ")" : "");
270
292
  }
271
- /// Get a [tree cursor](#common.TreeCursor) rooted at this tree. When
272
- /// `pos` is given, the cursor is [moved](#common.TreeCursor.moveTo)
273
- /// to the given position and side.
274
- cursor(pos, side = 0) {
275
- let scope = (pos != null && CachedNode.get(this)) || this.topNode;
293
+ /// Get a [tree cursor](#common.TreeCursor) positioned at the top of
294
+ /// the tree. Mode can be used to [control](#common.IterMode) which
295
+ /// nodes the cursor visits.
296
+ cursor(mode = 0) {
297
+ return new TreeCursor(this.topNode, mode);
298
+ }
299
+ /// Get a [tree cursor](#common.TreeCursor) pointing into this tree
300
+ /// at the given position and side (see
301
+ /// [`moveTo`](#common.TreeCursor.moveTo).
302
+ cursorAt(pos, side = 0, mode = 0) {
303
+ let scope = CachedNode.get(this) || this.topNode;
276
304
  let cursor = new TreeCursor(scope);
277
- if (pos != null) {
278
- cursor.moveTo(pos, side);
279
- CachedNode.set(this, cursor._tree);
280
- }
305
+ cursor.moveTo(pos, side);
306
+ CachedNode.set(this, cursor._tree);
281
307
  return cursor;
282
308
  }
283
- /// Get a [tree cursor](#common.TreeCursor) that, unlike regular
284
- /// cursors, doesn't skip through
285
- /// [anonymous](#common.NodeType.isAnonymous) nodes and doesn't
286
- /// automatically enter mounted nodes.
287
- fullCursor() {
288
- return new TreeCursor(this.topNode, 1 /* Full */);
289
- }
290
309
  /// Get a [syntax node](#common.SyntaxNode) object for the top of the
291
310
  /// tree.
292
311
  get topNode() {
@@ -319,23 +338,21 @@ class Tree {
319
338
  /// not have its children iterated over (or `leave` called).
320
339
  iterate(spec) {
321
340
  let { enter, leave, from = 0, to = this.length } = spec;
322
- for (let c = this.cursor(), get = () => c.node;;) {
323
- let mustLeave = false;
324
- if (c.from <= to && c.to >= from && (c.type.isAnonymous || enter(c.type, c.from, c.to, get) !== false)) {
341
+ for (let c = this.cursor((spec.mode || 0) | IterMode.IncludeAnonymous);;) {
342
+ let entered = false;
343
+ if (c.from <= to && c.to >= from && (c.type.isAnonymous || enter(c) !== false)) {
325
344
  if (c.firstChild())
326
345
  continue;
327
- if (!c.type.isAnonymous)
328
- mustLeave = true;
346
+ entered = true;
329
347
  }
330
348
  for (;;) {
331
- if (mustLeave && leave)
332
- leave(c.type, c.from, c.to, get);
333
- mustLeave = c.type.isAnonymous;
349
+ if (entered && leave && !c.type.isAnonymous)
350
+ leave(c);
334
351
  if (c.nextSibling())
335
352
  break;
336
353
  if (!c.parent())
337
354
  return;
338
- mustLeave = true;
355
+ entered = true;
339
356
  }
340
357
  }
341
358
  }
@@ -486,72 +503,73 @@ function resolveNode(node, pos, side, overlays) {
486
503
  return node;
487
504
  node = parent;
488
505
  }
506
+ let mode = overlays ? 0 : IterMode.IgnoreOverlays;
489
507
  // Must go up out of overlays when those do not overlap with pos
490
508
  if (overlays)
491
509
  for (let scan = node, parent = scan.parent; parent; scan = parent, parent = scan.parent) {
492
- if (scan instanceof TreeNode && scan.index < 0 && ((_a = parent.enter(pos, side, true)) === null || _a === void 0 ? void 0 : _a.from) != scan.from)
510
+ if (scan instanceof TreeNode && scan.index < 0 && ((_a = parent.enter(pos, side, mode)) === null || _a === void 0 ? void 0 : _a.from) != scan.from)
493
511
  node = parent;
494
512
  }
495
513
  for (;;) {
496
- let inner = node.enter(pos, side, overlays);
514
+ let inner = node.enter(pos, side, mode);
497
515
  if (!inner)
498
516
  return node;
499
517
  node = inner;
500
518
  }
501
519
  }
502
520
  class TreeNode {
503
- constructor(node, _from,
521
+ constructor(_tree, from,
504
522
  // Index in parent node, set to -1 if the node is not a direct child of _parent.node (overlay)
505
523
  index, _parent) {
506
- this.node = node;
507
- this._from = _from;
524
+ this._tree = _tree;
525
+ this.from = from;
508
526
  this.index = index;
509
527
  this._parent = _parent;
510
528
  }
511
- get type() { return this.node.type; }
512
- get name() { return this.node.type.name; }
513
- get from() { return this._from; }
514
- get to() { return this._from + this.node.length; }
529
+ get type() { return this._tree.type; }
530
+ get name() { return this._tree.type.name; }
531
+ get to() { return this.from + this._tree.length; }
515
532
  nextChild(i, dir, pos, side, mode = 0) {
516
533
  for (let parent = this;;) {
517
- for (let { children, positions } = parent.node, e = dir > 0 ? children.length : -1; i != e; i += dir) {
518
- let next = children[i], start = positions[i] + parent._from;
534
+ for (let { children, positions } = parent._tree, e = dir > 0 ? children.length : -1; i != e; i += dir) {
535
+ let next = children[i], start = positions[i] + parent.from;
519
536
  if (!checkSide(side, pos, start, start + next.length))
520
537
  continue;
521
538
  if (next instanceof TreeBuffer) {
522
- if (mode & 2 /* NoEnterBuffer */)
539
+ if (mode & IterMode.ExcludeBuffers)
523
540
  continue;
524
541
  let index = next.findChild(0, next.buffer.length, dir, pos - start, side);
525
542
  if (index > -1)
526
543
  return new BufferNode(new BufferContext(parent, next, i, start), null, index);
527
544
  }
528
- else if ((mode & 1 /* Full */) || (!next.type.isAnonymous || hasChild(next))) {
545
+ else if ((mode & IterMode.IncludeAnonymous) || (!next.type.isAnonymous || hasChild(next))) {
529
546
  let mounted;
530
- if (!(mode & 1 /* Full */) && next.props && (mounted = next.prop(NodeProp.mounted)) && !mounted.overlay)
547
+ if (!(mode & IterMode.IgnoreMounts) &&
548
+ next.props && (mounted = next.prop(NodeProp.mounted)) && !mounted.overlay)
531
549
  return new TreeNode(mounted.tree, start, i, parent);
532
550
  let inner = new TreeNode(next, start, i, parent);
533
- return (mode & 1 /* Full */) || !inner.type.isAnonymous ? inner
551
+ return (mode & IterMode.IncludeAnonymous) || !inner.type.isAnonymous ? inner
534
552
  : inner.nextChild(dir < 0 ? next.children.length - 1 : 0, dir, pos, side);
535
553
  }
536
554
  }
537
- if ((mode & 1 /* Full */) || !parent.type.isAnonymous)
555
+ if ((mode & IterMode.IncludeAnonymous) || !parent.type.isAnonymous)
538
556
  return null;
539
557
  if (parent.index >= 0)
540
558
  i = parent.index + dir;
541
559
  else
542
- i = dir < 0 ? -1 : parent._parent.node.children.length;
560
+ i = dir < 0 ? -1 : parent._parent._tree.children.length;
543
561
  parent = parent._parent;
544
562
  if (!parent)
545
563
  return null;
546
564
  }
547
565
  }
548
566
  get firstChild() { return this.nextChild(0, 1, 0, 4 /* DontCare */); }
549
- get lastChild() { return this.nextChild(this.node.children.length - 1, -1, 0, 4 /* DontCare */); }
567
+ get lastChild() { return this.nextChild(this._tree.children.length - 1, -1, 0, 4 /* DontCare */); }
550
568
  childAfter(pos) { return this.nextChild(0, 1, pos, 2 /* After */); }
551
- childBefore(pos) { return this.nextChild(this.node.children.length - 1, -1, pos, -2 /* Before */); }
552
- enter(pos, side, overlays = true, buffers = true) {
569
+ childBefore(pos) { return this.nextChild(this._tree.children.length - 1, -1, pos, -2 /* Before */); }
570
+ enter(pos, side, mode = 0) {
553
571
  let mounted;
554
- if (overlays && (mounted = this.node.prop(NodeProp.mounted)) && mounted.overlay) {
572
+ if (!(mode & IterMode.IgnoreOverlays) && (mounted = this._tree.prop(NodeProp.mounted)) && mounted.overlay) {
555
573
  let rPos = pos - this.from;
556
574
  for (let { from, to } of mounted.overlay) {
557
575
  if ((side > 0 ? from <= rPos : from < rPos) &&
@@ -559,7 +577,7 @@ class TreeNode {
559
577
  return new TreeNode(mounted.tree, mounted.overlay[0].from + this.from, -1, this);
560
578
  }
561
579
  }
562
- return this.nextChild(0, 1, pos, side, buffers ? 0 : 2 /* NoEnterBuffer */);
580
+ return this.nextChild(0, 1, pos, side, mode);
563
581
  }
564
582
  nextSignificantParent() {
565
583
  let val = this;
@@ -576,9 +594,9 @@ class TreeNode {
576
594
  get prevSibling() {
577
595
  return this._parent && this.index >= 0 ? this._parent.nextChild(this.index - 1, -1, 0, 4 /* DontCare */) : null;
578
596
  }
579
- get cursor() { return new TreeCursor(this); }
580
- get tree() { return this.node; }
581
- toTree() { return this.node; }
597
+ cursor(mode = 0) { return new TreeCursor(this, mode); }
598
+ get tree() { return this._tree; }
599
+ toTree() { return this._tree; }
582
600
  resolve(pos, side = 0) {
583
601
  return resolveNode(this, pos, side, false);
584
602
  }
@@ -594,10 +612,12 @@ class TreeNode {
594
612
  return getChildren(this, type, before, after);
595
613
  }
596
614
  /// @internal
597
- toString() { return this.node.toString(); }
615
+ toString() { return this._tree.toString(); }
616
+ get node() { return this; }
617
+ matchContext(context) { return matchNodeContext(this, context); }
598
618
  }
599
619
  function getChildren(node, type, before, after) {
600
- let cur = node.cursor, result = [];
620
+ let cur = node.cursor(), result = [];
601
621
  if (!cur.firstChild())
602
622
  return result;
603
623
  if (before != null)
@@ -613,6 +633,18 @@ function getChildren(node, type, before, after) {
613
633
  return after == null ? result : [];
614
634
  }
615
635
  }
636
+ function matchNodeContext(node, context, i = context.length - 1) {
637
+ for (let p = node.parent; i >= 0; p = p.parent) {
638
+ if (!p)
639
+ return false;
640
+ if (!p.type.isAnonymous) {
641
+ if (context[i] && context[i] != p.name)
642
+ return false;
643
+ i--;
644
+ }
645
+ }
646
+ return true;
647
+ }
616
648
  class BufferContext {
617
649
  constructor(parent, buffer, index, start) {
618
650
  this.parent = parent;
@@ -640,8 +672,8 @@ class BufferNode {
640
672
  get lastChild() { return this.child(-1, 0, 4 /* DontCare */); }
641
673
  childAfter(pos) { return this.child(1, pos, 2 /* After */); }
642
674
  childBefore(pos) { return this.child(-1, pos, -2 /* Before */); }
643
- enter(pos, side, overlays, buffers = true) {
644
- if (!buffers)
675
+ enter(pos, side, mode = 0) {
676
+ if (mode & IterMode.ExcludeBuffers)
645
677
  return null;
646
678
  let { buffer } = this.context;
647
679
  let index = buffer.findChild(this.index + 4, buffer.buffer[this.index + 3], side > 0 ? 1 : -1, pos - this.context.start, side);
@@ -667,7 +699,7 @@ class BufferNode {
667
699
  return this.externalSibling(-1);
668
700
  return new BufferNode(this.context, this._parent, buffer.findChild(parentStart, this.index, -1, 0, 4 /* DontCare */));
669
701
  }
670
- get cursor() { return new TreeCursor(this); }
702
+ cursor(mode = 0) { return new TreeCursor(this, mode); }
671
703
  get tree() { return null; }
672
704
  toTree() {
673
705
  let children = [], positions = [];
@@ -696,6 +728,8 @@ class BufferNode {
696
728
  getChildren(type, before = null, after = null) {
697
729
  return getChildren(this, type, before, after);
698
730
  }
731
+ get node() { return this; }
732
+ matchContext(context) { return matchNodeContext(this, context); }
699
733
  }
700
734
  /// A tree cursor object focuses on a given node in a syntax tree, and
701
735
  /// allows you to move to adjacent nodes.
@@ -705,8 +739,10 @@ class TreeCursor {
705
739
  /// @internal
706
740
  mode = 0) {
707
741
  this.mode = mode;
742
+ /// @internal
708
743
  this.buffer = null;
709
744
  this.stack = [];
745
+ /// @internal
710
746
  this.index = 0;
711
747
  this.bufferNode = null;
712
748
  if (node instanceof TreeNode) {
@@ -757,7 +793,7 @@ class TreeCursor {
757
793
  /// @internal
758
794
  enterChild(dir, pos, side) {
759
795
  if (!this.buffer)
760
- return this.yield(this._tree.nextChild(dir < 0 ? this._tree.node.children.length - 1 : 0, dir, pos, side, this.mode));
796
+ return this.yield(this._tree.nextChild(dir < 0 ? this._tree._tree.children.length - 1 : 0, dir, pos, side, this.mode));
761
797
  let { buffer } = this.buffer;
762
798
  let index = buffer.findChild(this.index + 4, buffer.buffer[this.index + 3], dir, pos - this.buffer.start, side);
763
799
  if (index < 0)
@@ -779,18 +815,18 @@ class TreeCursor {
779
815
  /// will also enter [overlaid](#common.MountedTree.overlay)
780
816
  /// [mounted](#common.NodeProp^mounted) trees unless `overlays` is
781
817
  /// set to false.
782
- enter(pos, side, overlays = true, buffers = true) {
818
+ enter(pos, side, mode = this.mode) {
783
819
  if (!this.buffer)
784
- return this.yield(this._tree.enter(pos, side, overlays && !(this.mode & 1 /* Full */), buffers));
785
- return buffers ? this.enterChild(1, pos, side) : false;
820
+ return this.yield(this._tree.enter(pos, side, mode));
821
+ return mode & IterMode.ExcludeBuffers ? false : this.enterChild(1, pos, side);
786
822
  }
787
823
  /// Move to the node's parent node, if this isn't the top node.
788
824
  parent() {
789
825
  if (!this.buffer)
790
- return this.yieldNode((this.mode & 1 /* Full */) ? this._tree._parent : this._tree.parent);
826
+ return this.yieldNode((this.mode & IterMode.IncludeAnonymous) ? this._tree._parent : this._tree.parent);
791
827
  if (this.stack.length)
792
828
  return this.yieldBuf(this.stack.pop());
793
- let parent = (this.mode & 1 /* Full */) ? this.buffer.parent : this.buffer.parent.nextSignificantParent();
829
+ let parent = (this.mode & IterMode.IncludeAnonymous) ? this.buffer.parent : this.buffer.parent.nextSignificantParent();
794
830
  this.buffer = null;
795
831
  return this.yieldNode(parent);
796
832
  }
@@ -836,9 +872,12 @@ class TreeCursor {
836
872
  }
837
873
  for (; parent; { index, _parent: parent } = parent) {
838
874
  if (index > -1)
839
- for (let i = index + dir, e = dir < 0 ? -1 : parent.node.children.length; i != e; i += dir) {
840
- let child = parent.node.children[i];
841
- if ((this.mode & 1 /* Full */) || child instanceof TreeBuffer || !child.type.isAnonymous || hasChild(child))
875
+ for (let i = index + dir, e = dir < 0 ? -1 : parent._tree.children.length; i != e; i += dir) {
876
+ let child = parent._tree.children[i];
877
+ if ((this.mode & IterMode.IncludeAnonymous) ||
878
+ child instanceof TreeBuffer ||
879
+ !child.type.isAnonymous ||
880
+ hasChild(child))
842
881
  return false;
843
882
  }
844
883
  }
@@ -906,7 +945,55 @@ class TreeCursor {
906
945
  /// any. Will return null when the node is in a [tree
907
946
  /// buffer](#common.TreeBuffer).
908
947
  get tree() {
909
- return this.buffer ? null : this._tree.node;
948
+ return this.buffer ? null : this._tree._tree;
949
+ }
950
+ /// Iterate over the current node and all its descendants, calling
951
+ /// `enter` when entering a node and `leave`, if given, when leaving
952
+ /// one. When `enter` returns `false`, any children of that node are
953
+ /// skipped, and `leave` isn't called for it.
954
+ iterate(enter, leave) {
955
+ for (let depth = 0;;) {
956
+ let mustLeave = false;
957
+ if (this.type.isAnonymous || enter(this) !== false) {
958
+ if (this.firstChild()) {
959
+ depth++;
960
+ continue;
961
+ }
962
+ if (!this.type.isAnonymous)
963
+ mustLeave = true;
964
+ }
965
+ for (;;) {
966
+ if (mustLeave && leave)
967
+ leave(this);
968
+ mustLeave = this.type.isAnonymous;
969
+ if (this.nextSibling())
970
+ break;
971
+ if (!depth)
972
+ return;
973
+ this.parent();
974
+ depth--;
975
+ mustLeave = true;
976
+ }
977
+ }
978
+ }
979
+ /// Test whether the current node matches a given context—a sequence
980
+ /// of direct parent node names. Empty strings in the context array
981
+ /// are treated as wildcards.
982
+ matchContext(context) {
983
+ if (!this.buffer)
984
+ return matchNodeContext(this.node, context);
985
+ let { buffer } = this.buffer, { types } = buffer.set;
986
+ for (let i = context.length - 1, d = this.stack.length - 1; i >= 0; d--) {
987
+ if (d < 0)
988
+ return matchNodeContext(this.node, context, i);
989
+ let type = types[buffer.buffer[this.stack[d]]];
990
+ if (!type.isAnonymous) {
991
+ if (context[i] && context[i] != type.name)
992
+ return false;
993
+ i--;
994
+ }
995
+ }
996
+ return true;
910
997
  }
911
998
  }
912
999
  function hasChild(tree) {
@@ -1166,6 +1253,48 @@ mkTree) {
1166
1253
  divide(children, positions, from, to, 0);
1167
1254
  return (mkTop || mkTree)(localChildren, localPositions, length);
1168
1255
  }
1256
+ /// Provides a way to associate values with pieces of trees. As long
1257
+ /// as that part of the tree is reused, the associated values can be
1258
+ /// retrieved from an updated tree.
1259
+ class NodeWeakMap {
1260
+ constructor() {
1261
+ this.map = new WeakMap();
1262
+ }
1263
+ setBuffer(buffer, index, value) {
1264
+ let inner = this.map.get(buffer);
1265
+ if (!inner)
1266
+ this.map.set(buffer, inner = new Map);
1267
+ inner.set(index, value);
1268
+ }
1269
+ getBuffer(buffer, index) {
1270
+ let inner = this.map.get(buffer);
1271
+ return inner && inner.get(index);
1272
+ }
1273
+ /// Set the value for this syntax node.
1274
+ set(node, value) {
1275
+ if (node instanceof BufferNode)
1276
+ this.setBuffer(node.context.buffer, node.index, value);
1277
+ else if (node instanceof TreeNode)
1278
+ this.map.set(node.tree, value);
1279
+ }
1280
+ /// Retrieve value for this syntax node, if it exists in the map.
1281
+ get(node) {
1282
+ return node instanceof BufferNode ? this.getBuffer(node.context.buffer, node.index)
1283
+ : node instanceof TreeNode ? this.map.get(node.tree) : undefined;
1284
+ }
1285
+ /// Set the value for the node that a cursor currently points to.
1286
+ cursorSet(cursor, value) {
1287
+ if (cursor.buffer)
1288
+ this.setBuffer(cursor.buffer.buffer, cursor.index, value);
1289
+ else
1290
+ this.map.set(cursor.tree, value);
1291
+ }
1292
+ /// Retrieve the value for the node that a cursor currently points
1293
+ /// to.
1294
+ cursorGet(cursor) {
1295
+ return cursor.buffer ? this.getBuffer(cursor.buffer.buffer, cursor.index) : this.map.get(cursor.tree);
1296
+ }
1297
+ }
1169
1298
 
1170
1299
  /// Tree fragments are used during [incremental
1171
1300
  /// parsing](#common.Parser.startParse) to track parts of old trees
@@ -1386,7 +1515,7 @@ class MixedParse {
1386
1515
  let fragmentCursor = new FragmentCursor(this.fragments);
1387
1516
  let overlay = null;
1388
1517
  let covered = null;
1389
- let cursor = new TreeCursor(new TreeNode(this.baseTree, this.ranges[0].from, 0, null), 1 /* Full */);
1518
+ let cursor = new TreeCursor(new TreeNode(this.baseTree, this.ranges[0].from, 0, null), IterMode.IncludeAnonymous | IterMode.IgnoreMounts);
1390
1519
  scan: for (let nest, isCovered; this.stoppedAt == null || cursor.from < this.stoppedAt;) {
1391
1520
  let enter = true, range;
1392
1521
  if (fragmentCursor.hasNode(cursor)) {
@@ -1395,7 +1524,7 @@ class MixedParse {
1395
1524
  if (match)
1396
1525
  for (let r of match.mount.overlay) {
1397
1526
  let from = r.from + match.pos, to = r.to + match.pos;
1398
- if (from >= cursor.from && to <= cursor.to)
1527
+ if (from >= cursor.from && to <= cursor.to && !overlay.ranges.some(r => r.from < to && r.to > from))
1399
1528
  overlay.ranges.push({ from, to });
1400
1529
  }
1401
1530
  }
@@ -1492,20 +1621,20 @@ function materialize(cursor) {
1492
1621
  let buf = base.children[i], b = buf.buffer;
1493
1622
  // Split a level in the buffer, putting the nodes before and after
1494
1623
  // the child that contains `node` into new buffers.
1495
- function split(startI, endI, type, innerOffset) {
1624
+ function split(startI, endI, type, innerOffset, length) {
1496
1625
  let i = startI;
1497
1626
  while (b[i + 2] + off <= node.from)
1498
1627
  i = b[i + 3];
1499
1628
  let children = [], positions = [];
1500
1629
  sliceBuf(buf, startI, i, children, positions, innerOffset);
1501
- let isTarget = b[i + 1] + off == node.from && b[i + 2] + off == node.to && b[i] == node.type.id;
1502
- children.push(isTarget ? node.toTree() : split(i + 4, b[i + 3], buf.set.types[b[i]], b[i + 1]));
1503
- positions.push(b[i + 1] - innerOffset);
1630
+ let from = b[i + 1], to = b[i + 2];
1631
+ let isTarget = from + off == node.from && to + off == node.to && b[i] == node.type.id;
1632
+ children.push(isTarget ? node.toTree() : split(i + 4, b[i + 3], buf.set.types[b[i]], from, to - from));
1633
+ positions.push(from - innerOffset);
1504
1634
  sliceBuf(buf, b[i + 3], endI, children, positions, innerOffset);
1505
- let last = children.length - 1;
1506
- return new Tree(type, children, positions, positions[last] + children[last].length);
1635
+ return new Tree(type, children, positions, length);
1507
1636
  }
1508
- base.children[i] = split(0, b.length, NodeType.none, 0);
1637
+ base.children[i] = split(0, b.length, NodeType.none, 0, buf.length);
1509
1638
  // Move the cursor back to the target node
1510
1639
  for (let d = 0; d <= depth; d++)
1511
1640
  cursor.childAfter(node.from);
@@ -1514,13 +1643,13 @@ class StructureCursor {
1514
1643
  constructor(root, offset) {
1515
1644
  this.offset = offset;
1516
1645
  this.done = false;
1517
- this.cursor = root.fullCursor();
1646
+ this.cursor = root.cursor(IterMode.IncludeAnonymous | IterMode.IgnoreMounts);
1518
1647
  }
1519
1648
  // Move to the first node (in pre-order) that starts at or after `pos`.
1520
1649
  moveTo(pos) {
1521
1650
  let { cursor } = this, p = pos - this.offset;
1522
1651
  while (!this.done && cursor.from < p) {
1523
- if (cursor.to >= pos && cursor.enter(p, 1, false, false)) ;
1652
+ if (cursor.to >= pos && cursor.enter(p, 1, IterMode.IgnoreOverlays | IterMode.ExcludeBuffers)) ;
1524
1653
  else if (!cursor.next(false))
1525
1654
  this.done = true;
1526
1655
  }
@@ -1684,4 +1813,4 @@ function enterFragments(mounts, ranges) {
1684
1813
  return result;
1685
1814
  }
1686
1815
 
1687
- export { DefaultBufferLength, MountedTree, NodeProp, NodeSet, NodeType, Parser, Tree, TreeBuffer, TreeCursor, TreeFragment, parseMixed };
1816
+ export { DefaultBufferLength, IterMode, MountedTree, NodeProp, NodeSet, NodeType, NodeWeakMap, Parser, Tree, TreeBuffer, TreeCursor, TreeFragment, parseMixed };
package/dist/mix.d.ts CHANGED
@@ -1,13 +1,13 @@
1
- import { TreeCursor } from "./tree";
1
+ import { SyntaxNodeRef } from "./tree";
2
2
  import { Input, Parser, ParseWrapper } from "./parse";
3
3
  export interface NestedParse {
4
4
  parser: Parser;
5
5
  overlay?: readonly {
6
6
  from: number;
7
7
  to: number;
8
- }[] | ((node: TreeCursor) => {
8
+ }[] | ((node: SyntaxNodeRef) => {
9
9
  from: number;
10
10
  to: number;
11
11
  } | boolean);
12
12
  }
13
- export declare function parseMixed(nest: (node: TreeCursor, input: Input) => NestedParse | null): ParseWrapper;
13
+ export declare function parseMixed(nest: (node: SyntaxNodeRef, input: Input) => NestedParse | null): ParseWrapper;