From 73e252e39bf85bbedc2e251a830cdedd6ab862cc Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 10 Feb 2021 16:14:24 -0800 Subject: [PATCH] Add unit test for child_by_field_name w/ hidden nodes --- cli/src/tests/node_test.rs | 30 ++++++++++++++++++++++++++++-- lib/src/node.c | 11 +++++++---- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/cli/src/tests/node_test.rs b/cli/src/tests/node_test.rs index 7e652cd5..9a47ce06 100644 --- a/cli/src/tests/node_test.rs +++ b/cli/src/tests/node_test.rs @@ -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] diff --git a/lib/src/node.c b/lib/src/node.c index e5710922..8498f9c5 100644 --- a/lib/src/node.c +++ b/lib/src/node.c @@ -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(); }