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