@lezer/common 1.0.4 → 1.1.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 CHANGED
@@ -1,7 +1,5 @@
1
1
  'use strict';
2
2
 
3
- // FIXME profile adding a per-Tree TreeNode cache, validating it by
4
- // parent pointer
5
3
  /**
6
4
  The default maximum length of a `TreeBuffer` node.
7
5
  */
@@ -116,6 +114,12 @@ class MountedTree {
116
114
  this.overlay = overlay;
117
115
  this.parser = parser;
118
116
  }
117
+ /**
118
+ @internal
119
+ */
120
+ static get(tree) {
121
+ return tree && tree.props && tree.props[NodeProp.mounted.id];
122
+ }
119
123
  }
120
124
  const noProps = Object.create(null);
121
125
  /**
@@ -371,7 +375,7 @@ class Tree {
371
375
  @internal
372
376
  */
373
377
  toString() {
374
- let mounted = this.prop(NodeProp.mounted);
378
+ let mounted = MountedTree.get(this);
375
379
  if (mounted && !mounted.overlay)
376
380
  return mounted.tree.toString();
377
381
  let children = "";
@@ -443,6 +447,16 @@ class Tree {
443
447
  return node;
444
448
  }
445
449
  /**
450
+ In some situations, it can be useful to iterate through all
451
+ nodes around a position, including those in overlays that don't
452
+ directly cover the position. This method gives you an iterator
453
+ that will produce all nodes, from small to big, around the given
454
+ position.
455
+ */
456
+ resolveStack(pos, side = 0) {
457
+ return stackIterator(this, pos, side);
458
+ }
459
+ /**
446
460
  Iterate over the tree and its children, calling `enter` for any
447
461
  node that touches the `from`/`to` region (if given) before
448
462
  running over such a node's children, and `leave` (if given) when
@@ -621,22 +635,6 @@ function checkSide(side, pos, from, to) {
621
635
  case 4 /* Side.DontCare */: return true;
622
636
  }
623
637
  }
624
- function enterUnfinishedNodesBefore(node, pos) {
625
- let scan = node.childBefore(pos);
626
- while (scan) {
627
- let last = scan.lastChild;
628
- if (!last || last.to != scan.to)
629
- break;
630
- if (last.type.isError && last.from == last.to) {
631
- node = scan;
632
- scan = last.prevSibling;
633
- }
634
- else {
635
- scan = last;
636
- }
637
- }
638
- return node;
639
- }
640
638
  function resolveNode(node, pos, side, overlays) {
641
639
  var _a;
642
640
  // Move up to a node that actually holds the position, if possible
@@ -662,10 +660,48 @@ function resolveNode(node, pos, side, overlays) {
662
660
  node = inner;
663
661
  }
664
662
  }
