MCPcopy Create free account
hub / github.com/DeusData/codebase-memory-mcp / resolve_member_call

Function resolve_member_call

internal/cbm/lsp/php_lsp.c:1680–1732  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1678}
1679
1680static void resolve_member_call(PHPLSPContext *ctx, TSNode call, CBMResolvedKind kind) {
1681 TSNode obj = ts_node_child_by_field_name(call, "object", 6);
1682 TSNode name_node = ts_node_child_by_field_name(call, "name", 4);
1683 if (ts_node_is_null(name_node))
1684 return;
1685 if (kind == CBM_RESOLVED_CALL_REFERENCE &&
1686 php_callable_reference_has_dynamic_member_name(ctx, call)) {
1687 return;
1688 }
1689 char *method_name = php_node_text(ctx, name_node);
1690 if (!method_name)
1691 return;
1692 if (ts_node_is_null(obj))
1693 return;
1694
1695 const CBMType *recv = php_eval_expr_type(ctx, obj);
1696 if (!recv)
1697 return;
1698 const char *class_qn = NULL;
1699 if (recv->kind == CBM_TYPE_NAMED) {
1700 class_qn = recv->data.named.qualified_name;
1701 } else if (recv->kind == CBM_TYPE_TEMPLATE) {
1702 /* `Collection<User>` resolves methods on `Collection`. */
1703 class_qn = recv->data.template_type.template_name;
1704 }
1705 if (!class_qn)
1706 return; /* unknown receiver; defer */
1707 const CBMRegisteredFunc *f = php_lookup_method(ctx, class_qn, method_name);
1708 if (f) {
1709 const char *strategy = (f->receiver_type && strcmp(f->receiver_type, class_qn) == 0)
1710 ? "php_method_typed"
1711 : "php_method_inherited";
1712 emit_resolved_kind(ctx, f->qualified_name, strategy, 0.95f, kind);
1713 return;
1714 }
1715 /* Receiver known but method missing — magic __call? The call dispatches to
1716 * the class's __call handler, so resolve to <class>.__call (a real node).
1717 * The textual callee is the dynamic method name (`anything`), not `__call`,
1718 * so stash it in reason for the join (lsp_resolve.h, php_method_dynamic).
1719 * Emit above the join's confidence floor — dispatch to __call is certain. */
1720 if (class_has_magic_call(ctx, class_qn, false)) {
1721 emit_resolved_reason_kind(ctx, cbm_arena_sprintf(ctx->arena, "%s.__call", class_qn),
1722 "php_method_dynamic", 0.85f, method_name, kind);
1723 return;
1724 }
1725 /* Receiver known but class not in registry (e.g. vendor type not indexed,
1726 * or method genuinely missing). Emit a synthetic resolved call pointing
1727 * at "<class_qn>.<method>" so the pipeline bridge can BLOCK the unified
1728 * extractor's likely-incorrect short-name fallback. The bridge filters
1729 * unknown targets and yields no edge — better than a wrong edge. */
1730 emit_resolved_kind(ctx, cbm_arena_sprintf(ctx->arena, "%s.%s", class_qn, method_name),
1731 "php_method_typed_unindexed", 0.55f, kind);
1732}
1733
1734static void resolve_static_call(PHPLSPContext *ctx, TSNode call, CBMResolvedKind kind) {
1735 TSNode scope = ts_node_child_by_field_name(call, "scope", 5);

Callers 1

Calls 8

php_node_textFunction · 0.85
php_eval_expr_typeFunction · 0.85
php_lookup_methodFunction · 0.85
emit_resolved_kindFunction · 0.85
class_has_magic_callFunction · 0.85
cbm_arena_sprintfFunction · 0.50

Tested by

no test coverage detected