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

Difference between tree-sitter playground and cursor.matches

Bennet-Sunder opened this issue · comments

Problem

I tried the following tree-sitter query in playground and it didn't show that the given code matched.
image

So I put this in my library and it actually found a match surprisingly.

Steps to reproduce

[dependencies]
tree-sitter = "0.20.6"
tree-sitter-ruby = "0.20.1"

use tree_sitter::{Parser, Query, QueryCursor};

fn main() {
    let mut parser = Parser::new();
    let language = tree_sitter_ruby::language();
    parser.set_language(language).unwrap();
    let query = r#"
    (
        (method
        name: (identifier) @method_definition
        body: (body_statement 
          . ((return (argument_list)? @_arglist)) .
        ))
        (#not-match? @_arglist ".")
    )
  "#;
    let query = Query::new(language, query).unwrap();
    let source_code = "
        def try_sample_method(account, expiry_date, additional_args = {})
            just_a_method_call
            return
        end
    ";
    let tree = parser.parse(source_code, None).unwrap();
    let mut binding = QueryCursor::new();
    let query_matches = binding.matches(&query, tree.root_node(), source_code.as_bytes());
    for query_match in query_matches.into_iter() {
        if let Some(captured_node) = query_match.captures.first() {
            println!("captured node {}", captured_node.node.utf8_text(&source_code.as_bytes()).unwrap().to_string());
          } else {
            println!("No captured node");
        }
    }
    println!("Done")

}

This code returns this.

captured node try_sample_method
Done

Expected behavior

Can you help me understand why this shows a match while the playground doesn't.

Although when I updated the tree-sitter-query to this

    (
        (method
        name: (identifier) @method_definition
        body: (body_statement 
          . (return (argument_list)? @_arglist) .
        ))
        (#not-match? @_arglist ".")
    )

This is working as expected that the method doesn't match as return isn't the sibling node.

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

tree-sitter = "0.20.6"

Operating system/version

macOS 14.3.1 (23D60)

A hacky query does not work correctly, what a surprise.
Try the latest tree-sitter version and see if it still works.


P.S. This query works:

(method
  name: (identifier) @method_definition
  body: (body_statement . (return "return" .)))

Testing with tree-sitter 0.22.5 shows no captures, matching the behavior of the playground. I did have to depend on a local clone of tree-sitter-ruby with its tree-sitter dependency bumped to get the program to compile, though.

image

Yeah, I'd say this is the expected behaviour.