@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 +105 -56
- package/dist/index.d.cts +19 -8
- package/dist/index.d.ts +19 -8
- package/dist/index.js +105 -56
- package/package.json +1 -1
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 =
|
|
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
|
|
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
|
|
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
|
-
|
|
874
|
-
|
|
875
|
-
|
|
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
|
-
|
|
878
|
-
|
|
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
|
|
881
|
-
|
|
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 =
|
|
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
|
|
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
|
|
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
|
-
|
|
872
|
-
|
|
873
|
-
|
|
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
|
-
|
|
876
|
-
|
|
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
|
|
879
|
-
|
|
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
|