fix(extract): restore meson command calls

Use the vendored Meson grammar's normal_command node and command field to extract Meson command callees such as project and executable.

Add exact call-edge canaries for Meson and Just. The rebuilt failed-first extraction run showed Meson missing project/executable calls while the Just canary already passed through the existing generic function_call path.

Validation: git diff --check; bash scripts/check-source-safety.sh; make -j8 -f Makefile.cbm build/c/test-runner; CBM_ONLY_SUITE=extraction ./build/c/test-runner passed 246/246.
Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
This commit is contained in:
Andrew Hundt
2026-07-01 09:30:10 -04:00
parent 9bcaf8a0f5
commit d5d5d3b7f4
3 changed files with 29 additions and 1 deletions
+13
View File
@@ -778,6 +778,15 @@ static char *extract_make_callee(CBMArena *a, TSNode node, const char *source, c
return ts_node_is_null(fn) ? NULL : cbm_node_text(a, fn, source);
}
// Meson normal_command stores its callee in the command field.
static char *extract_meson_callee(CBMArena *a, TSNode node, const char *source, const char *nk) {
if (strcmp(nk, "normal_command") != 0) {
return NULL;
}
TSNode cmd = ts_node_child_by_field_name(node, TS_FIELD("command"));
return ts_node_is_null(cmd) ? NULL : cbm_node_text(a, cmd, source);
}
// Puppet function_call stores its callee as the first named child.
static char *extract_puppet_callee(CBMArena *a, TSNode node, const char *source,
const char *nk) {
@@ -852,6 +861,10 @@ static char *extract_callee_lang_specific(CBMArena *a, TSNode node, const char *
char *c = extract_make_callee(a, node, source, nk);
return c ? c : extract_scripting_callee(a, node, source, lang, nk);
}
if (lang == CBM_LANG_MESON) {
char *c = extract_meson_callee(a, node, source, nk);
return c ? c : extract_scripting_callee(a, node, source, lang, nk);
}
if (lang == CBM_LANG_PUPPET) {
char *c = extract_puppet_callee(a, node, source, nk);
return c ? c : extract_scripting_callee(a, node, source, lang, nk);
+1 -1
View File
@@ -889,7 +889,7 @@ static const char *svelte_branch_types[] = {"if_statement", "each_statement", "a
// ==================== MESON ====================
static const char *meson_func_types[] = {"function_expression", NULL};
static const char *meson_module_types[] = {"source_file", NULL};
static const char *meson_call_types[] = {"function_expression", "command", NULL};
static const char *meson_call_types[] = {"normal_command", "function_expression", NULL};
static const char *meson_branch_types[] = {"if_statement", "foreach_statement", NULL};
static const char *meson_var_types[] = {"assignment_statement", NULL};
+15
View File
@@ -1638,6 +1638,8 @@ TEST(meson_project) {
ASSERT_NOT_NULL(r);
ASSERT_FALSE(r->has_error);
ASSERT_GTE(r->defs.count, 1);
ASSERT(has_call_exact(r, "project"));
ASSERT(has_call_exact(r, "executable"));
cbm_free_result(r);
PASS();
}
@@ -2193,6 +2195,18 @@ TEST(makefile_builtin_call_edges) {
PASS();
}
TEST(just_function_call_edge) {
CBMFileResult *r = extract("NAME := uppercase('hello')\n"
"default:\n"
"\techo {{ NAME }}\n",
CBM_LANG_JUST, "test", "justfile");
ASSERT_NOT_NULL(r);
ASSERT_FALSE(r->has_error);
ASSERT(has_call_exact(r, "uppercase"));
cbm_free_result(r);
PASS();
}
TEST(puppet_function_call_edge) {
CBMFileResult *r = extract("notice('ready')\n", CBM_LANG_PUPPET, "test", "site.pp");
ASSERT_NOT_NULL(r);
@@ -3430,6 +3444,7 @@ SUITE(extraction) {
RUN_TEST(makefile_multiple_targets);
RUN_TEST(makefile_variable_extraction);
RUN_TEST(makefile_builtin_call_edges);
RUN_TEST(just_function_call_edge);
RUN_TEST(puppet_function_call_edge);
RUN_TEST(vimscript_function_extraction);
RUN_TEST(vimscript_function_without_bang);