@lezer/common 0.15.6 → 0.15.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs 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.
@@ -286,7 +286,8 @@ class Tree {
286
286
  }
287
287
  /// Get a [tree cursor](#common.TreeCursor) that, unlike regular
288
288
  /// cursors, doesn't skip through
289
- /// [anonymous](#common.NodeType.isAnonymous) nodes.
289
+ /// [anonymous](#common.NodeType.isAnonymous) nodes and doesn't
290
+ /// automatically enter mounted nodes.
290
291
  fullCursor() {
291
292
  return new TreeCursor(this.topNode, 1 /* Full */);
292
293
  }
@@ -301,7 +302,9 @@ class Tree {
301
302
  /// position. With 0, it'll only enter nodes that cover the position
302
303
  /// from both sides.
303
304
  resolve(pos, side = 0) {
304
- 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;
305
308
  }
306
309
  /// Like [`resolve`](#common.Tree.resolve), but will enter
307
310
  /// [overlaid](#common.MountedTree.overlay) nodes, producing a syntax node
@@ -309,13 +312,9 @@ class Tree {
309
312
  /// (with parent links going through all parent structure, including
310
313
  /// the host trees).
311
314
  resolveInner(pos, side = 0) {
312
- let result = this.topNode;
313
- for (;;) {
314
- let inner = result.enter(pos, side);
315
- if (!inner)
316
- return result;
317
- result = inner;
318
- }
315
+ let node = resolveNode(CachedInnerNode.get(this) || this.topNode, pos, side, true);
316
+ CachedInnerNode.set(this, node);
317
+ return node;
319
318
  }
320
319
  /// Iterate over the tree and its children, calling `enter` for any
321
320
  /// node that touches the `from`/`to` region (if given) before
@@ -364,7 +363,7 @@ class Tree {
364
363
  /// [`NodeType.none`](#common.NodeType^none).
365
364
  balance(config = {}) {
366
365
  return this.children.length <= 8 /* BranchFactor */ ? this :
367
- balanceRange(this.type, 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)));
366
+ 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)));
368
367
  }
369
368
  /// Build a tree from a postfix-ordered buffer of node information,
370
369
  /// or a cursor over such a buffer.
@@ -480,6 +479,30 @@ function enterUnfinishedNodesBefore(node, pos) {
480
479
  }
481
480
  return node;
