Add TreeCursor.currentFieldName to wasm binding

This commit is contained in:
Max Brunsfeld 2019-02-08 17:53:21 -08:00
parent c90a532d8f
commit 1a33f1a665
4 changed files with 51 additions and 0 deletions

View file

@ -289,6 +289,11 @@ uint32_t ts_tree_cursor_end_index_wasm(const TSTree *tree) {
return byte_to_code_unit(ts_node_end_byte(node));
}
uint32_t ts_tree_cursor_current_field_id_wasm(const TSTree *tree) {
TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
return ts_tree_cursor_current_field_id(&cursor);
}
void ts_tree_cursor_current_node_wasm(const TSTree *tree) {
TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
marshal_node(TRANSFER_BUFFER, ts_tree_cursor_current_node(&cursor));

View file

@ -525,6 +525,12 @@ class TreeCursor {
return unmarshalNode(this.tree);
}
currentFieldName() {
marshalTreeCursor(this);
const fieldId = C._ts_tree_cursor_current_field_id_wasm(this.tree[0]);
return this.tree.language.fields[fieldId];
}
gotoFirstChild() {
marshalTreeCursor(this);
const result = C._ts_tree_cursor_goto_first_child_wasm(this.tree[0]);
@ -559,6 +565,15 @@ class Language {
this.types[i] = UTF8ToString(C._ts_language_symbol_name(this[0], i));
}
}
this.fields = new Array(C._ts_language_field_count(this[0]) + 1);
for (let i = 0, n = this.fields.length; i < n; i++) {
const fieldName = C._ts_language_field_name_for_id(this[0], i);
if (fieldName !== 0) {
this.fields[i] = UTF8ToString(fieldName);
} else {
this.fields[i] = null;
}
}
}
get version() {

View file

@ -30,6 +30,8 @@
"abort",
"_ts_init",
"_ts_language_field_count",
"_ts_language_field_name_for_id",
"_ts_language_symbol_count",
"_ts_language_symbol_name",
"_ts_language_symbol_type",
@ -64,6 +66,7 @@
"_ts_parser_new_wasm",
"_ts_parser_parse_wasm",
"_ts_parser_set_language",
"_ts_tree_cursor_current_field_id_wasm",
"_ts_tree_cursor_current_node_id_wasm",
"_ts_tree_cursor_current_node_is_missing_wasm",
"_ts_tree_cursor_current_node_is_named_wasm",

View file

@ -263,6 +263,34 @@ describe("Tree", () => {
assert(!cursor.gotoParent());
});
it('keeps track of the field name associated with each node', () => {
tree = parser.parse('a.b();');
cursor = tree.walk();
cursor.gotoFirstChild();
cursor.gotoFirstChild();
assert.equal(cursor.currentNode().type, 'call_expression');
assert.equal(cursor.currentFieldName(), null);
cursor.gotoFirstChild();
assert.equal(cursor.currentNode().type, 'member_expression');
assert.equal(cursor.currentFieldName(), 'function');
cursor.gotoFirstChild();
assert.equal(cursor.currentNode().type, 'identifier');
assert.equal(cursor.currentFieldName(), 'object');
cursor.gotoNextSibling();
cursor.gotoNextSibling();
assert.equal(cursor.currentNode().type, 'property_identifier');
assert.equal(cursor.currentFieldName(), 'property');
cursor.gotoParent();
cursor.gotoNextSibling();
assert.equal(cursor.currentNode().type, 'arguments');
assert.equal(cursor.currentFieldName(), 'arguments');
});
it('returns a cursor that can be reset anywhere in the tree', () => {
tree = parser.parse('a * b + c / d');
cursor = tree.walk();