@lezer/common 0.15.6 → 0.15.10
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 +89 -35
- package/dist/index.js +89 -35
- package/dist/tree.cjs +484 -347
- package/dist/tree.cjs.map +1 -1
- package/dist/tree.d.ts +77 -0
- package/dist/tree.es.js +482 -346
- package/dist/tree.es.js.map +1 -1
- package/package.json +1 -1
package/dist/tree.es.js
CHANGED
|
@@ -1,43 +1,36 @@
|
|
|
1
|
-
|
|
1
|
+
// FIXME profile adding a per-Tree TreeNode cache, validating it by
|
|
2
|
+
// parent pointer
|
|
3
|
+
/// The default maximum length of a `TreeBuffer` node (1024).
|
|
2
4
|
const DefaultBufferLength = 1024;
|
|
3
5
|
let nextPropID = 0;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
class Range {
|
|
7
|
+
constructor(from, to) {
|
|
8
|
+
this.from = from;
|
|
9
|
+
this.to = to;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/// Each [node type](#common.NodeType) or [individual tree](#common.Tree)
|
|
13
|
+
/// can have metadata associated with it in props. Instances of this
|
|
14
|
+
/// class represent prop names.
|
|
7
15
|
class NodeProp {
|
|
8
|
-
/// Create a new node prop type.
|
|
9
|
-
|
|
10
|
-
constructor({ deserialize } = {}) {
|
|
16
|
+
/// Create a new node prop type.
|
|
17
|
+
constructor(config = {}) {
|
|
11
18
|
this.id = nextPropID++;
|
|
12
|
-
this.
|
|
19
|
+
this.perNode = !!config.perNode;
|
|
20
|
+
this.deserialize = config.deserialize || (() => {
|
|
13
21
|
throw new Error("This node type doesn't define a deserialize function");
|
|
14
22
|
});
|
|
15
23
|
}
|
|
16
|
-
/// Create a string-valued node prop whose deserialize function is
|
|
17
|
-
/// the identity function.
|
|
18
|
-
static string() { return new NodeProp({ deserialize: str => str }); }
|
|
19
|
-
/// Create a number-valued node prop whose deserialize function is
|
|
20
|
-
/// just `Number`.
|
|
21
|
-
static number() { return new NodeProp({ deserialize: Number }); }
|
|
22
|
-
/// Creates a boolean-valued node prop whose deserialize function
|
|
23
|
-
/// returns true for any input.
|
|
24
|
-
static flag() { return new NodeProp({ deserialize: () => true }); }
|
|
25
|
-
/// Store a value for this prop in the given object. This can be
|
|
26
|
-
/// useful when building up a prop object to pass to the
|
|
27
|
-
/// [`NodeType`](#tree.NodeType) constructor. Returns its first
|
|
28
|
-
/// argument.
|
|
29
|
-
set(propObj, value) {
|
|
30
|
-
propObj[this.id] = value;
|
|
31
|
-
return propObj;
|
|
32
|
-
}
|
|
33
24
|
/// This is meant to be used with
|
|
34
|
-
/// [`NodeSet.extend`](#
|
|
35
|
-
/// [`
|
|
36
|
-
/// values for each node type in the set. Takes a [match
|
|
37
|
-
/// object](#
|
|
25
|
+
/// [`NodeSet.extend`](#common.NodeSet.extend) or
|
|
26
|
+
/// [`LRParser.configure`](#lr.ParserConfig.props) to compute
|
|
27
|
+
/// prop values for each node type in the set. Takes a [match
|
|
28
|
+
/// object](#common.NodeType^match) or function that returns undefined
|
|
38
29
|
/// if the node type doesn't get this prop, and the prop's value if
|
|
39
30
|
/// it does.
|
|
40
31
|
add(match) {
|
|
32
|
+
if (this.perNode)
|
|
33
|
+
throw new RangeError("Can't add per-node props to node types");
|
|
41
34
|
if (typeof match != "function")
|
|
42
35
|
match = NodeType.match(match);
|
|
43
36
|
return (type) => {
|
|
@@ -51,7 +44,7 @@ class NodeProp {
|
|
|
51
44
|
/// space-separated string when declaring this prop in a grammar)
|
|
52
45
|
/// for the node types of closing delimiters that match it.
|
|
53
46
|
NodeProp.closedBy = new NodeProp({ deserialize: str => str.split(" ") });
|
|
54
|
-
/// The inverse of [`closedBy`](#
|
|
47
|
+
/// The inverse of [`closedBy`](#common.NodeProp^closedBy). This is
|
|
55
48
|
/// attached to closing delimiters, holding an array of node names
|
|
56
49
|
/// of types of matching opening delimiters.
|
|
57
50
|
NodeProp.openedBy = new NodeProp({ deserialize: str => str.split(" ") });
|
|
@@ -59,6 +52,41 @@ NodeProp.openedBy = new NodeProp({ deserialize: str => str.split(" ") });
|
|
|
59
52
|
/// types that represent an expression could be tagged with an
|
|
60
53
|
/// `"Expression"` group).
|
|
61
54
|
NodeProp.group = new NodeProp({ deserialize: str => str.split(" ") });
|
|
55
|
+
/// The hash of the [context](#lr.ContextTracker.constructor)
|
|
56
|
+
/// that the node was parsed in, if any. Used to limit reuse of
|
|
57
|
+
/// contextual nodes.
|
|
58
|
+
NodeProp.contextHash = new NodeProp({ perNode: true });
|
|
59
|
+
/// The distance beyond the end of the node that the tokenizer
|
|
60
|
+
/// looked ahead for any of the tokens inside the node. (The LR
|
|
61
|
+
/// parser only stores this when it is larger than 25, for
|
|
62
|
+
/// efficiency reasons.)
|
|
63
|
+
NodeProp.lookAhead = new NodeProp({ perNode: true });
|
|
64
|
+
/// This per-node prop is used to replace a given node, or part of a
|
|
65
|
+
/// node, with another tree. This is useful to include trees from
|
|
66
|
+
/// different languages.
|
|
67
|
+
NodeProp.mounted = new NodeProp({ perNode: true });
|
|
68
|
+
/// A mounted tree, which can be [stored](#common.NodeProp^mounted) on
|
|
69
|
+
/// a tree node to indicate that parts of its content are
|
|
70
|
+
/// represented by another tree.
|
|
71
|
+
class MountedTree {
|
|
72
|
+
constructor(
|
|
73
|
+
/// The inner tree.
|
|
74
|
+
tree,
|
|
75
|
+
/// If this is null, this tree replaces the entire node (it will
|
|
76
|
+
/// be included in the regular iteration instead of its host
|
|
77
|
+
/// node). If not, only the given ranges are considered to be
|
|
78
|
+
/// covered by this tree. This is used for trees that are mixed in
|
|
79
|
+
/// a way that isn't strictly hierarchical. Such mounted trees are
|
|
80
|
+
/// only entered by [`resolveInner`](#common.Tree.resolveInner)
|
|
81
|
+
/// and [`enter`](#common.SyntaxNode.enter).
|
|
82
|
+
overlay,
|
|
83
|
+
/// The parser used to create this subtree.
|
|
84
|
+
parser) {
|
|
85
|
+
this.tree = tree;
|
|
86
|
+
this.overlay = overlay;
|
|
87
|
+
this.parser = parser;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
62
90
|
const noProps = Object.create(null);
|
|
63
91
|
/// Each node in a syntax tree has a node type associated with it.
|
|
64
92
|
class NodeType {
|
|
@@ -90,8 +118,11 @@ class NodeType {
|
|
|
90
118
|
for (let src of spec.props) {
|
|
91
119
|
if (!Array.isArray(src))
|
|
92
120
|
src = src(type);
|
|
93
|
-
if (src)
|
|
94
|
-
src[0].
|
|
121
|
+
if (src) {
|
|
122
|
+
if (src[0].perNode)
|
|
123
|
+
throw new RangeError("Can't store a per-node prop on a node type");
|
|
124
|
+
props[src[0].id] = src[1];
|
|
125
|
+
}
|
|
95
126
|
}
|
|
96
127
|
return type;
|
|
97
128
|
}
|
|
@@ -108,7 +139,7 @@ class NodeType {
|
|
|
108
139
|
/// named node, for example because it is used to cache repetition.
|
|
109
140
|
get isAnonymous() { return (this.flags & 8 /* Anonymous */) > 0; }
|
|
110
141
|
/// Returns true when this node's name or one of its
|
|
111
|
-
/// [groups](#
|
|
142
|
+
/// [groups](#common.NodeProp^group) matches the given string.
|
|
112
143
|
is(name) {
|
|
113
144
|
if (typeof name == 'string') {
|
|
114
145
|
if (this.name == name)
|
|
@@ -120,8 +151,8 @@ class NodeType {
|
|
|
120
151
|
}
|
|
121
152
|
/// Create a function from node types to arbitrary values by
|
|
122
153
|
/// specifying an object whose property names are node or
|
|
123
|
-
/// [group](#
|
|
124
|
-
/// [`NodeProp.add`](#
|
|
154
|
+
/// [group](#common.NodeProp^group) names. Often useful with
|
|
155
|
+
/// [`NodeProp.add`](#common.NodeProp.add). You can put multiple
|
|
125
156
|
/// names, separated by spaces, in a single property name to map
|
|
126
157
|
/// multiple node names to a single value.
|
|
127
158
|
static match(map) {
|
|
@@ -142,12 +173,11 @@ class NodeType {
|
|
|
142
173
|
NodeType.none = new NodeType("", Object.create(null), 0, 8 /* Anonymous */);
|
|
143
174
|
/// A node set holds a collection of node types. It is used to
|
|
144
175
|
/// compactly represent trees by storing their type ids, rather than a
|
|
145
|
-
/// full pointer to the type object, in a
|
|
146
|
-
/// [has](#
|
|
147
|
-
/// buffers](#
|
|
148
|
-
/// from the same set. A set can have a maximum of 2**16 (65536)
|
|
149
|
-
///
|
|
150
|
-
/// slots.
|
|
176
|
+
/// full pointer to the type object, in a numeric array. Each parser
|
|
177
|
+
/// [has](#lr.LRParser.nodeSet) a node set, and [tree
|
|
178
|
+
/// buffers](#common.TreeBuffer) can only store collections of nodes
|
|
179
|
+
/// from the same set. A set can have a maximum of 2**16 (65536) node
|
|
180
|
+
/// types in it, so that the ids fit into 16-bit typed array slots.
|
|
151
181
|
class NodeSet {
|
|
152
182
|
/// Create a set with the given types. The `id` property of each
|
|
153
183
|
/// type should correspond to its position within the array.
|
|
@@ -161,7 +191,7 @@ class NodeSet {
|
|
|
161
191
|
}
|
|
162
192
|
/// Create a copy of this set with some node properties added. The
|
|
163
193
|
/// arguments to this method should be created with
|
|
164
|
-
/// [`NodeProp.add`](#
|
|
194
|
+
/// [`NodeProp.add`](#common.NodeProp.add).
|
|
165
195
|
extend(...props) {
|
|
166
196
|
let newTypes = [];
|
|
167
197
|
for (let type of this.types) {
|
|
@@ -171,7 +201,7 @@ class NodeSet {
|
|
|
171
201
|
if (add) {
|
|
172
202
|
if (!newProps)
|
|
173
203
|
newProps = Object.assign({}, type.props);
|
|
174
|
-
add[0].
|
|
204
|
+
newProps[add[0].id] = add[1];
|
|
175
205
|
}
|
|
176
206
|
}
|
|
177
207
|
newTypes.push(newProps ? new NodeType(type.name, newProps, type.id, type.flags) : type);
|
|
@@ -179,6 +209,7 @@ class NodeSet {
|
|
|
179
209
|
return new NodeSet(newTypes);
|
|
180
210
|
}
|
|
181
211
|
}
|
|
212
|
+
const CachedNode = new WeakMap();
|
|
182
213
|
/// A piece of syntax tree. There are two ways to approach these
|
|
183
214
|
/// trees: the way they are actually stored in memory, and the
|
|
184
215
|
/// convenient way.
|
|
@@ -189,36 +220,56 @@ class NodeSet {
|
|
|
189
220
|
///
|
|
190
221
|
/// However, when you want to actually work with tree nodes, this
|
|
191
222
|
/// representation is very awkward, so most client code will want to
|
|
192
|
-
/// use the `TreeCursor`
|
|
193
|
-
///
|
|
194
|
-
///
|
|
223
|
+
/// use the [`TreeCursor`](#common.TreeCursor) or
|
|
224
|
+
/// [`SyntaxNode`](#common.SyntaxNode) interface instead, which provides
|
|
225
|
+
/// a view on some part of this data structure, and can be used to
|
|
226
|
+
/// move around to adjacent nodes.
|
|
195
227
|
class Tree {
|
|
196
|
-
/// Construct a new tree.
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
///
|
|
201
|
-
/// further `Tree` instances with their own internal structure.
|
|
228
|
+
/// Construct a new tree. See also [`Tree.build`](#common.Tree^build).
|
|
229
|
+
constructor(
|
|
230
|
+
/// The type of the top node.
|
|
231
|
+
type,
|
|
232
|
+
/// This node's child nodes.
|
|
202
233
|
children,
|
|
203
234
|
/// The positions (offsets relative to the start of this tree) of
|
|
204
235
|
/// the children.
|
|
205
236
|
positions,
|
|
206
237
|
/// The total length of this tree
|
|
207
|
-
length
|
|
238
|
+
length,
|
|
239
|
+
/// Per-node [node props](#common.NodeProp) to associate with this node.
|
|
240
|
+
props) {
|
|
208
241
|
this.type = type;
|
|
209
242
|
this.children = children;
|
|
210
243
|
this.positions = positions;
|
|
211
244
|
this.length = length;
|
|
245
|
+
/// @internal
|
|
246
|
+
this.props = null;
|
|
247
|
+
if (props && props.length) {
|
|
248
|
+
this.props = Object.create(null);
|
|
249
|
+
for (let [prop, value] of props)
|
|
250
|
+
this.props[typeof prop == "number" ? prop : prop.id] = value;
|
|
251
|
+
}
|
|
212
252
|
}
|
|
213
253
|
/// @internal
|
|
214
254
|
toString() {
|
|
215
|
-
let
|
|
255
|
+
let mounted = this.prop(NodeProp.mounted);
|
|
256
|
+
if (mounted && !mounted.overlay)
|
|
257
|
+
return mounted.tree.toString();
|
|
258
|
+
let children = "";
|
|
259
|
+
for (let ch of this.children) {
|
|
260
|
+
let str = ch.toString();
|
|
261
|
+
if (str) {
|
|
262
|
+
if (children)
|
|
263
|
+
children += ",";
|
|
264
|
+
children += str;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
216
267
|
return !this.type.name ? children :
|
|
217
268
|
(/\W/.test(this.type.name) && !this.type.isError ? JSON.stringify(this.type.name) : this.type.name) +
|
|
218
269
|
(children.length ? "(" + children + ")" : "");
|
|
219
270
|
}
|
|
220
|
-
/// Get a [tree cursor](#
|
|
221
|
-
/// `pos` is given, the cursor is [moved](#
|
|
271
|
+
/// Get a [tree cursor](#common.TreeCursor) rooted at this tree. When
|
|
272
|
+
/// `pos` is given, the cursor is [moved](#common.TreeCursor.moveTo)
|
|
222
273
|
/// to the given position and side.
|
|
223
274
|
cursor(pos, side = 0) {
|
|
224
275
|
let scope = (pos != null && CachedNode.get(this)) || this.topNode;
|
|
@@ -229,18 +280,19 @@ class Tree {
|
|
|
229
280
|
}
|
|
230
281
|
return cursor;
|
|
231
282
|
}
|
|
232
|
-
/// Get a [tree cursor](#
|
|
233
|
-
/// cursors, doesn't skip
|
|
234
|
-
/// nodes
|
|
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.
|
|
235
287
|
fullCursor() {
|
|
236
|
-
return new TreeCursor(this.topNode,
|
|
288
|
+
return new TreeCursor(this.topNode, 1 /* Full */);
|
|
237
289
|
}
|
|
238
|
-
/// Get a [syntax node](#
|
|
290
|
+
/// Get a [syntax node](#common.SyntaxNode) object for the top of the
|
|
239
291
|
/// tree.
|
|
240
292
|
get topNode() {
|
|
241
293
|
return new TreeNode(this, 0, 0, null);
|
|
242
294
|
}
|
|
243
|
-
/// Get the [syntax node](#
|
|
295
|
+
/// Get the [syntax node](#common.SyntaxNode) at the given position.
|
|
244
296
|
/// If `side` is -1, this will move into nodes that end at the
|
|
245
297
|
/// position. If 1, it'll move into nodes that start at the
|
|
246
298
|
/// position. With 0, it'll only enter nodes that cover the position
|
|
@@ -248,16 +300,30 @@ class Tree {
|
|
|
248
300
|
resolve(pos, side = 0) {
|
|
249
301
|
return this.cursor(pos, side).node;
|
|
250
302
|
}
|
|
303
|
+
/// Like [`resolve`](#common.Tree.resolve), but will enter
|
|
304
|
+
/// [overlaid](#common.MountedTree.overlay) nodes, producing a syntax node
|
|
305
|
+
/// pointing into the innermost overlaid tree at the given position
|
|
306
|
+
/// (with parent links going through all parent structure, including
|
|
307
|
+
/// the host trees).
|
|
308
|
+
resolveInner(pos, side = 0) {
|
|
309
|
+
let result = this.topNode;
|
|
310
|
+
for (;;) {
|
|
311
|
+
let inner = result.enter(pos, side);
|
|
312
|
+
if (!inner)
|
|
313
|
+
return result;
|
|
314
|
+
result = inner;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
251
317
|
/// Iterate over the tree and its children, calling `enter` for any
|
|
252
318
|
/// node that touches the `from`/`to` region (if given) before
|
|
253
319
|
/// running over such a node's children, and `leave` (if given) when
|
|
254
|
-
/// leaving the node. When `enter` returns `false`,
|
|
255
|
-
///
|
|
320
|
+
/// leaving the node. When `enter` returns `false`, that node will
|
|
321
|
+
/// not have its children iterated over (or `leave` called).
|
|
256
322
|
iterate(spec) {
|
|
257
323
|
let { enter, leave, from = 0, to = this.length } = spec;
|
|
258
|
-
for (let c = this.cursor();;) {
|
|
324
|
+
for (let c = this.cursor(), get = () => c.node;;) {
|
|
259
325
|
let mustLeave = false;
|
|
260
|
-
if (c.from <= to && c.to >= from && (c.type.isAnonymous || enter(c.type, c.from, c.to) !== false)) {
|
|
326
|
+
if (c.from <= to && c.to >= from && (c.type.isAnonymous || enter(c.type, c.from, c.to, get) !== false)) {
|
|
261
327
|
if (c.firstChild())
|
|
262
328
|
continue;
|
|
263
329
|
if (!c.type.isAnonymous)
|
|
@@ -265,7 +331,7 @@ class Tree {
|
|
|
265
331
|
}
|
|
266
332
|
for (;;) {
|
|
267
333
|
if (mustLeave && leave)
|
|
268
|
-
leave(c.type, c.from, c.to);
|
|
334
|
+
leave(c.type, c.from, c.to, get);
|
|
269
335
|
mustLeave = c.type.isAnonymous;
|
|
270
336
|
if (c.nextSibling())
|
|
271
337
|
break;
|
|
@@ -275,10 +341,27 @@ class Tree {
|
|
|
275
341
|
}
|
|
276
342
|
}
|
|
277
343
|
}
|
|
278
|
-
///
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
344
|
+
/// Get the value of the given [node prop](#common.NodeProp) for this
|
|
345
|
+
/// node. Works with both per-node and per-type props.
|
|
346
|
+
prop(prop) {
|
|
347
|
+
return !prop.perNode ? this.type.prop(prop) : this.props ? this.props[prop.id] : undefined;
|
|
348
|
+
}
|
|
349
|
+
/// Returns the node's [per-node props](#common.NodeProp.perNode) in a
|
|
350
|
+
/// format that can be passed to the [`Tree`](#common.Tree)
|
|
351
|
+
/// constructor.
|
|
352
|
+
get propValues() {
|
|
353
|
+
let result = [];
|
|
354
|
+
if (this.props)
|
|
355
|
+
for (let id in this.props)
|
|
356
|
+
result.push([+id, this.props[id]]);
|
|
357
|
+
return result;
|
|
358
|
+
}
|
|
359
|
+
/// Balance the direct children of this tree, producing a copy of
|
|
360
|
+
/// which may have children grouped into subtrees with type
|
|
361
|
+
/// [`NodeType.none`](#common.NodeType^none).
|
|
362
|
+
balance(config = {}) {
|
|
363
|
+
return this.children.length <= 8 /* BranchFactor */ ? this :
|
|
364
|
+
balanceRange(NodeType.none, this.children, this.positions, 0, this.children.length, 0, this.length, (children, positions, length) => new Tree(this.type, children, positions, length, this.propValues), config.makeTree || ((children, positions, length) => new Tree(NodeType.none, children, positions, length)));
|
|
282
365
|
}
|
|
283
366
|
/// Build a tree from a postfix-ordered buffer of node information,
|
|
284
367
|
/// or a cursor over such a buffer.
|
|
@@ -286,35 +369,39 @@ class Tree {
|
|
|
286
369
|
}
|
|
287
370
|
/// The empty tree
|
|
288
371
|
Tree.empty = new Tree(NodeType.none, [], [], 0);
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
return
|
|
372
|
+
class FlatBufferCursor {
|
|
373
|
+
constructor(buffer, index) {
|
|
374
|
+
this.buffer = buffer;
|
|
375
|
+
this.index = index;
|
|
376
|
+
}
|
|
377
|
+
get id() { return this.buffer[this.index - 4]; }
|
|
378
|
+
get start() { return this.buffer[this.index - 3]; }
|
|
379
|
+
get end() { return this.buffer[this.index - 2]; }
|
|
380
|
+
get size() { return this.buffer[this.index - 1]; }
|
|
381
|
+
get pos() { return this.index; }
|
|
382
|
+
next() { this.index -= 4; }
|
|
383
|
+
fork() { return new FlatBufferCursor(this.buffer, this.index); }
|
|
296
384
|
}
|
|
297
385
|
/// Tree buffers contain (type, start, end, endIndex) quads for each
|
|
298
386
|
/// node. In such a buffer, nodes are stored in prefix order (parents
|
|
299
387
|
/// before children, with the endIndex of the parent indicating which
|
|
300
388
|
/// children belong to it)
|
|
301
389
|
class TreeBuffer {
|
|
302
|
-
/// Create a tree buffer
|
|
390
|
+
/// Create a tree buffer.
|
|
303
391
|
constructor(
|
|
304
|
-
///
|
|
392
|
+
/// The buffer's content.
|
|
305
393
|
buffer,
|
|
306
394
|
/// The total length of the group of nodes in the buffer.
|
|
307
395
|
length,
|
|
308
|
-
///
|
|
309
|
-
set
|
|
310
|
-
/// An optional repeat node type associated with the buffer.
|
|
311
|
-
type = NodeType.none) {
|
|
396
|
+
/// The node set used in this buffer.
|
|
397
|
+
set) {
|
|
312
398
|
this.buffer = buffer;
|
|
313
399
|
this.length = length;
|
|
314
400
|
this.set = set;
|
|
315
|
-
this.type = type;
|
|
316
401
|
}
|
|
317
402
|
/// @internal
|
|
403
|
+
get type() { return NodeType.none; }
|
|
404
|
+
/// @internal
|
|
318
405
|
toString() {
|
|
319
406
|
let result = [];
|
|
320
407
|
for (let index = 0; index < this.buffer.length;) {
|
|
@@ -340,25 +427,10 @@ class TreeBuffer {
|
|
|
340
427
|
return result + "(" + children.join(",") + ")";
|
|
341
428
|
}
|
|
342
429
|
/// @internal
|
|
343
|
-
findChild(startIndex, endIndex, dir,
|
|
430
|
+
findChild(startIndex, endIndex, dir, pos, side) {
|
|
344
431
|
let { buffer } = this, pick = -1;
|
|
345
432
|
for (let i = startIndex; i != endIndex; i = buffer[i + 3]) {
|
|
346
|
-
if (
|
|
347
|
-
let start = buffer[i + 1], end = buffer[i + 2];
|
|
348
|
-
if (dir > 0) {
|
|
349
|
-
if (end > after)
|
|
350
|
-
pick = i;
|
|
351
|
-
if (end > after)
|
|
352
|
-
break;
|
|
353
|
-
}
|
|
354
|
-
else {
|
|
355
|
-
if (start < after)
|
|
356
|
-
pick = i;
|
|
357
|
-
if (end >= after)
|
|
358
|
-
break;
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
else {
|
|
433
|
+
if (checkSide(side, pos, buffer[i + 1], buffer[i + 2])) {
|
|
362
434
|
pick = i;
|
|
363
435
|
if (dir > 0)
|
|
364
436
|
break;
|
|
@@ -366,45 +438,107 @@ class TreeBuffer {
|
|
|
366
438
|
}
|
|
367
439
|
return pick;
|
|
368
440
|
}
|
|
441
|
+
/// @internal
|
|
442
|
+
slice(startI, endI, from, to) {
|
|
443
|
+
let b = this.buffer;
|
|
444
|
+
let copy = new Uint16Array(endI - startI);
|
|
445
|
+
for (let i = startI, j = 0; i < endI;) {
|
|
446
|
+
copy[j++] = b[i++];
|
|
447
|
+
copy[j++] = b[i++] - from;
|
|
448
|
+
copy[j++] = b[i++] - from;
|
|
449
|
+
copy[j++] = b[i++] - startI;
|
|
450
|
+
}
|
|
451
|
+
return new TreeBuffer(copy, to - from, this.set);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
function checkSide(side, pos, from, to) {
|
|
455
|
+
switch (side) {
|
|
456
|
+
case -2 /* Before */: return from < pos;
|
|
457
|
+
case -1 /* AtOrBefore */: return to >= pos && from < pos;
|
|
458
|
+
case 0 /* Around */: return from < pos && to > pos;
|
|
459
|
+
case 1 /* AtOrAfter */: return from <= pos && to > pos;
|
|
460
|
+
case 2 /* After */: return to > pos;
|
|
461
|
+
case 4 /* DontCare */: return true;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
function enterUnfinishedNodesBefore(node, pos) {
|
|
465
|
+
let scan = node.childBefore(pos);
|
|
466
|
+
while (scan) {
|
|
467
|
+
let last = scan.lastChild;
|
|
468
|
+
if (!last || last.to != scan.to)
|
|
469
|
+
break;
|
|
470
|
+
if (last.type.isError && last.from == last.to) {
|
|
471
|
+
node = scan;
|
|
472
|
+
scan = last.prevSibling;
|
|
473
|
+
}
|
|
474
|
+
else {
|
|
475
|
+
scan = last;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
return node;
|
|
369
479
|
}
|
|
370
480
|
class TreeNode {
|
|
371
|
-
constructor(node,
|
|
481
|
+
constructor(node, _from,
|
|
482
|
+
// Index in parent node, set to -1 if the node is not a direct child of _parent.node (overlay)
|
|
483
|
+
index, _parent) {
|
|
372
484
|
this.node = node;
|
|
373
|
-
this.
|
|
485
|
+
this._from = _from;
|
|
374
486
|
this.index = index;
|
|
375
487
|
this._parent = _parent;
|
|
376
488
|
}
|
|
377
489
|
get type() { return this.node.type; }
|
|
378
490
|
get name() { return this.node.type.name; }
|
|
379
|
-
get
|
|
380
|
-
|
|
491
|
+
get from() { return this._from; }
|
|
492
|
+
get to() { return this._from + this.node.length; }
|
|
493
|
+
nextChild(i, dir, pos, side, mode = 0) {
|
|
381
494
|
for (let parent = this;;) {
|
|
382
495
|
for (let { children, positions } = parent.node, e = dir > 0 ? children.length : -1; i != e; i += dir) {
|
|
383
|
-
let next = children[i], start = positions[i] + parent.
|
|
384
|
-
if (
|
|
496
|
+
let next = children[i], start = positions[i] + parent._from;
|
|
497
|
+
if (!checkSide(side, pos, start, start + next.length))
|
|
385
498
|
continue;
|
|
386
499
|
if (next instanceof TreeBuffer) {
|
|
387
|
-
|
|
500
|
+
if (mode & 2 /* NoEnterBuffer */)
|
|
501
|
+
continue;
|
|
502
|
+
let index = next.findChild(0, next.buffer.length, dir, pos - start, side);
|
|
388
503
|
if (index > -1)
|
|
389
504
|
return new BufferNode(new BufferContext(parent, next, i, start), null, index);
|
|
390
505
|
}
|
|
391
|
-
else if (
|
|
506
|
+
else if ((mode & 1 /* Full */) || (!next.type.isAnonymous || hasChild(next))) {
|
|
507
|
+
let mounted;
|
|
508
|
+
if (!(mode & 1 /* Full */) && next.props && (mounted = next.prop(NodeProp.mounted)) && !mounted.overlay)
|
|
509
|
+
return new TreeNode(mounted.tree, start, i, parent);
|
|
392
510
|
let inner = new TreeNode(next, start, i, parent);
|
|
393
|
-
return
|
|
511
|
+
return (mode & 1 /* Full */) || !inner.type.isAnonymous ? inner
|
|
512
|
+
: inner.nextChild(dir < 0 ? next.children.length - 1 : 0, dir, pos, side);
|
|
394
513
|
}
|
|
395
514
|
}
|
|
396
|
-
if (
|
|
515
|
+
if ((mode & 1 /* Full */) || !parent.type.isAnonymous)
|
|
397
516
|
return null;
|
|
398
|
-
|
|
517
|
+
if (parent.index >= 0)
|
|
518
|
+
i = parent.index + dir;
|
|
519
|
+
else
|
|
520
|
+
i = dir < 0 ? -1 : parent._parent.node.children.length;
|
|
399
521
|
parent = parent._parent;
|
|
400
522
|
if (!parent)
|
|
401
523
|
return null;
|
|
402
524
|
}
|
|
403
525
|
}
|
|
404
|
-
get firstChild() { return this.nextChild(0, 1,
|
|
405
|
-
get lastChild() { return this.nextChild(this.node.children.length - 1, -1,
|
|
406
|
-
childAfter(pos) { return this.nextChild(0, 1, pos); }
|
|
407
|
-
childBefore(pos) { return this.nextChild(this.node.children.length - 1, -1, pos); }
|
|
526
|
+
get firstChild() { return this.nextChild(0, 1, 0, 4 /* DontCare */); }
|
|
527
|
+
get lastChild() { return this.nextChild(this.node.children.length - 1, -1, 0, 4 /* DontCare */); }
|
|
528
|
+
childAfter(pos) { return this.nextChild(0, 1, pos, 2 /* After */); }
|
|
529
|
+
childBefore(pos) { return this.nextChild(this.node.children.length - 1, -1, pos, -2 /* Before */); }
|
|
530
|
+
enter(pos, side, overlays = true, buffers = true) {
|
|
531
|
+
let mounted;
|
|
532
|
+
if (overlays && (mounted = this.node.prop(NodeProp.mounted)) && mounted.overlay) {
|
|
533
|
+
let rPos = pos - this.from;
|
|
534
|
+
for (let { from, to } of mounted.overlay) {
|
|
535
|
+
if ((side > 0 ? from <= rPos : from < rPos) &&
|
|
536
|
+
(side < 0 ? to >= rPos : to > rPos))
|
|
537
|
+
return new TreeNode(mounted.tree, mounted.overlay[0].from + this.from, -1, this);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
return this.nextChild(0, 1, pos, side, buffers ? 0 : 2 /* NoEnterBuffer */);
|
|
541
|
+
}
|
|
408
542
|
nextSignificantParent() {
|
|
409
543
|
let val = this;
|
|
410
544
|
while (val.type.isAnonymous && val._parent)
|
|
@@ -415,15 +549,18 @@ class TreeNode {
|
|
|
415
549
|
return this._parent ? this._parent.nextSignificantParent() : null;
|
|
416
550
|
}
|
|
417
551
|
get nextSibling() {
|
|
418
|
-
return this._parent ? this._parent.nextChild(this.index + 1, 1,
|
|
552
|
+
return this._parent && this.index >= 0 ? this._parent.nextChild(this.index + 1, 1, 0, 4 /* DontCare */) : null;
|
|
419
553
|
}
|
|
420
554
|
get prevSibling() {
|
|
421
|
-
return this._parent ? this._parent.nextChild(this.index - 1, -1,
|
|
555
|
+
return this._parent && this.index >= 0 ? this._parent.nextChild(this.index - 1, -1, 0, 4 /* DontCare */) : null;
|
|
422
556
|
}
|
|
423
557
|
get cursor() { return new TreeCursor(this); }
|
|
558
|
+
get tree() { return this.node; }
|
|
559
|
+
toTree() { return this.node; }
|
|
424
560
|
resolve(pos, side = 0) {
|
|
425
561
|
return this.cursor.moveTo(pos, side).node;
|
|
426
562
|
}
|
|
563
|
+
enterUnfinishedNodesBefore(pos) { return enterUnfinishedNodesBefore(this, pos); }
|
|
427
564
|
getChild(type, before = null, after = null) {
|
|
428
565
|
let r = getChildren(this, type, before, after);
|
|
429
566
|
return r.length ? r[0] : null;
|
|
@@ -469,20 +606,27 @@ class BufferNode {
|
|
|
469
606
|
get name() { return this.type.name; }
|
|
470
607
|
get from() { return this.context.start + this.context.buffer.buffer[this.index + 1]; }
|
|
471
608
|
get to() { return this.context.start + this.context.buffer.buffer[this.index + 2]; }
|
|
472
|
-
child(dir,
|
|
609
|
+
child(dir, pos, side) {
|
|
610
|
+
let { buffer } = this.context;
|
|
611
|
+
let index = buffer.findChild(this.index + 4, buffer.buffer[this.index + 3], dir, pos - this.context.start, side);
|
|
612
|
+
return index < 0 ? null : new BufferNode(this.context, this, index);
|
|
613
|
+
}
|
|
614
|
+
get firstChild() { return this.child(1, 0, 4 /* DontCare */); }
|
|
615
|
+
get lastChild() { return this.child(-1, 0, 4 /* DontCare */); }
|
|
616
|
+
childAfter(pos) { return this.child(1, pos, 2 /* After */); }
|
|
617
|
+
childBefore(pos) { return this.child(-1, pos, -2 /* Before */); }
|
|
618
|
+
enter(pos, side, overlays, buffers = true) {
|
|
619
|
+
if (!buffers)
|
|
620
|
+
return null;
|
|
473
621
|
let { buffer } = this.context;
|
|
474
|
-
let index = buffer.findChild(this.index + 4, buffer.buffer[this.index + 3],
|
|
622
|
+
let index = buffer.findChild(this.index + 4, buffer.buffer[this.index + 3], side > 0 ? 1 : -1, pos - this.context.start, side);
|
|
475
623
|
return index < 0 ? null : new BufferNode(this.context, this, index);
|
|
476
624
|
}
|
|
477
|
-
get firstChild() { return this.child(1, -100000000 /* None */); }
|
|
478
|
-
get lastChild() { return this.child(-1, -100000000 /* None */); }
|
|
479
|
-
childAfter(pos) { return this.child(1, pos); }
|
|
480
|
-
childBefore(pos) { return this.child(-1, pos); }
|
|
481
625
|
get parent() {
|
|
482
626
|
return this._parent || this.context.parent.nextSignificantParent();
|
|
483
627
|
}
|
|
484
628
|
externalSibling(dir) {
|
|
485
|
-
return this._parent ? null : this.context.parent.nextChild(this.context.index + dir, dir,
|
|
629
|
+
return this._parent ? null : this.context.parent.nextChild(this.context.index + dir, dir, 0, 4 /* DontCare */);
|
|
486
630
|
}
|
|
487
631
|
get nextSibling() {
|
|
488
632
|
let { buffer } = this.context;
|
|
@@ -496,12 +640,25 @@ class BufferNode {
|
|
|
496
640
|
let parentStart = this._parent ? this._parent.index + 4 : 0;
|
|
497
641
|
if (this.index == parentStart)
|
|
498
642
|
return this.externalSibling(-1);
|
|
499
|
-
return new BufferNode(this.context, this._parent, buffer.findChild(parentStart, this.index, -1,
|
|
643
|
+
return new BufferNode(this.context, this._parent, buffer.findChild(parentStart, this.index, -1, 0, 4 /* DontCare */));
|
|
500
644
|
}
|
|
501
645
|
get cursor() { return new TreeCursor(this); }
|
|
646
|
+
get tree() { return null; }
|
|
647
|
+
toTree() {
|
|
648
|
+
let children = [], positions = [];
|
|
649
|
+
let { buffer } = this.context;
|
|
650
|
+
let startI = this.index + 4, endI = buffer.buffer[this.index + 3];
|
|
651
|
+
if (endI > startI) {
|
|
652
|
+
let from = buffer.buffer[this.index + 1], to = buffer.buffer[this.index + 2];
|
|
653
|
+
children.push(buffer.slice(startI, endI, from, to));
|
|
654
|
+
positions.push(0);
|
|
655
|
+
}
|
|
656
|
+
return new Tree(this.type, children, positions, this.to - this.from);
|
|
657
|
+
}
|
|
502
658
|
resolve(pos, side = 0) {
|
|
503
659
|
return this.cursor.moveTo(pos, side).node;
|
|
504
660
|
}
|
|
661
|
+
enterUnfinishedNodesBefore(pos) { return enterUnfinishedNodesBefore(this, pos); }
|
|
505
662
|
/// @internal
|
|
506
663
|
toString() { return this.context.buffer.childString(this.index); }
|
|
507
664
|
getChild(type, before = null, after = null) {
|
|
@@ -516,8 +673,10 @@ class BufferNode {
|
|
|
516
673
|
/// allows you to move to adjacent nodes.
|
|
517
674
|
class TreeCursor {
|
|
518
675
|
/// @internal
|
|
519
|
-
constructor(node,
|
|
520
|
-
|
|
676
|
+
constructor(node,
|
|
677
|
+
/// @internal
|
|
678
|
+
mode = 0) {
|
|
679
|
+
this.mode = mode;
|
|
521
680
|
this.buffer = null;
|
|
522
681
|
this.stack = [];
|
|
523
682
|
this.index = 0;
|
|
@@ -568,11 +727,11 @@ class TreeCursor {
|
|
|
568
727
|
return this.buffer ? this.buffer.buffer.childString(this.index) : this._tree.toString();
|
|
569
728
|
}
|
|
570
729
|
/// @internal
|
|
571
|
-
|
|
730
|
+
enterChild(dir, pos, side) {
|
|
572
731
|
if (!this.buffer)
|
|
573
|
-
return this.yield(this._tree.nextChild(dir < 0 ? this._tree.node.children.length - 1 : 0, dir,
|
|
732
|
+
return this.yield(this._tree.nextChild(dir < 0 ? this._tree.node.children.length - 1 : 0, dir, pos, side, this.mode));
|
|
574
733
|
let { buffer } = this.buffer;
|
|
575
|
-
let index = buffer.findChild(this.index + 4, buffer.buffer[this.index + 3], dir,
|
|
734
|
+
let index = buffer.findChild(this.index + 4, buffer.buffer[this.index + 3], dir, pos - this.buffer.start, side);
|
|
576
735
|
if (index < 0)
|
|
577
736
|
return false;
|
|
578
737
|
this.stack.push(this.index);
|
|
@@ -580,20 +739,30 @@ class TreeCursor {
|
|
|
580
739
|
}
|
|
581
740
|
/// Move the cursor to this node's first child. When this returns
|
|
582
741
|
/// false, the node has no child, and the cursor has not been moved.
|
|
583
|
-
firstChild() { return this.
|
|
742
|
+
firstChild() { return this.enterChild(1, 0, 4 /* DontCare */); }
|
|
584
743
|
/// Move the cursor to this node's last child.
|
|
585
|
-
lastChild() { return this.
|
|
586
|
-
/// Move the cursor to the first child that
|
|
587
|
-
childAfter(pos) { return this.
|
|
588
|
-
/// Move to the last child that
|
|
589
|
-
childBefore(pos) { return this.
|
|
590
|
-
/// Move the
|
|
744
|
+
lastChild() { return this.enterChild(-1, 0, 4 /* DontCare */); }
|
|
745
|
+
/// Move the cursor to the first child that ends after `pos`.
|
|
746
|
+
childAfter(pos) { return this.enterChild(1, pos, 2 /* After */); }
|
|
747
|
+
/// Move to the last child that starts before `pos`.
|
|
748
|
+
childBefore(pos) { return this.enterChild(-1, pos, -2 /* Before */); }
|
|
749
|
+
/// Move the cursor to the child around `pos`. If side is -1 the
|
|
750
|
+
/// child may end at that position, when 1 it may start there. This
|
|
751
|
+
/// will also enter [overlaid](#common.MountedTree.overlay)
|
|
752
|
+
/// [mounted](#common.NodeProp^mounted) trees unless `overlays` is
|
|
753
|
+
/// set to false.
|
|
754
|
+
enter(pos, side, overlays = true, buffers = true) {
|
|
755
|
+
if (!this.buffer)
|
|
756
|
+
return this.yield(this._tree.enter(pos, side, overlays && !(this.mode & 1 /* Full */), buffers));
|
|
757
|
+
return buffers ? this.enterChild(1, pos, side) : false;
|
|
758
|
+
}
|
|
759
|
+
/// Move to the node's parent node, if this isn't the top node.
|
|
591
760
|
parent() {
|
|
592
761
|
if (!this.buffer)
|
|
593
|
-
return this.yieldNode(this.
|
|
762
|
+
return this.yieldNode((this.mode & 1 /* Full */) ? this._tree._parent : this._tree.parent);
|
|
594
763
|
if (this.stack.length)
|
|
595
764
|
return this.yieldBuf(this.stack.pop());
|
|
596
|
-
let parent = this.
|
|
765
|
+
let parent = (this.mode & 1 /* Full */) ? this.buffer.parent : this.buffer.parent.nextSignificantParent();
|
|
597
766
|
this.buffer = null;
|
|
598
767
|
return this.yieldNode(parent);
|
|
599
768
|
}
|
|
@@ -601,19 +770,20 @@ class TreeCursor {
|
|
|
601
770
|
sibling(dir) {
|
|
602
771
|
if (!this.buffer)
|
|
603
772
|
return !this._tree._parent ? false
|
|
604
|
-
: this.yield(this._tree.
|
|
773
|
+
: this.yield(this._tree.index < 0 ? null
|
|
774
|
+
: this._tree._parent.nextChild(this._tree.index + dir, dir, 0, 4 /* DontCare */, this.mode));
|
|
605
775
|
let { buffer } = this.buffer, d = this.stack.length - 1;
|
|
606
776
|
if (dir < 0) {
|
|
607
777
|
let parentStart = d < 0 ? 0 : this.stack[d] + 4;
|
|
608
778
|
if (this.index != parentStart)
|
|
609
|
-
return this.yieldBuf(buffer.findChild(parentStart, this.index, -1,
|
|
779
|
+
return this.yieldBuf(buffer.findChild(parentStart, this.index, -1, 0, 4 /* DontCare */));
|
|
610
780
|
}
|
|
611
781
|
else {
|
|
612
782
|
let after = buffer.buffer[this.index + 3];
|
|
613
783
|
if (after < (d < 0 ? buffer.buffer.length : buffer.buffer[this.stack[d] + 3]))
|
|
614
784
|
return this.yieldBuf(after);
|
|
615
785
|
}
|
|
616
|
-
return d < 0 ? this.yield(this.buffer.parent.nextChild(this.buffer.index + dir, dir,
|
|
786
|
+
return d < 0 ? this.yield(this.buffer.parent.nextChild(this.buffer.index + dir, dir, 0, 4 /* DontCare */, this.mode)) : false;
|
|
617
787
|
}
|
|
618
788
|
/// Move to this node's next sibling, if any.
|
|
619
789
|
nextSibling() { return this.sibling(1); }
|
|
@@ -637,16 +807,17 @@ class TreeCursor {
|
|
|
637
807
|
({ index, _parent: parent } = this._tree);
|
|
638
808
|
}
|
|
639
809
|
for (; parent; { index, _parent: parent } = parent) {
|
|
640
|
-
|
|
641
|
-
let
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
810
|
+
if (index > -1)
|
|
811
|
+
for (let i = index + dir, e = dir < 0 ? -1 : parent.node.children.length; i != e; i += dir) {
|
|
812
|
+
let child = parent.node.children[i];
|
|
813
|
+
if ((this.mode & 1 /* Full */) || child instanceof TreeBuffer || !child.type.isAnonymous || hasChild(child))
|
|
814
|
+
return false;
|
|
815
|
+
}
|
|
645
816
|
}
|
|
646
817
|
return true;
|
|
647
818
|
}
|
|
648
|
-
move(dir) {
|
|
649
|
-
if (this.
|
|
819
|
+
move(dir, enter) {
|
|
820
|
+
if (enter && this.enterChild(dir, 0, 4 /* DontCare */))
|
|
650
821
|
return true;
|
|
651
822
|
for (;;) {
|
|
652
823
|
if (this.sibling(dir))
|
|
@@ -658,14 +829,14 @@ class TreeCursor {
|
|
|
658
829
|
/// Move to the next node in a
|
|
659
830
|
/// [pre-order](https://en.wikipedia.org/wiki/Tree_traversal#Pre-order_(NLR))
|
|
660
831
|
/// traversal, going from a node to its first child or, if the
|
|
661
|
-
/// current node is empty
|
|
662
|
-
/// the first parent node that has one.
|
|
663
|
-
next() { return this.move(1); }
|
|
832
|
+
/// current node is empty or `enter` is false, its next sibling or
|
|
833
|
+
/// the next sibling of the first parent node that has one.
|
|
834
|
+
next(enter = true) { return this.move(1, enter); }
|
|
664
835
|
/// Move to the next node in a last-to-first pre-order traveral. A
|
|
665
|
-
/// node is followed by
|
|
836
|
+
/// node is followed by its last child or, if it has none, its
|
|
666
837
|
/// previous sibling or the previous sibling of the first parent
|
|
667
838
|
/// node that has one.
|
|
668
|
-
prev() { return this.move(-1); }
|
|
839
|
+
prev(enter = true) { return this.move(-1, enter); }
|
|
669
840
|
/// Move the cursor to the innermost node that covers `pos`. If
|
|
670
841
|
/// `side` is -1, it will enter nodes that end at `pos`. If it is 1,
|
|
671
842
|
/// it will enter nodes that start at `pos`.
|
|
@@ -677,19 +848,10 @@ class TreeCursor {
|
|
|
677
848
|
if (!this.parent())
|
|
678
849
|
break;
|
|
679
850
|
// Then scan down into child nodes as far as possible
|
|
680
|
-
|
|
681
|
-
if (side < 0 ? !this.childBefore(pos) : !this.childAfter(pos))
|
|
682
|
-
break;
|
|
683
|
-
if (this.from == this.to ||
|
|
684
|
-
(side < 1 ? this.from >= pos : this.from > pos) ||
|
|
685
|
-
(side > -1 ? this.to <= pos : this.to < pos)) {
|
|
686
|
-
this.parent();
|
|
687
|
-
break;
|
|
688
|
-
}
|
|
689
|
-
}
|
|
851
|
+
while (this.enterChild(1, pos, side)) { }
|
|
690
852
|
return this;
|
|
691
853
|
}
|
|
692
|
-
/// Get a [syntax node](#
|
|
854
|
+
/// Get a [syntax node](#common.SyntaxNode) at the cursor's current
|
|
693
855
|
/// position.
|
|
694
856
|
get node() {
|
|
695
857
|
if (!this.buffer)
|
|
@@ -712,58 +874,54 @@ class TreeCursor {
|
|
|
712
874
|
result = new BufferNode(this.buffer, result, this.stack[i]);
|
|
713
875
|
return this.bufferNode = new BufferNode(this.buffer, result, this.index);
|
|
714
876
|
}
|
|
715
|
-
/// Get the [tree](#
|
|
877
|
+
/// Get the [tree](#common.Tree) that represents the current node, if
|
|
716
878
|
/// any. Will return null when the node is in a [tree
|
|
717
|
-
/// buffer](#
|
|
879
|
+
/// buffer](#common.TreeBuffer).
|
|
718
880
|
get tree() {
|
|
719
881
|
return this.buffer ? null : this._tree.node;
|
|
720
882
|
}
|
|
721
883
|
}
|
|
722
884
|
function hasChild(tree) {
|
|
723
|
-
return tree.children.some(ch => !ch.type.isAnonymous ||
|
|
885
|
+
return tree.children.some(ch => ch instanceof TreeBuffer || !ch.type.isAnonymous || hasChild(ch));
|
|
724
886
|
}
|
|
725
|
-
class FlatBufferCursor {
|
|
726
|
-
constructor(buffer, index) {
|
|
727
|
-
this.buffer = buffer;
|
|
728
|
-
this.index = index;
|
|
729
|
-
}
|
|
730
|
-
get id() { return this.buffer[this.index - 4]; }
|
|
731
|
-
get start() { return this.buffer[this.index - 3]; }
|
|
732
|
-
get end() { return this.buffer[this.index - 2]; }
|
|
733
|
-
get size() { return this.buffer[this.index - 1]; }
|
|
734
|
-
get pos() { return this.index; }
|
|
735
|
-
next() { this.index -= 4; }
|
|
736
|
-
fork() { return new FlatBufferCursor(this.buffer, this.index); }
|
|
737
|
-
}
|
|
738
|
-
const BalanceBranchFactor = 8;
|
|
739
887
|
function buildTree(data) {
|
|
740
888
|
var _a;
|
|
741
|
-
let { buffer, nodeSet,
|
|
889
|
+
let { buffer, nodeSet, maxBufferLength = DefaultBufferLength, reused = [], minRepeatType = nodeSet.types.length } = data;
|
|
742
890
|
let cursor = Array.isArray(buffer) ? new FlatBufferCursor(buffer, buffer.length) : buffer;
|
|
743
891
|
let types = nodeSet.types;
|
|
744
|
-
let contextHash = 0;
|
|
892
|
+
let contextHash = 0, lookAhead = 0;
|
|
745
893
|
function takeNode(parentStart, minPos, children, positions, inRepeat) {
|
|
746
894
|
let { id, start, end, size } = cursor;
|
|
747
|
-
let
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
895
|
+
let lookAheadAtStart = lookAhead;
|
|
896
|
+
while (size < 0) {
|
|
897
|
+
cursor.next();
|
|
898
|
+
if (size == -1 /* Reuse */) {
|
|
899
|
+
let node = reused[id];
|
|
900
|
+
children.push(node);
|
|
901
|
+
positions.push(start - parentStart);
|
|
902
|
+
return;
|
|
752
903
|
}
|
|
753
|
-
else { // Context change
|
|
904
|
+
else if (size == -3 /* ContextChange */) { // Context change
|
|
754
905
|
contextHash = id;
|
|
906
|
+
return;
|
|
907
|
+
}
|
|
908
|
+
else if (size == -4 /* LookAhead */) {
|
|
909
|
+
lookAhead = id;
|
|
910
|
+
return;
|
|
911
|
+
}
|
|
912
|
+
else {
|
|
913
|
+
throw new RangeError(`Unrecognized record size: ${size}`);
|
|
755
914
|
}
|
|
756
|
-
cursor.next();
|
|
757
|
-
return;
|
|
758
915
|
}
|
|
759
916
|
let type = types[id], node, buffer;
|
|
917
|
+
let startPos = start - parentStart;
|
|
760
918
|
if (end - start <= maxBufferLength && (buffer = findBufferSize(cursor.pos - minPos, inRepeat))) {
|
|
761
919
|
// Small enough for a buffer, and no reused nodes inside
|
|
762
920
|
let data = new Uint16Array(buffer.size - buffer.skip);
|
|
763
921
|
let endPos = cursor.pos - buffer.size, index = data.length;
|
|
764
922
|
while (cursor.pos > endPos)
|
|
765
|
-
index = copyToBuffer(buffer.start, data, index
|
|
766
|
-
node = new TreeBuffer(data, end - buffer.start, nodeSet
|
|
923
|
+
index = copyToBuffer(buffer.start, data, index);
|
|
924
|
+
node = new TreeBuffer(data, end - buffer.start, nodeSet);
|
|
767
925
|
startPos = buffer.start - parentStart;
|
|
768
926
|
}
|
|
769
927
|
else { // Make it a node
|
|
@@ -771,22 +929,67 @@ function buildTree(data) {
|
|
|
771
929
|
cursor.next();
|
|
772
930
|
let localChildren = [], localPositions = [];
|
|
773
931
|
let localInRepeat = id >= minRepeatType ? id : -1;
|
|
932
|
+
let lastGroup = 0, lastEnd = end;
|
|
774
933
|
while (cursor.pos > endPos) {
|
|
775
|
-
if (cursor.id == localInRepeat)
|
|
934
|
+
if (localInRepeat >= 0 && cursor.id == localInRepeat && cursor.size >= 0) {
|
|
935
|
+
if (cursor.end <= lastEnd - maxBufferLength) {
|
|
936
|
+
makeRepeatLeaf(localChildren, localPositions, start, lastGroup, cursor.end, lastEnd, localInRepeat, lookAheadAtStart);
|
|
937
|
+
lastGroup = localChildren.length;
|
|
938
|
+
lastEnd = cursor.end;
|
|
939
|
+
}
|
|
776
940
|
cursor.next();
|
|
777
|
-
|
|
941
|
+
}
|
|
942
|
+
else {
|
|
778
943
|
takeNode(start, endPos, localChildren, localPositions, localInRepeat);
|
|
944
|
+
}
|
|
779
945
|
}
|
|
946
|
+
if (localInRepeat >= 0 && lastGroup > 0 && lastGroup < localChildren.length)
|
|
947
|
+
makeRepeatLeaf(localChildren, localPositions, start, lastGroup, start, lastEnd, localInRepeat, lookAheadAtStart);
|
|
780
948
|
localChildren.reverse();
|
|
781
949
|
localPositions.reverse();
|
|
782
|
-
if (localInRepeat > -1 &&
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
950
|
+
if (localInRepeat > -1 && lastGroup > 0) {
|
|
951
|
+
let make = makeBalanced(type);
|
|
952
|
+
node = balanceRange(type, localChildren, localPositions, 0, localChildren.length, 0, end - start, make, make);
|
|
953
|
+
}
|
|
954
|
+
else {
|
|
955
|
+
node = makeTree(type, localChildren, localPositions, end - start, lookAheadAtStart - end);
|
|
956
|
+
}
|
|
786
957
|
}
|
|
787
958
|
children.push(node);
|
|
788
959
|
positions.push(startPos);
|
|
789
960
|
}
|
|
961
|
+
function makeBalanced(type) {
|
|
962
|
+
return (children, positions, length) => {
|
|
963
|
+
let lookAhead = 0, lastI = children.length - 1, last, lookAheadProp;
|
|
964
|
+
if (lastI >= 0 && (last = children[lastI]) instanceof Tree) {
|
|
965
|
+
if (!lastI && last.type == type && last.length == length)
|
|
966
|
+
return last;
|
|
967
|
+
if (lookAheadProp = last.prop(NodeProp.lookAhead))
|
|
968
|
+
lookAhead = positions[lastI] + last.length + lookAheadProp;
|
|
969
|
+
}
|
|
970
|
+
return makeTree(type, children, positions, length, lookAhead);
|
|
971
|
+
};
|
|
972
|
+
}
|
|
973
|
+
function makeRepeatLeaf(children, positions, base, i, from, to, type, lookAhead) {
|
|
974
|
+
let localChildren = [], localPositions = [];
|
|
975
|
+
while (children.length > i) {
|
|
976
|
+
localChildren.push(children.pop());
|
|
977
|
+
localPositions.push(positions.pop() + base - from);
|
|
978
|
+
}
|
|
979
|
+
children.push(makeTree(nodeSet.types[type], localChildren, localPositions, to - from, lookAhead - to));
|
|
980
|
+
positions.push(from - base);
|
|
981
|
+
}
|
|
982
|
+
function makeTree(type, children, positions, length, lookAhead = 0, props) {
|
|
983
|
+
if (contextHash) {
|
|
984
|
+
let pair = [NodeProp.contextHash, contextHash];
|
|
985
|
+
props = props ? [pair].concat(props) : [pair];
|
|
986
|
+
}
|
|
987
|
+
if (lookAhead > 25) {
|
|
988
|
+
let pair = [NodeProp.lookAhead, lookAhead];
|
|
989
|
+
props = props ? [pair].concat(props) : [pair];
|
|
990
|
+
}
|
|
991
|
+
return new Tree(type, children, positions, length, props);
|
|
992
|
+
}
|
|
790
993
|
function findBufferSize(maxSize, inRepeat) {
|
|
791
994
|
// Scan through the buffer to find previous siblings that fit
|
|
792
995
|
// together in a TreeBuffer, and don't contain any reused nodes
|
|
@@ -798,8 +1001,9 @@ function buildTree(data) {
|
|
|
798
1001
|
let size = 0, start = 0, skip = 0, minStart = fork.end - maxBufferLength;
|
|
799
1002
|
let result = { size: 0, start: 0, skip: 0 };
|
|
800
1003
|
scan: for (let minPos = fork.pos - maxSize; fork.pos > minPos;) {
|
|
1004
|
+
let nodeSize = fork.size;
|
|
801
1005
|
// Pretend nested repeat nodes of the same type don't exist
|
|
802
|
-
if (fork.id == inRepeat) {
|
|
1006
|
+
if (fork.id == inRepeat && nodeSize >= 0) {
|
|
803
1007
|
// Except that we store the current state as a valid return
|
|
804
1008
|
// value.
|
|
805
1009
|
result.size = size;
|
|
@@ -810,17 +1014,22 @@ function buildTree(data) {
|
|
|
810
1014
|
fork.next();
|
|
811
1015
|
continue;
|
|
812
1016
|
}
|
|
813
|
-
let
|
|
1017
|
+
let startPos = fork.pos - nodeSize;
|
|
814
1018
|
if (nodeSize < 0 || startPos < minPos || fork.start < minStart)
|
|
815
1019
|
break;
|
|
816
1020
|
let localSkipped = fork.id >= minRepeatType ? 4 : 0;
|
|
817
1021
|
let nodeStart = fork.start;
|
|
818
1022
|
fork.next();
|
|
819
1023
|
while (fork.pos > startPos) {
|
|
820
|
-
if (fork.size < 0)
|
|
821
|
-
|
|
822
|
-
|
|
1024
|
+
if (fork.size < 0) {
|
|
1025
|
+
if (fork.size == -3 /* ContextChange */)
|
|
1026
|
+
localSkipped += 4;
|
|
1027
|
+
else
|
|
1028
|
+
break scan;
|
|
1029
|
+
}
|
|
1030
|
+
else if (fork.id >= minRepeatType) {
|
|
823
1031
|
localSkipped += 4;
|
|
1032
|
+
}
|
|
824
1033
|
fork.next();
|
|
825
1034
|
}
|
|
826
1035
|
start = nodeStart;
|
|
@@ -834,174 +1043,101 @@ function buildTree(data) {
|
|
|
834
1043
|
}
|
|
835
1044
|
return result.size > 4 ? result : undefined;
|
|
836
1045
|
}
|
|
837
|
-
function copyToBuffer(bufferStart, buffer, index
|
|
1046
|
+
function copyToBuffer(bufferStart, buffer, index) {
|
|
838
1047
|
let { id, start, end, size } = cursor;
|
|
839
1048
|
cursor.next();
|
|
840
|
-
if (id
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
}
|
|
848
|
-
if (id < minRepeatType) { // Don't copy repeat nodes into buffers
|
|
1049
|
+
if (size >= 0 && id < minRepeatType) {
|
|
1050
|
+
let startIndex = index;
|
|
1051
|
+
if (size > 4) {
|
|
1052
|
+
let endPos = cursor.pos - (size - 4);
|
|
1053
|
+
while (cursor.pos > endPos)
|
|
1054
|
+
index = copyToBuffer(bufferStart, buffer, index);
|
|
1055
|
+
}
|
|
849
1056
|
buffer[--index] = startIndex;
|
|
850
1057
|
buffer[--index] = end - bufferStart;
|
|
851
1058
|
buffer[--index] = start - bufferStart;
|
|
852
1059
|
buffer[--index] = id;
|
|
853
1060
|
}
|
|
1061
|
+
else if (size == -3 /* ContextChange */) {
|
|
1062
|
+
contextHash = id;
|
|
1063
|
+
}
|
|
1064
|
+
else if (size == -4 /* LookAhead */) {
|
|
1065
|
+
lookAhead = id;
|
|
1066
|
+
}
|
|
854
1067
|
return index;
|
|
855
1068
|
}
|
|
856
1069
|
let children = [], positions = [];
|
|
857
1070
|
while (cursor.pos > 0)
|
|
858
|
-
takeNode(data.start || 0, 0, children, positions, -1);
|
|
1071
|
+
takeNode(data.start || 0, data.bufferStart || 0, children, positions, -1);
|
|
859
1072
|
let length = (_a = data.length) !== null && _a !== void 0 ? _a : (children.length ? positions[0] + children[0].length : 0);
|
|
860
|
-
return new Tree(types[topID], children.reverse(), positions.reverse(), length);
|
|
1073
|
+
return new Tree(types[data.topID], children.reverse(), positions.reverse(), length);
|
|
861
1074
|
}
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
if (
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
1075
|
+
const nodeSizeCache = new WeakMap;
|
|
1076
|
+
function nodeSize(balanceType, node) {
|
|
1077
|
+
if (!balanceType.isAnonymous || node instanceof TreeBuffer || node.type != balanceType)
|
|
1078
|
+
return 1;
|
|
1079
|
+
let size = nodeSizeCache.get(node);
|
|
1080
|
+
if (size == null) {
|
|
1081
|
+
size = 1;
|
|
1082
|
+
for (let child of node.children) {
|
|
1083
|
+
if (child.type != balanceType || !(child instanceof Tree)) {
|
|
1084
|
+
size = 1;
|
|
1085
|
+
break;
|
|
1086
|
+
}
|
|
1087
|
+
size += nodeSize(balanceType, child);
|
|
868
1088
|
}
|
|
1089
|
+
nodeSizeCache.set(node, size);
|
|
869
1090
|
}
|
|
870
|
-
|
|
871
|
-
|
|
1091
|
+
return size;
|
|
1092
|
+
}
|
|
1093
|
+
function balanceRange(
|
|
1094
|
+
// The type the balanced tree's inner nodes.
|
|
1095
|
+
balanceType,
|
|
1096
|
+
// The direct children and their positions
|
|
1097
|
+
children, positions,
|
|
1098
|
+
// The index range in children/positions to use
|
|
1099
|
+
from, to,
|
|
1100
|
+
// The start position of the nodes, relative to their parent.
|
|
1101
|
+
start,
|
|
1102
|
+
// Length of the outer node
|
|
1103
|
+
length,
|
|
1104
|
+
// Function to build the top node of the balanced tree
|
|
1105
|
+
mkTop,
|
|
1106
|
+
// Function to build internal nodes for the balanced tree
|
|
1107
|
+
mkTree) {
|
|
1108
|
+
let total = 0;
|
|
1109
|
+
for (let i = from; i < to; i++)
|
|
1110
|
+
total += nodeSize(balanceType, children[i]);
|
|
1111
|
+
let maxChild = Math.ceil((total * 1.5) / 8 /* BranchFactor */);
|
|
1112
|
+
let localChildren = [], localPositions = [];
|
|
1113
|
+
function divide(children, positions, from, to, offset) {
|
|
872
1114
|
for (let i = from; i < to;) {
|
|
873
|
-
let groupFrom = i, groupStart = positions[i];
|
|
1115
|
+
let groupFrom = i, groupStart = positions[i], groupSize = nodeSize(balanceType, children[i]);
|
|
874
1116
|
i++;
|
|
875
1117
|
for (; i < to; i++) {
|
|
876
|
-
let
|
|
877
|
-
if (
|
|
1118
|
+
let nextSize = nodeSize(balanceType, children[i]);
|
|
1119
|
+
if (groupSize + nextSize >= maxChild)
|
|
878
1120
|
break;
|
|
1121
|
+
groupSize += nextSize;
|
|
879
1122
|
}
|
|
880
1123
|
if (i == groupFrom + 1) {
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
localChildren.push(only.children[j]);
|
|
885
|
-
localPositions.push(only.positions[j] + groupStart - start);
|
|
886
|
-
}
|
|
1124
|
+
if (groupSize > maxChild) {
|
|
1125
|
+
let only = children[groupFrom]; // Only trees can have a size > 1
|
|
1126
|
+
divide(only.children, only.positions, 0, only.children.length, positions[groupFrom] + offset);
|
|
887
1127
|
continue;
|
|
888
1128
|
}
|
|
889
|
-
localChildren.push(only);
|
|
890
|
-
}
|
|
891
|
-
else if (i == groupFrom + 1) {
|
|
892
1129
|
localChildren.push(children[groupFrom]);
|
|
893
1130
|
}
|
|
894
1131
|
else {
|
|
895
|
-
let
|
|
896
|
-
|
|
897
|
-
inner = withHash(new Tree(NodeType.none, inner.children, inner.positions, inner.length), contextHash);
|
|
898
|
-
localChildren.push(inner);
|
|
1132
|
+
let length = positions[i - 1] + children[i - 1].length - groupStart;
|
|
1133
|
+
localChildren.push(balanceRange(balanceType, children, positions, groupFrom, i, groupStart, length, null, mkTree));
|
|
899
1134
|
}
|
|
900
|
-
localPositions.push(groupStart - start);
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
return withHash(new Tree(outerType, localChildren, localPositions, length), contextHash);
|
|
904
|
-
}
|
|
905
|
-
function containsType(nodes, type) {
|
|
906
|
-
for (let elt of nodes)
|
|
907
|
-
if (elt.type == type)
|
|
908
|
-
return true;
|
|
909
|
-
return false;
|
|
910
|
-
}
|
|
911
|
-
/// Tree fragments are used during [incremental
|
|
912
|
-
/// parsing](#lezer.ParseOptions.fragments) to track parts of old
|
|
913
|
-
/// trees that can be reused in a new parse. An array of fragments is
|
|
914
|
-
/// used to track regions of an old tree whose nodes might be reused
|
|
915
|
-
/// in new parses. Use the static
|
|
916
|
-
/// [`applyChanges`](#tree.TreeFragment^applyChanges) method to update
|
|
917
|
-
/// fragments for document changes.
|
|
918
|
-
class TreeFragment {
|
|
919
|
-
constructor(
|
|
920
|
-
/// The start of the unchanged range pointed to by this fragment.
|
|
921
|
-
/// This refers to an offset in the _updated_ document (as opposed
|
|
922
|
-
/// to the original tree).
|
|
923
|
-
from,
|
|
924
|
-
/// The end of the unchanged range.
|
|
925
|
-
to,
|
|
926
|
-
/// The tree that this fragment is based on.
|
|
927
|
-
tree,
|
|
928
|
-
/// The offset between the fragment's tree and the document that
|
|
929
|
-
/// this fragment can be used against. Add this when going from
|
|
930
|
-
/// document to tree positions, subtract it to go from tree to
|
|
931
|
-
/// document positions.
|
|
932
|
-
offset, open) {
|
|
933
|
-
this.from = from;
|
|
934
|
-
this.to = to;
|
|
935
|
-
this.tree = tree;
|
|
936
|
-
this.offset = offset;
|
|
937
|
-
this.open = open;
|
|
938
|
-
}
|
|
939
|
-
get openStart() { return (this.open & 1 /* Start */) > 0; }
|
|
940
|
-
get openEnd() { return (this.open & 2 /* End */) > 0; }
|
|
941
|
-
/// Apply a set of edits to an array of fragments, removing or
|
|
942
|
-
/// splitting fragments as necessary to remove edited ranges, and
|
|
943
|
-
/// adjusting offsets for fragments that moved.
|
|
944
|
-
static applyChanges(fragments, changes, minGap = 128) {
|
|
945
|
-
if (!changes.length)
|
|
946
|
-
return fragments;
|
|
947
|
-
let result = [];
|
|
948
|
-
let fI = 1, nextF = fragments.length ? fragments[0] : null;
|
|
949
|
-
for (let cI = 0, pos = 0, off = 0;; cI++) {
|
|
950
|
-
let nextC = cI < changes.length ? changes[cI] : null;
|
|
951
|
-
let nextPos = nextC ? nextC.fromA : 1e9;
|
|
952
|
-
if (nextPos - pos >= minGap)
|
|
953
|
-
while (nextF && nextF.from < nextPos) {
|
|
954
|
-
let cut = nextF;
|
|
955
|
-
if (pos >= cut.from || nextPos <= cut.to || off) {
|
|
956
|
-
let fFrom = Math.max(cut.from, pos) - off, fTo = Math.min(cut.to, nextPos) - off;
|
|
957
|
-
cut = fFrom >= fTo ? null :
|
|
958
|
-
new TreeFragment(fFrom, fTo, cut.tree, cut.offset + off, (cI > 0 ? 1 /* Start */ : 0) | (nextC ? 2 /* End */ : 0));
|
|
959
|
-
}
|
|
960
|
-
if (cut)
|
|
961
|
-
result.push(cut);
|
|
962
|
-
if (nextF.to > nextPos)
|
|
963
|
-
break;
|
|
964
|
-
nextF = fI < fragments.length ? fragments[fI++] : null;
|
|
965
|
-
}
|
|
966
|
-
if (!nextC)
|
|
967
|
-
break;
|
|
968
|
-
pos = nextC.toA;
|
|
969
|
-
off = nextC.toA - nextC.toB;
|
|
1135
|
+
localPositions.push(groupStart + offset - start);
|
|
970
1136
|
}
|
|
971
|
-
return result;
|
|
972
|
-
}
|
|
973
|
-
/// Create a set of fragments from a freshly parsed tree, or update
|
|
974
|
-
/// an existing set of fragments by replacing the ones that overlap
|
|
975
|
-
/// with a tree with content from the new tree. When `partial` is
|
|
976
|
-
/// true, the parse is treated as incomplete, and the token at its
|
|
977
|
-
/// end is not included in [`safeTo`](#tree.TreeFragment.safeTo).
|
|
978
|
-
static addTree(tree, fragments = [], partial = false) {
|
|
979
|
-
let result = [new TreeFragment(0, tree.length, tree, 0, partial ? 2 /* End */ : 0)];
|
|
980
|
-
for (let f of fragments)
|
|
981
|
-
if (f.to > tree.length)
|
|
982
|
-
result.push(f);
|
|
983
|
-
return result;
|
|
984
|
-
}
|
|
985
|
-
}
|
|
986
|
-
// Creates an `Input` that is backed by a single, flat string.
|
|
987
|
-
function stringInput(input) { return new StringInput(input); }
|
|
988
|
-
class StringInput {
|
|
989
|
-
constructor(string, length = string.length) {
|
|
990
|
-
this.string = string;
|
|
991
|
-
this.length = length;
|
|
992
|
-
}
|
|
993
|
-
get(pos) {
|
|
994
|
-
return pos < 0 || pos >= this.length ? -1 : this.string.charCodeAt(pos);
|
|
995
|
-
}
|
|
996
|
-
lineAfter(pos) {
|
|
997
|
-
if (pos < 0)
|
|
998
|
-
return "";
|
|
999
|
-
let end = this.string.indexOf("\n", pos);
|
|
1000
|
-
return this.string.slice(pos, end < 0 ? this.length : Math.min(end, this.length));
|
|
1001
1137
|
}
|
|
1002
|
-
|
|
1003
|
-
|
|
1138
|
+
divide(children, positions, from, to, 0);
|
|
1139
|
+
return (mkTop || mkTree)(localChildren, localPositions, length);
|
|
1004
1140
|
}
|
|
1005
1141
|
|
|
1006
|
-
export { DefaultBufferLength, NodeProp, NodeSet, NodeType, Tree, TreeBuffer, TreeCursor,
|
|
1142
|
+
export { DefaultBufferLength, MountedTree, NodeProp, NodeSet, NodeType, Range, Tree, TreeBuffer, TreeCursor, TreeNode };
|
|
1007
1143
|
//# sourceMappingURL=tree.es.js.map
|