feat(wasm)!: keep API in-line with upstream and start aligning with node

This commit is contained in:
Amaan Qureshi 2024-03-09 01:28:35 -05:00
parent c070c92722
commit 728793a160
8 changed files with 743 additions and 107 deletions

View file

@ -69,7 +69,7 @@ class ParserImpl {
parse(callback, oldTree, options) {
if (typeof callback === 'string') {
currentParseCallback = (index, _, endIndex) => callback.slice(index, endIndex);
currentParseCallback = (index, _) => callback.slice(index);
} else if (typeof callback === 'function') {
currentParseCallback = callback;
} else {
@ -120,14 +120,28 @@ class ParserImpl {
C._ts_parser_reset(this[0]);
}
setTimeoutMicros(timeout) {
C._ts_parser_set_timeout_micros(this[0], timeout);
getIncludedRanges() {
const count = C._malloc(SIZE_OF_INT);
const rangeAddress = C._ts_parser_included_ranges(this[0], count);
count = getValue(count, 'i32');
const result = new Array(count);
if (count > 0) {
let address = rangeAddress;
for (let i = 0; i < count; i++) {
result[i] = unmarshalRange(address);
address += SIZE_OF_RANGE;
}
}
}
getTimeoutMicros() {
return C._ts_parser_timeout_micros(this[0]);
}
setTimeoutMicros(timeout) {
C._ts_parser_set_timeout_micros(this[0], timeout);
}
setLogger(callback) {
if (!callback) {
callback = null;
@ -171,6 +185,14 @@ class Tree {
return unmarshalNode(this);
}
rootNodeWithOffset(offsetBytes, offsetExtent) {
const address = TRANSFER_BUFFER + SIZE_OF_NODE;
setValue(address, offsetBytes, 'i32');
marshalPoint(address + SIZE_OF_INT, offsetExtent);
C._ts_tree_root_node_with_offset_wasm(this[0]);
return unmarshalNode(this);
}
getLanguage() {
return this.language;
}
@ -198,6 +220,22 @@ class Tree {
}
return result;
}
getIncludedRanges() {
C._ts_tree_included_ranges_wasm(this[0]);
const count = getValue(TRANSFER_BUFFER, 'i32');
const buffer = getValue(TRANSFER_BUFFER + SIZE_OF_INT, 'i32');
const result = new Array(count);
if (count > 0) {
let address = buffer;
for (let i = 0; i < count; i++) {
result[i] = unmarshalRange(address);
address += SIZE_OF_RANGE;
}
C._free(buffer);
}
return result;
}
}
class Node {
@ -274,6 +312,11 @@ class Node {
return C._ts_node_is_missing_wasm(this.tree[0]) === 1;
}
get isExtra() {
marshalNode(this);
return C._ts_node_is_extra_wasm(this.tree[0]) === 1;
}
equals(other) {
return this.id === other.id;
}
@ -284,17 +327,6 @@ class Node {
return unmarshalNode(this.tree);
}
fieldNameForChild(index) {
marshalNode(this);
const address = C._ts_node_field_name_for_child_wasm(this.tree[0], index);
if (!address) {
return null;
}
const result = AsciiToString(address);
// must not free, the string memory is owned by the language
return result;
}
namedChild(index) {
marshalNode(this);
C._ts_node_named_child_wasm(this.tree[0], index);
@ -312,6 +344,55 @@ class Node {
if (fieldId !== -1) return this.childForFieldId(fieldId);
}
fieldNameForChild(index) {
marshalNode(this);
const address = C._ts_node_field_name_for_child_wasm(this.tree[0], index);
if (!address) {
return null;
}
const result = AsciiToString(address);
// must not free, the string memory is owned by the language
return result;
}
childrenForFieldName(fieldName) {
const fieldId = this.tree.language.fields.indexOf(fieldName);
if (fieldId !== -1 && fieldId !== 0) return this.childrenForFieldId(fieldId);
}
childrenForFieldId(fieldId) {
marshalNode(this);
C._ts_node_children_by_field_id_wasm(this.tree[0], fieldId);
const count = getValue(TRANSFER_BUFFER, 'i32');
const buffer = getValue(TRANSFER_BUFFER + SIZE_OF_INT, 'i32');
const result = new Array(count);
if (count > 0) {
let address = buffer;
for (let i = 0; i < count; i++) {
result[i] = unmarshalNode(this.tree, address);
address += SIZE_OF_NODE;
}
C._free(buffer);
}
return result;
}
firstChildForIndex(index) {
marshalNode(this);
const address = TRANSFER_BUFFER + SIZE_OF_NODE;
setValue(address, index, 'i32');
C._ts_node_first_child_for_byte_wasm(this.tree[0]);
return unmarshalNode(this.tree);
}
firstNamedChildForIndex(index) {
marshalNode(this);
const address = TRANSFER_BUFFER + SIZE_OF_NODE;
setValue(address, index, 'i32');
C._ts_node_first_named_child_for_byte_wasm(this.tree[0]);
return unmarshalNode(this.tree);
}
get childCount() {
marshalNode(this);
return C._ts_node_child_count_wasm(this.tree[0]);
@ -450,6 +531,11 @@ class Node {
return unmarshalNode(this.tree);
}
get descendantCount() {
marshalNode(this);
return C._ts_node_descendant_count_wasm(this.tree[0]);
}
get parent() {
marshalNode(this);
C._ts_node_parent_wasm(this.tree[0]);
@ -623,6 +709,16 @@ class TreeCursor {
return this.tree.language.fields[this.currentFieldId];
}
get currentDepth() {
marshalTreeCursor(this);
return C._ts_tree_cursor_current_depth_wasm(this.tree[0]);
}
get currentDescendantIndex() {
marshalTreeCursor(this);
return C._ts_tree_cursor_current_descendant_index_wasm(this.tree[0]);
}
gotoFirstChild() {
marshalTreeCursor(this);
const result = C._ts_tree_cursor_goto_first_child_wasm(this.tree[0]);
@ -637,6 +733,22 @@ class TreeCursor {
return result === 1;
}
gotoFirstChildForIndex(goalIndex) {
marshalTreeCursor(this);
setValue(TRANSFER_BUFFER + SIZE_OF_CURSOR, goalIndex, 'i32');
const result = C._ts_tree_cursor_goto_first_child_for_index_wasm(this.tree[0]);
unmarshalTreeCursor(this);
return result === 1;
}
gotoFirstChildForPosition(goalPosition) {
marshalTreeCursor(this);
marshalPoint(TRANSFER_BUFFER + SIZE_OF_CURSOR, goalPosition);
const result = C._ts_tree_cursor_goto_first_child_for_position_wasm(this.tree[0]);
unmarshalTreeCursor(this);
return result === 1;
}
gotoNextSibling() {
marshalTreeCursor(this);
const result = C._ts_tree_cursor_goto_next_sibling_wasm(this.tree[0]);
@ -651,6 +763,12 @@ class TreeCursor {
return result === 1;
}
gotoDescendant(goalDescendantindex) {
marshalTreeCursor(this);
C._ts_tree_cursor_goto_descendant_wasm(this.tree[0], goalDescendantindex);
unmarshalTreeCursor(this);
}
gotoParent() {
marshalTreeCursor(this);
const result = C._ts_tree_cursor_goto_parent_wasm(this.tree[0]);
@ -815,6 +933,7 @@ class Language {
const refutedProperties = new Array(patternCount);
const predicates = new Array(patternCount);
const textPredicates = new Array(patternCount);
for (let i = 0; i < patternCount; i++) {
const predicatesAddress = C._ts_query_predicates_for_pattern(
address,
@ -1141,15 +1260,18 @@ class Query {
this[0] = 0;
}
matches(node, startPosition, endPosition, options) {
if (!startPosition) startPosition = ZERO_POINT;
if (!endPosition) endPosition = ZERO_POINT;
if (!options) options = {};
let matchLimit = options.matchLimit;
if (typeof matchLimit === 'undefined') {
matchLimit = 0;
} else if (typeof matchLimit !== 'number') {
matches(
node,
{
startPosition = ZERO_POINT,
endPosition = ZERO_POINT,
startIndex = 0,
endIndex = 0,
matchLimit = 0xFFFFFFFF,
maxStartDepth = 0xFFFFFFFF,
} = {},
) {
if (typeof matchLimit !== 'number') {
throw new Error('Arguments must be numbers');
}
@ -1162,7 +1284,10 @@ class Query {
startPosition.column,
endPosition.row,
endPosition.column,
startIndex,
endIndex,
matchLimit,
maxStartDepth,
);
const rawCount = getValue(TRANSFER_BUFFER, 'i32');
@ -1198,15 +1323,18 @@ class Query {
return result;
}
captures(node, startPosition, endPosition, options) {
if (!startPosition) startPosition = ZERO_POINT;
if (!endPosition) endPosition = ZERO_POINT;
if (!options) options = {};
let matchLimit = options.matchLimit;
if (typeof matchLimit === 'undefined') {
matchLimit = 0;
} else if (typeof matchLimit !== 'number') {
captures(
node,
{
startPosition = ZERO_POINT,
endPosition = ZERO_POINT,
startIndex = 0,
endIndex = 0,
matchLimit = 0xFFFFFFFF,
maxStartDepth = 0xFFFFFFFF,
} = {},
) {
if (typeof matchLimit !== 'number') {
throw new Error('Arguments must be numbers');
}
@ -1219,7 +1347,10 @@ class Query {
startPosition.column,
endPosition.row,
endPosition.column,
startIndex,
endIndex,
matchLimit,
maxStartDepth,
);
const count = getValue(TRANSFER_BUFFER, 'i32');
@ -1261,6 +1392,14 @@ class Query {
return this.predicates[patternIndex];
}
disableCapture(captureName) {
const captureNameLength = lengthBytesUTF8(captureName);
const captureNameAddress = C._malloc(captureNameLength + 1);
stringToUTF8(captureName, captureNameAddress, captureNameLength + 1);
C._ts_query_disable_capture(this[0], captureNameAddress, captureNameLength);
C._free(captureNameAddress);
}
didExceedMatchLimit() {
return this.exceededMatchLimit;
}