mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-04 10:48:20 +00:00
fix(python): skip annotation-only imports without a new raw free
The memory-core linter counts raw allocator calls per file and fails when a file grows. The TYPE_CHECKING change freed the copied local name of an annotation-only import with a new raw free in two import-map builders. build_import_map now asks the predicate on the name's span in the edge properties before copying it (cbm_imports_local_span_binds_runtime_name, which cbm_imports_local_binds_runtime_name now wraps), and the cross-LSP builder routes an annotation-only name through its existing no-value path. Same behaviour, no new raw allocator site. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
This commit is contained in:
1 parent
2455e75578
commit
3ead775d0b
4 files changed
+36
-19
No files matched your search
+10
-3
@@ -402,14 +402,16 @@ void cbm_imports_push(CBMImportArray *arr, CBMArena *a, CBMImport imp) {
|
||||
arr->items[arr->count++] = imp;
|
||||
}
|
||||
|
||||
bool cbm_imports_local_binds_runtime_name(const CBMImportArray *imports, const char *local_name) {
|
||||
if (!imports || !local_name) {
|
||||
bool cbm_imports_local_span_binds_runtime_name(const CBMImportArray *imports, const char *name,
|
||||
size_t len) {
|
||||
if (!imports || !name) {
|
||||
return true;
|
||||
}
|
||||
bool seen = false;
|
||||
for (int i = 0; i < imports->count; i++) {
|
||||
const CBMImport *imp = &imports->items[i];
|
||||
if (!imp->local_name || strcmp(imp->local_name, local_name) != 0) {
|
||||
if (!imp->local_name || strncmp(imp->local_name, name, len) != 0 ||
|
||||
imp->local_name[len] != '\0') {
|
||||
continue;
|
||||
}
|
||||
if (cbm_import_binds_runtime_name(imp)) {
|
||||
@@ -420,6 +422,11 @@ bool cbm_imports_local_binds_runtime_name(const CBMImportArray *imports, const c
|
||||
return !seen;
|
||||
}
|
||||
|
||||
bool cbm_imports_local_binds_runtime_name(const CBMImportArray *imports, const char *local_name) {
|
||||
return !local_name ||
|
||||
cbm_imports_local_span_binds_runtime_name(imports, local_name, strlen(local_name));
|
||||
}
|
||||
|
||||
void cbm_usages_push(CBMUsageArray *arr, CBMArena *a, CBMUsage usage) {
|
||||
GROW_ARRAY(arr, a);
|
||||
arr->items[arr->count++] = usage;
|
||||
|
||||
@@ -1321,6 +1321,10 @@ void cbm_imports_push(CBMImportArray *arr, CBMArena *a, CBMImport imp);
|
||||
* annotation-only (cbm_import_binds_runtime_name), so also true when no import
|
||||
* names it: the rule for the builders that key IMPORTS edges by local name. */
|
||||
bool cbm_imports_local_binds_runtime_name(const CBMImportArray *imports, const char *local_name);
|
||||
/* The same for the `len` bytes at `name` (not NUL-terminated): lets a caller
|
||||
* decide before it copies the name. */
|
||||
bool cbm_imports_local_span_binds_runtime_name(const CBMImportArray *imports, const char *name,
|
||||
size_t len);
|
||||
void cbm_usages_push(CBMUsageArray *arr, CBMArena *a, CBMUsage usage);
|
||||
void cbm_throws_push(CBMThrowArray *arr, CBMArena *a, CBMThrow thr);
|
||||
void cbm_rw_push(CBMRWArray *arr, CBMArena *a, CBMReadWrite rw);
|
||||
|
||||
+18
-10
@@ -95,21 +95,24 @@ static const char *itoa_log(int val) {
|
||||
|
||||
/* Build per-file import map from cached extraction result or graph buffer edges.
|
||||
* Returns parallel arrays of (local_name, module_qn) pairs. Caller frees. */
|
||||
/* Parse "local_name":"value" from JSON properties string. Returns strdup'd key or NULL. */
|
||||
static char *extract_local_name_from_json(const char *props_json) {
|
||||
/* The "local_name":"value" of a JSON properties string, as a span of it;
|
||||
* false when absent or empty. */
|
||||
static bool local_name_span_from_json(const char *props_json, const char **out, size_t *len) {
|
||||
if (!props_json) {
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
const char *start = strstr(props_json, "\"local_name\":\"");
|
||||
if (!start) {
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
start += strlen("\"local_name\":\"");
|
||||
const char *end = strchr(start, '"');
|
||||
if (!end || end <= start) {
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
return cbm_strndup(start, end - start);
|
||||
*out = start;
|
||||
*len = (size_t)(end - start);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* The graph node whose QN is cbm_pipeline_fqn_compute(project, rel_path, name),
|
||||
@@ -193,11 +196,16 @@ static int build_import_map(cbm_pipeline_ctx_t *ctx, const char *rel_path,
|
||||
if (!target) {
|
||||
continue;
|
||||
}
|
||||
char *key = extract_local_name_from_json(e->properties_json);
|
||||
if (key && !cbm_imports_local_binds_runtime_name(result ? &result->imports : NULL, key)) {
|
||||
free(key); /* annotation-only import (#1277): no CALLS binding */
|
||||
key = NULL;
|
||||
const char *name = NULL;
|
||||
size_t name_len = 0;
|
||||
/* An annotation-only import (#1277) binds no CALLS name: skipped before
|
||||
* the key is copied. */
|
||||
if (!local_name_span_from_json(e->properties_json, &name, &name_len) ||
|
||||
!cbm_imports_local_span_binds_runtime_name(result ? &result->imports : NULL, name,
|
||||
name_len)) {
|
||||
continue;
|
||||
}
|
||||
char *key = cbm_strndup(name, name_len);
|
||||
if (key) {
|
||||
keys[count] = key;
|
||||
vals[count] = target->qualified_name;
|
||||
|
||||
@@ -1147,12 +1147,10 @@ int cbm_pxc_build_import_map_ex(const cbm_gbuf_t *gbuf, const char *project_name
|
||||
continue;
|
||||
memcpy(local, start, n);
|
||||
local[n] = '\0';
|
||||
if (!include_type_only &&
|
||||
!cbm_imports_local_binds_runtime_name(result ? &result->imports : NULL, local)) {
|
||||
free(local); /* annotation-only import (#1277): no CALLS binding */
|
||||
continue;
|
||||
}
|
||||
char *value = pxc_import_value_qn(lang, result, local, target);
|
||||
/* An annotation-only import (#1277) binds no CALLS name: it gets no value. */
|
||||
bool binds = include_type_only ||
|
||||
cbm_imports_local_binds_runtime_name(result ? &result->imports : NULL, local);
|
||||
char *value = binds ? pxc_import_value_qn(lang, result, local, target) : NULL;
|
||||
if (!value) {
|
||||
free(local);
|
||||
continue;
|
||||
|
||||
Reference in new issue
Block a user