| 841 | } |
| 842 | |
| 843 | static void py_emit_resolved_reference(PyLSPContext *ctx, const char *callee_qn, |
| 844 | const char *source_name, TSNode site, |
| 845 | const char *strategy) { |
| 846 | if (!ctx || !ctx->resolved_calls || !callee_qn || !ctx->enclosing_func_qn || |
| 847 | ts_node_is_null(site)) { |
| 848 | return; |
| 849 | } |
| 850 | uint32_t start = ts_node_start_byte(site); |
| 851 | uint32_t end = ts_node_end_byte(site); |
| 852 | for (int i = ctx->resolved_calls->count - 1; i >= 0; i--) { |
| 853 | CBMResolvedCall *existing = &ctx->resolved_calls->items[i]; |
| 854 | if (existing->kind == CBM_RESOLVED_CALL_REFERENCE && existing->site_start_byte == start && |
| 855 | existing->site_end_byte == end && existing->caller_qn && existing->callee_qn && |
| 856 | strcmp(existing->caller_qn, ctx->enclosing_func_qn) == 0 && |
| 857 | strcmp(existing->callee_qn, callee_qn) == 0) { |
| 858 | return; |
| 859 | } |
| 860 | } |
| 861 | CBMResolvedCall rc = {0}; |
| 862 | rc.caller_qn = ctx->enclosing_func_qn; |
| 863 | rc.callee_qn = cbm_arena_strdup(ctx->arena, callee_qn); |
| 864 | rc.strategy = strategy ? strategy : "lsp_callable_value_reference"; |
| 865 | rc.confidence = 0.97f; |
| 866 | const char *leaf = strrchr(callee_qn, '.'); |
| 867 | leaf = leaf ? leaf + 1 : callee_qn; |
| 868 | rc.reason = source_name && strcmp(source_name, leaf) != 0 |
| 869 | ? cbm_arena_strdup(ctx->arena, source_name) |
| 870 | : NULL; |
| 871 | rc.kind = CBM_RESOLVED_CALL_REFERENCE; |
| 872 | rc.site_start_byte = start; |
| 873 | rc.site_end_byte = end; |
| 874 | cbm_resolvedcall_push(ctx->resolved_calls, ctx->arena, rc); |
| 875 | } |
| 876 | |
| 877 | static void py_emit_unresolved_reference(PyLSPContext *ctx, const char *candidate_qn, TSNode site) { |
| 878 | if (!ctx || !ctx->resolved_calls || !candidate_qn || !ctx->enclosing_func_qn || |
no test coverage detected