Resolve throws/raises for one file. */
| 2657 | |
| 2658 | /* Resolve throws/raises for one file. */ |
| 2659 | static void resolve_file_throws(resolve_ctx_t *rc, resolve_worker_state_t *ws, |
| 2660 | CBMFileResult *result, const char *rel, const char *module_qn, |
| 2661 | const char **imp_keys, const char **imp_vals, int imp_count) { |
| 2662 | for (int t = 0; t < result->throws.count; t++) { |
| 2663 | CBMThrow *thr = &result->throws.items[t]; |
| 2664 | if (!thr->exception_name || !thr->enclosing_func_qn) { |
| 2665 | continue; |
| 2666 | } |
| 2667 | /* find_source_node falls back to the per-file File node when the |
| 2668 | * lookup lands on a shared Folder/Project node (#787, #842) — same |
| 2669 | * guard resolve_file_calls/usages/rw already use. */ |
| 2670 | const cbm_gbuf_node_t *src = |
| 2671 | find_source_node(rc->main_gbuf, rc->project_name, rel, thr->enclosing_func_qn); |
| 2672 | if (!src) { |
| 2673 | continue; |
| 2674 | } |
| 2675 | const char *edge_type = is_checked_exception(thr->exception_name) ? "THROWS" : "RAISES"; |
| 2676 | cbm_resolution_t res = cbm_registry_resolve(rc->registry, thr->exception_name, module_qn, |
| 2677 | imp_keys, imp_vals, imp_count); |
| 2678 | if (!res.qualified_name || res.qualified_name[0] == '\0') { |
| 2679 | continue; |
| 2680 | } |
| 2681 | const cbm_gbuf_node_t *tgt = cbm_gbuf_find_by_qn(rc->main_gbuf, res.qualified_name); |
| 2682 | if (!tgt || src->id == tgt->id) { |
| 2683 | continue; |
| 2684 | } |
| 2685 | cbm_gbuf_insert_edge(ws->local_edge_buf, src->id, tgt->id, edge_type, "{}"); |
| 2686 | } |
| 2687 | } |
| 2688 | |
| 2689 | /* Resolve reads/writes for one file. */ |
| 2690 | static void resolve_file_rw(resolve_ctx_t *rc, resolve_worker_state_t *ws, CBMFileResult *result, |
no test coverage detected