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