feat(web): add missing API functions

Co-authored-by: Will Lillis <will.lillis24@gmail.com>
This commit is contained in:
Amaan Qureshi 2025-01-05 22:06:33 -05:00
parent dcdd6ce2d2
commit 45fa028201
11 changed files with 436 additions and 35 deletions

View file

@ -24,6 +24,10 @@ let MIN_COMPATIBLE_VERSION;
let TRANSFER_BUFFER;
let currentParseCallback;
// eslint-disable-next-line no-unused-vars
let currentProgressCallback;
// eslint-disable-next-line no-unused-vars
let currentQueryProgressCallback;
// eslint-disable-next-line no-unused-vars
let currentLogCallback;
// eslint-disable-next-line no-unused-vars
@ -82,6 +86,12 @@ class ParserImpl {
throw new Error('Argument must be a string or a function');
}
if (options?.progressCallback) {
currentProgressCallback = options.progressCallback;
} else {
currentProgressCallback = null;
}
if (this.logCallback) {
currentLogCallback = this.logCallback;
C._ts_parser_enable_logger_wasm(this[0], 1);
@ -113,12 +123,14 @@ class ParserImpl {
if (!treeAddress) {
currentParseCallback = null;
currentLogCallback = null;
currentProgressCallback = null;
throw new Error('Parsing failed');
}
const result = new Tree(INTERNAL, treeAddress, this.language, currentParseCallback);
currentParseCallback = null;
currentLogCallback = null;
currentProgressCallback = null;
return result;
}
@ -326,7 +338,7 @@ class Node {
}
equals(other) {
return this.id === other.id;
return this.tree === other.tree && this.id === other.id;
}
child(index) {
@ -364,6 +376,20 @@ class Node {
return result;
}
fieldNameForNamedChild(index) {
marshalNode(this);
const address = C._ts_node_field_name_for_named_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);
@ -610,6 +636,35 @@ class Node {
return new TreeCursor(INTERNAL, this.tree);
}
edit(edit) {
if (this.startIndex >= edit.oldEndIndex) {
this.startIndex = edit.newEndIndex + (this.startIndex - edit.oldEndIndex);
let subbedPointRow;
let subbedPointColumn;
if (this.startPosition.row > edit.oldEndPosition.row) {
subbedPointRow = this.startPosition.row - edit.oldEndPosition.row;
subbedPointColumn = this.startPosition.column;
} else {
subbedPointRow = 0;
if (this.startPosition.column >= edit.oldEndPosition.column) {
subbedPointColumn =
this.startPosition.column - edit.oldEndPosition.column;
}
}
if (subbedPointRow > 0) {
this.startPosition.row += subbedPointRow;
this.startPosition.column = subbedPointColumn;
} else {
this.startPosition.column += subbedPointColumn;
}
} else if (this.startIndex > edit.startIndex) {
this.startIndex = edit.newEndIndex;
this.startPosition.row = edit.newEndPosition.row;
this.startPosition.column = edit.newEndPosition.column;
}
}
toString() {
marshalNode(this);
const address = C._ts_node_to_string_wasm(this.tree[0]);
@ -626,6 +681,13 @@ class TreeCursor {
unmarshalTreeCursor(this);
}
copy() {
const copy = new TreeCursor(INTERNAL, this.tree);
C._ts_tree_cursor_copy_wasm(this.tree[0]);
unmarshalTreeCursor(copy);
return copy;
}
delete() {
marshalTreeCursor(this);
C._ts_tree_cursor_delete_wasm(this.tree[0]);
@ -808,6 +870,10 @@ class Language {
}
}
get name() {
return UTF8ToString(C._ts_language_name(this[0]));
}
get version() {
return C._ts_language_version(this[0]);
}
@ -951,6 +1017,7 @@ class Language {
const captureCount = C._ts_query_capture_count(address);
const patternCount = C._ts_query_pattern_count(address);
const captureNames = new Array(captureCount);
const captureQuantifiers = new Array(patternCount);
const stringValues = new Array(stringCount);
for (let i = 0; i < captureCount; i++) {
@ -963,6 +1030,15 @@ class Language {
captureNames[i] = UTF8ToString(nameAddress, nameLength);
}
for (let i = 0; i < patternCount; i++) {
const captureQuantifiersArray = new Array(captureCount);
for (let j = 0; j < captureCount; j++) {
const quantifier = C._ts_query_capture_quantifier_for_id(address, i, j);
captureQuantifiersArray[j] = quantifier;
}
captureQuantifiers[i] = captureQuantifiersArray;
}
for (let i = 0; i < stringCount; i++) {
const valueAddress = C._ts_query_string_value_for_id(
address,
@ -1185,6 +1261,7 @@ class Language {
INTERNAL,
address,
captureNames,
captureQuantifiers,
textPredicates,
predicates,
Object.freeze(setProperties),
@ -1281,12 +1358,14 @@ class LookaheadIterable {
class Query {
constructor(
internal, address, captureNames, textPredicates, predicates,
internal, address,
captureNames, captureQuantifiers, textPredicates, predicates,
setProperties, assertedProperties, refutedProperties,
) {
assertInternal(internal);
this[0] = address;
this.captureNames = captureNames;
this.captureQuantifiers = captureQuantifiers;
this.textPredicates = textPredicates;
this.predicates = predicates;
this.setProperties = setProperties;
@ -1310,6 +1389,7 @@ class Query {
matchLimit = 0xFFFFFFFF,
maxStartDepth = 0xFFFFFFFF,
timeoutMicros = 0,
progressCallback,
} = {},
) {
if (typeof matchLimit !== 'number') {
@ -1323,6 +1403,10 @@ class Query {
throw new Error('`startPosition` cannot be greater than `endPosition`');
}
if (progressCallback) {
currentQueryProgressCallback = progressCallback;
}
marshalNode(node);
C._ts_query_matches_wasm(
@ -1369,6 +1453,7 @@ class Query {
result.length = filteredCount;
C._free(startAddress);
currentQueryProgressCallback = null;
return result;
}
@ -1382,6 +1467,7 @@ class Query {
matchLimit = 0xFFFFFFFF,
maxStartDepth = 0xFFFFFFFF,
timeoutMicros = 0,
progressCallback,
} = {},
) {
if (typeof matchLimit !== 'number') {
@ -1395,6 +1481,10 @@ class Query {
throw new Error('`startPosition` cannot be greater than `endPosition`');
}
if (progressCallback) {
currentQueryProgressCallback = progressCallback;
}
marshalNode(node);
C._ts_query_captures_wasm(
@ -1443,6 +1533,7 @@ class Query {
}
C._free(startAddress);
currentQueryProgressCallback = null;
return result;
}
@ -1458,9 +1549,54 @@ class Query {
C._free(captureNameAddress);
}
disablePattern(patternIndex) {
if (patternIndex >= this.predicates.length) {
throw new Error(
`Pattern index is ${patternIndex} but the pattern count is ${this.predicates.length}`,
);
}
C._ts_query_disable_pattern(this[0], patternIndex);
}
didExceedMatchLimit() {
return this.exceededMatchLimit;
}
startIndexForPattern(patternIndex) {
if (patternIndex >= this.predicates.length) {
throw new Error(
`Pattern index is ${patternIndex} but the pattern count is ${this.predicates.length}`,
);
}
return C._ts_query_start_byte_for_pattern(this[0], patternIndex);
}
endIndexForPattern(patternIndex) {
if (patternIndex >= this.predicates.length) {
throw new Error(
`Pattern index is ${patternIndex} but the pattern count is ${this.predicates.length}`,
);
}
return C._ts_query_end_byte_for_pattern(this[0], patternIndex);
}
isPatternNonLocal(patternIndex) {
return C._ts_query_is_pattern_non_local(this[0], patternIndex) === 1;
}
isPatternRooted(patternIndex) {
return C._ts_query_is_pattern_rooted(this[0], patternIndex) === 1;
}
isPatternGuaranteedAtStep(patternIndex, stepIndex) {
return (
C._ts_query_is_pattern_guaranteed_at_step(
this[0],
patternIndex,
stepIndex,
) === 1
);
}
}
function getText(tree, startIndex, endIndex) {