Add unit test for child_by_field_name w/ hidden nodes

This commit is contained in:
Max Brunsfeld 2021-02-10 16:14:24 -08:00
parent 038f4fcef8
commit 73e252e39b
2 changed files with 35 additions and 6 deletions

View file

@ -232,12 +232,38 @@ fn test_node_parent_of_child_by_field_name() {
let mut parser = Parser::new();
parser.set_language(get_language("javascript")).unwrap();
let tree = parser.parse("foo(a().b[0].c.d.e())", None).unwrap();
let call_node = tree.root_node().named_child(0).unwrap().named_child(0).unwrap();
let call_node = tree
.root_node()
.named_child(0)
.unwrap()
.named_child(0)
.unwrap();
assert_eq!(call_node.kind(), "call_expression");
// Regression test - when a field points to a hidden node (in this case, `_expression`)
// the hidden node should not be added to the node parent cache.
assert_eq!(call_node.child_by_field_name("function").unwrap().parent(), Some(call_node));
assert_eq!(
call_node.child_by_field_name("function").unwrap().parent(),
Some(call_node)
);
}
#[test]
fn test_node_child_by_field_name_with_extra_hidden_children() {
let mut parser = Parser::new();
parser.set_language(get_language("python")).unwrap();
// In the Python grammar, some fields are applied to `suite` nodes,
// which consist of an invisible `indent` token followed by a block.
// Check that when searching for a child with a field name, we don't
//
let tree = parser.parse("while a:\n pass", None).unwrap();
let while_node = tree.root_node().child(0).unwrap();
assert_eq!(while_node.kind(), "while_statement");
assert_eq!(
while_node.child_by_field_name("body").unwrap(),
while_node.child(3).unwrap(),
);
}
#[test]

View file

@ -561,11 +561,14 @@ recur:
return child;
}
// If the field refers to a hidden node, return its first visible
// child.
// If the field refers to a hidden node with visible children,
// return the first visible child.
else if (ts_node_child_count(child) > 0 ) {
return ts_node_child(child, 0);
}
// Otherwise, continue searching subsequent children.
else {
TSNode result = ts_node_child(child, 0);
if (result.id) return result;
field_map++;
if (field_map == field_map_end) return ts_node__null();
}