@lezer/common 1.0.3 → 1.0.4
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 +506 -282
- package/dist/index.d.cts +1115 -0
- package/dist/index.d.ts +1115 -3
- package/dist/index.js +506 -280
- package/package.json +5 -10
- package/dist/mix.d.ts +0 -13
- package/dist/parse.d.ts +0 -48
- package/dist/tree.d.ts +0 -262
package/dist/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// FIXME profile adding a per-Tree TreeNode cache, validating it by
|
|
2
2
|
// parent pointer
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
The default maximum length of a `TreeBuffer` node.
|
|
5
|
+
*/
|
|
4
6
|
const DefaultBufferLength = 1024;
|
|
5
7
|
let nextPropID = 0;
|
|
6
8
|
class Range {
|
|
@@ -9,11 +11,15 @@ class Range {
|
|
|
9
11
|
this.to = to;
|
|
10
12
|
}
|
|
11
13
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
/**
|
|
15
|
+
Each [node type](#common.NodeType) or [individual tree](#common.Tree)
|
|
16
|
+
can have metadata associated with it in props. Instances of this
|
|
17
|
+
class represent prop names.
|
|
18
|
+
*/
|
|
15
19
|
class NodeProp {
|
|
16
|
-
|
|
20
|
+
/**
|
|
21
|
+
Create a new node prop type.
|
|
22
|
+
*/
|
|
17
23
|
constructor(config = {}) {
|
|
18
24
|
this.id = nextPropID++;
|
|
19
25
|
this.perNode = !!config.perNode;
|
|
@@ -21,13 +27,15 @@ class NodeProp {
|
|
|
21
27
|
throw new Error("This node type doesn't define a deserialize function");
|
|
22
28
|
});
|
|
23
29
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
/**
|
|
31
|
+
This is meant to be used with
|
|
32
|
+
[`NodeSet.extend`](#common.NodeSet.extend) or
|
|
33
|
+
[`LRParser.configure`](#lr.ParserConfig.props) to compute
|
|
34
|
+
prop values for each node type in the set. Takes a [match
|
|
35
|
+
object](#common.NodeType^match) or function that returns undefined
|
|
36
|
+
if the node type doesn't get this prop, and the prop's value if
|
|
37
|
+
it does.
|
|
38
|
+
*/
|
|
31
39
|
add(match) {
|
|
32
40
|
if (this.perNode)
|
|
33
41
|
throw new RangeError("Can't add per-node props to node types");
|
|
@@ -39,48 +47,68 @@ class NodeProp {
|
|
|
39
47
|
};
|
|
40
48
|
}
|
|
41
49
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
50
|
+
/**
|
|
51
|
+
Prop that is used to describe matching delimiters. For opening
|
|
52
|
+
delimiters, this holds an array of node names (written as a
|
|
53
|
+
space-separated string when declaring this prop in a grammar)
|
|
54
|
+
for the node types of closing delimiters that match it.
|
|
55
|
+
*/
|
|
46
56
|
NodeProp.closedBy = new NodeProp({ deserialize: str => str.split(" ") });
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
57
|
+
/**
|
|
58
|
+
The inverse of [`closedBy`](#common.NodeProp^closedBy). This is
|
|
59
|
+
attached to closing delimiters, holding an array of node names
|
|
60
|
+
of types of matching opening delimiters.
|
|
61
|
+
*/
|
|
50
62
|
NodeProp.openedBy = new NodeProp({ deserialize: str => str.split(" ") });
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
63
|
+
/**
|
|
64
|
+
Used to assign node types to groups (for example, all node
|
|
65
|
+
types that represent an expression could be tagged with an
|
|
66
|
+
`"Expression"` group).
|
|
67
|
+
*/
|
|
54
68
|
NodeProp.group = new NodeProp({ deserialize: str => str.split(" ") });
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
69
|
+
/**
|
|
70
|
+
The hash of the [context](#lr.ContextTracker.constructor)
|
|
71
|
+
that the node was parsed in, if any. Used to limit reuse of
|
|
72
|
+
contextual nodes.
|
|
73
|
+
*/
|
|
58
74
|
NodeProp.contextHash = new NodeProp({ perNode: true });
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
75
|
+
/**
|
|
76
|
+
The distance beyond the end of the node that the tokenizer
|
|
77
|
+
looked ahead for any of the tokens inside the node. (The LR
|
|
78
|
+
parser only stores this when it is larger than 25, for
|
|
79
|
+
efficiency reasons.)
|
|
80
|
+
*/
|
|
63
81
|
NodeProp.lookAhead = new NodeProp({ perNode: true });
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
82
|
+
/**
|
|
83
|
+
This per-node prop is used to replace a given node, or part of a
|
|
84
|
+
node, with another tree. This is useful to include trees from
|
|
85
|
+
different languages in mixed-language parsers.
|
|
86
|
+
*/
|
|
67
87
|
NodeProp.mounted = new NodeProp({ perNode: true });
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
88
|
+
/**
|
|
89
|
+
A mounted tree, which can be [stored](#common.NodeProp^mounted) on
|
|
90
|
+
a tree node to indicate that parts of its content are
|
|
91
|
+
represented by another tree.
|
|
92
|
+
*/
|
|
71
93
|
class MountedTree {
|
|
72
94
|
constructor(
|
|
73
|
-
|
|
95
|
+
/**
|
|
96
|
+
The inner tree.
|
|
97
|
+
*/
|
|
74
98
|
tree,
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
99
|
+
/**
|
|
100
|
+
If this is null, this tree replaces the entire node (it will
|
|
101
|
+
be included in the regular iteration instead of its host
|
|
102
|
+
node). If not, only the given ranges are considered to be
|
|
103
|
+
covered by this tree. This is used for trees that are mixed in
|
|
104
|
+
a way that isn't strictly hierarchical. Such mounted trees are
|
|
105
|
+
only entered by [`resolveInner`](#common.Tree.resolveInner)
|
|
106
|
+
and [`enter`](#common.SyntaxNode.enter).
|
|
107
|
+
*/
|
|
82
108
|
overlay,
|
|
83
|
-
|
|
109
|
+
/**
|
|
110
|
+
The parser used to create this subtree.
|
|
111
|
+
*/
|
|
84
112
|
parser) {
|
|
85
113
|
this.tree = tree;
|
|
86
114
|
this.overlay = overlay;
|
|
@@ -88,28 +116,42 @@ class MountedTree {
|
|
|
88
116
|
}
|
|
89
117
|
}
|
|
90
118
|
const noProps = Object.create(null);
|
|
91
|
-
|
|
119
|
+
/**
|
|
120
|
+
Each node in a syntax tree has a node type associated with it.
|
|
121
|
+
*/
|
|
92
122
|
class NodeType {
|
|
93
|
-
|
|
123
|
+
/**
|
|
124
|
+
@internal
|
|
125
|
+
*/
|
|
94
126
|
constructor(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
127
|
+
/**
|
|
128
|
+
The name of the node type. Not necessarily unique, but if the
|
|
129
|
+
grammar was written properly, different node types with the
|
|
130
|
+
same name within a node set should play the same semantic
|
|
131
|
+
role.
|
|
132
|
+
*/
|
|
99
133
|
name,
|
|
100
|
-
|
|
134
|
+
/**
|
|
135
|
+
@internal
|
|
136
|
+
*/
|
|
101
137
|
props,
|
|
102
|
-
|
|
103
|
-
|
|
138
|
+
/**
|
|
139
|
+
The id of this node in its set. Corresponds to the term ids
|
|
140
|
+
used in the parser.
|
|
141
|
+
*/
|
|
104
142
|
id,
|
|
105
|
-
|
|
143
|
+
/**
|
|
144
|
+
@internal
|
|
145
|
+
*/
|
|
106
146
|
flags = 0) {
|
|
107
147
|
this.name = name;
|
|
108
148
|
this.props = props;
|
|
109
149
|
this.id = id;
|
|
110
150
|
this.flags = flags;
|
|
111
151
|
}
|
|
112
|
-
|
|
152
|
+
/**
|
|
153
|
+
Define a node type.
|
|
154
|
+
*/
|
|
113
155
|
static define(spec) {
|
|
114
156
|
let props = spec.props && spec.props.length ? Object.create(null) : noProps;
|
|
115
157
|
let flags = (spec.top ? 1 /* NodeFlag.Top */ : 0) | (spec.skipped ? 2 /* NodeFlag.Skipped */ : 0) |
|
|
@@ -127,20 +169,32 @@ class NodeType {
|
|
|
127
169
|
}
|
|
128
170
|
return type;
|
|
129
171
|
}
|
|
130
|
-
|
|
131
|
-
|
|
172
|
+
/**
|
|
173
|
+
Retrieves a node prop for this type. Will return `undefined` if
|
|
174
|
+
the prop isn't present on this node.
|
|
175
|
+
*/
|
|
132
176
|
prop(prop) { return this.props[prop.id]; }
|
|
133
|
-
|
|
177
|
+
/**
|
|
178
|
+
True when this is the top node of a grammar.
|
|
179
|
+
*/
|
|
134
180
|
get isTop() { return (this.flags & 1 /* NodeFlag.Top */) > 0; }
|
|
135
|
-
|
|
181
|
+
/**
|
|
182
|
+
True when this node is produced by a skip rule.
|
|
183
|
+
*/
|
|
136
184
|
get isSkipped() { return (this.flags & 2 /* NodeFlag.Skipped */) > 0; }
|
|
137
|
-
|
|
185
|
+
/**
|
|
186
|
+
Indicates whether this is an error node.
|
|
187
|
+
*/
|
|
138
188
|
get isError() { return (this.flags & 4 /* NodeFlag.Error */) > 0; }
|
|
139
|
-
|
|
140
|
-
|
|
189
|
+
/**
|
|
190
|
+
When true, this node type doesn't correspond to a user-declared
|
|
191
|
+
named node, for example because it is used to cache repetition.
|
|
192
|
+
*/
|
|
141
193
|
get isAnonymous() { return (this.flags & 8 /* NodeFlag.Anonymous */) > 0; }
|
|
142
|
-
|
|
143
|
-
|
|
194
|
+
/**
|
|
195
|
+
Returns true when this node's name or one of its
|
|
196
|
+
[groups](#common.NodeProp^group) matches the given string.
|
|
197
|
+
*/
|
|
144
198
|
is(name) {
|
|
145
199
|
if (typeof name == 'string') {
|
|
146
200
|
if (this.name == name)
|
|
@@ -150,12 +204,14 @@ class NodeType {
|
|
|
150
204
|
}
|
|
151
205
|
return this.id == name;
|
|
152
206
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
207
|
+
/**
|
|
208
|
+
Create a function from node types to arbitrary values by
|
|
209
|
+
specifying an object whose property names are node or
|
|
210
|
+
[group](#common.NodeProp^group) names. Often useful with
|
|
211
|
+
[`NodeProp.add`](#common.NodeProp.add). You can put multiple
|
|
212
|
+
names, separated by spaces, in a single property name to map
|
|
213
|
+
multiple node names to a single value.
|
|
214
|
+
*/
|
|
159
215
|
static match(map) {
|
|
160
216
|
let direct = Object.create(null);
|
|
161
217
|
for (let prop in map)
|
|
@@ -170,29 +226,39 @@ class NodeType {
|
|
|
170
226
|
};
|
|
171
227
|
}
|
|
172
228
|
}
|
|
173
|
-
|
|
229
|
+
/**
|
|
230
|
+
An empty dummy node type to use when no actual type is available.
|
|
231
|
+
*/
|
|
174
232
|
NodeType.none = new NodeType("", Object.create(null), 0, 8 /* NodeFlag.Anonymous */);
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
233
|
+
/**
|
|
234
|
+
A node set holds a collection of node types. It is used to
|
|
235
|
+
compactly represent trees by storing their type ids, rather than a
|
|
236
|
+
full pointer to the type object, in a numeric array. Each parser
|
|
237
|
+
[has](#lr.LRParser.nodeSet) a node set, and [tree
|
|
238
|
+
buffers](#common.TreeBuffer) can only store collections of nodes
|
|
239
|
+
from the same set. A set can have a maximum of 2**16 (65536) node
|
|
240
|
+
types in it, so that the ids fit into 16-bit typed array slots.
|
|
241
|
+
*/
|
|
182
242
|
class NodeSet {
|
|
183
|
-
|
|
184
|
-
|
|
243
|
+
/**
|
|
244
|
+
Create a set with the given types. The `id` property of each
|
|
245
|
+
type should correspond to its position within the array.
|
|
246
|
+
*/
|
|
185
247
|
constructor(
|
|
186
|
-
|
|
248
|
+
/**
|
|
249
|
+
The node types in this set, by id.
|
|
250
|
+
*/
|
|
187
251
|
types) {
|
|
188
252
|
this.types = types;
|
|
189
253
|
for (let i = 0; i < types.length; i++)
|
|
190
254
|
if (types[i].id != i)
|
|
191
255
|
throw new RangeError("Node type ids should correspond to array positions when creating a node set");
|
|
192
256
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
257
|
+
/**
|
|
258
|
+
Create a copy of this set with some node properties added. The
|
|
259
|
+
arguments to this method can be created with
|
|
260
|
+
[`NodeProp.add`](#common.NodeProp.add).
|
|
261
|
+
*/
|
|
196
262
|
extend(...props) {
|
|
197
263
|
let newTypes = [];
|
|
198
264
|
for (let type of this.types) {
|
|
@@ -211,61 +277,87 @@ class NodeSet {
|
|
|
211
277
|
}
|
|
212
278
|
}
|
|
213
279
|
const CachedNode = new WeakMap(), CachedInnerNode = new WeakMap();
|
|
214
|
-
|
|
215
|
-
|
|
280
|
+
/**
|
|
281
|
+
Options that control iteration. Can be combined with the `|`
|
|
282
|
+
operator to enable multiple ones.
|
|
283
|
+
*/
|
|
216
284
|
var IterMode;
|
|
217
285
|
(function (IterMode) {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
286
|
+
/**
|
|
287
|
+
When enabled, iteration will only visit [`Tree`](#common.Tree)
|
|
288
|
+
objects, not nodes packed into
|
|
289
|
+
[`TreeBuffer`](#common.TreeBuffer)s.
|
|
290
|
+
*/
|
|
221
291
|
IterMode[IterMode["ExcludeBuffers"] = 1] = "ExcludeBuffers";
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
292
|
+
/**
|
|
293
|
+
Enable this to make iteration include anonymous nodes (such as
|
|
294
|
+
the nodes that wrap repeated grammar constructs into a balanced
|
|
295
|
+
tree).
|
|
296
|
+
*/
|
|
225
297
|
IterMode[IterMode["IncludeAnonymous"] = 2] = "IncludeAnonymous";
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
298
|
+
/**
|
|
299
|
+
By default, regular [mounted](#common.NodeProp^mounted) nodes
|
|
300
|
+
replace their base node in iteration. Enable this to ignore them
|
|
301
|
+
instead.
|
|
302
|
+
*/
|
|
229
303
|
IterMode[IterMode["IgnoreMounts"] = 4] = "IgnoreMounts";
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
304
|
+
/**
|
|
305
|
+
This option only applies in
|
|
306
|
+
[`enter`](#common.SyntaxNode.enter)-style methods. It tells the
|
|
307
|
+
library to not enter mounted overlays if one covers the given
|
|
308
|
+
position.
|
|
309
|
+
*/
|
|
234
310
|
IterMode[IterMode["IgnoreOverlays"] = 8] = "IgnoreOverlays";
|
|
235
311
|
})(IterMode || (IterMode = {}));
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
312
|
+
/**
|
|
313
|
+
A piece of syntax tree. There are two ways to approach these
|
|
314
|
+
trees: the way they are actually stored in memory, and the
|
|
315
|
+
convenient way.
|
|
316
|
+
|
|
317
|
+
Syntax trees are stored as a tree of `Tree` and `TreeBuffer`
|
|
318
|
+
objects. By packing detail information into `TreeBuffer` leaf
|
|
319
|
+
nodes, the representation is made a lot more memory-efficient.
|
|
320
|
+
|
|
321
|
+
However, when you want to actually work with tree nodes, this
|
|
322
|
+
representation is very awkward, so most client code will want to
|
|
323
|
+
use the [`TreeCursor`](#common.TreeCursor) or
|
|
324
|
+
[`SyntaxNode`](#common.SyntaxNode) interface instead, which provides
|
|
325
|
+
a view on some part of this data structure, and can be used to
|
|
326
|
+
move around to adjacent nodes.
|
|
327
|
+
*/
|
|
250
328
|
class Tree {
|
|
251
|
-
|
|
329
|
+
/**
|
|
330
|
+
Construct a new tree. See also [`Tree.build`](#common.Tree^build).
|
|
331
|
+
*/
|
|
252
332
|
constructor(
|
|
253
|
-
|
|
333
|
+
/**
|
|
334
|
+
The type of the top node.
|
|
335
|
+
*/
|
|
254
336
|
type,
|
|
255
|
-
|
|
337
|
+
/**
|
|
338
|
+
This node's child nodes.
|
|
339
|
+
*/
|
|
256
340
|
children,
|
|
257
|
-
|
|
258
|
-
|
|
341
|
+
/**
|
|
342
|
+
The positions (offsets relative to the start of this tree) of
|
|
343
|
+
the children.
|
|
344
|
+
*/
|
|
259
345
|
positions,
|
|
260
|
-
|
|
346
|
+
/**
|
|
347
|
+
The total length of this tree
|
|
348
|
+
*/
|
|
261
349
|
length,
|
|
262
|
-
|
|
350
|
+
/**
|
|
351
|
+
Per-node [node props](#common.NodeProp) to associate with this node.
|
|
352
|
+
*/
|
|
263
353
|
props) {
|
|
264
354
|
this.type = type;
|
|
265
355
|
this.children = children;
|
|
266
356
|
this.positions = positions;
|
|
267
357
|
this.length = length;
|
|
268
|
-
|
|
358
|
+
/**
|
|
359
|
+
@internal
|
|
360
|
+
*/
|
|
269
361
|
this.props = null;
|
|
270
362
|
if (props && props.length) {
|
|
271
363
|
this.props = Object.create(null);
|
|
@@ -273,7 +365,9 @@ class Tree {
|
|
|
273
365
|
this.props[typeof prop == "number" ? prop : prop.id] = value;
|
|
274
366
|
}
|
|
275
367
|
}
|
|
276
|
-
|
|
368
|
+
/**
|
|
369
|
+
@internal
|
|
370
|
+
*/
|
|
277
371
|
toString() {
|
|
278
372
|
let mounted = this.prop(NodeProp.mounted);
|
|
279
373
|
if (mounted && !mounted.overlay)
|
|
@@ -291,15 +385,19 @@ class Tree {
|
|
|
291
385
|
(/\W/.test(this.type.name) && !this.type.isError ? JSON.stringify(this.type.name) : this.type.name) +
|
|
292
386
|
(children.length ? "(" + children + ")" : "");
|
|
293
387
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
388
|
+
/**
|
|
389
|
+
Get a [tree cursor](#common.TreeCursor) positioned at the top of
|
|
390
|
+
the tree. Mode can be used to [control](#common.IterMode) which
|
|
391
|
+
nodes the cursor visits.
|
|
392
|
+
*/
|
|
297
393
|
cursor(mode = 0) {
|
|
298
394
|
return new TreeCursor(this.topNode, mode);
|
|
299
395
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
396
|
+
/**
|
|
397
|
+
Get a [tree cursor](#common.TreeCursor) pointing into this tree
|
|
398
|
+
at the given position and side (see
|
|
399
|
+
[`moveTo`](#common.TreeCursor.moveTo).
|
|
400
|
+
*/
|
|
303
401
|
cursorAt(pos, side = 0, mode = 0) {
|
|
304
402
|
let scope = CachedNode.get(this) || this.topNode;
|
|
305
403
|
let cursor = new TreeCursor(scope);
|
|
@@ -307,40 +405,48 @@ class Tree {
|
|
|
307
405
|
CachedNode.set(this, cursor._tree);
|
|
308
406
|
return cursor;
|
|
309
407
|
}
|
|
310
|
-
|
|
311
|
-
|
|
408
|
+
/**
|
|
409
|
+
Get a [syntax node](#common.SyntaxNode) object for the top of the
|
|
410
|
+
tree.
|
|
411
|
+
*/
|
|
312
412
|
get topNode() {
|
|
313
413
|
return new TreeNode(this, 0, 0, null);
|
|
314
414
|
}
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
415
|
+
/**
|
|
416
|
+
Get the [syntax node](#common.SyntaxNode) at the given position.
|
|
417
|
+
If `side` is -1, this will move into nodes that end at the
|
|
418
|
+
position. If 1, it'll move into nodes that start at the
|
|
419
|
+
position. With 0, it'll only enter nodes that cover the position
|
|
420
|
+
from both sides.
|
|
421
|
+
|
|
422
|
+
Note that this will not enter
|
|
423
|
+
[overlays](#common.MountedTree.overlay), and you often want
|
|
424
|
+
[`resolveInner`](#common.Tree.resolveInner) instead.
|
|
425
|
+
*/
|
|
324
426
|
resolve(pos, side = 0) {
|
|
325
427
|
let node = resolveNode(CachedNode.get(this) || this.topNode, pos, side, false);
|
|
326
428
|
CachedNode.set(this, node);
|
|
327
429
|
return node;
|
|
328
430
|
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
431
|
+
/**
|
|
432
|
+
Like [`resolve`](#common.Tree.resolve), but will enter
|
|
433
|
+
[overlaid](#common.MountedTree.overlay) nodes, producing a syntax node
|
|
434
|
+
pointing into the innermost overlaid tree at the given position
|
|
435
|
+
(with parent links going through all parent structure, including
|
|
436
|
+
the host trees).
|
|
437
|
+
*/
|
|
334
438
|
resolveInner(pos, side = 0) {
|
|
335
439
|
let node = resolveNode(CachedInnerNode.get(this) || this.topNode, pos, side, true);
|
|
336
440
|
CachedInnerNode.set(this, node);
|
|
337
441
|
return node;
|
|
338
442
|
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
443
|
+
/**
|
|
444
|
+
Iterate over the tree and its children, calling `enter` for any
|
|
445
|
+
node that touches the `from`/`to` region (if given) before
|
|
446
|
+
running over such a node's children, and `leave` (if given) when
|
|
447
|
+
leaving the node. When `enter` returns `false`, that node will
|
|
448
|
+
not have its children iterated over (or `leave` called).
|
|
449
|
+
*/
|
|
344
450
|
iterate(spec) {
|
|
345
451
|
let { enter, leave, from = 0, to = this.length } = spec;
|
|
346
452
|
let mode = spec.mode || 0, anon = (mode & IterMode.IncludeAnonymous) > 0;
|
|
@@ -362,14 +468,18 @@ class Tree {
|
|
|
362
468
|
}
|
|
363
469
|
}
|
|
364
470
|
}
|
|
365
|
-
|
|
366
|
-
|
|
471
|
+
/**
|
|
472
|
+
Get the value of the given [node prop](#common.NodeProp) for this
|
|
473
|
+
node. Works with both per-node and per-type props.
|
|
474
|
+
*/
|
|
367
475
|
prop(prop) {
|
|
368
476
|
return !prop.perNode ? this.type.prop(prop) : this.props ? this.props[prop.id] : undefined;
|
|
369
477
|
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
478
|
+
/**
|
|
479
|
+
Returns the node's [per-node props](#common.NodeProp.perNode) in a
|
|
480
|
+
format that can be passed to the [`Tree`](#common.Tree)
|
|
481
|
+
constructor.
|
|
482
|
+
*/
|
|
373
483
|
get propValues() {
|
|
374
484
|
let result = [];
|
|
375
485
|
if (this.props)
|
|
@@ -377,18 +487,24 @@ class Tree {
|
|
|
377
487
|
result.push([+id, this.props[id]]);
|
|
378
488
|
return result;
|
|
379
489
|
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
490
|
+
/**
|
|
491
|
+
Balance the direct children of this tree, producing a copy of
|
|
492
|
+
which may have children grouped into subtrees with type
|
|
493
|
+
[`NodeType.none`](#common.NodeType^none).
|
|
494
|
+
*/
|
|
383
495
|
balance(config = {}) {
|
|
384
496
|
return this.children.length <= 8 /* Balance.BranchFactor */ ? this :
|
|
385
497
|
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)));
|
|
386
498
|
}
|
|
387
|
-
|
|
388
|
-
|
|
499
|
+
/**
|
|
500
|
+
Build a tree from a postfix-ordered buffer of node information,
|
|
501
|
+
or a cursor over such a buffer.
|
|
502
|
+
*/
|
|
389
503
|
static build(data) { return buildTree(data); }
|
|
390
504
|
}
|
|
391
|
-
|
|
505
|
+
/**
|
|
506
|
+
The empty tree
|
|
507
|
+
*/
|
|
392
508
|
Tree.empty = new Tree(NodeType.none, [], [], 0);
|
|
393
509
|
class FlatBufferCursor {
|
|
394
510
|
constructor(buffer, index) {
|
|
@@ -403,26 +519,40 @@ class FlatBufferCursor {
|
|
|
403
519
|
next() { this.index -= 4; }
|
|
404
520
|
fork() { return new FlatBufferCursor(this.buffer, this.index); }
|
|
405
521
|
}
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
522
|
+
/**
|
|
523
|
+
Tree buffers contain (type, start, end, endIndex) quads for each
|
|
524
|
+
node. In such a buffer, nodes are stored in prefix order (parents
|
|
525
|
+
before children, with the endIndex of the parent indicating which
|
|
526
|
+
children belong to it).
|
|
527
|
+
*/
|
|
410
528
|
class TreeBuffer {
|
|
411
|
-
|
|
529
|
+
/**
|
|
530
|
+
Create a tree buffer.
|
|
531
|
+
*/
|
|
412
532
|
constructor(
|
|
413
|
-
|
|
533
|
+
/**
|
|
534
|
+
The buffer's content.
|
|
535
|
+
*/
|
|
414
536
|
buffer,
|
|
415
|
-
|
|
537
|
+
/**
|
|
538
|
+
The total length of the group of nodes in the buffer.
|
|
539
|
+
*/
|
|
416
540
|
length,
|
|
417
|
-
|
|
541
|
+
/**
|
|
542
|
+
The node set used in this buffer.
|
|
543
|
+
*/
|
|
418
544
|
set) {
|
|
419
545
|
this.buffer = buffer;
|
|
420
546
|
this.length = length;
|
|
421
547
|
this.set = set;
|
|
422
548
|
}
|
|
423
|
-
|
|
549
|
+
/**
|
|
550
|
+
@internal
|
|
551
|
+
*/
|
|
424
552
|
get type() { return NodeType.none; }
|
|
425
|
-
|
|
553
|
+
/**
|
|
554
|
+
@internal
|
|
555
|
+
*/
|
|
426
556
|
toString() {
|
|
427
557
|
let result = [];
|
|
428
558
|
for (let index = 0; index < this.buffer.length;) {
|
|
@@ -431,7 +561,9 @@ class TreeBuffer {
|
|
|
431
561
|
}
|
|
432
562
|
return result.join(",");
|
|
433
563
|
}
|
|
434
|
-
|
|
564
|
+
/**
|
|
565
|
+
@internal
|
|
566
|
+
*/
|
|
435
567
|
childString(index) {
|
|
436
568
|
let id = this.buffer[index], endIndex = this.buffer[index + 3];
|
|
437
569
|
let type = this.set.types[id], result = type.name;
|
|
@@ -447,7 +579,9 @@ class TreeBuffer {
|
|
|
447
579
|
}
|
|
448
580
|
return result + "(" + children.join(",") + ")";
|
|
449
581
|
}
|
|
450
|
-
|
|
582
|
+
/**
|
|
583
|
+
@internal
|
|
584
|
+
*/
|
|
451
585
|
findChild(startIndex, endIndex, dir, pos, side) {
|
|
452
586
|
let { buffer } = this, pick = -1;
|
|
453
587
|
for (let i = startIndex; i != endIndex; i = buffer[i + 3]) {
|
|
@@ -459,7 +593,9 @@ class TreeBuffer {
|
|
|
459
593
|
}
|
|
460
594
|
return pick;
|
|
461
595
|
}
|
|
462
|
-
|
|
596
|
+
/**
|
|
597
|
+
@internal
|
|
598
|
+
*/
|
|
463
599
|
slice(startI, endI, from) {
|
|
464
600
|
let b = this.buffer;
|
|
465
601
|
let copy = new Uint16Array(endI - startI), len = 0;
|
|
@@ -618,7 +754,9 @@ class TreeNode {
|
|
|
618
754
|
getChildren(type, before = null, after = null) {
|
|
619
755
|
return getChildren(this, type, before, after);
|
|
620
756
|
}
|
|
621
|
-
|
|
757
|
+
/**
|
|
758
|
+
@internal
|
|
759
|
+
*/
|
|
622
760
|
toString() { return this._tree.toString(); }
|
|
623
761
|
get node() { return this; }
|
|
624
762
|
matchContext(context) { return matchNodeContext(this, context); }
|
|
@@ -726,7 +864,9 @@ class BufferNode {
|
|
|
726
864
|
return resolveNode(this, pos, side, true);
|
|
727
865
|
}
|
|
728
866
|
enterUnfinishedNodesBefore(pos) { return enterUnfinishedNodesBefore(this, pos); }
|
|
729
|
-
|
|
867
|
+
/**
|
|
868
|
+
@internal
|
|
869
|
+
*/
|
|
730
870
|
toString() { return this.context.buffer.childString(this.index); }
|
|
731
871
|
getChild(type, before = null, after = null) {
|
|
732
872
|
let r = getChildren(this, type, before, after);
|
|
@@ -738,20 +878,32 @@ class BufferNode {
|
|
|
738
878
|
get node() { return this; }
|
|
739
879
|
matchContext(context) { return matchNodeContext(this, context); }
|
|
740
880
|
}
|
|
741
|
-
|
|
742
|
-
|
|
881
|
+
/**
|
|
882
|
+
A tree cursor object focuses on a given node in a syntax tree, and
|
|
883
|
+
allows you to move to adjacent nodes.
|
|
884
|
+
*/
|
|
743
885
|
class TreeCursor {
|
|
744
|
-
|
|
886
|
+
/**
|
|
887
|
+
Shorthand for `.type.name`.
|
|
888
|
+
*/
|
|
745
889
|
get name() { return this.type.name; }
|
|
746
|
-
|
|
890
|
+
/**
|
|
891
|
+
@internal
|
|
892
|
+
*/
|
|
747
893
|
constructor(node,
|
|
748
|
-
|
|
894
|
+
/**
|
|
895
|
+
@internal
|
|
896
|
+
*/
|
|
749
897
|
mode = 0) {
|
|
750
898
|
this.mode = mode;
|
|
751
|
-
|
|
899
|
+
/**
|
|
900
|
+
@internal
|
|
901
|
+
*/
|
|
752
902
|
this.buffer = null;
|
|
753
903
|
this.stack = [];
|
|
754
|
-
|
|
904
|
+
/**
|
|
905
|
+
@internal
|
|
906
|
+
*/
|
|
755
907
|
this.index = 0;
|
|
756
908
|
this.bufferNode = null;
|
|
757
909
|
if (node instanceof TreeNode) {
|
|
@@ -793,11 +945,15 @@ class TreeCursor {
|
|
|
793
945
|
this.buffer = node.context;
|
|
794
946
|
return this.yieldBuf(node.index, node.type);
|
|
795
947
|
}
|
|
796
|
-
|
|
948
|
+
/**
|
|
949
|
+
@internal
|
|
950
|
+
*/
|
|
797
951
|
toString() {
|
|
798
952
|
return this.buffer ? this.buffer.buffer.childString(this.index) : this._tree.toString();
|
|
799
953
|
}
|
|
800
|
-
|
|
954
|
+
/**
|
|
955
|
+
@internal
|
|
956
|
+
*/
|
|
801
957
|
enterChild(dir, pos, side) {
|
|
802
958
|
if (!this.buffer)
|
|
803
959
|
return this.yield(this._tree.nextChild(dir < 0 ? this._tree._tree.children.length - 1 : 0, dir, pos, side, this.mode));
|
|
@@ -808,26 +964,38 @@ class TreeCursor {
|
|
|
808
964
|
this.stack.push(this.index);
|
|
809
965
|
return this.yieldBuf(index);
|
|
810
966
|
}
|
|
811
|
-
|
|
812
|
-
|
|
967
|
+
/**
|
|
968
|
+
Move the cursor to this node's first child. When this returns
|
|
969
|
+
false, the node has no child, and the cursor has not been moved.
|
|
970
|
+
*/
|
|
813
971
|
firstChild() { return this.enterChild(1, 0, 4 /* Side.DontCare */); }
|
|
814
|
-
|
|
972
|
+
/**
|
|
973
|
+
Move the cursor to this node's last child.
|
|
974
|
+
*/
|
|
815
975
|
lastChild() { return this.enterChild(-1, 0, 4 /* Side.DontCare */); }
|
|
816
|
-
|
|
976
|
+
/**
|
|
977
|
+
Move the cursor to the first child that ends after `pos`.
|
|
978
|
+
*/
|
|
817
979
|
childAfter(pos) { return this.enterChild(1, pos, 2 /* Side.After */); }
|
|
818
|
-
|
|
980
|
+
/**
|
|
981
|
+
Move to the last child that starts before `pos`.
|
|
982
|
+
*/
|
|
819
983
|
childBefore(pos) { return this.enterChild(-1, pos, -2 /* Side.Before */); }
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
984
|
+
/**
|
|
985
|
+
Move the cursor to the child around `pos`. If side is -1 the
|
|
986
|
+
child may end at that position, when 1 it may start there. This
|
|
987
|
+
will also enter [overlaid](#common.MountedTree.overlay)
|
|
988
|
+
[mounted](#common.NodeProp^mounted) trees unless `overlays` is
|
|
989
|
+
set to false.
|
|
990
|
+
*/
|
|
825
991
|
enter(pos, side, mode = this.mode) {
|
|
826
992
|
if (!this.buffer)
|
|
827
993
|
return this.yield(this._tree.enter(pos, side, mode));
|
|
828
994
|
return mode & IterMode.ExcludeBuffers ? false : this.enterChild(1, pos, side);
|
|
829
995
|
}
|
|
830
|
-
|
|
996
|
+
/**
|
|
997
|
+
Move to the node's parent node, if this isn't the top node.
|
|
998
|
+
*/
|
|
831
999
|
parent() {
|
|
832
1000
|
if (!this.buffer)
|
|
833
1001
|
return this.yieldNode((this.mode & IterMode.IncludeAnonymous) ? this._tree._parent : this._tree.parent);
|
|
@@ -837,7 +1005,9 @@ class TreeCursor {
|
|
|
837
1005
|
this.buffer = null;
|
|
838
1006
|
return this.yieldNode(parent);
|
|
839
1007
|
}
|
|
840
|
-
|
|
1008
|
+
/**
|
|
1009
|
+
@internal
|
|
1010
|
+
*/
|
|
841
1011
|
sibling(dir) {
|
|
842
1012
|
if (!this.buffer)
|
|
843
1013
|
return !this._tree._parent ? false
|
|
@@ -856,9 +1026,13 @@ class TreeCursor {
|
|
|
856
1026
|
}
|
|
857
1027
|
return d < 0 ? this.yield(this.buffer.parent.nextChild(this.buffer.index + dir, dir, 0, 4 /* Side.DontCare */, this.mode)) : false;
|
|
858
1028
|
}
|
|
859
|
-
|
|
1029
|
+
/**
|
|
1030
|
+
Move to this node's next sibling, if any.
|
|
1031
|
+
*/
|
|
860
1032
|
nextSibling() { return this.sibling(1); }
|
|
861
|
-
|
|
1033
|
+
/**
|
|
1034
|
+
Move to this node's previous sibling, if any.
|
|
1035
|
+
*/
|
|
862
1036
|
prevSibling() { return this.sibling(-1); }
|
|
863
1037
|
atLastNode(dir) {
|
|
864
1038
|
let index, parent, { buffer } = this;
|
|
@@ -900,20 +1074,26 @@ class TreeCursor {
|
|
|
900
1074
|
return false;
|
|
901
1075
|
}
|
|
902
1076
|
}
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
1077
|
+
/**
|
|
1078
|
+
Move to the next node in a
|
|
1079
|
+
[pre-order](https://en.wikipedia.org/wiki/Tree_traversal#Pre-order,_NLR)
|
|
1080
|
+
traversal, going from a node to its first child or, if the
|
|
1081
|
+
current node is empty or `enter` is false, its next sibling or
|
|
1082
|
+
the next sibling of the first parent node that has one.
|
|
1083
|
+
*/
|
|
908
1084
|
next(enter = true) { return this.move(1, enter); }
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
1085
|
+
/**
|
|
1086
|
+
Move to the next node in a last-to-first pre-order traveral. A
|
|
1087
|
+
node is followed by its last child or, if it has none, its
|
|
1088
|
+
previous sibling or the previous sibling of the first parent
|
|
1089
|
+
node that has one.
|
|
1090
|
+
*/
|
|
913
1091
|
prev(enter = true) { return this.move(-1, enter); }
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
1092
|
+
/**
|
|
1093
|
+
Move the cursor to the innermost node that covers `pos`. If
|
|
1094
|
+
`side` is -1, it will enter nodes that end at `pos`. If it is 1,
|
|
1095
|
+
it will enter nodes that start at `pos`.
|
|
1096
|
+
*/
|
|
917
1097
|
moveTo(pos, side = 0) {
|
|
918
1098
|
// Move up to a node that actually holds the position, if possible
|
|
919
1099
|
while (this.from == this.to ||
|
|
@@ -925,8 +1105,10 @@ class TreeCursor {
|
|
|
925
1105
|
while (this.enterChild(1, pos, side)) { }
|
|
926
1106
|
return this;
|
|
927
1107
|
}
|
|
928
|
-
|
|
929
|
-
|
|
1108
|
+
/**
|
|
1109
|
+
Get a [syntax node](#common.SyntaxNode) at the cursor's current
|
|
1110
|
+
position.
|
|
1111
|
+
*/
|
|
930
1112
|
get node() {
|
|
931
1113
|
if (!this.buffer)
|
|
932
1114
|
return this._tree;
|
|
@@ -948,16 +1130,20 @@ class TreeCursor {
|
|
|
948
1130
|
result = new BufferNode(this.buffer, result, this.stack[i]);
|
|
949
1131
|
return this.bufferNode = new BufferNode(this.buffer, result, this.index);
|
|
950
1132
|
}
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
1133
|
+
/**
|
|
1134
|
+
Get the [tree](#common.Tree) that represents the current node, if
|
|
1135
|
+
any. Will return null when the node is in a [tree
|
|
1136
|
+
buffer](#common.TreeBuffer).
|
|
1137
|
+
*/
|
|
954
1138
|
get tree() {
|
|
955
1139
|
return this.buffer ? null : this._tree._tree;
|
|
956
1140
|
}
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
1141
|
+
/**
|
|
1142
|
+
Iterate over the current node and all its descendants, calling
|
|
1143
|
+
`enter` when entering a node and `leave`, if given, when leaving
|
|
1144
|
+
one. When `enter` returns `false`, any children of that node are
|
|
1145
|
+
skipped, and `leave` isn't called for it.
|
|
1146
|
+
*/
|
|
961
1147
|
iterate(enter, leave) {
|
|
962
1148
|
for (let depth = 0;;) {
|
|
963
1149
|
let mustLeave = false;
|
|
@@ -983,9 +1169,11 @@ class TreeCursor {
|
|
|
983
1169
|
}
|
|
984
1170
|
}
|
|
985
1171
|
}
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
1172
|
+
/**
|
|
1173
|
+
Test whether the current node matches a given context—a sequence
|
|
1174
|
+
of direct parent node names. Empty strings in the context array
|
|
1175
|
+
are treated as wildcards.
|
|
1176
|
+
*/
|
|
989
1177
|
matchContext(context) {
|
|
990
1178
|
if (!this.buffer)
|
|
991
1179
|
return matchNodeContext(this.node, context);
|
|
@@ -1260,9 +1448,11 @@ mkTree) {
|
|
|
1260
1448
|
divide(children, positions, from, to, 0);
|
|
1261
1449
|
return (mkTop || mkTree)(localChildren, localPositions, length);
|
|
1262
1450
|
}
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1451
|
+
/**
|
|
1452
|
+
Provides a way to associate values with pieces of trees. As long
|
|
1453
|
+
as that part of the tree is reused, the associated values can be
|
|
1454
|
+
retrieved from an updated tree.
|
|
1455
|
+
*/
|
|
1266
1456
|
class NodeWeakMap {
|
|
1267
1457
|
constructor() {
|
|
1268
1458
|
this.map = new WeakMap();
|
|
@@ -1277,57 +1467,77 @@ class NodeWeakMap {
|
|
|
1277
1467
|
let inner = this.map.get(buffer);
|
|
1278
1468
|
return inner && inner.get(index);
|
|
1279
1469
|
}
|
|
1280
|
-
|
|
1470
|
+
/**
|
|
1471
|
+
Set the value for this syntax node.
|
|
1472
|
+
*/
|
|
1281
1473
|
set(node, value) {
|
|
1282
1474
|
if (node instanceof BufferNode)
|
|
1283
1475
|
this.setBuffer(node.context.buffer, node.index, value);
|
|
1284
1476
|
else if (node instanceof TreeNode)
|
|
1285
1477
|
this.map.set(node.tree, value);
|
|
1286
1478
|
}
|
|
1287
|
-
|
|
1479
|
+
/**
|
|
1480
|
+
Retrieve value for this syntax node, if it exists in the map.
|
|
1481
|
+
*/
|
|
1288
1482
|
get(node) {
|
|
1289
1483
|
return node instanceof BufferNode ? this.getBuffer(node.context.buffer, node.index)
|
|
1290
1484
|
: node instanceof TreeNode ? this.map.get(node.tree) : undefined;
|
|
1291
1485
|
}
|
|
1292
|
-
|
|
1486
|
+
/**
|
|
1487
|
+
Set the value for the node that a cursor currently points to.
|
|
1488
|
+
*/
|
|
1293
1489
|
cursorSet(cursor, value) {
|
|
1294
1490
|
if (cursor.buffer)
|
|
1295
1491
|
this.setBuffer(cursor.buffer.buffer, cursor.index, value);
|
|
1296
1492
|
else
|
|
1297
1493
|
this.map.set(cursor.tree, value);
|
|
1298
1494
|
}
|
|
1299
|
-
|
|
1300
|
-
|
|
1495
|
+
/**
|
|
1496
|
+
Retrieve the value for the node that a cursor currently points
|
|
1497
|
+
to.
|
|
1498
|
+
*/
|
|
1301
1499
|
cursorGet(cursor) {
|
|
1302
1500
|
return cursor.buffer ? this.getBuffer(cursor.buffer.buffer, cursor.index) : this.map.get(cursor.tree);
|
|
1303
1501
|
}
|
|
1304
1502
|
}
|
|
1305
1503
|
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1504
|
+
/**
|
|
1505
|
+
Tree fragments are used during [incremental
|
|
1506
|
+
parsing](#common.Parser.startParse) to track parts of old trees
|
|
1507
|
+
that can be reused in a new parse. An array of fragments is used
|
|
1508
|
+
to track regions of an old tree whose nodes might be reused in new
|
|
1509
|
+
parses. Use the static
|
|
1510
|
+
[`applyChanges`](#common.TreeFragment^applyChanges) method to
|
|
1511
|
+
update fragments for document changes.
|
|
1512
|
+
*/
|
|
1313
1513
|
class TreeFragment {
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1514
|
+
/**
|
|
1515
|
+
Construct a tree fragment. You'll usually want to use
|
|
1516
|
+
[`addTree`](#common.TreeFragment^addTree) and
|
|
1517
|
+
[`applyChanges`](#common.TreeFragment^applyChanges) instead of
|
|
1518
|
+
calling this directly.
|
|
1519
|
+
*/
|
|
1318
1520
|
constructor(
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1521
|
+
/**
|
|
1522
|
+
The start of the unchanged range pointed to by this fragment.
|
|
1523
|
+
This refers to an offset in the _updated_ document (as opposed
|
|
1524
|
+
to the original tree).
|
|
1525
|
+
*/
|
|
1322
1526
|
from,
|
|
1323
|
-
|
|
1527
|
+
/**
|
|
1528
|
+
The end of the unchanged range.
|
|
1529
|
+
*/
|
|
1324
1530
|
to,
|
|
1325
|
-
|
|
1531
|
+
/**
|
|
1532
|
+
The tree that this fragment is based on.
|
|
1533
|
+
*/
|
|
1326
1534
|
tree,
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1535
|
+
/**
|
|
1536
|
+
The offset between the fragment's tree and the document that
|
|
1537
|
+
this fragment can be used against. Add this when going from
|
|
1538
|
+
document to tree positions, subtract it to go from tree to
|
|
1539
|
+
document positions.
|
|
1540
|
+
*/
|
|
1331
1541
|
offset, openStart = false, openEnd = false) {
|
|
1332
1542
|
this.from = from;
|
|
1333
1543
|
this.to = to;
|
|
@@ -1335,20 +1545,26 @@ class TreeFragment {
|
|
|
1335
1545
|
this.offset = offset;
|
|
1336
1546
|
this.open = (openStart ? 1 /* Open.Start */ : 0) | (openEnd ? 2 /* Open.End */ : 0);
|
|
1337
1547
|
}
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1548
|
+
/**
|
|
1549
|
+
Whether the start of the fragment represents the start of a
|
|
1550
|
+
parse, or the end of a change. (In the second case, it may not
|
|
1551
|
+
be safe to reuse some nodes at the start, depending on the
|
|
1552
|
+
parsing algorithm.)
|
|
1553
|
+
*/
|
|
1342
1554
|
get openStart() { return (this.open & 1 /* Open.Start */) > 0; }
|
|
1343
|
-
|
|
1344
|
-
|
|
1555
|
+
/**
|
|
1556
|
+
Whether the end of the fragment represents the end of a
|
|
1557
|
+
full-document parse, or the start of a change.
|
|
1558
|
+
*/
|
|
1345
1559
|
get openEnd() { return (this.open & 2 /* Open.End */) > 0; }
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1560
|
+
/**
|
|
1561
|
+
Create a set of fragments from a freshly parsed tree, or update
|
|
1562
|
+
an existing set of fragments by replacing the ones that overlap
|
|
1563
|
+
with a tree with content from the new tree. When `partial` is
|
|
1564
|
+
true, the parse is treated as incomplete, and the resulting
|
|
1565
|
+
fragment has [`openEnd`](#common.TreeFragment.openEnd) set to
|
|
1566
|
+
true.
|
|
1567
|
+
*/
|
|
1352
1568
|
static addTree(tree, fragments = [], partial = false) {
|
|
1353
1569
|
let result = [new TreeFragment(0, tree.length, tree, 0, false, partial)];
|
|
1354
1570
|
for (let f of fragments)
|
|
@@ -1356,9 +1572,11 @@ class TreeFragment {
|
|
|
1356
1572
|
result.push(f);
|
|
1357
1573
|
return result;
|
|
1358
1574
|
}
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1575
|
+
/**
|
|
1576
|
+
Apply a set of edits to an array of fragments, removing or
|
|
1577
|
+
splitting fragments as necessary to remove edited ranges, and
|
|
1578
|
+
adjusting offsets for fragments that moved.
|
|
1579
|
+
*/
|
|
1362
1580
|
static applyChanges(fragments, changes, minGap = 128) {
|
|
1363
1581
|
if (!changes.length)
|
|
1364
1582
|
return fragments;
|
|
@@ -1388,23 +1606,29 @@ class TreeFragment {
|
|
|
1388
1606
|
return result;
|
|
1389
1607
|
}
|
|
1390
1608
|
}
|
|
1391
|
-
|
|
1609
|
+
/**
|
|
1610
|
+
A superclass that parsers should extend.
|
|
1611
|
+
*/
|
|
1392
1612
|
class Parser {
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1613
|
+
/**
|
|
1614
|
+
Start a parse, returning a [partial parse](#common.PartialParse)
|
|
1615
|
+
object. [`fragments`](#common.TreeFragment) can be passed in to
|
|
1616
|
+
make the parse incremental.
|
|
1617
|
+
|
|
1618
|
+
By default, the entire input is parsed. You can pass `ranges`,
|
|
1619
|
+
which should be a sorted array of non-empty, non-overlapping
|
|
1620
|
+
ranges, to parse only those ranges. The tree returned in that
|
|
1621
|
+
case will start at `ranges[0].from`.
|
|
1622
|
+
*/
|
|
1401
1623
|
startParse(input, fragments, ranges) {
|
|
1402
1624
|
if (typeof input == "string")
|
|
1403
1625
|
input = new StringInput(input);
|
|
1404
1626
|
ranges = !ranges ? [new Range(0, input.length)] : ranges.length ? ranges.map(r => new Range(r.from, r.to)) : [new Range(0, 0)];
|
|
1405
1627
|
return this.createParse(input, fragments || [], ranges);
|
|
1406
1628
|
}
|
|
1407
|
-
|
|
1629
|
+
/**
|
|
1630
|
+
Run a full parse, returning the resulting tree.
|
|
1631
|
+
*/
|
|
1408
1632
|
parse(input, fragments, ranges) {
|
|
1409
1633
|
let parse = this.startParse(input, fragments, ranges);
|
|
1410
1634
|
for (;;) {
|
|
@@ -1424,11 +1648,13 @@ class StringInput {
|
|
|
1424
1648
|
read(from, to) { return this.string.slice(from, to); }
|
|
1425
1649
|
}
|
|
1426
1650
|
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1651
|
+
/**
|
|
1652
|
+
Create a parse wrapper that, after the inner parse completes,
|
|
1653
|
+
scans its tree for mixed language regions with the `nest`
|
|
1654
|
+
function, runs the resulting [inner parses](#common.NestedParse),
|
|
1655
|
+
and then [mounts](#common.NodeProp^mounted) their results onto the
|
|
1656
|
+
tree.
|
|
1657
|
+
*/
|
|
1432
1658
|
function parseMixed(nest) {
|
|
1433
1659
|
return (parse, input, fragments, ranges) => new MixedParse(parse, nest, input, fragments, ranges);
|
|
1434
1660
|
}
|