#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; }