@lezer/common 1.2.3 → 1.4.0

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
@@ -26,6 +26,7 @@ class NodeProp {
26
26
  this.deserialize = config.deserialize || (() => {
27
27
  throw new Error("This node type doesn't define a deserialize function");
28
28
  });
29
+ this.combine = config.combine || null;
29
30
  }
30
31
  /**
31
32
  This is meant to be used with
@@ -290,7 +291,10 @@ class NodeSet {
290
291
  if (add) {
291
292
  if (!newProps)
292
293
  newProps = Object.assign({}, type.props);
293
- newProps[add[0].id] = add[1];
294
+ let value = add[1], prop = add[0];
295
+ if (prop.combine && prop.id in newProps)
296
+ value = prop.combine(newProps[prop.id], value);
297
+ newProps[prop.id] = value;
294
298
  }
295
299
  }
296
300
  newTypes.push(newProps ? new NodeType(type.name, newProps, type.id, type.flags) : type);
@@ -763,6 +767,7 @@ class TreeNode extends BaseNode {
763
767
  get lastChild() { return this.nextChild(this._tree.children.length - 1, -1, 0, 4 /* Side.DontCare */); }
764
768
  childAfter(pos) { return this.nextChild(0, 1, pos, 2 /* Side.After */); }
765
769
  childBefore(pos) { return this.nextChild(this._tree.children.length - 1, -1, pos, -2 /* Side.Before */); }
