wasm: Implement Node.descendantsOfType
This commit is contained in:
parent
1733180d48
commit
f00b310908
5 changed files with 151 additions and 4 deletions
|
|
@ -4,6 +4,7 @@ const SIZE_OF_INT = 4;
|
|||
const SIZE_OF_NODE = 5 * SIZE_OF_INT;
|
||||
const SIZE_OF_POINT = 2 * SIZE_OF_INT;
|
||||
const SIZE_OF_RANGE = 2 * SIZE_OF_INT + 2 * SIZE_OF_POINT;
|
||||
const ZERO_POINT = {row: 0, column: 0};
|
||||
|
||||
var VERSION;
|
||||
var MIN_COMPATIBLE_VERSION;
|
||||
|
|
@ -355,6 +356,56 @@ class Node {
|
|||
return this._namedChildren;
|
||||
}
|
||||
|
||||
descendantsOfType(types, startPosition, endPosition) {
|
||||
if (!Array.isArray(types)) types = [types];
|
||||
if (!startPosition) startPosition = ZERO_POINT;
|
||||
if (!endPosition) endPosition = ZERO_POINT;
|
||||
|
||||
// Convert the type strings to numeric type symbols.
|
||||
const symbols = [];
|
||||
const typesBySymbol = this.tree.language.types;
|
||||
for (let i = 0, n = typesBySymbol.length; i < n; i++) {
|
||||
if (types.includes(typesBySymbol[i])) {
|
||||
symbols.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the array of symbols to the WASM heap.
|
||||
const symbolsAddress = C._malloc(SIZE_OF_INT * symbols.count);
|
||||
for (let i = 0, n = symbols.length; i < n; i++) {
|
||||
setValue(symbolsAddress + i * SIZE_OF_INT, symbols[i], 'i32');
|
||||
}
|
||||
|
||||
// Call the C API to compute the descendants.
|
||||
marshalNode(this);
|
||||
C._ts_node_descendants_of_type_wasm(
|
||||
this.tree[0],
|
||||
symbolsAddress,
|
||||
symbols.length,
|
||||
startPosition.row,
|
||||
startPosition.column,
|
||||
endPosition.row,
|
||||
endPosition.column
|
||||
);
|
||||
|
||||
// Instantiate the nodes based on the data returned.
|
||||
const descendantCount = getValue(TRANSFER_BUFFER, 'i32');
|
||||
const descendantAddress = getValue(TRANSFER_BUFFER + SIZE_OF_INT, 'i32');
|
||||
const result = new Array(descendantCount);
|
||||
if (descendantCount > 0) {
|
||||
let address = descendantAddress;
|
||||
for (let i = 0; i < descendantCount; i++) {
|
||||
result[i] = unmarshalNode(this.tree, address);
|
||||
address += SIZE_OF_NODE;
|
||||
}
|
||||
}
|
||||
|
||||
// Free the intermediate buffers
|
||||
C._free(descendantAddress);
|
||||
C._free(symbolsAddress);
|
||||
return result;
|
||||
}
|
||||
|
||||
get nextSibling() {
|
||||
marshalNode(this);
|
||||
C._ts_node_next_sibling_wasm(this.tree[0]);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue