mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-15 13:56:34 +08:00
fix(pipeline): exclude project identity from service patterns
Signed-off-by: DavidHLP <lysf15520112973@163.com>
This commit is contained in:
@@ -1170,6 +1170,17 @@ cbm_svc_kind_t cbm_service_pattern_match(const char *resolved_qn) {
|
||||
return result;
|
||||
}
|
||||
|
||||
cbm_svc_kind_t cbm_service_pattern_match_in_project(const char *resolved_qn, const char *name,
|
||||
const char *project_name) {
|
||||
if (resolved_qn && project_name && project_name[0]) {
|
||||
size_t len = strlen(project_name);
|
||||
if (strncmp(resolved_qn, project_name, len) == 0 && resolved_qn[len] == '.') {
|
||||
resolved_qn += len + 1;
|
||||
}
|
||||
}
|
||||
return cbm_service_pattern_match_named(resolved_qn, name);
|
||||
}
|
||||
|
||||
cbm_svc_kind_t cbm_service_pattern_match_named(const char *resolved_qn, const char *name) {
|
||||
if (!resolved_qn || !name) {
|
||||
return cbm_service_pattern_match(resolved_qn);
|
||||
|
||||
@@ -35,6 +35,9 @@ void cbm_service_patterns_init(void);
|
||||
* "project.venv.requests.api.get"). Import-alias transparent. */
|
||||
cbm_svc_kind_t cbm_service_pattern_match(const char *resolved_qn);
|
||||
cbm_svc_kind_t cbm_service_pattern_match_named(const char *resolved_qn, const char *name);
|
||||
/* For graph-qualified symbols: project identity is not library evidence. */
|
||||
cbm_svc_kind_t cbm_service_pattern_match_in_project(const char *resolved_qn, const char *name,
|
||||
const char *project_name);
|
||||
|
||||
/* True for a bare, unqualified call to the native `fetch()` API. Deliberately
|
||||
* NOT part of the substring tables above: those are matched unconditionally
|
||||
|
||||
@@ -852,8 +852,11 @@ static bool emit_classified_edge(cbm_pipeline_ctx_t *ctx, const CBMCall *call,
|
||||
const char **imp_keys, const char **imp_vals, int imp_count,
|
||||
bool suppress_plain_calls, const char *route_mount,
|
||||
CBMLanguage lang) {
|
||||
cbm_svc_kind_t svc =
|
||||
cbm_service_pattern_match_named(res->qualified_name, target ? target->name : NULL);
|
||||
cbm_svc_kind_t svc = cbm_service_pattern_match_in_project(
|
||||
res->qualified_name, target ? target->name : NULL,
|
||||
target && res->qualified_name && strcmp(target->qualified_name, res->qualified_name) == 0
|
||||
? ctx->project_name
|
||||
: NULL);
|
||||
if (svc == CBM_SVC_ROUTE_REG && route_reg_path(call, lang) != NULL) {
|
||||
return handle_route_registration(ctx, call, source, module_qn, imp_keys, imp_vals,
|
||||
imp_count, route_mount, lang);
|
||||
@@ -1387,12 +1390,15 @@ static int resolve_single_call(cbm_pipeline_ctx_t *ctx, CBMCall *call, const CBM
|
||||
* the missing target must NOT drop the call — otherwise no HTTP_CALLS edge
|
||||
* is written and cross-repo matching finds nothing (#523). Emit directly
|
||||
* when the call carries a URL/topic first argument. */
|
||||
if (calls_emit_service_call(ctx, call, source_node,
|
||||
cbm_service_pattern_match(res.qualified_name), &res, evidence)) {
|
||||
const cbm_gbuf_node_t *target_node = cbm_gbuf_find_by_qn(ctx->gbuf, res.qualified_name);
|
||||
if (calls_emit_service_call(
|
||||
ctx, call, source_node,
|
||||
cbm_service_pattern_match_in_project(res.qualified_name, NULL,
|
||||
target_node ? ctx->project_name : NULL),
|
||||
&res, evidence)) {
|
||||
return SKIP_ONE;
|
||||
}
|
||||
|
||||
const cbm_gbuf_node_t *target_node = cbm_gbuf_find_by_qn(ctx->gbuf, res.qualified_name);
|
||||
if (!target_node || source_node->id == target_node->id) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2866,12 +2866,15 @@ static void emit_trpc_edge(cbm_gbuf_t *gbuf, const cbm_gbuf_node_t *source, cons
|
||||
static bool emit_service_edge(cbm_gbuf_t *gbuf, const cbm_gbuf_node_t *source,
|
||||
const cbm_gbuf_node_t *target, const CBMCall *call,
|
||||
const cbm_resolution_t *res, const char *module_qn,
|
||||
const cbm_registry_t *registry, const cbm_gbuf_t *main_gbuf,
|
||||
const char **imp_keys, const char **imp_vals, int imp_count,
|
||||
bool suppress_plain_calls, const char *route_mount,
|
||||
CBMLanguage lang) {
|
||||
cbm_svc_kind_t svc =
|
||||
cbm_service_pattern_match_named(res->qualified_name, target ? target->name : NULL);
|
||||
const char *project_name, const cbm_registry_t *registry,
|
||||
const cbm_gbuf_t *main_gbuf, const char **imp_keys,
|
||||
const char **imp_vals, int imp_count, bool suppress_plain_calls,
|
||||
const char *route_mount, CBMLanguage lang) {
|
||||
cbm_svc_kind_t svc = cbm_service_pattern_match_in_project(
|
||||
res->qualified_name, target ? target->name : NULL,
|
||||
target && res->qualified_name && strcmp(target->qualified_name, res->qualified_name) == 0
|
||||
? project_name
|
||||
: NULL);
|
||||
const char *arg = call->first_string_arg;
|
||||
|
||||
/* Also detect route registration by callee name suffix alone (handles unresolved
|
||||
@@ -3620,8 +3623,8 @@ static void resolve_file_calls(resolve_ctx_t *rc, resolve_worker_state_t *ws, CB
|
||||
.strategy = "service_pattern"};
|
||||
site_evidence->calls_emitted |=
|
||||
emit_service_edge(ws->local_edge_buf, source_node, source_node, call, &svc_res,
|
||||
module_qn, rc->registry, rc->main_gbuf, imp_keys, imp_vals,
|
||||
imp_count, false, route_mount, lang);
|
||||
module_qn, rc->project_name, rc->registry, rc->main_gbuf,
|
||||
imp_keys, imp_vals, imp_count, false, route_mount, lang);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -3643,8 +3646,8 @@ static void resolve_file_calls(resolve_ctx_t *rc, resolve_worker_state_t *ws, CB
|
||||
site_evidence->candidate_qn = count == SKIP_ONE ? target->qualified_name : NULL;
|
||||
site_evidence->calls_emitted |=
|
||||
emit_service_edge(ws->local_edge_buf, source_node, target, call, &selected,
|
||||
module_qn, rc->registry, rc->main_gbuf, imp_keys,
|
||||
imp_vals, imp_count, false, route_mount, lang);
|
||||
module_qn, rc->project_name, rc->registry, rc->main_gbuf,
|
||||
imp_keys, imp_vals, imp_count, false, route_mount, lang);
|
||||
ws->calls_resolved++;
|
||||
}
|
||||
continue;
|
||||
@@ -3680,8 +3683,8 @@ static void resolve_file_calls(resolve_ctx_t *rc, resolve_worker_state_t *ws, CB
|
||||
* route/HTTP/service classification is unchanged. */
|
||||
site_evidence->calls_emitted |=
|
||||
emit_service_edge(ws->local_edge_buf, source_node, source_node, call, &fake_res,
|
||||
module_qn, rc->registry, rc->main_gbuf, imp_keys, imp_vals,
|
||||
imp_count, true, route_mount, lang);
|
||||
module_qn, rc->project_name, rc->registry, rc->main_gbuf,
|
||||
imp_keys, imp_vals, imp_count, true, route_mount, lang);
|
||||
} else if (cbm_service_pattern_is_global_fetch(call->callee_name)) {
|
||||
/* Native `fetch()` (#856): only the global API once resolution
|
||||
* has failed to find a local/imported `fetch`. Call the low-level
|
||||
@@ -3790,9 +3793,10 @@ static void resolve_file_calls(resolve_ctx_t *rc, resolve_worker_state_t *ws, CB
|
||||
(u[0] == '/' || strstr(u, "://") != NULL ||
|
||||
(psvc == CBM_SVC_ASYNC && strlen(u) > PP_ESC_SPACE));
|
||||
if (url_or_topic) {
|
||||
site_evidence->calls_emitted |= emit_service_edge(
|
||||
ws->local_edge_buf, source_node, NULL, call, &res, module_qn, rc->registry,
|
||||
rc->main_gbuf, imp_keys, imp_vals, imp_count, false, route_mount, lang);
|
||||
site_evidence->calls_emitted |=
|
||||
emit_service_edge(ws->local_edge_buf, source_node, NULL, call, &res,
|
||||
module_qn, rc->project_name, rc->registry, rc->main_gbuf,
|
||||
imp_keys, imp_vals, imp_count, false, route_mount, lang);
|
||||
ws->calls_resolved++;
|
||||
}
|
||||
}
|
||||
@@ -3800,9 +3804,10 @@ static void resolve_file_calls(resolve_ctx_t *rc, resolve_worker_state_t *ws, CB
|
||||
}
|
||||
site_evidence->candidate_qn = target_node->qualified_name;
|
||||
_rc_t0 = extract_now_ns();
|
||||
site_evidence->calls_emitted |= emit_service_edge(
|
||||
ws->local_edge_buf, source_node, target_node, call, &res, module_qn, rc->registry,
|
||||
rc->main_gbuf, imp_keys, imp_vals, imp_count, drop_plain_call, route_mount, lang);
|
||||
site_evidence->calls_emitted |=
|
||||
emit_service_edge(ws->local_edge_buf, source_node, target_node, call, &res, module_qn,
|
||||
rc->project_name, rc->registry, rc->main_gbuf, imp_keys, imp_vals,
|
||||
imp_count, drop_plain_call, route_mount, lang);
|
||||
atomic_fetch_add_explicit(&rc->time_ns_rc_emit, extract_now_ns() - _rc_t0,
|
||||
memory_order_relaxed);
|
||||
ws->calls_resolved++;
|
||||
|
||||
@@ -184,6 +184,12 @@ TEST(infrascan_service_pattern_match_rejects_ids_inside_words) {
|
||||
};
|
||||
ASSERT_EQ(svc_case_mismatches(cases), 0);
|
||||
ASSERT_EQ(cbm_service_pattern_match_named("proj.worker.run(_:Alamofire)", "run"), CBM_SVC_NONE);
|
||||
ASSERT_EQ(cbm_service_pattern_match_in_project("Dio.src.nav.navigateTo", "navigateTo", "Dio"),
|
||||
CBM_SVC_NONE);
|
||||
ASSERT_EQ(cbm_service_pattern_match_in_project("Dio.src.axios.get", "get", "Dio"),
|
||||
CBM_SVC_HTTP);
|
||||
ASSERT_EQ(cbm_service_pattern_match_in_project("axios.get", NULL, "Dio"), CBM_SVC_HTTP);
|
||||
ASSERT_EQ(cbm_service_pattern_match_in_project("Dio.client.get", "get", "Di"), CBM_SVC_HTTP);
|
||||
ASSERT_EQ(cbm_service_pattern_match_named("proj.Alamofire.request(_:String)", "request"),
|
||||
CBM_SVC_HTTP);
|
||||
/* A field whose name contains a call keeps its complete QN. */
|
||||
|
||||
@@ -16065,7 +16065,7 @@ TEST(pipeline_arg_url_skips_client_navigation) {
|
||||
free(saved_single);
|
||||
FAIL("save environment");
|
||||
}
|
||||
char tmp[256] = "/tmp/cbm_arg_url_nav_XXXXXX";
|
||||
char tmp[256] = "/tmp/cbm_arg_url_nav_Dio_XXXXXX";
|
||||
if (!cbm_mkdtemp(tmp)) {
|
||||
free(saved_workers);
|
||||
free(saved_single);
|
||||
|
||||
Reference in New Issue
Block a user