mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-10-27 06:53:11 +08:00
fix(dart): attribute in-body calls to the enclosing function (signature/body siblings)
Dart models a function as a function_signature plus a SIBLING function_body (both children of program/class_body), not a single node containing the body. So a scope pushed at the signature never covers the body, and the signature's name was also unresolved by the shared resolver — in-body calls sourced to the Module (enclosing-func drift). Two parts in the unified walk: - compute_func_qn resolves a dart function_signature/method_signature name from its identifier child (method_signature wraps a function_signature). - push_boundary_scopes pushes the SCOPE_FUNC at the function_body, computing the QN from the preceding signature sibling, so the body's children attribute to the function. grammar_scripting and enclosing_parity dart cases now green. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
This commit is contained in:
@@ -322,6 +322,32 @@ static const char *compute_func_qn(CBMExtractCtx *ctx, TSNode node, const CBMLan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Dart: function_signature / method_signature have no `name` field; the name
|
||||||
|
* is an `identifier` child (method_signature wraps a function_signature). The
|
||||||
|
* shared resolver doesn't cover them, so resolve here for call-scope so an
|
||||||
|
* in-body call sources to the function, not the Module. */
|
||||||
|
if (ctx->language == CBM_LANG_DART && (strcmp(ts_node_type(node), "function_signature") == 0 ||
|
||||||
|
strcmp(ts_node_type(node), "method_signature") == 0)) {
|
||||||
|
TSNode sig = node;
|
||||||
|
if (strcmp(ts_node_type(node), "method_signature") == 0) {
|
||||||
|
TSNode fs = cbm_find_child_by_kind(node, "function_signature");
|
||||||
|
if (!ts_node_is_null(fs)) {
|
||||||
|
sig = fs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TSNode id = cbm_find_child_by_kind(sig, "identifier");
|
||||||
|
if (!ts_node_is_null(id)) {
|
||||||
|
char *nm = cbm_node_text(ctx->arena, id, ctx->source);
|
||||||
|
if (nm && nm[0]) {
|
||||||
|
if (state->enclosing_class_qn) {
|
||||||
|
return cbm_arena_sprintf(ctx->arena, "%s.%s", state->enclosing_class_qn, nm);
|
||||||
|
}
|
||||||
|
return cbm_fqn_compute_source_lang(ctx->arena, ctx->project, ctx->rel_path, nm,
|
||||||
|
ctx->language);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Resolve the function name via the single shared resolver (extract_defs) so
|
/* Resolve the function name via the single shared resolver (extract_defs) so
|
||||||
* call-scope attribution agrees with definition extraction across all ~130
|
* call-scope attribution agrees with definition extraction across all ~130
|
||||||
* grammars. The old private 4-case copy returned NULL for Fortran subroutine,
|
* grammars. The old private 4-case copy returned NULL for Fortran subroutine,
|
||||||
@@ -1071,6 +1097,24 @@ static void push_boundary_scopes(CBMExtractCtx *ctx, TSNode node, const CBMLangS
|
|||||||
push_scope(state, SCOPE_CLASS, depth, tqn);
|
push_scope(state, SCOPE_CLASS, depth, tqn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (ctx->language == CBM_LANG_DART && strcmp(ts_node_type(node), "function_body") == 0) {
|
||||||
|
/* Dart models a function as `function_signature` + `function_body` SIBLINGS
|
||||||
|
* (the signature node does not contain the body). A scope pushed at the
|
||||||
|
* signature never covers the body, so in-body calls source to the Module.
|
||||||
|
* Push the function scope at the BODY using the preceding signature
|
||||||
|
* sibling's QN, so the body's children attribute to the function. */
|
||||||
|
TSNode prev = ts_node_prev_sibling(node);
|
||||||
|
while (!ts_node_is_null(prev) &&
|
||||||
|
strcmp(ts_node_type(prev), "function_signature") != 0 &&
|
||||||
|
strcmp(ts_node_type(prev), "method_signature") != 0) {
|
||||||
|
prev = ts_node_prev_sibling(prev);
|
||||||
|
}
|
||||||
|
if (!ts_node_is_null(prev)) {
|
||||||
|
const char *fqn = compute_func_qn(ctx, prev, spec, state);
|
||||||
|
if (fqn) {
|
||||||
|
push_scope(state, SCOPE_FUNC, depth, fqn);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spec->call_node_types && cbm_kind_in_set(node, spec->call_node_types)) {
|
if (spec->call_node_types && cbm_kind_in_set(node, spec->call_node_types)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user