diff --git a/tooling2/tool.cpp b/tooling2/tool.cpp index 5e11bcd3..ef7fb16b 100644 --- a/tooling2/tool.cpp +++ b/tooling2/tool.cpp @@ -134,6 +134,44 @@ std::string getFunctionName(TSNode node, const char* source_code) { return ""; } +std::string getCommentBeforeNode(TSNode node, const char* source_code) { + uint32_t start_byte = ts_node_start_byte(node); + + // Look backwards from the start of the node to find comments + if (start_byte == 0) return ""; + + // Get text before the node + std::string before_text(source_code, start_byte); + + // Find the last occurrence of "//" before this node + size_t last_comment = before_text.rfind("//"); + if (last_comment != std::string::npos) { + // Find the start of the line containing this comment + size_t line_start = before_text.rfind('\n', last_comment); + if (line_start == std::string::npos) { + line_start = 0; + } else { + line_start++; // Move past the newline + } + + // Extract the comment line + std::string comment_line = before_text.substr(line_start, start_byte - line_start); + + // Check if this comment line is close to the function (within a few lines) + size_t newlines_between = 0; + for (size_t i = last_comment; i < start_byte; i++) { + if (before_text[i] == '\n') newlines_between++; + } + + // If comment is within 3 lines of the function, consider it related + if (newlines_between <= 3) { + return comment_line; + } + } + + return ""; +} + std::string getCommentAfterNode(TSNode node, const char* source_code, uint32_t source_length) { uint32_t end_byte = ts_node_end_byte(node); @@ -185,6 +223,21 @@ bool isExternDeclaration(TSNode node, const char* source_code) { return false; } +bool hasFunctionBody(TSNode node) { + // Check if this function definition has a compound statement (body) + if (strcmp(ts_node_type(node), "function_definition") == 0) { + 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); + const char* child_type = ts_node_type(child); + if (strcmp(child_type, "compound_statement") == 0) { + return true; + } + } + } + return false; +} + void findFunctions(TSNode node, const char* source_code, uint32_t source_length, std::vector& functions) { const char* type = ts_node_type(node); @@ -198,11 +251,26 @@ void findFunctions(TSNode node, const char* source_code, uint32_t source_length, std::string comment = getCommentAfterNode(node, source_code, source_length); std::string address = extractAddress(comment); + // If no address found after, try looking before (for function definitions) + if (address.empty() && strcmp(type, "function_definition") == 0) { + comment = getCommentBeforeNode(node, source_code); + address = extractAddress(comment); + } + if (!address.empty()) { FunctionInfo func; func.name = func_name; func.address = address; - func.is_import = (strcmp(type, "declaration") == 0) || isExternDeclaration(node, source_code); + + // Determine if it's an import based on whether it has a body + // Function definitions with bodies are actual functions + // Declarations without bodies are imports + if (strcmp(type, "function_definition") == 0) { + func.is_import = !hasFunctionBody(node); + } else { + func.is_import = true; // Pure declarations are always imports + } + functions.push_back(func); } }