Skip to content

Commit b46c6d4

Browse files
fix(registry): widen CALLS families for CUDA, ObjC, HTML (#1702)
Add CUDA and Objective-C to c_cpp_family, HTML to js_ts_family, and skip suppression when the target extension is content-disambiguated (.m, .cls, .inc, .cfc, .frm). Move pipeline #1572 integration test to the external-specifier follow-up branch. Signed-off-by: rudi193-cmd <rudi193@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 7e6750d commit b46c6d4

3 files changed

Lines changed: 34 additions & 80 deletions

File tree

‎src/pipeline/registry.c‎

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -698,14 +698,16 @@ bool cbm_suppress_weak_local_binding_call(bool enabled, bool callee_is_locally_b
698698
static bool js_ts_family(CBMLanguage lang) {
699699
return lang == CBM_LANG_JAVASCRIPT || lang == CBM_LANG_TYPESCRIPT || lang == CBM_LANG_TSX ||
700700
lang == CBM_LANG_ARKTS || lang == CBM_LANG_VUE || lang == CBM_LANG_SVELTE ||
701-
lang == CBM_LANG_ASTRO;
701+
lang == CBM_LANG_ASTRO || lang == CBM_LANG_HTML;
702702
}
703703

704704
/* C and C++ are one family for cross-language checks: .h maps to CBM_LANG_CPP
705705
* in the extension table, so a .c file referencing a symbol declared in its
706-
* own header would otherwise read as a language boundary. */
706+
* own header would otherwise read as a language boundary. CUDA and Objective-C
707+
* use the same front end for header calls (#1702 census addendum). */
707708
static bool c_cpp_family(CBMLanguage lang) {
708-
return lang == CBM_LANG_C || lang == CBM_LANG_CPP;
709+
return lang == CBM_LANG_C || lang == CBM_LANG_CPP || lang == CBM_LANG_CUDA ||
710+
lang == CBM_LANG_OBJC;
709711
}
710712

711713
static bool jvm_family(CBMLanguage lang) {
@@ -726,6 +728,19 @@ static const char *path_basename(const char *path) {
726728
return slash ? slash + 1 : path;
727729
}
728730

731+
/* Target language from basename alone is wrong for extensions whose real
732+
* language is decided by file content during discovery (.m → MATLAB in the
733+
* table but often Objective-C, etc.). Never suppress on filename guess alone. */
734+
static bool target_lang_from_filename_ambiguous(const char *target_file_path) {
735+
const char *base = path_basename(target_file_path);
736+
const char *dot = strrchr(base, '.');
737+
if (!dot || dot == base) {
738+
return false;
739+
}
740+
return strcmp(dot, ".m") == 0 || strcmp(dot, ".cls") == 0 || strcmp(dot, ".inc") == 0 ||
741+
strcmp(dot, ".cfc") == 0 || strcmp(dot, ".frm") == 0;
742+
}
743+
729744
bool cbm_suppress_cross_language_suffix_match(CBMLanguage caller_lang, const char *target_file_path,
730745
const char *strategy) {
731746
/* Two same-named symbols in different languages: suffix_match picks one
@@ -749,6 +764,9 @@ bool cbm_suppress_cross_language_suffix_match(CBMLanguage caller_lang, const cha
749764
if (caller_lang == target_lang) {
750765
return false;
751766
}
767+
if (target_lang_from_filename_ambiguous(target_file_path)) {
768+
return false;
769+
}
752770
if (js_ts_family(caller_lang) && js_ts_family(target_lang)) {
753771
return false;
754772
}
@@ -783,6 +801,9 @@ bool cbm_suppress_cross_language_ref(CBMLanguage caller_lang, const char *target
783801
if (caller_lang == target_lang) {
784802
return false;
785803
}
804+
if (target_lang_from_filename_ambiguous(target_file_path)) {
805+
return false;
806+
}
786807
if (js_ts_family(caller_lang) && js_ts_family(target_lang)) {
787808
return false;
788809
}

‎tests/test_pipeline.c‎

Lines changed: 0 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -8183,82 +8183,6 @@ TEST(pipeline_cross_language_same_name_does_not_share_calls_issue725) {
81838183
PASS();
81848184
}
81858185

8186-
/* #1572: unique_name (candidates==1) must not bind a Python mock.patch
8187-
* call to the only project symbol named `patch` when that symbol is TSX.
8188-
* The issue fixture is two files: frontend/Panel.tsx and backend/test_thing.py. */
8189-
TEST(pipeline_cross_language_unique_name_does_not_share_calls_issue1572) {
8190-
const char *files[] = {"frontend/Panel.tsx", "backend/test_thing.py"};
8191-
const char *contents[] = {
8192-
"function patch(x: string) {\n"
8193-
" return x;\n"
8194-
"}\n",
8195-
8196-
"from unittest.mock import patch\n"
8197-
"\n"
8198-
"def test_one():\n"
8199-
" with patch(\"os.path.exists\"):\n"
8200-
" pass\n"
8201-
"\n"
8202-
"def test_two():\n"
8203-
" with patch(\"os.path.join\"):\n"
8204-
" pass\n"};
8205-
8206-
if (setup_lang_repo(files, contents, 2) != 0)
8207-
FAIL("tmpdir");
8208-
char db[512];
8209-
snprintf(db, sizeof(db), "%s/test.db", g_lang_tmpdir);
8210-
8211-
cbm_pipeline_t *p = cbm_pipeline_new(g_lang_tmpdir, db, CBM_MODE_FULL);
8212-
ASSERT_NOT_NULL(p);
8213-
ASSERT_EQ(cbm_pipeline_run(p), 0);
8214-
8215-
cbm_store_t *s = cbm_store_open_path(db);
8216-
ASSERT_NOT_NULL(s);
8217-
const char *proj = cbm_pipeline_project_name(p);
8218-
8219-
cbm_node_t *patches = NULL;
8220-
int npatch = 0;
8221-
cbm_store_find_nodes_by_name(s, proj, "patch", &patches, &npatch);
8222-
ASSERT_GT(npatch, 0);
8223-
8224-
int64_t tsx_id = 0;
8225-
for (int i = 0; i < npatch; i++) {
8226-
if (patches[i].file_path && strstr(patches[i].file_path, "Panel.tsx"))
8227-
tsx_id = patches[i].id;
8228-
}
8229-
ASSERT_TRUE(tsx_id != 0);
8230-
8231-
cbm_edge_t *into_tsx = NULL;
8232-
int ntsx = 0;
8233-
cbm_store_find_edges_by_target_type(s, tsx_id, "CALLS", &into_tsx, &ntsx);
8234-
ASSERT_EQ(ntsx, 0);
8235-
8236-
const char *callers[] = {"test_one", "test_two"};
8237-
for (int c = 0; c < 2; c++) {
8238-
cbm_node_t *fns = NULL;
8239-
int nfn = 0;
8240-
cbm_store_find_nodes_by_name(s, proj, callers[c], &fns, &nfn);
8241-
ASSERT_GT(nfn, 0);
8242-
cbm_edge_t *from_fn = NULL;
8243-
int nfrom = 0;
8244-
cbm_store_find_edges_by_source_type(s, fns[0].id, "CALLS", &from_fn, &nfrom);
8245-
for (int i = 0; i < nfrom; i++) {
8246-
ASSERT_TRUE(from_fn[i].target_id != tsx_id);
8247-
}
8248-
if (from_fn)
8249-
cbm_store_free_edges(from_fn, nfrom);
8250-
cbm_store_free_nodes(fns, nfn);
8251-
}
8252-
8253-
if (into_tsx)
8254-
cbm_store_free_edges(into_tsx, ntsx);
8255-
cbm_store_free_nodes(patches, npatch);
8256-
cbm_store_close(s);
8257-
cbm_pipeline_free(p);
8258-
teardown_lang_repo();
8259-
PASS();
8260-
}
8261-
82628186
TEST(pipeline_go_type_classification) {
82638187
/* Port of TestGoTypeClassification */
82648188
const char *files[] = {"types.go"};
@@ -15267,7 +15191,6 @@ SUITE(pipeline) {
1526715191
RUN_TEST(pipeline_swift_cross_package_import);
1526815192
RUN_TEST(pipeline_python_cross_module_call);
1526915193
RUN_TEST(pipeline_cross_language_same_name_does_not_share_calls_issue725);
15270-
RUN_TEST(pipeline_cross_language_unique_name_does_not_share_calls_issue1572);
1527115194
RUN_TEST(pipeline_go_type_classification);
1527215195
RUN_TEST(pipeline_go_grouped_types);
1527315196
RUN_TEST(pipeline_kotlin_project);

‎tests/test_registry.c‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,16 @@ TEST(cross_language_unique_name_drops_py_vs_tsx) {
10151015
"unique_name"));
10161016
ASSERT_FALSE(cbm_suppress_cross_language_suffix_match(CBM_LANG_VUE, "services/Queue.ts",
10171017
"unique_name"));
1018+
/* #1702 addendum: CUDA / ObjC / HTML inline script stay in-family. */
1019+
ASSERT_FALSE(
1020+
cbm_suppress_cross_language_suffix_match(CBM_LANG_CUDA, "kernels/vec.h", "unique_name"));
1021+
ASSERT_FALSE(
1022+
cbm_suppress_cross_language_suffix_match(CBM_LANG_OBJC, "include/Foo.h", "unique_name"));
1023+
ASSERT_FALSE(
1024+
cbm_suppress_cross_language_suffix_match(CBM_LANG_HTML, "static/app.js", "unique_name"));
1025+
/* .m targets are MATLAB by extension table but often ObjC — do not suppress. */
1026+
ASSERT_FALSE(
1027+
cbm_suppress_cross_language_suffix_match(CBM_LANG_OBJC, "models/Foo.m", "unique_name"));
10181028
PASS();
10191029
}
10201030

0 commit comments

Comments
 (0)