482
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
+ }
483
506
  class TreeNode {
484
507
  constructor(node, _from,
485
508
  // Index in parent node, set to -1 if the node is not a direct child of _parent.node (overlay)
@@ -508,7 +531,7 @@ class TreeNode {
508
531
  }
509
532
  else if ((mode & 1 /* Full */) || (!next.type.isAnonymous || hasChild(next))) {
510
533
  let mounted;
511
- if (next.props && (mounted = next.prop(NodeProp.mounted)) && !mounted.overlay)
534
+ if (!(mode & 1 /* Full */) && next.props && (mounted = next.prop(NodeProp.mounted)) && !mounted.overlay)
512
535
  return new TreeNode(mounted.tree, start, i, parent);
513
536
  let inner = new TreeNode(next, start, i, parent);
514
537
  return (mode & 1 /* Full */) || !inner.type.isAnonymous ? inner
@@ -561,7 +584,10 @@ class TreeNode {
561
584
  get tree() { return this.node; }
562
585
  toTree() { return this.node; }
563
586
  resolve(pos, side = 0) {
564
- 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);
565
591
  }
566
592
  enterUnfinishedNodesBefore(pos) { return enterUnfinishedNodesBefore(this, pos); }
567
593
  getChild(type, before = null, after = null) {
@@ -659,7 +685,10 @@ class BufferNode {
659
685
  return new Tree(this.type, children, positions, this.to - this.from);
660
686
  }
661
687
  resolve(pos, side = 0) {
662
- 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);
663
692
  }
664
693
  enterUnfinishedNodesBefore(pos) { return enterUnfinishedNodesBefore(this, pos); }
665
694
  /// @internal
@@ -756,10 +785,10 @@ class TreeCursor {
756
785
  /// set to false.
757
786
  enter(pos, side, overlays = true, buffers = true) {
758
787
  if (!this.buffer)
759
- return this.yield(this._tree.enter(pos, side, overlays, buffers));
788
+ return this.yield(this._tree.enter(pos, side, overlays && !(this.mode & 1 /* Full */), buffers));
760
789
  return buffers ? this.enterChild(1, pos, side) : false;
761
790
  }
762
- /// Move the node's parent node, if this isn't the top node.
791
+ /// Move to the node's parent node, if this isn't the top node.
763
792
  parent() {
764
793
  if (!this.buffer)
765
794
  return this.yieldNode((this.mode & 1 /* Full */) ? this._tree._parent : this._tree.parent);
@@ -1081,15 +1110,21 @@ function nodeSize(balanceType, node) {
1081
1110
  return 1;
1082
1111
  let size = nodeSizeCache.get(node);
1083
1112
  if (size == null) {
1084
- size = node.children.reduce((s, ch) => s + nodeSize(balanceType, ch), 1);
1113
+ size = 1;
1114
+ for (let child of node.children) {
1115
+ if (child.type != balanceType || !(child instanceof Tree)) {
1116
+ size = 1;
1117
+ break;
1118
+ }
1119
+ size += nodeSize(balanceType, child);
1120
+ }
1085
1121
  nodeSizeCache.set(node, size);
1086
1122
  }
1087
1123
  return size;
1088
1124
  }
1089
1125
  function balanceRange(
1090
- // The type to tag the resulting tree with. Will also be used for
1091
- // internal nodes when it is an anonymous type
1092
- type,
1126
+ // The type the balanced tree's inner nodes.
1127
+ balanceType,
1093
1128
  // The direct children and their positions
1094
1129
  children, positions,
1095
1130
  // The index range in children/positions to use
@@ -1104,22 +1139,22 @@ mkTop,
1104
1139
  mkTree) {
1105
1140
  let total = 0;
1106
1141
  for (let i = from; i < to; i++)
1107
- total += nodeSize(type, children[i]);
1142
+ total += nodeSize(balanceType, children[i]);
1108
1143
  let maxChild = Math.ceil((total * 1.5) / 8 /* BranchFactor */);
1109
1144
  let localChildren = [], localPositions = [];
1110
1145
  function divide(children, positions, from, to, offset) {
1111
1146
  for (let i = from; i < to;) {
1112
- let groupFrom = i, groupStart = positions[i], groupSize = nodeSize(type, children[i]);
1147
+ let groupFrom = i, groupStart = positions[i], groupSize = nodeSize(balanceType, children[i]);
1113
1148
  i++;
1114
1149
  for (; i < to; i++) {
1115
- let nextSize = nodeSize(type, children[i]);
1150
+ let nextSize = nodeSize(balanceType, children[i]);
1116
1151
  if (groupSize + nextSize >= maxChild)
1117
1152
  break;
1118
1153
  groupSize += nextSize;
1119
1154
  }
1120
1155
  if (i == groupFrom + 1) {
1121
1156
  if (groupSize > maxChild) {
1122
- let only = children[groupFrom];
1157
+ let only = children[groupFrom]; // Only trees can have a size > 1
1123
1158
  divide(only.children, only.positions, 0, only.children.length, positions[groupFrom] + offset);
1124
1159
  continue;
1125
1160
  }
@@ -1127,7 +1162,7 @@ mkTree) {
1127
1162
  }
1128
1163
  else {
1129
1164
  let length = positions[i - 1] + children[i - 1].length - groupStart;
1130
- localChildren.push(balanceRange(type, children, positions, groupFrom, i, groupStart, length, null, mkTree));
1165
+ localChildren.push(balanceRange(balanceType, children, positions, groupFrom, i, groupStart, length, null, mkTree));
1131
1166
  }
1132
1167
  localPositions.push(groupStart + offset - start);
1133
1168
  }
@@ -1268,11 +1303,12 @@ function parseMixed(nest) {
1268
1303
  return (parse, input, fragments, ranges) => new MixedParse(parse, nest, input, fragments, ranges);
1269
1304
  }
1270
1305
  class InnerParse {
1271
- constructor(parser, parse, overlay, target) {
1306
+ constructor(parser, parse, overlay, target, ranges) {
1272
1307
  this.parser = parser;
1273
1308
  this.parse = parse;
1274
1309
  this.overlay = overlay;
1275
1310
  this.target = target;
1311
+ this.ranges = ranges;
1276
1312
  }
1277
1313
  }
1278
1314
  class ActiveOverlay {
@@ -1288,6 +1324,7 @@ class ActiveOverlay {
1288
1324
  this.ranges = [];
1289
1325
  }
1290
1326
  }
1327
+ const stoppedInner = new NodeProp({ perNode: true });
1291
1328
  class MixedParse {
1292
1329
  constructor(base, nest, input, fragments, ranges) {
1293
1330
  this.nest = nest;
@@ -1308,9 +1345,16 @@ class MixedParse {
1308
1345
  this.baseParse = null;
1309
1346
  this.baseTree = done;
1310
1347
  this.startInner();
1348
+ if (this.stoppedAt != null)
1349
+ for (let inner of this.inner)
1350
+ inner.parse.stopAt(this.stoppedAt);
1351
+ }
1352
+ if (this.innerDone == this.inner.length) {
1353
+ let result = this.baseTree;
1354
+ if (this.stoppedAt != null)
1355
+ result = new Tree(result.type, result.children, result.positions, result.length, result.propValues.concat([[stoppedInner, this.stoppedAt]]));
1356
+ return result;
1311
1357
  }
1312
- if (this.innerDone == this.inner.length)
1313
- return this.baseTree;
1314
1358
  let inner = this.inner[this.innerDone], done = inner.parse.advance();
1315
1359
  if (done) {
1316
1360
  this.innerDone++;
@@ -1327,8 +1371,12 @@ class MixedParse {
1327
1371
  get parsedPos() {
1328
1372
  if (this.baseParse)
1329
1373
  return 0;
1330
- let next = this.inner[this.innerDone];
1331
- return next ? next.parse.parsedPos : this.input.length;
1374
+ let pos = this.input.length;
1375
+ for (let i = this.innerDone; i < this.inner.length; i++) {
1376
+ if (this.inner[i].ranges[0].from < pos)
1377
+ pos = Math.min(pos, this.inner[i].parse.parsedPos);
1378
+ }
1379
+ return pos;
1332
1380
  }
1333
1381
  stopAt(pos) {
1334
1382
  this.stoppedAt = pos;
@@ -1342,7 +1390,8 @@ class MixedParse {
1342
1390
  let fragmentCursor = new FragmentCursor(this.fragments);
1343
1391
  let overlay = null;
1344
1392
  let covered = null;
1345
- scan: for (let cursor = this.baseTree.fullCursor(), nest, isCovered;;) {
1393
+ let cursor = new TreeCursor(new TreeNode(this.baseTree, this.ranges[0].from, 0, null), 1 /* Full */);
1394
+ scan: for (let nest, isCovered; this.stoppedAt == null || cursor.from < this.stoppedAt;) {
1346
1395
  let enter = true, range;
1347
1396
  if (fragmentCursor.hasNode(cursor)) {
1348
1397
  if (overlay) {
@@ -1369,7 +1418,7 @@ class MixedParse {
1369
1418
  else {
1370
1419
  let ranges = punchRanges(this.ranges, nest.overlay || [new Range(cursor.from, cursor.to)]);
1371
1420
  if (ranges.length)
1372
- this.inner.push(new InnerParse(nest.parser, nest.parser.startParse(this.input, enterFragments(oldMounts, ranges), ranges), nest.overlay ? nest.overlay.map(r => new Range(r.from - cursor.from, r.to - cursor.from)) : null, cursor.tree));
1421
+ this.inner.push(new InnerParse(nest.parser, nest.parser.startParse(this.input, enterFragments(oldMounts, ranges), ranges), nest.overlay ? nest.overlay.map(r => new Range(r.from - cursor.from, r.to - cursor.from)) : null, cursor.tree, ranges));
1373
1422
  if (!nest.overlay)
1374
1423
  enter = false;
1375
1424
  else if (ranges.length)
@@ -1397,7 +1446,7 @@ class MixedParse {
1397
1446
  if (overlay && !--overlay.depth) {
1398
1447
  let ranges = punchRanges(this.ranges, overlay.ranges);
1399
1448
  if (ranges.length)
1400
- this.inner.splice(overlay.index, 0, new InnerParse(overlay.parser, overlay.parser.startParse(this.input, enterFragments(overlay.mounts, ranges), ranges), overlay.ranges.map(r => new Range(r.from - overlay.start, r.to - overlay.start)), overlay.target));
1449
+ this.inner.splice(overlay.index, 0, new InnerParse(overlay.parser, overlay.parser.startParse(this.input, enterFragments(overlay.mounts, ranges), ranges), overlay.ranges.map(r => new Range(r.from - overlay.start, r.to - overlay.start)), overlay.target, ranges));
1401
1450
  overlay = overlay.prev;
1402
1451
  }
1403
1452
  if (covered && !--covered.depth)
@@ -1497,10 +1546,13 @@ class StructureCursor {
1497
1546
  }
1498
1547
  class FragmentCursor {
1499
1548
  constructor(fragments) {
1549
+ var _a;
1500
1550
  this.fragments = fragments;
1551
+ this.curTo = 0;
1501
1552
  this.fragI = 0;
1502
1553
  if (fragments.length) {
1503
1554
  let first = this.curFrag = fragments[0];
1555
+ this.curTo = (_a = first.tree.prop(stoppedInner)) !== null && _a !== void 0 ? _a : first.to;
1504
1556
  this.inner = new StructureCursor(first.tree, -first.offset);
1505
1557
  }
1506
1558
  else {
@@ -1508,17 +1560,19 @@ class FragmentCursor {
1508
1560
  }
1509
1561
  }
1510
1562
  hasNode(node) {
1511
- while (this.curFrag && node.from >= this.curFrag.to)
1563
+ while (this.curFrag && node.from >= this.curTo)
1512
1564
  this.nextFrag();
1513
- return this.curFrag && this.curFrag.from <= node.from && this.curFrag.to >= node.to && this.inner.hasNode(node);
1565
+ return this.curFrag && this.curFrag.from <= node.from && this.curTo >= node.to && this.inner.hasNode(node);
1514
1566
  }
1515
1567
  nextFrag() {
1568
+ var _a;
1516
1569
  this.fragI++;
1517
1570
  if (this.fragI == this.fragments.length) {
1518
1571
  this.curFrag = this.inner = null;
1519
1572
  }
1520
1573
  else {
1521
1574
  let frag = this.curFrag = this.fragments[this.fragI];
1575
+ this.curTo = (_a = frag.tree.prop(stoppedInner)) !== null && _a !== void 0 ? _a : frag.to;
1522
1576
  this.inner = new StructureCursor(frag.tree, -frag.offset);
1523
1577
  }
1524
1578
  }
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.
@@ -282,7 +282,8 @@ class Tree {
282
282
  }
283
283
  /// Get a [tree cursor](#common.TreeCursor) that, unlike regular
284
284
  /// cursors, doesn't skip through
285
- /// [anonymous](#common.NodeType.isAnonymous) nodes.
285
+ /// [anonymous](#common.NodeType.isAnonymous) nodes and doesn't
286
+ /// automatically enter mounted nodes.
286
287
  fullCursor() {
287
288
  return new TreeCursor(this.topNode, 1 /* Full */);
288
289
  }
@@ -297,7 +298,9 @@ class Tree {
297
298
  /// position. With 0, it'll only enter nodes that cover the position
298
299
  /// from both sides.
299
300
  resolve(pos, side = 0) {
300
- 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;
301
304
  }
302
305
  /// Like [`resolve`](#common.Tree.resolve), but will enter
303
306
  /// [overlaid](#common.MountedTree.overlay) nodes, producing a syntax node
@@ -305,13 +308,9 @@ class Tree {
305
308
  /// (with parent links going through all parent structure, including
306
309
  /// the host trees).
307
310
  resolveInner(pos, side = 0) {
308
- let result = this.topNode;
309
- for (;;) {
310
- let inner = result.enter(pos, side);
311
- if (!inner)
312
- return result;
313
- result = inner;
314
- }
311
+ let node = resolveNode(CachedInnerNode.get(this) || this.topNode, pos, side, true);
312
+ CachedInnerNode.set(this, node);
313
+ return node;
315
314
  }
316
315
  /// Iterate over the tree and its children, calling `enter` for any
317
316
  /// node that touches the `from`/`to` region (if given) before
@@ -360,7 +359,7 @@ class Tree {
360
359
  /// [`NodeType.none`](#common.NodeType^none).
361
360
  balance(config = {}) {
362
361
  return this.children.length <= 8 /* BranchFactor */ ? this :
363
- balanceRange(this.type, 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)));
362
+ 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)));
364
363
  }
365
364
  /// Build a tree from a postfix-ordered buffer of node information,
366
365
  /// or a cursor over such a buffer.
@@ -476,6 +475,30 @@ function enterUnfinishedNodesBefore(node, pos) {
476
475
  }
477
476
  return node;
478
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
+ }
479
502
  class TreeNode {
480
503
  constructor(node, _from,
481
504
  // Index in parent node, set to -1 if the node is not a direct child of _parent.node (overlay)
@@ -504,7 +527,7 @@ class TreeNode {
504
527
  }
505
528
  else if ((mode & 1 /* Full */) || (!next.type.isAnonymous || hasChild(next))) {
506
529
  let mounted;
507
- if (next.props && (mounted = next.prop(NodeProp.mounted)) && !mounted.overlay)
530
+ if (!(mode & 1 /* Full */) && next.props && (mounted = next.prop(NodeProp.mounted)) && !mounted.overlay)
508
531
  return new TreeNode(mounted.tree, start, i, parent);
509
532
  let inner = new TreeNode(next, start, i, parent);
510
533
  return (mode & 1 /* Full */) || !inner.type.isAnonymous ? inner
@@ -557,7 +580,10 @@ class TreeNode {
557
580
  get tree() { return this.node; }
558
581
  toTree() { return this.node; }
559
582
  resolve(pos, side = 0) {
560
- 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);
561
587
  }
562
588
  enterUnfinishedNodesBefore(pos) { return enterUnfinishedNodesBefore(this, pos); }
563
589
  getChild(type, before = null, after = null) {
@@ -655,7 +681,10 @@ class BufferNode {
655
681
  return new Tree(this.type, children, positions, this.to - this.from);
656
682
  }
657
683
  resolve(pos, side = 0) {
658
- 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);
659
688
  }
660
689
  enterUnfinishedNodesBefore(pos) { return enterUnfinishedNodesBefore(this, pos); }
661
690
  /// @internal
@@ -752,10 +781,10 @@ class TreeCursor {
752
781
  /// set to false.
753
782
  enter(pos, side, overlays = true, buffers = true) {
754
783
  if (!this.buffer)
755
- return this.yield(this._tree.enter(pos, side, overlays, buffers));
784
+ return this.yield(this._tree.enter(pos, side, overlays && !(this.mode & 1 /* Full */), buffers));
756
785
  return buffers ? this.enterChild(1, pos, side) : false;
757
786
  }
758
- /// Move the node's parent node, if this isn't the top node.
787
+ /// Move to the node's parent node, if this isn't the top node.
759
788
  parent() {
760
789
  if (!this.buffer)
761
790
  return this.yieldNode((this.mode & 1 /* Full */) ? this._tree._parent : this._tree.parent);
@@ -1077,15 +1106,21 @@ function nodeSize(balanceType, node) {
1077
1106
  return 1;
1078
1107
  let size = nodeSizeCache.get(node);
1079
1108
  if (size == null) {
1080
- size = node.children.reduce((s, ch) => s + nodeSize(balanceType, ch), 1);
1109
+ size = 1;
1110
+ for (let child of node.children) {
1111
+ if (child.type != balanceType || !(child instanceof Tree)) {
1112
+ size = 1;
1113
+ break;
1114
+ }
1115
+ size += nodeSize(balanceType, child);
1116
+ }
1081
1117
  nodeSizeCache.set(node, size);
1082
1118
  }
1083
1119
  return size;
1084
1120
  }
1085
1121
  function balanceRange(
1086
- // The type to tag the resulting tree with. Will also be used for
1087
- // internal nodes when it is an anonymous type
1088
- type,
1122
+ // The type the balanced tree's inner nodes.
1123
+ balanceType,
1089
1124
  // The direct children and their positions
1090
1125
  children, positions,
1091
1126
  // The index range in children/positions to use
@@ -1100,22 +1135,22 @@ mkTop,
1100
1135
  mkTree) {
1101
1136
  let total = 0;
1102
1137
  for (let i = from; i < to; i++)
1103
- total += nodeSize(type, children[i]);
1138
+ total += nodeSize(balanceType, children[i]);
1104
1139
  let maxChild = Math.ceil((total * 1.5) / 8 /* BranchFactor */);
1105
1140
  let localChildren = [], localPositions = [];
1106
1141
  function divide(children, positions, from, to, offset) {
1107
1142
  for (let i = from; i < to;) {
1108
- let groupFrom = i, groupStart = positions[i], groupSize = nodeSize(type, children[i]);
1143
+ let groupFrom = i, groupStart = positions[i], groupSize = nodeSize(balanceType, children[i]);
1109
1144
  i++;
1110
1145
  for (; i < to; i++) {
1111
- let nextSize = nodeSize(type, children[i]);
1146
+ let nextSize = nodeSize(balanceType, children[i]);
1112
1147
  if (groupSize + nextSize >= maxChild)
1113
1148
  break;
1114
1149
  groupSize += nextSize;
1115
1150
  }
1116
1151
  if (i == groupFrom + 1) {
1117
1152
  if (groupSize > maxChild) {
1118
- let only = children[groupFrom];
1153
+ let only = children[groupFrom]; // Only trees can have a size > 1
1119
1154
  divide(only.children, only.positions, 0, only.children.length, positions[groupFrom] + offset);
1120
1155
  continue;
1121
1156
  }
@@ -1123,7 +1158,7 @@ mkTree) {
1123
1158
  }
1124
1159
  else {
1125
1160
  let length = positions[i - 1] + children[i - 1].length - groupStart;
1126
- localChildren.push(balanceRange(type, children, positions, groupFrom, i, groupStart, length, null, mkTree));
1161
+ localChildren.push(balanceRange(balanceType, children, positions, groupFrom, i, groupStart, length, null, mkTree));
1127
1162
  }
1128
1163
  localPositions.push(groupStart + offset - start);
1129
1164
  }
@@ -1264,11 +1299,12 @@ function parseMixed(nest) {
1264
1299
  return (parse, input, fragments, ranges) => new MixedParse(parse, nest, input, fragments, ranges);
1265
1300
  }
1266
1301
  class InnerParse {
1267
- constructor(parser, parse, overlay, target) {
1302
+ constructor(parser, parse, overlay, target, ranges) {
1268
1303
  this.parser = parser;
1269
1304
  this.parse = parse;
1270
1305
  this.overlay = overlay;
1271
1306
  this.target = target;
1307
+ this.ranges = ranges;
1272
1308
  }
1273
1309
  }
1274
1310
  class ActiveOverlay {
@@ -1284,6 +1320,7 @@ class ActiveOverlay {
1284
1320
  this.ranges = [];
1285
1321
  }
1286
1322
  }
1323
+ const stoppedInner = new NodeProp({ perNode: true });
1287
1324
  class MixedParse {
1288
1325
  constructor(base, nest, input, fragments, ranges) {
1289
1326
  this.nest = nest;
@@ -1304,9 +1341,16 @@ class MixedParse {
1304
1341
  this.baseParse = null;
1305
1342
  this.baseTree = done;
1306
1343
  this.startInner();
1344
+ if (this.stoppedAt != null)
1345
+ for (let inner of this.inner)
1346
+ inner.parse.stopAt(this.stoppedAt);
1347
+ }
1348
+ if (this.innerDone == this.inner.length) {
1349
+ let result = this.baseTree;
1350
+ if (this.stoppedAt != null)
1351
+ result = new Tree(result.type, result.children, result.positions, result.length, result.propValues.concat([[stoppedInner, this.stoppedAt]]));
1352
+ return result;
1307
1353
  }
1308
- if (this.innerDone == this.inner.length)
1309
- return this.baseTree;
1310
1354
  let inner = this.inner[this.innerDone], done = inner.parse.advance();
1311
1355
  if (done) {
1312
1356
  this.innerDone++;
@@ -1323,8 +1367,12 @@ class MixedParse {
1323
1367
  get parsedPos() {
1324
1368
  if (this.baseParse)
1325
1369
  return 0;
1326
- let next = this.inner[this.innerDone];
1327
- return next ? next.parse.parsedPos : this.input.length;
1370
+ let pos = this.input.length;
1371
+ for (let i = this.innerDone; i < this.inner.length; i++) {
1372
+ if (this.inner[i].ranges[0].from < pos)
1373
+ pos = Math.min(pos, this.inner[i].parse.parsedPos);
1374
+ }
1375
+ return pos;
1328
1376
  }
1329
1377
  stopAt(pos) {
1330
1378
  this.stoppedAt = pos;
@@ -1338,7 +1386,8 @@ class MixedParse {
1338
1386
  let fragmentCursor = new FragmentCursor(this.fragments);
1339
1387
  let overlay = null;
1340
1388
  let covered = null;
1341
- scan: for (let cursor = this.baseTree.fullCursor(), nest, isCovered;;) {
1389
+ let cursor = new TreeCursor(new TreeNode(this.baseTree, this.ranges[0].from, 0, null), 1 /* Full */);
1390
+ scan: for (let nest, isCovered; this.stoppedAt == null || cursor.from < this.stoppedAt;) {
1342
1391
  let enter = true, range;
1343
1392
  if (fragmentCursor.hasNode(cursor)) {
1344
1393
  if (overlay) {
@@ -1365,7 +1414,7 @@ class MixedParse {
1365
1414
  else {
1366
1415
  let ranges = punchRanges(this.ranges, nest.overlay || [new Range(cursor.from, cursor.to)]);
1367
1416
  if (ranges.length)
1368
- this.inner.push(new InnerParse(nest.parser, nest.parser.startParse(this.input, enterFragments(oldMounts, ranges), ranges), nest.overlay ? nest.overlay.map(r => new Range(r.from - cursor.from, r.to - cursor.from)) : null, cursor.tree));
1417
+ this.inner.push(new InnerParse(nest.parser, nest.parser.startParse(this.input, enterFragments(oldMounts, ranges), ranges), nest.overlay ? nest.overlay.map(r => new Range(r.from - cursor.from, r.to - cursor.from)) : null, cursor.tree, ranges));
1369
1418
  if (!nest.overlay)
1370
1419
  enter = false;
1371
1420
  else if (ranges.length)
@@ -1393,7 +1442,7 @@ class MixedParse {
1393
1442
  if (overlay && !--overlay.depth) {
1394
1443
  let ranges = punchRanges(this.ranges, overlay.ranges);
1395
1444
  if (ranges.length)
1396
- this.inner.splice(overlay.index, 0, new InnerParse(overlay.parser, overlay.parser.startParse(this.input, enterFragments(overlay.mounts, ranges), ranges), overlay.ranges.map(r => new Range(r.from - overlay.start, r.to - overlay.start)), overlay.target));
1445
+ this.inner.splice(overlay.index, 0, new InnerParse(overlay.parser, overlay.parser.startParse(this.input, enterFragments(overlay.mounts, ranges), ranges), overlay.ranges.map(r => new Range(r.from - overlay.start, r.to - overlay.start)), overlay.target, ranges));
1397
1446
  overlay = overlay.prev;
1398
1447
  }
1399
1448
  if (covered && !--covered.depth)
@@ -1493,10 +1542,13 @@ class StructureCursor {
1493
1542
  }
1494
1543
  class FragmentCursor {
1495
1544
  constructor(fragments) {
1545
+ var _a;
1496
1546
  this.fragments = fragments;
1547
+ this.curTo = 0;
1497
1548
  this.fragI = 0;
1498
1549
  if (fragments.length) {
1499
1550
  let first = this.curFrag = fragments[0];
1551
+ this.curTo = (_a = first.tree.prop(stoppedInner)) !== null && _a !== void 0 ? _a : first.to;
1500
1552
  this.inner = new StructureCursor(first.tree, -first.offset);
1501
1553
  }
1502
1554
  else {
@@ -1504,17 +1556,19 @@ class FragmentCursor {
1504
1556
  }
1505
1557
  }
1506
1558
  hasNode(node) {
1507
- while (this.curFrag && node.from >= this.curFrag.to)
1559
+ while (this.curFrag && node.from >= this.curTo)
1508
1560
  this.nextFrag();
1509
- return this.curFrag && this.curFrag.from <= node.from && this.curFrag.to >= node.to && this.inner.hasNode(node);
1561
+ return this.curFrag && this.curFrag.from <= node.from && this.curTo >= node.to && this.inner.hasNode(node);
1510
1562
  }
1511
1563
  nextFrag() {
1564
+ var _a;
1512
1565
  this.fragI++;
1513
1566
  if (this.fragI == this.fragments.length) {
1514
1567
  this.curFrag = this.inner = null;
1515
1568
  }
1516
1569
  else {
1517
1570
  let frag = this.curFrag = this.fragments[this.fragI];
1571
+ this.curTo = (_a = frag.tree.prop(stoppedInner)) !== null && _a !== void 0 ? _a : frag.to;
1518
1572
  this.inner = new StructureCursor(frag.tree, -frag.offset);
1519
1573
  }
1520
1574
  }