Preserve the historical registry fallback for an unshadowed function: it * keeps ordinary direct-call resolution stable. When a definition actually * replaces a prior binding (import, wildcard uncertainty, class, assignment), * record the new exact callable value or clear the stale identity. */
| 4234 | * replaces a prior binding (import, wildcard uncertainty, class, assignment), |
| 4235 | * record the new exact callable value or clear the stale identity. */ |
| 4236 | static void py_bind_module_function(PyLSPContext *ctx, TSNode func_node) { |
| 4237 | if (!ctx || ts_node_is_null(func_node) || !ctx->module_qn) |
| 4238 | return; |
| 4239 | TSNode name_node = ts_node_child_by_field_name(func_node, "name", 4); |
| 4240 | char *name = py_node_text(ctx, name_node); |
| 4241 | if (!name || !name[0]) { |
| 4242 | py_disable_callable_value_proof(ctx); |
| 4243 | return; |
| 4244 | } |
| 4245 | if (!cbm_scope_contains(ctx->current_scope, name)) |
| 4246 | return; |
| 4247 | |
| 4248 | const char *qn = cbm_arena_sprintf(ctx->arena, "%s.%s", ctx->module_qn, name); |
| 4249 | if (!qn) { |
| 4250 | py_disable_callable_value_proof(ctx); |
| 4251 | py_scope_bind(ctx, name, cbm_type_unknown()); |
| 4252 | return; |
| 4253 | } |
| 4254 | const CBMRegisteredFunc *func = cbm_registry_lookup_func(ctx->registry, qn); |
| 4255 | if (py_func_is_exact_callable_value(func)) { |
| 4256 | py_scope_bind_callable(ctx, name, cbm_type_unknown(), func->qualified_name); |
| 4257 | } else { |
| 4258 | py_scope_bind(ctx, name, cbm_type_unknown()); |
| 4259 | } |
| 4260 | } |
| 4261 | |
| 4262 | static bool py_import_statement_is_wildcard(TSNode stmt) { |
| 4263 | uint32_t count = ts_node_named_child_count(stmt); |
no test coverage detected