tree-sitter / tree-sitter

An incremental parsing system for programming tools

Home Page:https://tree-sitter.github.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`ts_node_field_name_for_child()` can incorrectly assign field names to `extras`

DavisVaughan opened this issue · comments

Problem

In the following C example, the comment is recognized as having an operator field name for some reason. It isn't specific to the C grammar, so I think it is a tree-sitter core bug.

int w = x +
  // something important about y!
  y;

Here's a full test for this, adapted from one of your own, which I've also pushed here (DavisVaughan@449b5ee). It should not be passing, but is!

#[test]
fn test_node_field_name_for_child() {
    let mut parser = Parser::new();
    parser.set_language(&get_language("c")).unwrap();
    let text = "
        int w = x +
            // something important about y!
            y;";
    let tree = parser.parse(text, None).unwrap();
    let translation_unit_node = tree.root_node();
    let declaration_node = translation_unit_node.named_child(0).unwrap();

    let binary_expression_node = declaration_node
        .child_by_field_name("declarator")
        .unwrap()
        .child_by_field_name("value")
        .unwrap();

    assert_eq!(binary_expression_node.field_name_for_child(0), Some("left"));
    assert_eq!(
        binary_expression_node.field_name_for_child(1),
        Some("operator")
    );
    // WAT? This should not be an `operator`! It's a comment!
    assert_eq!(
        binary_expression_node.field_name_for_child(2),
        Some("operator")
    );
    assert_eq!(
        binary_expression_node.child(2).unwrap().kind(),
        "comment".to_string()
    );
    assert_eq!(
        binary_expression_node.field_name_for_child(3),
        Some("right")
    );
    // Negative test - Not a valid child index
    assert_eq!(binary_expression_node.field_name_for_child(4), None);
}

Steps to reproduce

Copy in that test from above and run the cli tests

Expected behavior

The comment should have a None field name

Tree-sitter version (tree-sitter --version)

tree-sitter 0.22.5

Operating system/version

macOS 13.6.5

Nice investigation, seems like there's no logic to handle nodes that are extras in ts_node_field_name_for_child, while there is in the node iterator, hence the mismatch