lezer-tree
Advanced tools
Comparing version 0.3.0 to 0.4.0
@@ -0,1 +1,11 @@ | ||
## 0.4.0 (2019-09-10) | ||
### Bug fixes | ||
Export `BufferCursor` again, which was accidentally removed from the exports in 0.3.0. | ||
### Breaking changes | ||
The `iterate` method now takes an object instead of separate parameters. | ||
## 0.3.0 (2019-08-22) | ||
@@ -2,0 +12,0 @@ |
@@ -8,4 +8,10 @@ export declare const DefaultBufferLength = 1024; | ||
} | ||
export declare type EnterFunc<T> = (type: NodeType, start: number, end: number) => T | false | undefined; | ||
export declare type LeaveFunc = (type: NodeType, start: number, end: number) => void; | ||
declare type EnterFunc<T> = (type: NodeType, start: number, end: number) => T | false | undefined; | ||
declare type LeaveFunc = (type: NodeType, start: number, end: number) => void; | ||
declare type IterateArgs<T> = { | ||
enter: EnterFunc<T>; | ||
leave?: LeaveFunc; | ||
from?: number; | ||
to?: number; | ||
}; | ||
declare class Iteration<T> { | ||
@@ -73,3 +79,3 @@ readonly enter: EnterFunc<T>; | ||
abstract toString(): string; | ||
abstract iterate<T = any>(from: number, to: number, enter: EnterFunc<T>, leave?: LeaveFunc): T | undefined; | ||
abstract iterate<T = any>(args: IterateArgs<T>): T | undefined; | ||
resolve(pos: number, side?: -1 | 0 | 1): Subtree; | ||
@@ -96,5 +102,5 @@ abstract resolveAt(pos: number): Subtree; | ||
static empty: Tree; | ||
iterate<T = any>(from: number, to: number, enter: EnterFunc<T>, leave?: LeaveFunc): T | undefined; | ||
iterate<T = any>({ from, to, enter, leave }: IterateArgs<T>): T | undefined; | ||
iterInner<T>(from: number, to: number, offset: number, iter: Iteration<T>): void; | ||
resolveAt(pos: number, side?: -1 | 0 | 1): Subtree; | ||
resolveAt(pos: number): Subtree; | ||
childBefore(pos: number): Subtree | null; | ||
@@ -122,3 +128,3 @@ childAfter(pos: number): Subtree | null; | ||
} | ||
interface BufferCursor { | ||
export interface BufferCursor { | ||
pos: number; | ||
@@ -125,0 +131,0 @@ id: number; |
@@ -321,3 +321,5 @@ "use strict"; | ||
var children = this.children.map(function (c) { return c.toString(); }).join(); | ||
return !this.name ? children : (/\W/.test(this.name) ? JSON.stringify(this.name) : this.name) + (children.length ? "(" + children + ")" : ""); | ||
return !this.name ? children : | ||
(/\W/.test(this.name) && !this.type.prop(NodeProp.error) ? JSON.stringify(this.name) : this.name) + | ||
(children.length ? "(" + children + ")" : ""); | ||
}; | ||
@@ -392,3 +394,4 @@ Tree.prototype.partial = function (start, end, offset, children, positions) { | ||
/// @internal | ||
Tree.prototype.iterate = function (from, to, enter, leave) { | ||
Tree.prototype.iterate = function (_a) { | ||
var _b = _a.from, from = _b === void 0 ? this.start : _b, _c = _a.to, to = _c === void 0 ? this.end : _c, enter = _a.enter, leave = _a.leave; | ||
var iter = new Iteration(enter, leave); | ||
@@ -427,5 +430,15 @@ this.iterInner(from, to, 0, iter); | ||
/// @internal | ||
Tree.prototype.resolveAt = function (pos, side) { | ||
if (side === void 0) { side = 0; } | ||
return this.resolveInner(pos, 0, this); | ||
Tree.prototype.resolveAt = function (pos) { | ||
if (cacheRoot == this) { | ||
for (var tree = cached;;) { | ||
var next = tree.parent; | ||
if (!next) | ||
break; | ||
if (tree.start < pos && tree.end > pos) | ||
return tree.resolve(pos); | ||
tree = next; | ||
} | ||
} | ||
cacheRoot = this; | ||
return cached = this.resolveInner(pos, 0, this); | ||
}; | ||
@@ -505,2 +518,7 @@ /// @internal | ||
Tree.prototype.parent = null; | ||
// Top-level `resolveAt` calls store their last result here, so that | ||
// if the next call is near the last, parent trees can be cheaply | ||
// reused. | ||
var cacheRoot = Tree.empty; | ||
var cached = Tree.empty; | ||
/// Tree buffers contain (type, start, end, endIndex) quads for each | ||
@@ -527,4 +545,4 @@ /// node. In such a buffer, nodes are stored in prefix order (parents | ||
var id = this.buffer[index], endIndex = this.buffer[index + 3]; | ||
var result = this.group.types[id].name; | ||
if (/\W/.test(result)) | ||
var type = this.group.types[id], result = type.name; | ||
if (/\W/.test(result) && !type.prop(NodeProp.error)) | ||
result = JSON.stringify(result); | ||
@@ -688,3 +706,4 @@ index += 4; | ||
NodeSubtree.prototype.toString = function () { return this.node.toString(); }; | ||
NodeSubtree.prototype.iterate = function (from, to, enter, leave) { | ||
NodeSubtree.prototype.iterate = function (_a) { | ||
var _b = _a.from, from = _b === void 0 ? this.start : _b, _c = _a.to, to = _c === void 0 ? this.end : _c, enter = _a.enter, leave = _a.leave; | ||
var iter = new Iteration(enter, leave); | ||
@@ -734,3 +753,4 @@ this.node.iterInner(from, to, this.start, iter); | ||
}; | ||
BufferSubtree.prototype.iterate = function (from, to, enter, leave) { | ||
BufferSubtree.prototype.iterate = function (_a) { | ||
var _b = _a.from, from = _b === void 0 ? this.start : _b, _c = _a.to, to = _c === void 0 ? this.end : _c, enter = _a.enter, leave = _a.leave; | ||
var iter = new Iteration(enter, leave); | ||
@@ -737,0 +757,0 @@ if (from <= to) |
{ | ||
"name": "lezer-tree", | ||
"version": "0.3.0", | ||
"version": "0.4.0", | ||
"description": "Syntax tree data structure for the lezer parser", | ||
@@ -5,0 +5,0 @@ "main": "dist/tree.js", |
@@ -28,1 +28,3 @@ ### Trees | ||
@DefaultBufferLength | ||
@BufferCursor |
@@ -16,18 +16,32 @@ /// The default maximum length of a `TreeBuffer` node. | ||
/// Signature of the `enter` function passed to `Subtree.iterate`. It is given | ||
/// a node's tag, start position, and end position for every node, | ||
/// and can return... | ||
/// | ||
/// * `undefined` to proceed iterating as normal. | ||
/// | ||
/// * `false` to not further iterate this node, but continue | ||
/// iterating nodes after it. | ||
/// | ||
/// * Any other value to immediately stop iteration and return the | ||
/// value from the `iterate` method. | ||
export type EnterFunc<T> = (type: NodeType, start: number, end: number) => T | false | undefined | ||
type EnterFunc<T> = (type: NodeType, start: number, end: number) => T | false | undefined | ||
/// Signature of the `leave` function passed to `Subtree.iterate`. | ||
export type LeaveFunc = (type: NodeType, start: number, end: number) => void | ||
type LeaveFunc = (type: NodeType, start: number, end: number) => void | ||
/// passed to `Subtree.iterate`. | ||
type IterateArgs<T> = { | ||
/// The function called when entering a node. It is given a node's | ||
/// type, start position, and end position, and can return... | ||
/// | ||
/// * `undefined` to proceed iterating as normal. | ||
/// | ||
/// * `false` to not further iterate this node, but continue | ||
/// iterating nodes after it. | ||
/// | ||
/// * Any other value to immediately stop iteration and return that | ||
/// value from the `iterate` method. | ||
enter: EnterFunc<T>, | ||
/// The function to be called when leaving a node. | ||
leave?: LeaveFunc, | ||
/// The position in the tree to start iterating. All nodes that | ||
/// overlap with this position (including those that start/end | ||
/// directly at it) are included in the iteration. Defaults to the | ||
/// start of the subtree. | ||
from?: number, | ||
/// The position in the tree to iterate towards. May be less than | ||
/// `from` to perform a reverse iteration. Defaults to the end of | ||
/// the subtree. | ||
to?: number | ||
} | ||
class Iteration<T> { | ||
@@ -243,5 +257,5 @@ result: T | undefined = undefined | ||
/// Iterate over all nodes in this subtree. Will iterate through the | ||
/// tree in, calling `enter` for each node it enters and, if given, | ||
/// `leave` when it leaves a node. | ||
abstract iterate<T = any>(from: number, to: number, enter: EnterFunc<T>, leave?: LeaveFunc): T | undefined | ||
/// tree in, calling `args.enter` for each node it enters and, if | ||
/// given, `args.leave` when it leaves a node. | ||
abstract iterate<T = any>(args: IterateArgs<T>): T | undefined | ||
@@ -324,3 +338,5 @@ /// Find the node at a given position. By default, this will return | ||
let children = this.children.map(c => c.toString()).join() | ||
return !this.name ? children : (/\W/.test(this.name) ? JSON.stringify(this.name) : this.name) + (children.length ? "(" + children + ")" : "") | ||
return !this.name ? children : | ||
(/\W/.test(this.name) && !this.type.prop(NodeProp.error) ? JSON.stringify(this.name) : this.name) + | ||
(children.length ? "(" + children + ")" : "") | ||
} | ||
@@ -394,3 +410,3 @@ | ||
/// @internal | ||
iterate<T = any>(from: number, to: number, enter: EnterFunc<T>, leave?: LeaveFunc) { | ||
iterate<T = any>({from = this.start, to = this.end, enter, leave}: IterateArgs<T>) { | ||
let iter = new Iteration(enter, leave) | ||
@@ -426,4 +442,13 @@ this.iterInner(from, to, 0, iter) | ||
/// @internal | ||
resolveAt(pos: number, side: -1 | 0 | 1 = 0): Subtree { | ||
return this.resolveInner(pos, 0, this) | ||
resolveAt(pos: number): Subtree { | ||
if (cacheRoot == this) { | ||
for (let tree = cached;;) { | ||
let next = tree.parent | ||
if (!next) break | ||
if (tree.start < pos && tree.end > pos) return tree.resolve(pos) | ||
tree = next | ||
} | ||
} | ||
cacheRoot = this | ||
return cached = this.resolveInner(pos, 0, this) | ||
} | ||
@@ -499,2 +524,8 @@ | ||
// Top-level `resolveAt` calls store their last result here, so that | ||
// if the next call is near the last, parent trees can be cheaply | ||
// reused. | ||
let cacheRoot: Tree = Tree.empty | ||
let cached: Subtree = Tree.empty | ||
/// Tree buffers contain (type, start, end, endIndex) quads for each | ||
@@ -519,4 +550,4 @@ /// node. In such a buffer, nodes are stored in prefix order (parents | ||
let id = this.buffer[index], endIndex = this.buffer[index + 3] | ||
let result = this.group.types[id].name | ||
if (/\W/.test(result)) result = JSON.stringify(result) | ||
let type = this.group.types[id], result = type.name | ||
if (/\W/.test(result) && !type.prop(NodeProp.error)) result = JSON.stringify(result) | ||
index += 4 | ||
@@ -666,3 +697,3 @@ if (endIndex > index) { | ||
iterate<T = any>(from: number, to: number, enter: EnterFunc<T>, leave?: LeaveFunc) { | ||
iterate<T = any>({from = this.start, to = this.end, enter, leave}: IterateArgs<T>) { | ||
let iter = new Iteration(enter, leave) | ||
@@ -698,3 +729,3 @@ this.node.iterInner(from, to, this.start, iter) | ||
iterate<T = any>(from: number, to: number, enter: EnterFunc<T>, leave?: LeaveFunc) { | ||
iterate<T = any>({from = this.start, to = this.end, enter, leave}: IterateArgs<T>) { | ||
let iter = new Iteration(enter, leave) | ||
@@ -723,3 +754,3 @@ if (from <= to) | ||
// a tree buffer. | ||
interface BufferCursor { | ||
export interface BufferCursor { | ||
pos: number | ||
@@ -726,0 +757,0 @@ id: number |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
117163
11
1930