mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-03 08:03:38 +08:00
fix(extract): restore HDL call edges
Add a shared Verilog/SystemVerilog leaf-identifier resolver for wrapped subroutine and tf_call nodes, and include SystemVerilog subroutine_call nodes exposed by the vendored grammar. Evidence: AST probes confirmed the wrapper shapes, failed-first canaries produced 252 passed / 2 failed before the fix, and the focused extraction suite now passes 254/254. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
This commit is contained in:
@@ -834,6 +834,33 @@ static char *extract_vhdl_callee(CBMArena *a, TSNode node, const char *source, c
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *extract_first_leaf_identifier(CBMArena *a, TSNode node, const char *source) {
|
||||
TSNode cur = node;
|
||||
enum { CALLEE_LEAF_DESCENT_LIMIT = 8 };
|
||||
for (int depth = 0; depth < CALLEE_LEAF_DESCENT_LIMIT && !ts_node_is_null(cur); depth++) {
|
||||
const char *k = ts_node_type(cur);
|
||||
if (strcmp(k, "simple_identifier") == 0 || strcmp(k, "identifier") == 0 ||
|
||||
strcmp(k, "word") == 0 || strcmp(k, "name") == 0 || strcmp(k, "qid") == 0) {
|
||||
char *t = cbm_node_text(a, cur, source);
|
||||
return (t && t[0]) ? t : NULL;
|
||||
}
|
||||
if (ts_node_named_child_count(cur) == 0) {
|
||||
return NULL;
|
||||
}
|
||||
cur = ts_node_named_child(cur, 0);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// HDL callees are often wrapped by subroutine/tf/hierarchical identifier nodes.
|
||||
static char *extract_hdl_callee(CBMArena *a, TSNode node, const char *source, const char *nk) {
|
||||
if (strcmp(nk, "function_subroutine_call") != 0 && strcmp(nk, "subroutine_call") != 0 &&
|
||||
strcmp(nk, "tf_call") != 0 && strcmp(nk, "system_tf_call") != 0) {
|
||||
return NULL;
|
||||
}
|
||||
return extract_first_leaf_identifier(a, node, source);
|
||||
}
|
||||
|
||||
// Make builtins are represented as function_call nodes; $(shell ...) is shell_function.
|
||||
static char *extract_make_callee(CBMArena *a, TSNode node, const char *source, const char *nk) {
|
||||
if (strcmp(nk, "shell_function") == 0) {
|
||||
@@ -943,6 +970,10 @@ static char *extract_callee_lang_specific(CBMArena *a, TSNode node, const char *
|
||||
char *c = extract_vhdl_callee(a, node, source, nk);
|
||||
return c ? c : extract_scripting_callee(a, node, source, lang, nk);
|
||||
}
|
||||
if (lang == CBM_LANG_VERILOG || lang == CBM_LANG_SYSTEMVERILOG) {
|
||||
char *c = extract_hdl_callee(a, node, source, nk);
|
||||
return c ? c : extract_scripting_callee(a, node, source, lang, nk);
|
||||
}
|
||||
|
||||
if (lang == CBM_LANG_CLOJURE || lang == CBM_LANG_COMMONLISP || lang == CBM_LANG_SCHEME ||
|
||||
lang == CBM_LANG_FENNEL || lang == CBM_LANG_RACKET || lang == CBM_LANG_EMACSLISP) {
|
||||
|
||||
@@ -1384,7 +1384,7 @@ static const char *systemverilog_class_types[] = {"class_declaration",
|
||||
"type_declaration",
|
||||
NULL};
|
||||
static const char *systemverilog_call_types[] = {"function_subroutine_call", "system_tf_call",
|
||||
"method_call", NULL};
|
||||
"subroutine_call", "method_call", NULL};
|
||||
static const char *systemverilog_import_types[] = {
|
||||
"package_import_declaration", "extends", "import", "include",
|
||||
"include_statement", "instance", "use_clause", NULL};
|
||||
|
||||
@@ -1260,6 +1260,40 @@ TEST(vhdl_function_call_edge) {
|
||||
PASS();
|
||||
}
|
||||
|
||||
TEST(verilog_function_call_edge) {
|
||||
CBMFileResult *r = extract("module m;\n"
|
||||
" function integer foo;\n"
|
||||
" input integer x;\n"
|
||||
" begin foo = x; end\n"
|
||||
" endfunction\n"
|
||||
" integer y;\n"
|
||||
" initial begin\n"
|
||||
" y = foo(1);\n"
|
||||
" end\n"
|
||||
"endmodule\n",
|
||||
CBM_LANG_VERILOG, "t", "mod.v");
|
||||
ASSERT_NOT_NULL(r);
|
||||
ASSERT_FALSE(r->has_error);
|
||||
ASSERT(has_call_exact(r, "foo"));
|
||||
cbm_free_result(r);
|
||||
PASS();
|
||||
}
|
||||
|
||||
TEST(systemverilog_subroutine_call_edge) {
|
||||
CBMFileResult *r = extract("module m;\n"
|
||||
" function int foo(); return 1; endfunction\n"
|
||||
" initial begin\n"
|
||||
" foo();\n"
|
||||
" end\n"
|
||||
"endmodule\n",
|
||||
CBM_LANG_SYSTEMVERILOG, "t", "mod.sv");
|
||||
ASSERT_NOT_NULL(r);
|
||||
ASSERT_FALSE(r->has_error);
|
||||
ASSERT(has_call_exact(r, "foo"));
|
||||
cbm_free_result(r);
|
||||
PASS();
|
||||
}
|
||||
|
||||
/* --- Fortran --- */
|
||||
TEST(fortran_function) {
|
||||
/* Fortran subroutine name extraction is incomplete — just verify no crash */
|
||||
@@ -3456,6 +3490,8 @@ SUITE(extraction) {
|
||||
RUN_TEST(nickel_function_application_edge);
|
||||
RUN_TEST(func_function_application_edge);
|
||||
RUN_TEST(vhdl_function_call_edge);
|
||||
RUN_TEST(verilog_function_call_edge);
|
||||
RUN_TEST(systemverilog_subroutine_call_edge);
|
||||
RUN_TEST(fortran_function);
|
||||
|
||||
/* OOP/Systems variants */
|
||||
|
||||
Reference in New Issue
Block a user