reman3/tooling/cmd_dump.cpp

89 lines
2.6 KiB
C++

#include "tool.hpp"
#include <CLI11.hpp>
#include <tree_sitter/api.h>
// Forward declarations
extern "C" TSLanguage *tree_sitter_cpp();
static std::string filepath;
// Helper function to dump Tree-sitter AST
void dumpTreeSitterAST(TSNode node, const char *source_code, int depth) {
std::string indent(depth * 2, ' ');
const char *type = ts_node_type(node);
uint32_t start = ts_node_start_byte(node);
uint32_t end = ts_node_end_byte(node);
// Get the text content for leaf nodes or small nodes
std::string content;
if (end - start < 100) { // Only show content for small nodes
content = extractNodeText(node, source_code);
// Replace newlines with \n for better readability
std::regex newline_regex("\n");
content = std::regex_replace(content, newline_regex, "\\n");
// Truncate if still too long
if (content.length() > 50) {
content = content.substr(0, 47) + "...";
}
}
if (!content.empty()) {
spdlog::info("{}{}[{}:{}] \"{}\"", indent, type, start, end, content);
} else {
spdlog::info("{}{}[{}:{}]", indent, type, start, end);
}
// Recursively dump children
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);
dumpTreeSitterAST(child, source_code, depth + 1);
}
}
bool dumpTreeFile(const std::string &filepath) {
std::ifstream file(filepath);
if (!file.is_open()) {
spdlog::error("Could not open file {}", filepath);
return false;
}
std::string file_content((std::istreambuf_iterator<char>(file)),
std::istreambuf_iterator<char>());
TSParser *parser = ts_parser_new();
ts_parser_set_language(parser, tree_sitter_cpp());
TSTree *tree = ts_parser_parse_string(parser, nullptr, file_content.c_str(),
file_content.length());
TSNode root_node = ts_tree_root_node(tree);
if (ts_node_is_null(root_node)) {
spdlog::error("Failed to parse file {}", filepath);
ts_tree_delete(tree);
ts_parser_delete(parser);
return false;
}
spdlog::info("=== Tree-sitter AST for {} ===", filepath);
dumpTreeSitterAST(root_node, file_content.c_str());
spdlog::info("=== End of AST dump ===");
ts_tree_delete(tree);
ts_parser_delete(parser);
return true;
}
void register_cmd_dump(CLI::App &app) {
auto cmd =
app.add_subcommand("dump-tree", "Dump the tree-sitter AST for a file");
cmd->add_option("-f,--filepath", filepath,
"File to dump the tree-sitter AST for")
->required();
cmd->final_callback([]() {
spdlog::info("=== Processing: {} ===", filepath);
dumpTreeFile(filepath);
});
}