770
+ prop(prop) { return this._tree.prop(prop); }
766
771
  enter(pos, side, mode = 0) {
767
772
  let mounted;
768
773
  if (!(mode & exports.IterMode.IgnoreOverlays) && (mounted = MountedTree.get(this._tree)) && mounted.overlay) {
@@ -856,6 +861,7 @@ class BufferNode extends BaseNode {
856
861
  get lastChild() { return this.child(-1, 0, 4 /* Side.DontCare */); }
857
862
  childAfter(pos) { return this.child(1, pos, 2 /* Side.After */); }
858
863
  childBefore(pos) { return this.child(-1, pos, -2 /* Side.Before */); }
864
+ prop(prop) { return this.type.prop(prop); }
859
865
  enter(pos, side, mode = 0) {
860
866
  if (mode & exports.IterMode.ExcludeBuffers)
861
867
  return null;
@@ -1273,7 +1279,7 @@ function buildTree(data) {
1273
1279
  function takeNode(parentStart, minPos, children, positions, inRepeat, depth) {
1274
1280
  let { id, start, end, size } = cursor;
1275
1281
  let lookAheadAtStart = lookAhead, contextAtStart = contextHash;
1276
- while (size < 0) {
1282
+ if (size < 0) {
1277
1283
  cursor.next();
1278
1284
  if (size == -1 /* SpecialRecord.Reuse */) {
1279
1285
  let node = reused[id];
@@ -1437,7 +1443,7 @@ function buildTree(data) {
1437
1443
  fork.next();
1438
1444
  while (fork.pos > startPos) {
1439
1445
  if (fork.size < 0) {
1440
- if (fork.size == -3 /* SpecialRecord.ContextChange */)
1446
+ if (fork.size == -3 /* SpecialRecord.ContextChange */ || fork.size == -4 /* SpecialRecord.LookAhead */)
1441
1447
  localSkipped += 4;
1442
1448
  else
1443
1449
  break scan;
@@ -1878,8 +1884,15 @@ class MixedParse {
1878
1884
  }
1879
1885
  else if (!cursor.type.isAnonymous && (nest = this.nest(cursor, this.input)) &&
1880
1886
  (cursor.from < cursor.to || !nest.overlay)) {
1881
- if (!cursor.tree)
1887
+ if (!cursor.tree) {
1882
1888
  materialize(cursor);
1889
+ // materialize create one more level of nesting
1890
+ // we need to add depth to active overlay for going backwards
1891
+ if (overlay)
1892
+ overlay.depth++;
1893
+ if (covered)
1894
+ covered.depth++;
1895
+ }
1883
1896
  let oldMounts = fragmentCursor.findMounts(cursor.from, nest.parser);
1884
1897
  if (typeof nest.overlay == "function") {
1885
1898
  overlay = new ActiveOverlay(nest.parser, nest.overlay, oldMounts, this.inner.length, cursor.from, cursor.tree, overlay);
package/dist/index.d.cts CHANGED
@@ -244,6 +244,13 @@ declare class NodeProp<T> {
244
244
  */
245
245
  deserialize?: (str: string) => T;
246
246
  /**
247
+ If configuring another value for this prop when it already
248
+ exists on a node should combine the old and new values, rather
249
+ than overwrite the old value, you can pass a function that
250
+ does the combining here.
251
+ */
252
+ combine?: (a: T, b: T) => T;
253
+ /**
247
254
  By default, node props are stored in the [node
248
255
  type](#common.NodeType). It can sometimes be useful to directly
249
256
  store information (usually related to the parsing algorithm)
@@ -911,6 +918,10 @@ interface SyntaxNode extends SyntaxNodeRef {
911
918
  */
912
919
  prevSibling: SyntaxNode | null;
913
920
  /**
921
+ Read the given node prop from this node.
922
+ */
923
+ prop<T>(prop: NodeProp<T>): T | undefined;
924
+ /**
914
925
  A [tree cursor](#common.TreeCursor) starting at this node.
915
926
  */
916
927
  cursor(mode?: IterMode): TreeCursor;
@@ -1134,4 +1145,4 @@ tree.
1134
1145
  */
1135
1146
  declare function parseMixed(nest: (node: SyntaxNodeRef, input: Input) => NestedParse | null): ParseWrapper;
1136
1147
 
1137
- export { BufferCursor, ChangedRange, DefaultBufferLength, Input, IterMode, MountedTree, NestedParse, NodeIterator, NodeProp, NodePropSource, NodeSet, NodeType, NodeWeakMap, ParseWrapper, Parser, PartialParse, SyntaxNode, SyntaxNodeRef, Tree, TreeBuffer, TreeCursor, TreeFragment, parseMixed };
1148
+ export { type BufferCursor, type ChangedRange, DefaultBufferLength, type Input, IterMode, MountedTree, type NestedParse, type NodeIterator, NodeProp, type NodePropSource, NodeSet, NodeType, NodeWeakMap, type ParseWrapper, Parser, type PartialParse, type SyntaxNode, type SyntaxNodeRef, Tree, TreeBuffer, TreeCursor, TreeFragment, parseMixed };
package/dist/index.d.ts CHANGED
@@ -244,6 +244,13 @@ declare class NodeProp<T> {
244
244
  */
245
245
  deserialize?: (str: string) => T;
246
246
  /**
247
+ If configuring another value for this prop when it already
248
+ exists on a node should combine the old and new values, rather
249
+ than overwrite the old value, you can pass a function that
250
+ does the combining here.
251
+ */
252
+ combine?: (a: T, b: T) => T;
253
+ /**
247
254
  By default, node props are stored in the [node
248
255
  type](#common.NodeType). It can sometimes be useful to directly
249
256
  store information (usually related to the parsing algorithm)
@@ -911,6 +918,10 @@ interface SyntaxNode extends SyntaxNodeRef {
911
918
  */
912
919
  prevSibling: SyntaxNode | null;
913
920
  /**
921
+ Read the given node prop from this node.
922
+ */
923
+ prop<T>(prop: NodeProp<T>): T | undefined;
924
+ /**
914
925
  A [tree cursor](#common.TreeCursor) starting at this node.
915
926
  */
916
927
  cursor(mode?: IterMode): TreeCursor;
@@ -1134,4 +1145,4 @@ tree.
1134
1145
  */
1135
1146
  declare function parseMixed(nest: (node: SyntaxNodeRef, input: Input) => NestedParse | null): ParseWrapper;
1136
1147
 
1137
- export { BufferCursor, ChangedRange, DefaultBufferLength, Input, IterMode, MountedTree, NestedParse, NodeIterator, NodeProp, NodePropSource, NodeSet, NodeType, NodeWeakMap, ParseWrapper, Parser, PartialParse, SyntaxNode, SyntaxNodeRef, Tree, TreeBuffer, TreeCursor, TreeFragment, parseMixed };
1148
+ export { type BufferCursor, type ChangedRange, DefaultBufferLength, type Input, IterMode, MountedTree, type NestedParse, type NodeIterator, NodeProp, type NodePropSource, NodeSet, NodeType, NodeWeakMap, type ParseWrapper, Parser, type PartialParse, type SyntaxNode, type SyntaxNodeRef, Tree, TreeBuffer, TreeCursor, TreeFragment, parseMixed };
package/dist/index.js CHANGED
@@ -24,6 +24,7 @@ class NodeProp {
24
24
  this.deserialize = config.deserialize || (() => {
25
25
  throw new Error("This node type doesn't define a deserialize function");
26
26
  });
27
+ this.combine = config.combine || null;
27
28
  }
28
29
  /**
29
30
  This is meant to be used with
@@ -288,7 +289,10 @@ class NodeSet {
288
289
  if (add) {
289
290
  if (!newProps)
290
291
  newProps = Object.assign({}, type.props);
291
- newProps[add[0].id] = add[1];
292
+ let value = add[1], prop = add[0];
293
+ if (prop.combine && prop.id in newProps)
294
+ value = prop.combine(newProps[prop.id], value);
295
+ newProps[prop.id] = value;
292
296
  }
293
297
  }
294
298
  newTypes.push(newProps ? new NodeType(type.name, newProps, type.id, type.flags) : type);
@@ -761,6 +765,7 @@ class TreeNode extends BaseNode {
761
765
  get lastChild() { return this.nextChild(this._tree.children.length - 1, -1, 0, 4 /* Side.DontCare */); }
762
766
  childAfter(pos) { return this.nextChild(0, 1, pos, 2 /* Side.After */); }
763
767
  childBefore(pos) { return this.nextChild(this._tree.children.length - 1, -1, pos, -2 /* Side.Before */); }
768
+ prop(prop) { return this._tree.prop(prop); }
764
769
  enter(pos, side, mode = 0) {
765
770
  let mounted;
766
771
  if (!(mode & IterMode.IgnoreOverlays) && (mounted = MountedTree.get(this._tree)) && mounted.overlay) {
@@ -854,6 +859,7 @@ class BufferNode extends BaseNode {
854
859
  get lastChild() { return this.child(-1, 0, 4 /* Side.DontCare */); }
855
860
  childAfter(pos) { return this.child(1, pos, 2 /* Side.After */); }
856
861
  childBefore(pos) { return this.child(-1, pos, -2 /* Side.Before */); }
862
+ prop(prop) { return this.type.prop(prop); }
857
863
  enter(pos, side, mode = 0) {
858
864
  if (mode & IterMode.ExcludeBuffers)
859
865
  return null;
@@ -1271,7 +1277,7 @@ function buildTree(data) {
1271
1277
  function takeNode(parentStart, minPos, children, positions, inRepeat, depth) {
1272
1278
  let { id, start, end, size } = cursor;
1273
1279
  let lookAheadAtStart = lookAhead, contextAtStart = contextHash;
1274
- while (size < 0) {
1280
+ if (size < 0) {
1275
1281
  cursor.next();
1276
1282
  if (size == -1 /* SpecialRecord.Reuse */) {
1277
1283
  let node = reused[id];
@@ -1435,7 +1441,7 @@ function buildTree(data) {
1435
1441
  fork.next();
1436
1442
  while (fork.pos > startPos) {
1437
1443
  if (fork.size < 0) {
1438
- if (fork.size == -3 /* SpecialRecord.ContextChange */)
1444
+ if (fork.size == -3 /* SpecialRecord.ContextChange */ || fork.size == -4 /* SpecialRecord.LookAhead */)
1439
1445
  localSkipped += 4;
1440
1446
  else
1441
1447
  break scan;
@@ -1876,8 +1882,15 @@ class MixedParse {
1876
1882
  }
1877
1883
  else if (!cursor.type.isAnonymous && (nest = this.nest(cursor, this.input)) &&
1878
1884
  (cursor.from < cursor.to || !nest.overlay)) {
1879
- if (!cursor.tree)
1885
+ if (!cursor.tree) {
1880
1886
  materialize(cursor);
1887
+ // materialize create one more level of nesting
1888
+ // we need to add depth to active overlay for going backwards
1889
+ if (overlay)
1890
+ overlay.depth++;
1891
+ if (covered)
1892
+ covered.depth++;
1893
+ }
1881
1894
  let oldMounts = fragmentCursor.findMounts(cursor.from, nest.parser);
1882
1895
  if (typeof nest.overlay == "function") {
1883
1896
  overlay = new ActiveOverlay(nest.parser, nest.overlay, oldMounts, this.inner.length, cursor.from, cursor.tree, overlay);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lezer/common",
3
- "version": "1.2.3",
3
+ "version": "1.4.0",
4
4
  "description": "Syntax tree data structure and parser interfaces for the lezer parser",
5
5
  "main": "dist/index.cjs",
6
6
  "type": "module",