Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tree-sitter is blocking #3199

Open
juli1 opened this issue Mar 20, 2024 · 1 comment
Open

tree-sitter is blocking #3199

juli1 opened this issue Mar 20, 2024 · 1 comment
Labels
perf Performance related query Related to tree-sitter queries executor

Comments

@juli1
Copy link

juli1 commented Mar 20, 2024

Problem

Tree-sitter is blocking when iterating on the results of a rule for Java. This is happening only with some queries.

Added a fully reproducible example for Java.

Steps to reproduce

git clone https://github.com/juli1/tree-sitter-debug
cd tree-sitter-debug
cargo run

Expected behavior

The program should finish.

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

tree-sitter 0.22.2

Operating system/version

macOS

@juli1 juli1 added the bug label Mar 20, 2024
@WillLillis
Copy link
Contributor

WillLillis commented Mar 22, 2024

Tree-sitter's playground becomes unresponsive after attempting to scroll the source code box (query box is fine, syntax tree stutters a bit but also scrolls up and down) past a certain point with the same code/ query:

ts_java_hang

EDIT: I ran the same query with the same source code overnight using the C API and it finished with a total of 307,383 matches iterated through. So it looks like there isn't a bug, but just a lot of matches?

#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <tree_sitter/api.h>

const TSLanguage *tree_sitter_java(void);

int main() {
    // Create a parser.
    TSParser *parser = ts_parser_new();

    // Set the parser's language (JSON in this case).
    ts_parser_set_language(parser, tree_sitter_java());

    // Build a syntax tree based on source code stored in a string.
    const char *source_code =
                              "\n"
                              "/*\n"
                              " * Graphics2D Tester\n"
                              /** Rest of source code here... **/
                              "            this.single = single;\n"
                              "        }\n"
                              "    }\n"
                              "\n"
                              "}\n"
                              "";
    TSTree *tree =
        ts_parser_parse_string(parser, NULL, source_code, strlen(source_code));

    if (tree == NULL) {
        perror("tree is NULL\n");
    }

    // Get the root node of the syntax tree.
    TSNode root_node = ts_tree_root_node(tree);

    const char *query_source = "(block\n"
                               "    (local_variable_declaration\n"
                               "        type: (type_identifier) @type\n"
                               "        declarator: (variable_declarator\n"
                               "            name: (identifier) @varname\n"
                               "        )\n"
                               "\n"
                               "    ) @decl\n"
                               "    (_)*\n"
                               "    (expression_statement\n"
                               "        (method_invocation\n"
                               "            object: (identifier) @object1\n"
                               "            name: (identifier) @name1\n"
                               "        )\n"
                               "\n"
                               "    )? @defaulttyping\n"
                               "    (_)*\n"
                               "    (expression_statement\n"
                               "        (method_invocation\n"
                               "            object: (identifier) @object2\n"
                               "            name: (identifier) @name2\n"
                               "        )\n"
                               "\n"
                               "    )\n"
                               "    (#eq? @object1 @varname)\n"
                               "    (#eq? @name1 \"enableDefaultTyping\")\n"
                               "    (#eq? @type \"ObjectMapper\")\n"
                               "    (#eq? @object2 @varname)\n"
                               "    (#eq? @name2 \"readValue\")\n"
                               ")";

    uint32_t err_offset;
    TSQueryError err_type;
    TSQuery *query = ts_query_new(tree_sitter_java(), query_source,
                                  strlen(query_source), &err_offset, &err_type);
    if (query == NULL) {
        perror("query is NULL\n");
    }
    if (err_type != 0) {
        perror("query construction error\n");
    }
    TSQueryCursor *cursor = ts_query_cursor_new();
    if (cursor == NULL) {
        perror("cursor is NULL\n");
    }
    ts_query_cursor_exec(cursor, query, root_node);

    TSQueryMatch match;
    uintmax_t count = 0;
    while (ts_query_cursor_next_match(cursor, &match)) {
        // printf("%zu id: %u, pattern_index: %hu, capture_count: %hu\n", count++,
        //        match.id, match.pattern_index, match.capture_count);
        printf("Count: %zu\n", count++);
                
    }

    // Free all of the heap-allocated memory.
    ts_tree_delete(tree);
    ts_parser_delete(parser);
    ts_query_delete(query);
    return 0;
}

@ObserverOfTime ObserverOfTime added perf Performance related query Related to tree-sitter queries executor and removed bug labels Apr 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
perf Performance related query Related to tree-sitter queries executor
Projects
None yet
Development

No branches or pull requests

3 participants