fix(web): correct childWithDescendant() functionality
This fix allows for more granular address control when marshalling nodes across WASM. This is necessary for node methods which accept another node as a parameter (i.e., `childWithDescendant()`)
This commit is contained in:
parent
45a281c962
commit
21390af2dd
4 changed files with 30 additions and 10 deletions
|
|
@ -44,17 +44,22 @@ static inline void marshal_node(const void **buffer, TSNode node) {
|
|||
buffer[4] = (const void *)node.context[3];
|
||||
}
|
||||
|
||||
static inline TSNode unmarshal_node(const TSTree *tree) {
|
||||
static inline TSNode unmarshal_node_at(const TSTree *tree, uint32_t index) {
|
||||
TSNode node;
|
||||
node.id = TRANSFER_BUFFER[0];
|
||||
node.context[0] = code_unit_to_byte((uint32_t)TRANSFER_BUFFER[1]);
|
||||
node.context[1] = (uint32_t)TRANSFER_BUFFER[2];
|
||||
node.context[2] = code_unit_to_byte((uint32_t)TRANSFER_BUFFER[3]);
|
||||
node.context[3] = (uint32_t)TRANSFER_BUFFER[4];
|
||||
const void **buffer = TRANSFER_BUFFER + index * SIZE_OF_NODE;
|
||||
node.id = buffer[0];
|
||||
node.context[0] = code_unit_to_byte((uint32_t)buffer[1]);
|
||||
node.context[1] = (uint32_t)buffer[2];
|
||||
node.context[2] = code_unit_to_byte((uint32_t)buffer[3]);
|
||||
node.context[3] = (uint32_t)buffer[4];
|
||||
node.tree = tree;
|
||||
return node;
|
||||
}
|
||||
|
||||
static inline TSNode unmarshal_node(const TSTree *tree) {
|
||||
return unmarshal_node_at(tree, 0);
|
||||
}
|
||||
|
||||
static inline void marshal_cursor(const TSTreeCursor *cursor) {
|
||||
TRANSFER_BUFFER[0] = cursor->id;
|
||||
TRANSFER_BUFFER[1] = (const void *)cursor->context[0];
|
||||
|
|
@ -616,7 +621,7 @@ void ts_node_parent_wasm(const TSTree *tree) {
|
|||
|
||||
void ts_node_child_with_descendant_wasm(const TSTree *tree) {
|
||||
TSNode node = unmarshal_node(tree);
|
||||
TSNode descendant = unmarshal_node(tree);
|
||||
TSNode descendant = unmarshal_node_at(tree, 1);
|
||||
marshal_node(TRANSFER_BUFFER, ts_node_child_with_descendant(node, descendant));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ export function unmarshalCaptures(
|
|||
*
|
||||
* Marshals a {@link Node} to the transfer buffer.
|
||||
*/
|
||||
export function marshalNode(node: Node) {
|
||||
let address = TRANSFER_BUFFER;
|
||||
export function marshalNode(node: Node, index = 0) {
|
||||
let address = TRANSFER_BUFFER + index * SIZE_OF_NODE;
|
||||
C.setValue(address, node.id, 'i32');
|
||||
address += SIZE_OF_INT;
|
||||
C.setValue(address, node.startIndex, 'i32');
|
||||
|
|
|
|||
|
|
@ -522,7 +522,7 @@ export class Node {
|
|||
*/
|
||||
childWithDescendant(descendant: Node): Node | null {
|
||||
marshalNode(this);
|
||||
marshalNode(descendant);
|
||||
marshalNode(descendant, 1);
|
||||
C._ts_node_child_with_descendant_wasm(this.tree[0]);
|
||||
return unmarshalNode(this.tree);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -189,6 +189,21 @@ describe('Node', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('.childWithDescendant()', () => {
|
||||
it('correctly retrieves immediate children', () => {
|
||||
const sourceCode = 'let x = 1; console.log(x);';
|
||||
tree = parser.parse(sourceCode)!;
|
||||
const root = tree.rootNode
|
||||
const child = root.children[0].children[0]
|
||||
const a = root.childWithDescendant(child)
|
||||
expect(a!.startIndex).toBe(0)
|
||||
const b = a!.childWithDescendant(child)
|
||||
expect(b).toEqual(child)
|
||||
const c = b!.childWithDescendant(child)
|
||||
expect(c).toBeNull()
|
||||
});
|
||||
});
|
||||
|
||||
describe('.nextSibling and .previousSibling', () => {
|
||||
it('returns the node\'s next and previous sibling', () => {
|
||||
tree = parser.parse('x10 + 1000')!;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue