@lezer/common 0.15.9 → 0.15.12

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 CHANGED
@@ -213,7 +213,7 @@ class NodeSet {
213
213
  return new NodeSet(newTypes);
214
214
  }
215
215
  }
216
- const CachedNode = new WeakMap();
216
+ const CachedNode = new WeakMap(), CachedInnerNode = new WeakMap();
217
217
  /// A piece of syntax tree. There are two ways to approach these
218
218
  /// trees: the way they are actually stored in memory, and the
219
219
  /// convenient way.
@@ -302,7 +302,9 @@ class Tree {
302
302
  /// position. With 0, it'll only enter nodes that cover the position
303
303
  /// from both sides.
304
304
  resolve(pos, side = 0) {
305
- return this.cursor(pos, side).node;
305
+ let node = resolveNode(CachedNode.get(this) || this.topNode, pos, side, false);
306
+ CachedNode.set(this, node);
307
+ return node;
306
308
  }
307
309
  /// Like [`resolve`](#common.Tree.resolve), but will enter
308
310
  /// [overlaid](#common.MountedTree.overlay) nodes, producing a syntax node
@@ -310,13 +312,9 @@ class Tree {
310
312
  /// (with parent links going through all parent structure, including
311
313
  /// the host trees).
312
314
  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
- }
315
+ let node = resolveNode(CachedInnerNode.get(this) || this.topNode, pos, side, true);
316
+ CachedInnerNode.set(this, node);
317
+ return node;
320
318
  }
321
319
  /// Iterate over the tree and its children, calling `enter` for any
322
320
  /// node that touches the `from`/`to` region (if given) before
@@ -481,6 +479,30 @@ function enterUnfinishedNodesBefore(node, pos) {
481
479
  }
482
480
  return node;
483
481
  }
482
+ function resolveNode(node, pos, side, overlays) {
483
+ var _a;
484
+ // Move up to a node that actually holds the position, if possible
485
+ while (node.from == node.to ||
486
+ (side < 1 ? node.from >= pos : node.from > pos) ||
487
+ (side > -1 ? node.to <= pos : node.to < pos)) {
488
+ let parent = !overlays && node instanceof TreeNode && node.index < 0 ? null : node.parent;
489
+ if (!parent)
490
+ return node;
491
+ node = parent;
492
+ }
493
+ // Must go up out of overlays when those do not overlap with pos
494
+ if (overlays)
495
+ for (let scan = node, parent = scan.parent; parent; scan = parent, parent = scan.parent) {
496
+ if (scan instanceof TreeNode && scan.index < 0 && ((_a = parent.enter(pos, side, true)) === null || _a === void 0 ? void 0 : _a.from) != scan.from)
497
+ node = parent;
498
+ }
499
+ for (;;) {
500
+ let inner = node.enter(pos, side, overlays);
501
+ if (!inner)
502
+ return node;
503
+ node = inner;
504
+ }
505
+ }
484
506
  class TreeNode {
485
507
  constructor(node, _from,
486
508
  // Index in parent node, set to -1 if the node is not a direct child of _parent.node (overlay)
@@ -562,7 +584,10 @@ class TreeNode {
562
584
  get tree() { return this.node; }
563
585
  toTree() { return this.node; }
564
586
  resolve(pos, side = 0) {
565
- return this.cursor.moveTo(pos, side).node;
587
+ return resolveNode(this, pos, side, false);
588
+ }
589
+ resolveInner(pos, side = 0) {
590
+ return resolveNode(this, pos, side, true);
566
591
  }
567
592
  enterUnfinishedNodesBefore(pos) { return enterUnfinishedNodesBefore(this, pos); }
568
593
  getChild(type, before = null, after = null) {
@@ -660,7 +685,10 @@ class BufferNode {
660
685
  return new Tree(this.type, children, positions, this.to - this.from);
661
686
  }
662
687
  resolve(pos, side = 0) {
663
- return this.cursor.moveTo(pos, side).node;
688
+ return resolveNode(this, pos, side, false);
689
+ }
690
+ resolveInner(pos, side = 0) {
691
+ return resolveNode(this, pos, side, true);
664
692
  }
665
693
  enterUnfinishedNodesBefore(pos) { return enterUnfinishedNodesBefore(this, pos); }
666
694
  /// @internal
@@ -1317,6 +1345,9 @@ class MixedParse {
1317
1345
  this.baseParse = null;
1318
1346
  this.baseTree = done;
1319
1347
  this.startInner();
1348
+ if (this.stoppedAt != null)
1349
+ for (let inner of this.inner)
1350
+ inner.parse.stopAt(this.stoppedAt);
1320
1351
  }
1321
1352
  if (this.innerDone == this.inner.length) {
1322
1353
  let result = this.baseTree;
@@ -1360,7 +1391,7 @@ class MixedParse {
1360
1391
  let overlay = null;
1361
1392
  let covered = null;
1362
1393
  let cursor = new TreeCursor(new TreeNode(this.baseTree, this.ranges[0].from, 0, null), 1 /* Full */);
1363
- scan: for (let nest, isCovered;;) {
1394
+ scan: for (let nest, isCovered; this.stoppedAt == null || cursor.from < this.stoppedAt;) {
1364
1395
  let enter = true, range;
1365
1396
  if (fragmentCursor.hasNode(cursor)) {
1366
1397
  if (overlay) {
@@ -1368,7 +1399,7 @@ class MixedParse {
1368
1399
  if (match)
1369
1400
  for (let r of match.mount.overlay) {
1370
1401
  let from = r.from + match.pos, to = r.to + match.pos;
1371
- if (from >= cursor.from && to <= cursor.to)
1402
+ if (from >= cursor.from && to <= cursor.to && !overlay.ranges.some(r => r.from < to && r.to > from))
1372
1403
  overlay.ranges.push({ from, to });
1373
1404
  }
1374
1405
  }
@@ -1465,20 +1496,20 @@ function materialize(cursor) {
1465
1496
  let buf = base.children[i], b = buf.buffer;
1466
1497
  // Split a level in the buffer, putting the nodes before and after
1467
1498
  // the child that contains `node` into new buffers.
1468
- function split(startI, endI, type, innerOffset) {
1499
+ function split(startI, endI, type, innerOffset, length) {
1469
1500
  let i = startI;
1470
1501
  while (b[i + 2] + off <= node.from)
1471
1502
  i = b[i + 3];
1472
1503
  let children = [], positions = [];
1473
1504
  sliceBuf(buf, startI, i, children, positions, innerOffset);
1474
- let isTarget = b[i + 1] + off == node.from && b[i + 2] + off == node.to && b[i] == node.type.id;
1475
- children.push(isTarget ? node.toTree() : split(i + 4, b[i + 3], buf.set.types[b[i]], b[i + 1]));
1476
- positions.push(b[i + 1] - innerOffset);
1505
+ let from = b[i + 1], to = b[i + 2];
1506
+ let isTarget = from + off == node.from && to + off == node.to && b[i] == node.type.id;
1507
+ children.push(isTarget ? node.toTree() : split(i + 4, b[i + 3], buf.set.types[b[i]], from, to - from));
1508
+ positions.push(from - innerOffset);
1477
1509
  sliceBuf(buf, b[i + 3], endI, children, positions, innerOffset);
1478
- let last = children.length - 1;
1479
- return new Tree(type, children, positions, positions[last] + children[last].length);
1510
+ return new Tree(type, children, positions, length);
1480
1511
  }
1481
- base.children[i] = split(0, b.length, NodeType.none, 0);
1512
+ base.children[i] = split(0, b.length, NodeType.none, 0, buf.length);
1482
1513
  // Move the cursor back to the target node
1483
1514
  for (let d = 0; d <= depth; d++)
1484
1515
  cursor.childAfter(node.from);
package/dist/index.js CHANGED
@@ -209,7 +209,7 @@ class NodeSet {
209
209
  return new NodeSet(newTypes);
210
210
  }
211
211
  }
212
- const CachedNode = new WeakMap();
212
+ const CachedNode = new WeakMap(), CachedInnerNode = new WeakMap();
213
213
  /// A piece of syntax tree. There are two ways to approach these
214
214
  /// trees: the way they are actually stored in memory, and the
215
215
  /// convenient way.
@@ -298,7 +298,9 @@ class Tree {
298
298
  /// position. With 0, it'll only enter nodes that cover the position
299
299
  /// from both sides.
300
300
  resolve(pos, side = 0) {
301
- return this.cursor(pos, side).node;
301
+ let node = resolveNode(CachedNode.get(this) || this.topNode, pos, side, false);
302
+ CachedNode.set(this, node);
303
+ return node;
302
304
  }
303
305
  /// Like [`resolve`](#common.Tree.resolve), but will enter
304
306
  /// [overlaid](#common.MountedTree.overlay) nodes, producing a syntax node
@@ -306,13 +308,9 @@ class Tree {
306
308
  /// (with parent links going through all parent structure, including
307
309
  /// the host trees).
308
310
  resolveInner(pos, side = 0) {
309
- let result = this.topNode;
310
- for (;;) {
311
- let inner = result.enter(pos, side);
312
- if (!inner)
313
- return result;
314
- result = inner;
315
- }
311
+ let node = resolveNode(CachedInnerNode.get(this) || this.topNode, pos, side, true);
312
+ CachedInnerNode.set(this, node);
313
+ return node;
316
314
  }
317
315
  /// Iterate over the tree and its children, calling `enter` for any
318
316
  /// node that touches the `from`/`to` region (if given) before
@@ -477,6 +475,30 @@ function enterUnfinishedNodesBefore(node, pos) {
477
475
  }
478
476
  return node;
479
477
  }
478
+ function resolveNode(node, pos, side, overlays) {
479
+ var _a;
480
+ // Move up to a node that actually holds the position, if possible
481
+ while (node.from == node.to ||
482
+ (side < 1 ? node.from >= pos : node.from > pos) ||
483
+ (side > -1 ? node.to <= pos : node.to < pos)) {
484
+ let parent = !overlays && node instanceof TreeNode && node.index < 0 ? null : node.parent;
485
+ if (!parent)
486
+ return node;
487
+ node = parent;
488
+ }
489
+ // Must go up out of overlays when those do not overlap with pos
490
+ if (overlays)
491
+ for (let scan = node, parent = scan.parent; parent; scan = parent, parent = scan.parent) {
492
+ if (scan instanceof TreeNode && scan.index < 0 && ((_a = parent.enter(pos, side, true)) === null || _a === void 0 ? void 0 : _a.from) != scan.from)
493
+ node = parent;
494
+ }
495
+ for (;;) {
496
+ let inner = node.enter(pos, side, overlays);
497
+ if (!inner)
498
+ return node;
499
+ node = inner;
500
+ }
501
+ }
480
502
  class TreeNode {
481
503
  constructor(node, _from,
482
504
  // Index in parent node, set to -1 if the node is not a direct child of _parent.node (overlay)
@@ -558,7 +580,10 @@ class TreeNode {
558
580
  get tree() { return this.node; }
559
581
  toTree() { return this.node; }
560
582
  resolve(pos, side = 0) {
561
- return this.cursor.moveTo(pos, side).node;
583
+ return resolveNode(this, pos, side, false);
584
+ }
585
+ resolveInner(pos, side = 0) {
586
+ return resolveNode(this, pos, side, true);
562
587
  }
563
588
  enterUnfinishedNodesBefore(pos) { return enterUnfinishedNodesBefore(this, pos); }
564
589
  getChild(type, before = null, after = null) {
@@ -656,7 +681,10 @@ class BufferNode {
656
681
  return new Tree(this.type, children, positions, this.to - this.from);
657
682
  }
658
683
  resolve(pos, side = 0) {
659
- return this.cursor.moveTo(pos, side).node;
684
+ return resolveNode(this, pos, side, false);
685
+ }
686
+ resolveInner(pos, side = 0) {
687
+ return resolveNode(this, pos, side, true);
660
688
  }
661
689
  enterUnfinishedNodesBefore(pos) { return enterUnfinishedNodesBefore(this, pos); }
662
690
  /// @internal
@@ -1313,6 +1341,9 @@ class MixedParse {
1313
1341
  this.baseParse = null;
1314
1342
  this.baseTree = done;
1315
1343
  this.startInner();
1344
+ if (this.stoppedAt != null)
1345
+ for (let inner of this.inner)
1346
+ inner.parse.stopAt(this.stoppedAt);
1316
1347
  }
1317
1348
  if (this.innerDone == this.inner.length) {
1318
1349
  let result = this.baseTree;
@@ -1356,7 +1387,7 @@ class MixedParse {
1356
1387
  let overlay = null;
1357
1388
  let covered = null;
1358
1389
  let cursor = new TreeCursor(new TreeNode(this.baseTree, this.ranges[0].from, 0, null), 1 /* Full */);
1359
- scan: for (let nest, isCovered;;) {
1390
+ scan: for (let nest, isCovered; this.stoppedAt == null || cursor.from < this.stoppedAt;) {
1360
1391
  let enter = true, range;
1361
1392
  if (fragmentCursor.hasNode(cursor)) {
1362
1393
  if (overlay) {
@@ -1364,7 +1395,7 @@ class MixedParse {
1364
1395
  if (match)
1365
1396
  for (let r of match.mount.overlay) {
1366
1397
  let from = r.from + match.pos, to = r.to + match.pos;
1367
- if (from >= cursor.from && to <= cursor.to)
1398
+ if (from >= cursor.from && to <= cursor.to && !overlay.ranges.some(r => r.from < to && r.to > from))
1368
1399
  overlay.ranges.push({ from, to });
1369
1400
  }
1370
1401
  }
@@ -1461,20 +1492,20 @@ function materialize(cursor) {
1461
1492
  let buf = base.children[i], b = buf.buffer;
1462
1493
  // Split a level in the buffer, putting the nodes before and after
1463
1494
  // the child that contains `node` into new buffers.
1464
- function split(startI, endI, type, innerOffset) {
1495
+ function split(startI, endI, type, innerOffset, length) {
1465
1496
  let i = startI;
1466
1497
  while (b[i + 2] + off <= node.from)
1467
1498
  i = b[i + 3];
1468
1499
  let children = [], positions = [];
1469
1500
  sliceBuf(buf, startI, i, children, positions, innerOffset);
1470
- let isTarget = b[i + 1] + off == node.from && b[i + 2] + off == node.to && b[i] == node.type.id;
1471
- children.push(isTarget ? node.toTree() : split(i + 4, b[i + 3], buf.set.types[b[i]], b[i + 1]));
1472
- positions.push(b[i + 1] - innerOffset);
1501
+ let from = b[i + 1], to = b[i + 2];
1502
+ let isTarget = from + off == node.from && to + off == node.to && b[i] == node.type.id;
1503
+ children.push(isTarget ? node.toTree() : split(i + 4, b[i + 3], buf.set.types[b[i]], from, to - from));
1504
+ positions.push(from - innerOffset);
1473
1505
  sliceBuf(buf, b[i + 3], endI, children, positions, innerOffset);
1474
- let last = children.length - 1;
1475
- return new Tree(type, children, positions, positions[last] + children[last].length);
1506
+ return new Tree(type, children, positions, length);
1476
1507
  }
1477
- base.children[i] = split(0, b.length, NodeType.none, 0);
1508
+ base.children[i] = split(0, b.length, NodeType.none, 0, buf.length);
1478
1509
  // Move the cursor back to the target node
1479
1510
  for (let d = 0; d <= depth; d++)
1480
1511
  cursor.childAfter(node.from);
package/dist/tree.d.ts CHANGED
@@ -128,6 +128,7 @@ export interface SyntaxNode {
128
128
  prevSibling: SyntaxNode | null;
129
129
  cursor: TreeCursor;
130
130
  resolve(pos: number, side?: -1 | 0 | 1): SyntaxNode;
131
+ resolveInner(pos: number, side?: -1 | 0 | 1): SyntaxNode;
131
132
  enterUnfinishedNodesBefore(pos: number): SyntaxNode;
132
133
  tree: Tree | null;
133
134
  toTree(): Tree;
@@ -170,6 +171,7 @@ export declare class TreeNode implements SyntaxNode {
170
171
  get tree(): Tree;
171
172
  toTree(): Tree;
172
173
  resolve(pos: number, side?: -1 | 0 | 1): SyntaxNode;
174
+ resolveInner(pos: number, side?: -1 | 0 | 1): SyntaxNode;
173
175
  enterUnfinishedNodesBefore(pos: number): SyntaxNode;
174
176
  getChild(type: string | number, before?: string | number | null, after?: string | number | null): SyntaxNode;
175
177
  getChildren(type: string | number, before?: string | number | null, after?: string | number | null): SyntaxNode[];
@@ -204,6 +206,7 @@ declare class BufferNode implements SyntaxNode {
204
206
  get tree(): any;
205
207
  toTree(): Tree;
206
208
  resolve(pos: number, side?: -1 | 0 | 1): SyntaxNode;
209
+ resolveInner(pos: number, side?: -1 | 0 | 1): SyntaxNode;
207
210
  enterUnfinishedNodesBefore(pos: number): SyntaxNode;
208
211
  getChild(type: string | number, before?: string | number | null, after?: string | number | null): SyntaxNode;
209
212
  getChildren(type: string | number, before?: string | number | null, after?: string | number | null): SyntaxNode[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lezer/common",
3
- "version": "0.15.9",
3
+ "version": "0.15.12",
4
4
  "description": "Syntax tree data structure and parser interfaces for the lezer parser",
5
5
  "main": "dist/index.cjs",
6
6
  "type": "module",
@@ -1,42 +0,0 @@
1
- import { Tree, SyntaxNode } from "./tree";
2
- import { Parser, PartialParse, TreeFragment, Input } from "./parse";
3
- export declare class SubtreeRange {
4
- constructor(from: number, to: number, parser: Parser, cont?: any);
5
- }
6
- export declare class CompositeParser extends Parser {
7
- private subtreeRanges;
8
- private subtreeCache;
9
- constructor(main: Parser, subtreeRanges: {
10
- [nodeID: number]: (node: SyntaxNode, input: Input) => (readonly SubtreeRange[] | null);
11
- });
12
- startParseInner(input: Input, fragments: readonly TreeFragment[], ranges: readonly {
13
- from: number;
14
- to: number;
15
- }[]): CompositeParse;
16
- }
17
- declare class CompositeParse implements PartialParse {
18
- readonly input: Input;
19
- readonly fragments: readonly TreeFragment[];
20
- readonly ranges: readonly {
21
- from: number;
22
- to: number;
23
- }[];
24
- readonly parser: CompositeParser;
25
- main: PartialParse;
26
- mainResult: Tree | null;
27
- mainSub: Tree[];
28
- inner: PartialParse[];
29
- subtrees: Tree[];
30
- stoppedAt: number | null;
31
- constructor(input: Input, fragments: readonly TreeFragment[], ranges: readonly {
32
- from: number;
33
- to: number;
34
- }[], parser: CompositeParser);
35
- advance(): Tree | null;
36
- private startSub;
37
- private startInner;
38
- private reuseInner;
39
- stopAt(pos: number): void;
40
- get parsedPos(): number;
41
- }
42
- export {};
package/dist/frame.d.ts DELETED
@@ -1,25 +0,0 @@
1
- import { Parser, ParseSpec, FullParseSpec, PartialParse } from "./parse";
2
- import { Tree, NodeType } from "./tree";
3
- export declare class FramingParser extends Parser {
4
- constructor(config: {
5
- frame: Parser;
6
- fill: Parser;
7
- frameNodes: readonly NodeType[];
8
- });
9
- startParse(spec: ParseSpec): FramingParse;
10
- }
11
- declare class FramingParse implements PartialParse {
12
- readonly parser: FramingParser;
13
- readonly spec: FullParseSpec;
14
- outerTree: Tree | null;
15
- outer: PartialParse;
16
- inner: PartialParse | null;
17
- stoppedAt: null | number;
18
- constructor(parser: FramingParser, spec: FullParseSpec);
19
- get parsedPos(): number;
20
- advance(): Tree;
21
- stopAt(pos: number): void;
22
- private startInner;
23
- private finishParse;
24
- }
25
- export {};
@@ -1,25 +0,0 @@
1
- import { Parser, ParseSpec, FullParseSpec, PartialParse } from "./parse";
2
- import { Tree, NodeType } from "./tree";
3
- export declare class ScaffoldParser extends Parser {
4
- constructor(config: {
5
- scaffold: Parser;
6
- fill: Parser;
7
- scaffoldNodes: readonly NodeType[];
8
- });
9
- startParse(spec: ParseSpec): ScaffoldParse;
10
- }
11
- declare class ScaffoldParse implements PartialParse {
12
- readonly parser: ScaffoldParser;
13
- readonly spec: FullParseSpec;
14
- outerTree: Tree | null;
15
- outer: PartialParse;
16
- inner: PartialParse | null;
17
- stoppedAt: null | number;
18
- constructor(parser: ScaffoldParser, spec: FullParseSpec);
19
- get parsedPos(): number;
20
- advance(): Tree;
21
- stopAt(pos: number): void;
22
- private startInner;
23
- private finishParse;
24
- }
25
- export {};