From 376c86051a6cf871ebaf77519fe529b185bfaa54 Mon Sep 17 00:00:00 2001 From: Guus Waals <_@guusw.nl> Date: Mon, 26 May 2025 23:21:16 +0800 Subject: [PATCH] WIP Tooling --- tooling2/.gitignore | 2 + tooling2/CMakeLists.txt | 10 +++ tooling2/cmake-variants.yaml | 27 ++++++ tooling2/third_party/tree-sitter | 2 +- tooling2/third_party/tree-sitter-cpp | 2 +- tooling2/tool.cpp | 129 +++++++++++++++++++++++++++ 6 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 tooling2/.gitignore create mode 100644 tooling2/CMakeLists.txt create mode 100644 tooling2/cmake-variants.yaml create mode 100644 tooling2/tool.cpp diff --git a/tooling2/.gitignore b/tooling2/.gitignore new file mode 100644 index 00000000..df4b93b4 --- /dev/null +++ b/tooling2/.gitignore @@ -0,0 +1,2 @@ +build/ +.claude/ \ No newline at end of file diff --git a/tooling2/CMakeLists.txt b/tooling2/CMakeLists.txt new file mode 100644 index 00000000..e44a2561 --- /dev/null +++ b/tooling2/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 4.0) +project(ShardsSandbox) + +set(BUILD_SHARED_LIBS OFF) +add_subdirectory(../third_party/spdlog deps/spdlog) +add_subdirectory(third_party/tree-sitter/lib deps/tree-sitter) +add_subdirectory(third_party/tree-sitter-cpp deps/tree-sitter-cpp) + +add_executable(r3_gh_tool tool.cpp) +target_link_libraries(r3_gh_tool PRIVATE spdlog::spdlog tree-sitter tree-sitter-cpp) diff --git a/tooling2/cmake-variants.yaml b/tooling2/cmake-variants.yaml new file mode 100644 index 00000000..ac65431a --- /dev/null +++ b/tooling2/cmake-variants.yaml @@ -0,0 +1,27 @@ +buildType: + default: debug + choices: + debug: + short: Debug + long: Emit debug information + buildType: Debug + debug-tracy: + short: Debug +tracy + long: Debug with tracy enabled + buildType: Debug + settings: + TRACY_ENABLE: ON + release-deb-info: + short: Release +debug + long: Release with debug information + buildType: RelWithDebInfo + release: + short: Release + long: Release, no debug info + buildType: Release + release-tracy: + short: Release +tracy +debug + long: Release with tracy enabled and debug information + buildType: RelWithDebInfo + settings: + TRACY_ENABLE: ON diff --git a/tooling2/third_party/tree-sitter b/tooling2/third_party/tree-sitter index 06537fda..99805657 160000 --- a/tooling2/third_party/tree-sitter +++ b/tooling2/third_party/tree-sitter @@ -1 +1 @@ -Subproject commit 06537fda832d02afed750a4b574fa5aa656ef6ed +Subproject commit 998056577bb7d3ade32231f1eca2016211f379f3 diff --git a/tooling2/third_party/tree-sitter-cpp b/tooling2/third_party/tree-sitter-cpp index 56455f42..28c8cf1d 160000 --- a/tooling2/third_party/tree-sitter-cpp +++ b/tooling2/third_party/tree-sitter-cpp @@ -1 +1 @@ -Subproject commit 56455f4245baf4ea4e0881c5169de69d7edd5ae7 +Subproject commit 28c8cf1d6150e3e6a7f07cad55d3e2e6bc326911 diff --git a/tooling2/tool.cpp b/tooling2/tool.cpp new file mode 100644 index 00000000..254fc4ed --- /dev/null +++ b/tooling2/tool.cpp @@ -0,0 +1,129 @@ +#include +#include +#include +#include +#include +#include +#include +#include "tree_sitter/api.h" +extern "C" TSLanguage *tree_sitter_cpp(); + +struct VariableReference { + std::string name; + uint32_t start_byte; + uint32_t end_byte; + uint32_t start_row; + uint32_t start_col; + uint32_t end_row; + uint32_t end_col; +}; + +bool is_function_context(TSNode node) { + const char* type = ts_node_type(node); + return (strcmp(type, "function_definition") == 0 || + strcmp(type, "constructor_definition") == 0 || + strcmp(type, "destructor_definition") == 0 || + strcmp(type, "lambda_expression") == 0 || + strcmp(type, "function_declarator") == 0); +} + +bool is_initializer_context(TSNode node) { + const char* type = ts_node_type(node); + return (strcmp(type, "initializer_list") == 0 || + strcmp(type, "constructor_definition") == 0 || + strcmp(type, "assignment_expression") == 0 || + strcmp(type, "init_declarator") == 0); +} + +bool is_variable_reference(TSNode node) { + const char* type = ts_node_type(node); + return (strcmp(type, "identifier") == 0); +} + +bool is_in_function_or_initializer(TSNode node) { + TSNode current = ts_node_parent(node); + while (!ts_node_is_null(current)) { + if (is_function_context(current) || is_initializer_context(current)) { + return true; + } + current = ts_node_parent(current); + } + return false; +} + +void find_variable_references(TSNode node, const char* source_code, std::vector& references) { + if (is_variable_reference(node) && is_in_function_or_initializer(node)) { + uint32_t start_byte = ts_node_start_byte(node); + uint32_t end_byte = ts_node_end_byte(node); + + TSPoint start_point = ts_node_start_point(node); + TSPoint end_point = ts_node_end_point(node); + + std::string name(source_code + start_byte, end_byte - start_byte); + + VariableReference ref; + ref.name = name; + ref.start_byte = start_byte; + ref.end_byte = end_byte; + ref.start_row = start_point.row; + ref.start_col = start_point.column; + ref.end_row = end_point.row; + ref.end_col = end_point.column; + + references.push_back(ref); + } + + uint32_t child_count = ts_node_child_count(node); + for (uint32_t i = 0; i < child_count; i++) { + TSNode child = ts_node_child(node, i); + find_variable_references(child, source_code, references); + } +} + +int main(int argc, char* argv[]) { + if (argc != 2) { + std::cerr << "Usage: " << argv[0] << " " << std::endl; + return 1; + } + + std::ifstream file(argv[1]); + if (!file.is_open()) { + std::cerr << "Error: Could not open file " << argv[1] << std::endl; + return 1; + } + + std::stringstream buffer; + buffer << file.rdbuf(); + std::string file_content = buffer.str(); + const char *source_code = file_content.c_str(); + + TSParser *parser = ts_parser_new(); + ts_parser_set_language(parser, tree_sitter_cpp()); + + TSTree *tree = ts_parser_parse_string(parser, nullptr, source_code, file_content.length()); + TSNode root_node = ts_tree_root_node(tree); + + if (ts_node_is_null(root_node)) { + std::cerr << "Error: Failed to parse file" << std::endl; + return 1; + } + + std::vector references; + find_variable_references(root_node, source_code, references); + + std::cout << "Variable references found in functions/initializers:" << std::endl; + std::cout << "Format: name [start_byte:end_byte] (row:col)-(row:col)" << std::endl; + std::cout << "========================================" << std::endl; + + for (const auto& ref : references) { + std::cout << ref.name + << " [" << ref.start_byte << ":" << ref.end_byte << "] " + << "(" << ref.start_row << ":" << ref.start_col << ")-" + << "(" << ref.end_row << ":" << ref.end_col << ")" << std::endl; + } + + ts_tree_delete(tree); + ts_parser_delete(parser); + + return 0; +}