feat(web): document the API
This commit is contained in:
parent
a4b20c1c56
commit
09cb4c5729
17 changed files with 1155 additions and 198 deletions
|
|
@ -4,6 +4,7 @@ import { Node } from './node';
|
|||
import { TRANSFER_BUFFER } from './parser';
|
||||
import { getText, Tree } from './tree';
|
||||
|
||||
/** A stateful object for walking a syntax {@link Tree} efficiently. */
|
||||
export class TreeCursor {
|
||||
/** @internal */
|
||||
private [0] = 0; // Internal handle for WASM
|
||||
|
|
@ -20,12 +21,14 @@ export class TreeCursor {
|
|||
/** @internal */
|
||||
private tree: Tree;
|
||||
|
||||
/** @internal */
|
||||
constructor(internal: Internal, tree: Tree) {
|
||||
assertInternal(internal);
|
||||
this.tree = tree;
|
||||
unmarshalTreeCursor(this);
|
||||
}
|
||||
|
||||
/** Creates a deep copy of the tree cursor. This allocates new memory. */
|
||||
copy(): TreeCursor {
|
||||
const copy = new TreeCursor(INTERNAL, this.tree);
|
||||
C._ts_tree_cursor_copy_wasm(this.tree[0]);
|
||||
|
|
@ -33,55 +36,99 @@ export class TreeCursor {
|
|||
return copy;
|
||||
}
|
||||
|
||||
/** Delete the tree cursor, freeing its resources. */
|
||||
delete(): void {
|
||||
marshalTreeCursor(this);
|
||||
C._ts_tree_cursor_delete_wasm(this.tree[0]);
|
||||
this[0] = this[1] = this[2] = 0;
|
||||
}
|
||||
|
||||
reset(node: Node): void {
|
||||
marshalNode(node);
|
||||
marshalTreeCursor(this, TRANSFER_BUFFER + SIZE_OF_NODE);
|
||||
C._ts_tree_cursor_reset_wasm(this.tree[0]);
|
||||
unmarshalTreeCursor(this);
|
||||
/** Get the tree cursor's current {@link Node}. */
|
||||
get currentNode(): Node {
|
||||
marshalTreeCursor(this);
|
||||
C._ts_tree_cursor_current_node_wasm(this.tree[0]);
|
||||
return unmarshalNode(this.tree)!;
|
||||
}
|
||||
|
||||
resetTo(cursor: TreeCursor): void {
|
||||
marshalTreeCursor(this, TRANSFER_BUFFER);
|
||||
marshalTreeCursor(cursor, TRANSFER_BUFFER + SIZE_OF_CURSOR);
|
||||
C._ts_tree_cursor_reset_to_wasm(this.tree[0], cursor.tree[0]);
|
||||
unmarshalTreeCursor(this);
|
||||
/**
|
||||
* Get the numerical field id of this tree cursor's current node.
|
||||
*
|
||||
* See also {@link TreeCursor#currentFieldName}.
|
||||
*/
|
||||
get currentFieldId(): number {
|
||||
marshalTreeCursor(this);
|
||||
return C._ts_tree_cursor_current_field_id_wasm(this.tree[0]);
|
||||
}
|
||||
|
||||
/** Get the field name of this tree cursor's current node. */
|
||||
get currentFieldName(): string | null {
|
||||
return this.tree.language.fields[this.currentFieldId];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the depth of the cursor's current node relative to the original
|
||||
* node that the cursor was constructed with.
|
||||
*/
|
||||
get currentDepth(): number {
|
||||
marshalTreeCursor(this);
|
||||
return C._ts_tree_cursor_current_depth_wasm(this.tree[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index of the cursor's current node out of all of the
|
||||
* descendants of the original node that the cursor was constructed with.
|
||||
*/
|
||||
get currentDescendantIndex(): number {
|
||||
marshalTreeCursor(this);
|
||||
return C._ts_tree_cursor_current_descendant_index_wasm(this.tree[0]);
|
||||
}
|
||||
|
||||
/** Get the type of the cursor's current node. */
|
||||
get nodeType(): string {
|
||||
return this.tree.language.types[this.nodeTypeId] || 'ERROR';
|
||||
}
|
||||
|
||||
/** Get the type id of the cursor's current node. */
|
||||
get nodeTypeId(): number {
|
||||
marshalTreeCursor(this);
|
||||
return C._ts_tree_cursor_current_node_type_id_wasm(this.tree[0]);
|
||||
}
|
||||
|
||||
/** Get the state id of the cursor's current node. */
|
||||
get nodeStateId(): number {
|
||||
marshalTreeCursor(this);
|
||||
return C._ts_tree_cursor_current_node_state_id_wasm(this.tree[0]);
|
||||
}
|
||||
|
||||
/** Get the id of the cursor's current node. */
|
||||
get nodeId(): number {
|
||||
marshalTreeCursor(this);
|
||||
return C._ts_tree_cursor_current_node_id_wasm(this.tree[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the cursor's current node is *named*.
|
||||
*
|
||||
* Named nodes correspond to named rules in the grammar, whereas
|
||||
* *anonymous* nodes correspond to string literals in the grammar.
|
||||
*/
|
||||
get nodeIsNamed(): boolean {
|
||||
marshalTreeCursor(this);
|
||||
return C._ts_tree_cursor_current_node_is_named_wasm(this.tree[0]) === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the cursor's current node is *missing*.
|
||||
*
|
||||
* Missing nodes are inserted by the parser in order to recover from
|
||||
* certain kinds of syntax errors.
|
||||
*/
|
||||
get nodeIsMissing(): boolean {
|
||||
marshalTreeCursor(this);
|
||||
return C._ts_tree_cursor_current_node_is_missing_wasm(this.tree[0]) === 1;
|
||||
}
|
||||
|
||||
/** Get the string content of the cursor's current node. */
|
||||
get nodeText(): string {
|
||||
marshalTreeCursor(this);
|
||||
const startIndex = C._ts_tree_cursor_start_index_wasm(this.tree[0]);
|
||||
|
|
@ -91,53 +138,38 @@ export class TreeCursor {
|
|||
return getText(this.tree, startIndex, endIndex, startPosition);
|
||||
}
|
||||
|
||||
/** Get the start position of the cursor's current node. */
|
||||
get startPosition(): Point {
|
||||
marshalTreeCursor(this);
|
||||
C._ts_tree_cursor_start_position_wasm(this.tree[0]);
|
||||
return unmarshalPoint(TRANSFER_BUFFER);
|
||||
}
|
||||
|
||||
/** Get the end position of the cursor's current node. */
|
||||
get endPosition(): Point {
|
||||
marshalTreeCursor(this);
|
||||
C._ts_tree_cursor_end_position_wasm(this.tree[0]);
|
||||
return unmarshalPoint(TRANSFER_BUFFER);
|
||||
}
|
||||
|
||||
/** Get the start index of the cursor's current node. */
|
||||
get startIndex(): number {
|
||||
marshalTreeCursor(this);
|
||||
return C._ts_tree_cursor_start_index_wasm(this.tree[0]);
|
||||
}
|
||||
|
||||
/** Get the end index of the cursor's current node. */
|
||||
get endIndex(): number {
|
||||
marshalTreeCursor(this);
|
||||
return C._ts_tree_cursor_end_index_wasm(this.tree[0]);
|
||||
}
|
||||
|
||||
get currentNode(): Node {
|
||||
marshalTreeCursor(this);
|
||||
C._ts_tree_cursor_current_node_wasm(this.tree[0]);
|
||||
return unmarshalNode(this.tree)!;
|
||||
}
|
||||
|
||||
get currentFieldId(): number {
|
||||
marshalTreeCursor(this);
|
||||
return C._ts_tree_cursor_current_field_id_wasm(this.tree[0]);
|
||||
}
|
||||
|
||||
get currentFieldName(): string | null {
|
||||
return this.tree.language.fields[this.currentFieldId];
|
||||
}
|
||||
|
||||
get currentDepth(): number {
|
||||
marshalTreeCursor(this);
|
||||
return C._ts_tree_cursor_current_depth_wasm(this.tree[0]);
|
||||
}
|
||||
|
||||
get currentDescendantIndex(): number {
|
||||
marshalTreeCursor(this);
|
||||
return C._ts_tree_cursor_current_descendant_index_wasm(this.tree[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move this cursor to the first child of its current node.
|
||||
*
|
||||
* This returns `true` if the cursor successfully moved, and returns
|
||||
* `false` if there were no children.
|
||||
*/
|
||||
gotoFirstChild(): boolean {
|
||||
marshalTreeCursor(this);
|
||||
const result = C._ts_tree_cursor_goto_first_child_wasm(this.tree[0]);
|
||||
|
|
@ -145,6 +177,16 @@ export class TreeCursor {
|
|||
return result === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move this cursor to the last child of its current node.
|
||||
*
|
||||
* This returns `true` if the cursor successfully moved, and returns
|
||||
* `false` if there were no children.
|
||||
*
|
||||
* Note that this function may be slower than
|
||||
* {@link TreeCursor#gotoFirstChild} because it needs to
|
||||
* iterate through all the children to compute the child's position.
|
||||
*/
|
||||
gotoLastChild(): boolean {
|
||||
marshalTreeCursor(this);
|
||||
const result = C._ts_tree_cursor_goto_last_child_wasm(this.tree[0]);
|
||||
|
|
@ -152,6 +194,77 @@ export class TreeCursor {
|
|||
return result === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move this cursor to the parent of its current node.
|
||||
*
|
||||
* This returns `true` if the cursor successfully moved, and returns
|
||||
* `false` if there was no parent node (the cursor was already on the
|
||||
* root node).
|
||||
*
|
||||
* Note that the node the cursor was constructed with is considered the root
|
||||
* of the cursor, and the cursor cannot walk outside this node.
|
||||
*/
|
||||
gotoParent(): boolean {
|
||||
marshalTreeCursor(this);
|
||||
const result = C._ts_tree_cursor_goto_parent_wasm(this.tree[0]);
|
||||
unmarshalTreeCursor(this);
|
||||
return result === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move this cursor to the next sibling of its current node.
|
||||
*
|
||||
* This returns `true` if the cursor successfully moved, and returns
|
||||
* `false` if there was no next sibling node.
|
||||
*
|
||||
* Note that the node the cursor was constructed with is considered the root
|
||||
* of the cursor, and the cursor cannot walk outside this node.
|
||||
*/
|
||||
gotoNextSibling(): boolean {
|
||||
marshalTreeCursor(this);
|
||||
const result = C._ts_tree_cursor_goto_next_sibling_wasm(this.tree[0]);
|
||||
unmarshalTreeCursor(this);
|
||||
return result === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move this cursor to the previous sibling of its current node.
|
||||
*
|
||||
* This returns `true` if the cursor successfully moved, and returns
|
||||
* `false` if there was no previous sibling node.
|
||||
*
|
||||
* Note that this function may be slower than
|
||||
* {@link TreeCursor#gotoNextSibling} due to how node
|
||||
* positions are stored. In the worst case, this will need to iterate
|
||||
* through all the children up to the previous sibling node to recalculate
|
||||
* its position. Also note that the node the cursor was constructed with is
|
||||
* considered the root of the cursor, and the cursor cannot walk outside this node.
|
||||
*/
|
||||
gotoPreviousSibling(): boolean {
|
||||
marshalTreeCursor(this);
|
||||
const result = C._ts_tree_cursor_goto_previous_sibling_wasm(this.tree[0]);
|
||||
unmarshalTreeCursor(this);
|
||||
return result === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the cursor to the node that is the nth descendant of
|
||||
* the original node that the cursor was constructed with, where
|
||||
* zero represents the original node itself.
|
||||
*/
|
||||
gotoDescendant(goalDescendantIndex: number): void {
|
||||
marshalTreeCursor(this);
|
||||
C._ts_tree_cursor_goto_descendant_wasm(this.tree[0], goalDescendantIndex);
|
||||
unmarshalTreeCursor(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move this cursor to the first child of its current node that contains or
|
||||
* starts after the given byte offset.
|
||||
*
|
||||
* This returns `true` if the cursor successfully moved to a child node, and returns
|
||||
* `false` if no such child was found.
|
||||
*/
|
||||
gotoFirstChildForIndex(goalIndex: number): boolean {
|
||||
marshalTreeCursor(this);
|
||||
C.setValue(TRANSFER_BUFFER + SIZE_OF_CURSOR, goalIndex, 'i32');
|
||||
|
|
@ -160,6 +273,13 @@ export class TreeCursor {
|
|||
return result === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move this cursor to the first child of its current node that contains or
|
||||
* starts after the given byte offset.
|
||||
*
|
||||
* This returns the index of the child node if one was found, and returns
|
||||
* `null` if no such child was found.
|
||||
*/
|
||||
gotoFirstChildForPosition(goalPosition: Point): boolean {
|
||||
marshalTreeCursor(this);
|
||||
marshalPoint(TRANSFER_BUFFER + SIZE_OF_CURSOR, goalPosition);
|
||||
|
|
@ -168,30 +288,27 @@ export class TreeCursor {
|
|||
return result === 1;
|
||||
}
|
||||
|
||||
gotoNextSibling(): boolean {
|
||||
marshalTreeCursor(this);
|
||||
const result = C._ts_tree_cursor_goto_next_sibling_wasm(this.tree[0]);
|
||||
unmarshalTreeCursor(this);
|
||||
return result === 1;
|
||||
}
|
||||
|
||||
gotoPreviousSibling(): boolean {
|
||||
marshalTreeCursor(this);
|
||||
const result = C._ts_tree_cursor_goto_previous_sibling_wasm(this.tree[0]);
|
||||
unmarshalTreeCursor(this);
|
||||
return result === 1;
|
||||
}
|
||||
|
||||
gotoDescendant(goalDescendantIndex: number): void {
|
||||
marshalTreeCursor(this);
|
||||
C._ts_tree_cursor_goto_descendant_wasm(this.tree[0], goalDescendantIndex);
|
||||
/**
|
||||
* Re-initialize this tree cursor to start at the original node that the
|
||||
* cursor was constructed with.
|
||||
*/
|
||||
reset(node: Node): void {
|
||||
marshalNode(node);
|
||||
marshalTreeCursor(this, TRANSFER_BUFFER + SIZE_OF_NODE);
|
||||
C._ts_tree_cursor_reset_wasm(this.tree[0]);
|
||||
unmarshalTreeCursor(this);
|
||||
}
|
||||
|
||||
gotoParent(): boolean {
|
||||
marshalTreeCursor(this);
|
||||
const result = C._ts_tree_cursor_goto_parent_wasm(this.tree[0]);
|
||||
/**
|
||||
* Re-initialize a tree cursor to the same position as another cursor.
|
||||
*
|
||||
* Unlike {@link TreeCursor#reset}, this will not lose parent
|
||||
* information and allows reusing already created cursors.
|
||||
*/
|
||||
resetTo(cursor: TreeCursor): void {
|
||||
marshalTreeCursor(this, TRANSFER_BUFFER);
|
||||
marshalTreeCursor(cursor, TRANSFER_BUFFER + SIZE_OF_CURSOR);
|
||||
C._ts_tree_cursor_reset_to_wasm(this.tree[0], cursor.tree[0]);
|
||||
unmarshalTreeCursor(this);
|
||||
return result === 1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue