3#include <unordered_map>
12bool TreeSitterParser::is_function_empty(TSNode body) {
13 if (ts_node_is_null(body))
return true;
15 uint32_t n = ts_node_named_child_count(body);
20std::string TreeSitterParser::detect_language(
const std::string& path) {
23 std::string ext = fs::path(path).extension().string();
25 auto it = ext_map.find(ext);
26 if (it != ext_map.end()) {
33std::string TreeSitterParser::get_full_signature(TSNode func_node,
const std::string& source) {
34 uint32_t signature_start = ts_node_start_byte(func_node);
36 TSNode body = get_body(func_node);
38 uint32_t signature_end = ts_node_start_byte(body);
40 return source.substr(signature_start, signature_end - signature_start);
43static const char* field_names[] = {
48 for (
const auto& field_name : field_names) {
49 TSNode name = ts_node_child_by_field_name(node, field_name, strlen(field_name));
50 if (!ts_node_is_null(name)) {
51 std::string_view type = ts_node_type(name);
52 if (type ==
"identifier") {
56 if (type ==
"qualified_identifier") {
57 TSNode qualified_identifier_name = ts_node_child_by_field_name(name,
"name", strlen(
"name"));
58 if (!ts_node_is_null(qualified_identifier_name)) {
60 ts_node_start_byte(qualified_identifier_name),
61 ts_node_end_byte(qualified_identifier_name) - ts_node_start_byte(qualified_identifier_name)
68 uint32_t count = ts_node_child_count(node);
69 for (uint32_t i = 0; i < count; i++) {
70 TSNode child = ts_node_child(node, i);
72 if (!result.empty())
return result;
78std::string TreeSitterParser::get_function_name(TSNode func_node,
const std::string& source) {
82TSNode TreeSitterParser::get_body(TSNode node) {
83 TSNode body = ts_node_child_by_field_name(node,
"body", strlen(
"body"));
85 if (!ts_node_is_null(body))
88 uint32_t count = ts_node_child_count(node);
90 for (uint32_t i = 0; i < count; i++) {
91 TSNode child = ts_node_child(node, i);
92 std::string_view type = ts_node_type(child);
101void TreeSitterParser::collect_functions(
103 const std::string& source,
104 const fs::path& relative_path,
105 const std::shared_ptr<TSTree>& tree,
108 std::string_view type = ts_node_type(node);
110 TSPoint start = ts_node_start_point(node);
111 TSPoint end = ts_node_end_point(node);
113 TSNode body = get_body(node);
115 if (is_function_empty(body))
return;
117 std::string function_name = get_function_name(node, source);
118 if (function_name.empty())
return;
120 TSPoint body_start = ts_node_start_point(body);
121 uint32_t start_byte = ts_node_start_byte(node);
122 uint32_t end_byte = ts_node_end_byte(node);
124 std::string signature = get_full_signature(node, source);
125 std::string code = source.substr(start_byte + signature.size(), end_byte - (start_byte + signature.size()));
128 function.
path = relative_path.string();
131 auto source = std::make_shared<SourceFeature>();
135 auto ast = std::make_shared<ASTFeature>();
140 auto metadata = std::make_shared<MetadataFeature>();
141 metadata->signature = signature;
142 metadata->line_declaration = start.row;
143 metadata->start_number_line = body_start.row;
144 metadata->end_number_line = end.row;
150 uint32_t count = ts_node_child_count(node);
151 for (uint32_t i = 0; i < count; i++) {
153 ts_node_child(node, i),
163 const fs::path& file_path,
164 const fs::path& relative_path,
165 const std::string& source_code,
168 auto lang_name = detect_language(file_path);
170 if (lang_name.empty())
return;
173 auto it = language_map.find(lang_name);
174 if (it == language_map.end()) {
175 std::cerr <<
"Language not found: " << lang_name <<
"\n";
178 TSLanguage* language = it->second();
180 static TSLanguage* current_language =
nullptr;
181 static std::unique_ptr<TSParser,
decltype(&ts_parser_delete)> parser(
185 if (current_language != language) {
186 if (!ts_parser_set_language(parser.get(), language)) {
189 current_language = language;
192 std::shared_ptr<TSTree> tree(
193 ts_parser_parse_string(
201 TSNode root_node = ts_tree_root_node(tree.get());
203 collect_functions(root_node, source_code, relative_path, tree, callback);
std::string function_name
Name of the function.
void add_feature(std::shared_ptr< T > feature)
static void process_file(const fs::path &file_path, const fs::path &relative_path, const std::string &source_code, std::function< void(const FunctionData &)> callback)
std::unordered_map< std::string, std::string > get_extension_map()
std::string extract_name_generic(TSNode node, const std::string &source)
std::unordered_map< std::string, TSLanguage *(*)()> get_language_map()
Defines utility functions used across all files.