665
- class TreeNode {
663
+ class BaseNode {
664
+ cursor(mode = 0) { return new TreeCursor(this, mode); }
665
+ getChild(type, before = null, after = null) {
666
+ let r = getChildren(this, type, before, after);
667
+ return r.length ? r[0] : null;
668
+ }
669
+ getChildren(type, before = null, after = null) {
670
+ return getChildren(this, type, before, after);
671
+ }
672
+ resolve(pos, side = 0) {
673
+ return resolveNode(this, pos, side, false);
674
+ }
675
+ resolveInner(pos, side = 0) {
676
+ return resolveNode(this, pos, side, true);
677
+ }
678
+ matchContext(context) {
679
+ return matchNodeContext(this, context);
680
+ }
681
+ enterUnfinishedNodesBefore(pos) {
682
+ let scan = this.childBefore(pos), node = this;
683
+ while (scan) {
684
+ let last = scan.lastChild;
685
+ if (!last || last.to != scan.to)
686
+ break;
687
+ if (last.type.isError && last.from == last.to) {
688
+ node = scan;
689
+ scan = last.prevSibling;
690
+ }
691
+ else {
692
+ scan = last;
693
+ }
694
+ }
695
+ return node;
696
+ }
697
+ get node() { return this; }
698
+ get next() { return this.parent; }
699
+ }
700
+ class TreeNode extends BaseNode {
666
701
  constructor(_tree, from,
667
702
  // Index in parent node, set to -1 if the node is not a direct child of _parent.node (overlay)
668
703
  index, _parent) {
704
+ super();
669
705
  this._tree = _tree;
670
706
  this.from = from;
671
707
  this.index = index;
@@ -689,8 +725,7 @@ class TreeNode {
689
725
  }
690
726
  else if ((mode & exports.IterMode.IncludeAnonymous) || (!next.type.isAnonymous || hasChild(next))) {
691
727
  let mounted;
692
- if (!(mode & exports.IterMode.IgnoreMounts) &&
693
- next.props && (mounted = next.prop(NodeProp.mounted)) && !mounted.overlay)
728
+ if (!(mode & exports.IterMode.IgnoreMounts) && (mounted = MountedTree.get(next)) && !mounted.overlay)
694
729
  return new TreeNode(mounted.tree, start, i, parent);
695
730
  let inner = new TreeNode(next, start, i, parent);
696
731
  return (mode & exports.IterMode.IncludeAnonymous) || !inner.type.isAnonymous ? inner
@@ -714,7 +749,7 @@ class TreeNode {
714
749
  childBefore(pos) { return this.nextChild(this._tree.children.length - 1, -1, pos, -2 /* Side.Before */); }
715
750
  enter(pos, side, mode = 0) {
716
751
  let mounted;
717
- if (!(mode & exports.IterMode.IgnoreOverlays) && (mounted = this._tree.prop(NodeProp.mounted)) && mounted.overlay) {
752
+ if (!(mode & exports.IterMode.IgnoreOverlays) && (mounted = MountedTree.get(this._tree)) && mounted.overlay) {
718
753
  let rPos = pos - this.from;
719
754
  for (let { from, to } of mounted.overlay) {
720
755
  if ((side > 0 ? from <= rPos : from < rPos) &&
@@ -739,29 +774,12 @@ class TreeNode {
739
774
  get prevSibling() {
740
775
  return this._parent && this.index >= 0 ? this._parent.nextChild(this.index - 1, -1, 0, 4 /* Side.DontCare */) : null;
741
776
  }
742
- cursor(mode = 0) { return new TreeCursor(this, mode); }
743
777
  get tree() { return this._tree; }
744
778
  toTree() { return this._tree; }
745
- resolve(pos, side = 0) {
746
- return resolveNode(this, pos, side, false);
747
- }
748
- resolveInner(pos, side = 0) {
749
- return resolveNode(this, pos, side, true);
750
- }
751
- enterUnfinishedNodesBefore(pos) { return enterUnfinishedNodesBefore(this, pos); }
752
- getChild(type, before = null, after = null) {
753
- let r = getChildren(this, type, before, after);
754
- return r.length ? r[0] : null;
755
- }
756
- getChildren(type, before = null, after = null) {
757
- return getChildren(this, type, before, after);
758
- }
759
779
  /**
760
780
  @internal
761
781
  */
762
782
  toString() { return this._tree.toString(); }
763
- get node() { return this; }
764
- matchContext(context) { return matchNodeContext(this, context); }
765
783
  }
766
784
  function getChildren(node, type, before, after) {
767
785
  let cur = node.cursor(), result = [];
@@ -800,11 +818,12 @@ class BufferContext {
800
818
  this.start = start;
801
819
  }
802
820
  }
803
- class BufferNode {
821
+ class BufferNode extends BaseNode {
804
822
  get name() { return this.type.name; }
805
823
  get from() { return this.context.start + this.context.buffer.buffer[this.index + 1]; }
806
824
  get to() { return this.context.start + this.context.buffer.buffer[this.index + 2]; }
807
825
  constructor(context, _parent, index) {
826
+ super();
808
827
  this.context = context;
809
828
  this._parent = _parent;
810
829
  this.index = index;
@@ -846,7 +865,6 @@ class BufferNode {
846
865
  return this.externalSibling(-1);
847
866
  return new BufferNode(this.context, this._parent, buffer.findChild(parentStart, this.index, -1, 0, 4 /* Side.DontCare */));
848
867
  }
849
- cursor(mode = 0) { return new TreeCursor(this, mode); }
850
868
  get tree() { return null; }
851
869
  toTree() {
852
870
  let children = [], positions = [];
@@ -859,26 +877,57 @@ class BufferNode {
859
877
  }
860
878
  return new Tree(this.type, children, positions, this.to - this.from);
861
879
  }
862
- resolve(pos, side = 0) {
863
- return resolveNode(this, pos, side, false);
864
- }
865
- resolveInner(pos, side = 0) {
866
- return resolveNode(this, pos, side, true);
867
- }
868
- enterUnfinishedNodesBefore(pos) { return enterUnfinishedNodesBefore(this, pos); }
869
880
  /**
870
881
  @internal
871
882
  */
872
883
  toString() { return this.context.buffer.childString(this.index); }
873
- getChild(type, before = null, after = null) {
874
- let r = getChildren(this, type, before, after);
875
- return r.length ? r[0] : null;
884
+ }
885
+ function iterStack(heads) {
886
+ if (!heads.length)
887
+ return null;
888
+ if (heads.length == 1)
889
+ return heads[0];
890
+ let pick = 0, picked = heads[0];
891
+ for (let i = 1; i < heads.length; i++) {
892
+ let node = heads[i];
893
+ if (node.from > picked.from || node.to < picked.to) {
894
+ picked = node;
895
+ pick = i;
896
+ }
876
897
  }
877
- getChildren(type, before = null, after = null) {
878
- return getChildren(this, type, before, after);
898
+ let next = picked instanceof TreeNode && picked.index < 0 ? null : picked.parent;
899
+ let newHeads = heads.slice();
900
+ if (next)
901
+ newHeads[pick] = next;
902
+ else
903
+ newHeads.splice(pick, 1);
904
+ return new StackIterator(newHeads, picked);
905
+ }
906
+ class StackIterator {
907
+ constructor(heads, node) {
908
+ this.heads = heads;
909
+ this.node = node;
879
910
  }
880
- get node() { return this; }
881
- matchContext(context) { return matchNodeContext(this, context); }
911
+ get next() { return iterStack(this.heads); }
912
+ }
913
+ function stackIterator(tree, pos, side) {
914
+ let inner = tree.resolveInner(pos, side), layers = null;
915
+ for (let scan = inner instanceof TreeNode ? inner : inner.context.parent; scan; scan = scan.parent) {
916
+ if (scan.index < 0) { // This is an overlay root
917
+ let parent = scan.parent;
918
+ (layers || (layers = [inner])).push(parent.resolve(pos, side));
919
+ scan = parent;
920
+ }
921
+ else {
922
+ let mount = MountedTree.get(scan.tree);
923
+ // Relevant overlay branching off
924
+ if (mount && mount.overlay && mount.overlay[0].from <= pos && mount.overlay[mount.overlay.length - 1].to >= pos) {
925
+ let root = new TreeNode(mount.tree, mount.overlay[0].from + scan.from, 0, null);
926
+ (layers || (layers = [inner])).push(resolveNode(root, pos, side, false));
927
+ }
928
+ }
929
+ }
930
+ return layers ? iterStack(layers) : inner;
882
931
  }
883
932
  /**
884
933
  A tree cursor object focuses on a given node in a syntax tree, and
package/dist/index.d.cts CHANGED
@@ -615,6 +615,14 @@ declare class Tree {
615
615
  */
616
616
  resolveInner(pos: number, side?: -1 | 0 | 1): SyntaxNode;
617
617
  /**
618
+ In some situations, it can be useful to iterate through all
619
+ nodes around a position, including those in overlays that don't
620
+ directly cover the position. This method gives you an iterator
621
+ that will produce all nodes, from small to big, around the given
622
+ position.
623
+ */
624
+ resolveStack(pos: number, side?: -1 | 0 | 1): NodeIterator;
625
+ /**
618
626
  Iterate over the tree and its children, calling `enter` for any
619
627
  node that touches the `from`/`to` region (if given) before
620
628
  running over such a node's children, and `leave` (if given) when
@@ -656,6 +664,13 @@ declare class Tree {
656
664
  */
657
665
  static build(data: BuildData): Tree;
658
666
  }
667
+ /**
668
+ Represents a sequence of nodes.
669
+ */
670
+ type NodeIterator = {
671
+ node: SyntaxNode;
672
+ next: NodeIterator | null;
673
+ };
659
674
  type BuildData = {
660
675
  /**
661
676
  The buffer or buffer cursor to read the node data from.
@@ -827,7 +842,9 @@ interface SyntaxNodeRef {
827
842
  */
828
843
  readonly node: SyntaxNode;
829
844
  /**
830
- Test whether the node matches a given context.
845
+ Test whether the node matches a given context—a sequence of
846
+ direct parent nodes. Empty strings in the context array act as
847
+ wildcards, other strings must match the ancestor node's name.
831
848
  */
832
849
  matchContext(context: readonly string[]): boolean;
833
850
  }
@@ -921,12 +938,6 @@ interface SyntaxNode extends SyntaxNodeRef {
921
938
  matching children, not just the first.
922
939
  */
923
940
  getChildren(type: string | number, before?: string | number | null, after?: string | number | null): SyntaxNode[];
924
- /**
925
- Test whether the node matches a given context—a sequence of
926
- direct parent nodes. Empty strings in the context array act as
927
- wildcards, other strings must match the ancestor node's name.
928
- */
929
- matchContext(context: readonly string[]): boolean;
930
941
  }
931
942
  /**
932
943
  A tree cursor object focuses on a given node in a syntax tree, and
@@ -1112,4 +1123,4 @@ tree.
1112
1123
  */
1113
1124
  declare function parseMixed(nest: (node: SyntaxNodeRef, input: Input) => NestedParse | null): ParseWrapper;
1114
1125
 
1115
- export { BufferCursor, ChangedRange, DefaultBufferLength, Input, IterMode, MountedTree, NestedParse, NodeProp, NodePropSource, NodeSet, NodeType, NodeWeakMap, ParseWrapper, Parser, PartialParse, SyntaxNode, SyntaxNodeRef, Tree, TreeBuffer, TreeCursor, TreeFragment, parseMixed };
1126
+ export { BufferCursor, ChangedRange, DefaultBufferLength, Input, IterMode, MountedTree, NestedParse, NodeIterator, NodeProp, NodePropSource, NodeSet, NodeType, NodeWeakMap, ParseWrapper, Parser, PartialParse, SyntaxNode, SyntaxNodeRef, Tree, TreeBuffer, TreeCursor, TreeFragment, parseMixed };
package/dist/index.d.ts CHANGED
@@ -615,6 +615,14 @@ declare class Tree {
615
615
  */
616
616
  resolveInner(pos: number, side?: -1 | 0 | 1): SyntaxNode;
617
617
  /**
618
+ In some situations, it can be useful to iterate through all
619
+ nodes around a position, including those in overlays that don't
620
+ directly cover the position. This method gives you an iterator
621
+ that will produce all nodes, from small to big, around the given
622
+ position.
623
+ */
624
+ resolveStack(pos: number, side?: -1 | 0 | 1): NodeIterator;
625
+ /**
618
626
  Iterate over the tree and its children, calling `enter` for any
619
627
  node that touches the `from`/`to` region (if given) before
620
628
  running over such a node's children, and `leave` (if given) when
@@ -656,6 +664,13 @@ declare class Tree {
656
664
  */
657
665
  static build(data: BuildData): Tree;
658
666
  }
667
+ /**
668
+ Represents a sequence of nodes.
669
+ */
670
+ type NodeIterator = {
671
+ node: SyntaxNode;
672
+ next: NodeIterator | null;
673
+ };
659
674
  type BuildData = {
660
675
  /**
661
676
  The buffer or buffer cursor to read the node data from.
@@ -827,7 +842,9 @@ interface SyntaxNodeRef {
827
842
  */
828
843
  readonly node: SyntaxNode;
829
844
  /**
830
- Test whether the node matches a given context.
845
+ Test whether the node matches a given context—a sequence of
846
+ direct parent nodes. Empty strings in the context array act as
847
+ wildcards, other strings must match the ancestor node's name.
831
848
  */
832
849
  matchContext(context: readonly string[]): boolean;
833
850
  }
@@ -921,12 +938,6 @@ interface SyntaxNode extends SyntaxNodeRef {
921
938
  matching children, not just the first.
922
939
  */
923
940
  getChildren(type: string | number, before?: string | number | null, after?: string | number | null): SyntaxNode[];
924
- /**
925
- Test whether the node matches a given context—a sequence of
926
- direct parent nodes. Empty strings in the context array act as
927
- wildcards, other strings must match the ancestor node's name.
928
- */
929
- matchContext(context: readonly string[]): boolean;
930
941
  }
931
942
  /**
932
943
  A tree cursor object focuses on a given node in a syntax tree, and
@@ -1112,4 +1123,4 @@ tree.
1112
1123
  */
1113
1124
  declare function parseMixed(nest: (node: SyntaxNodeRef, input: Input) => NestedParse | null): ParseWrapper;
1114
1125
 
1115
- export { BufferCursor, ChangedRange, DefaultBufferLength, Input, IterMode, MountedTree, NestedParse, NodeProp, NodePropSource, NodeSet, NodeType, NodeWeakMap, ParseWrapper, Parser, PartialParse, SyntaxNode, SyntaxNodeRef, Tree, TreeBuffer, TreeCursor, TreeFragment, parseMixed };
1126
+ export { BufferCursor, ChangedRange, DefaultBufferLength, Input, IterMode, MountedTree, NestedParse, NodeIterator, NodeProp, NodePropSource, NodeSet, NodeType, NodeWeakMap, ParseWrapper, Parser, PartialParse, SyntaxNode, SyntaxNodeRef, Tree, TreeBuffer, TreeCursor, TreeFragment, parseMixed };
package/dist/index.js CHANGED
@@ -1,5 +1,3 @@
1
- // FIXME profile adding a per-Tree TreeNode cache, validating it by
2
- // parent pointer
3
1
  /**
4
2
  The default maximum length of a `TreeBuffer` node.
5
3
  */
@@ -114,6 +112,12 @@ class MountedTree {
114
112
  this.overlay = overlay;
115
113
  this.parser = parser;
116
114
  }
115
+ /**
116
+ @internal
117
+ */
118
+ static get(tree) {
119
+ return tree && tree.props && tree.props[NodeProp.mounted.id];
120
+ }
117
121
  }
118
122
  const noProps = Object.create(null);
119
123
  /**
@@ -369,7 +373,7 @@ class Tree {
369
373
  @internal
370
374
  */
371
375
  toString() {
372
- let mounted = this.prop(NodeProp.mounted);
376
+ let mounted = MountedTree.get(this);
373
377
  if (mounted && !mounted.overlay)
374
378
  return mounted.tree.toString();
375
379
  let children = "";
@@ -441,6 +445,16 @@ class Tree {
441
445
  return node;
442
446
  }
443
447
  /**
448
+ In some situations, it can be useful to iterate through all
449
+ nodes around a position, including those in overlays that don't
450
+ directly cover the position. This method gives you an iterator
451
+ that will produce all nodes, from small to big, around the given
452
+ position.
453
+ */
454
+ resolveStack(pos, side = 0) {
455
+ return stackIterator(this, pos, side);
456
+ }
457
+ /**
444
458
  Iterate over the tree and its children, calling `enter` for any
445
459
  node that touches the `from`/`to` region (if given) before
446
460
  running over such a node's children, and `leave` (if given) when
@@ -619,22 +633,6 @@ function checkSide(side, pos, from, to) {
619
633
  case 4 /* Side.DontCare */: return true;
620
634
  }
621
635
  }
622
- function enterUnfinishedNodesBefore(node, pos) {
623
- let scan = node.childBefore(pos);
624
- while (scan) {
625
- let last = scan.lastChild;
626
- if (!last || last.to != scan.to)
627
- break;
628
- if (last.type.isError && last.from == last.to) {
629
- node = scan;
630
- scan = last.prevSibling;
631
- }
632
- else {
633
- scan = last;
634
- }
635
- }
636
- return node;
637
- }
638
636
  function resolveNode(node, pos, side, overlays) {
639
637
  var _a;
640
638
  // Move up to a node that actually holds the position, if possible
@@ -660,10 +658,48 @@ function resolveNode(node, pos, side, overlays) {
660
658
  node = inner;
661
659
  }
662
660
  }
663
- class TreeNode {
661
+ class BaseNode {
662
+ cursor(mode = 0) { return new TreeCursor(this, mode); }
663
+ getChild(type, before = null, after = null) {
664
+ let r = getChildren(this, type, before, after);
665
+ return r.length ? r[0] : null;
666
+ }
667
+ getChildren(type, before = null, after = null) {
668
+ return getChildren(this, type, before, after);
669
+ }
670
+ resolve(pos, side = 0) {
671
+ return resolveNode(this, pos, side, false);
672
+ }
673
+ resolveInner(pos, side = 0) {
674
+ return resolveNode(this, pos, side, true);
675
+ }
676
+ matchContext(context) {
677
+ return matchNodeContext(this, context);
678
+ }
679
+ enterUnfinishedNodesBefore(pos) {
680
+ let scan = this.childBefore(pos), node = this;
681
+ while (scan) {
682
+ let last = scan.lastChild;
683
+ if (!last || last.to != scan.to)
684
+ break;
685
+ if (last.type.isError && last.from == last.to) {
686
+ node = scan;
687
+ scan = last.prevSibling;
688
+ }
689
+ else {
690
+ scan = last;
691
+ }
692
+ }
693
+ return node;
694
+ }
695
+ get node() { return this; }
696
+ get next() { return this.parent; }
697
+ }
698
+ class TreeNode extends BaseNode {
664
699
  constructor(_tree, from,
665
700
  // Index in parent node, set to -1 if the node is not a direct child of _parent.node (overlay)
666
701
  index, _parent) {
702
+ super();
667
703
  this._tree = _tree;
668
704
  this.from = from;
669
705
  this.index = index;
@@ -687,8 +723,7 @@ class TreeNode {
687
723
  }
688
724
  else if ((mode & IterMode.IncludeAnonymous) || (!next.type.isAnonymous || hasChild(next))) {
689
725
  let mounted;
690
- if (!(mode & IterMode.IgnoreMounts) &&
691
- next.props && (mounted = next.prop(NodeProp.mounted)) && !mounted.overlay)
726
+ if (!(mode & IterMode.IgnoreMounts) && (mounted = MountedTree.get(next)) && !mounted.overlay)
692
727
  return new TreeNode(mounted.tree, start, i, parent);
693
728
  let inner = new TreeNode(next, start, i, parent);
694
729
  return (mode & IterMode.IncludeAnonymous) || !inner.type.isAnonymous ? inner
@@ -712,7 +747,7 @@ class TreeNode {
712
747
  childBefore(pos) { return this.nextChild(this._tree.children.length - 1, -1, pos, -2 /* Side.Before */); }
713
748
  enter(pos, side, mode = 0) {
714
749
  let mounted;
715
- if (!(mode & IterMode.IgnoreOverlays) && (mounted = this._tree.prop(NodeProp.mounted)) && mounted.overlay) {
750
+ if (!(mode & IterMode.IgnoreOverlays) && (mounted = MountedTree.get(this._tree)) && mounted.overlay) {
716
751
  let rPos = pos - this.from;
717
752
  for (let { from, to } of mounted.overlay) {
718
753
  if ((side > 0 ? from <= rPos : from < rPos) &&
@@ -737,29 +772,12 @@ class TreeNode {
737
772
  get prevSibling() {
738
773
  return this._parent && this.index >= 0 ? this._parent.nextChild(this.index - 1, -1, 0, 4 /* Side.DontCare */) : null;
739
774
  }
740
- cursor(mode = 0) { return new TreeCursor(this, mode); }
741
775
  get tree() { return this._tree; }
742
776
  toTree() { return this._tree; }
743
- resolve(pos, side = 0) {
744
- return resolveNode(this, pos, side, false);
745
- }
746
- resolveInner(pos, side = 0) {
747
- return resolveNode(this, pos, side, true);
748
- }
749
- enterUnfinishedNodesBefore(pos) { return enterUnfinishedNodesBefore(this, pos); }
750
- getChild(type, before = null, after = null) {
751
- let r = getChildren(this, type, before, after);
752
- return r.length ? r[0] : null;
753
- }
754
- getChildren(type, before = null, after = null) {
755
- return getChildren(this, type, before, after);
756
- }
757
777
  /**
758
778
  @internal
759
779
  */
760
780
  toString() { return this._tree.toString(); }
761
- get node() { return this; }
762
- matchContext(context) { return matchNodeContext(this, context); }
763
781
  }
764
782
  function getChildren(node, type, before, after) {
765
783
  let cur = node.cursor(), result = [];
@@ -798,11 +816,12 @@ class BufferContext {
798
816
  this.start = start;
799
817
  }
800
818
  }
801
- class BufferNode {
819
+ class BufferNode extends BaseNode {
802
820
  get name() { return this.type.name; }
803
821
  get from() { return this.context.start + this.context.buffer.buffer[this.index + 1]; }
804
822
  get to() { return this.context.start + this.context.buffer.buffer[this.index + 2]; }
805
823
  constructor(context, _parent, index) {
824
+ super();
806
825
  this.context = context;
807
826
  this._parent = _parent;
808
827
  this.index = index;
@@ -844,7 +863,6 @@ class BufferNode {
844
863
  return this.externalSibling(-1);
845
864
  return new BufferNode(this.context, this._parent, buffer.findChild(parentStart, this.index, -1, 0, 4 /* Side.DontCare */));
846
865
  }
847
- cursor(mode = 0) { return new TreeCursor(this, mode); }
848
866
  get tree() { return null; }
849
867
  toTree() {
850
868
  let children = [], positions = [];
@@ -857,26 +875,57 @@ class BufferNode {
857
875
  }
858
876
  return new Tree(this.type, children, positions, this.to - this.from);
859
877
  }
860
- resolve(pos, side = 0) {
861
- return resolveNode(this, pos, side, false);
862
- }
863
- resolveInner(pos, side = 0) {
864
- return resolveNode(this, pos, side, true);
865
- }
866
- enterUnfinishedNodesBefore(pos) { return enterUnfinishedNodesBefore(this, pos); }
867
878
  /**
868
879
  @internal
869
880
  */
870
881
  toString() { return this.context.buffer.childString(this.index); }
871
- getChild(type, before = null, after = null) {
872
- let r = getChildren(this, type, before, after);
873
- return r.length ? r[0] : null;
882
+ }
883
+ function iterStack(heads) {
884
+ if (!heads.length)
885
+ return null;
886
+ if (heads.length == 1)
887
+ return heads[0];
888
+ let pick = 0, picked = heads[0];
889
+ for (let i = 1; i < heads.length; i++) {
890
+ let node = heads[i];
891
+ if (node.from > picked.from || node.to < picked.to) {
892
+ picked = node;
893
+ pick = i;
894
+ }
874
895
  }
875
- getChildren(type, before = null, after = null) {
876
- return getChildren(this, type, before, after);
896
+ let next = picked instanceof TreeNode && picked.index < 0 ? null : picked.parent;
897
+ let newHeads = heads.slice();
898
+ if (next)
899
+ newHeads[pick] = next;
900
+ else
901
+ newHeads.splice(pick, 1);
902
+ return new StackIterator(newHeads, picked);
903
+ }
904
+ class StackIterator {
905
+ constructor(heads, node) {
906
+ this.heads = heads;
907
+ this.node = node;
877
908
  }
878
- get node() { return this; }
879
- matchContext(context) { return matchNodeContext(this, context); }
909
+ get next() { return iterStack(this.heads); }
910
+ }
911
+ function stackIterator(tree, pos, side) {
912
+ let inner = tree.resolveInner(pos, side), layers = null;
913
+ for (let scan = inner instanceof TreeNode ? inner : inner.context.parent; scan; scan = scan.parent) {
914
+ if (scan.index < 0) { // This is an overlay root
915
+ let parent = scan.parent;
916
+ (layers || (layers = [inner])).push(parent.resolve(pos, side));
917
+ scan = parent;
918
+ }
919
+ else {
920
+ let mount = MountedTree.get(scan.tree);
921
+ // Relevant overlay branching off
922
+ if (mount && mount.overlay && mount.overlay[0].from <= pos && mount.overlay[mount.overlay.length - 1].to >= pos) {
923
+ let root = new TreeNode(mount.tree, mount.overlay[0].from + scan.from, 0, null);
924
+ (layers || (layers = [inner])).push(resolveNode(root, pos, side, false));
925
+ }
926
+ }
927
+ }
928
+ return layers ? iterStack(layers) : inner;
880
929
  }
881
930
  /**
882
931
  A tree cursor object focuses on a given node in a syntax tree, and
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lezer/common",
3
- "version": "1.0.4",
3
+ "version": "1.1.0",
4
4
  "description": "Syntax tree data structure and parser interfaces for the lezer parser",
5
5
  "main": "dist/index.cjs",
6
6
  "type": "module",