| 2757 | } |
| 2758 | |
| 2759 | static yyjson_mut_val *bfs_to_json_array(yyjson_mut_doc *doc, cbm_traverse_result_t *tr, |
| 2760 | bool risk_labels, bool include_tests, bool data_flow) { |
| 2761 | yyjson_mut_val *arr = yyjson_mut_arr(doc); |
| 2762 | for (int i = 0; i < tr->visited_count; i++) { |
| 2763 | const char *fp = tr->visited[i].node.file_path; |
| 2764 | bool test = is_test_file(fp); |
| 2765 | if (!include_tests && test) { |
| 2766 | continue; |
| 2767 | } |
| 2768 | yyjson_mut_val *item = yyjson_mut_obj(doc); |
| 2769 | yyjson_mut_obj_add_str(doc, item, "name", |
| 2770 | tr->visited[i].node.name ? tr->visited[i].node.name : ""); |
| 2771 | yyjson_mut_obj_add_str( |
| 2772 | doc, item, "qualified_name", |
| 2773 | tr->visited[i].node.qualified_name ? tr->visited[i].node.qualified_name : ""); |
| 2774 | yyjson_mut_obj_add_int(doc, item, "hop", tr->visited[i].hop); |
| 2775 | if (risk_labels) { |
| 2776 | yyjson_mut_obj_add_str(doc, item, "risk", |
| 2777 | cbm_risk_label(cbm_hop_to_risk(tr->visited[i].hop))); |
| 2778 | } |
| 2779 | if (test) { |
| 2780 | yyjson_mut_obj_add_bool(doc, item, "is_test", true); |
| 2781 | } |
| 2782 | /* data_flow mode promises argument expressions at each call site; surface |
| 2783 | * the CALLS edge's serialized args array as a raw JSON value (#514). */ |
| 2784 | if (data_flow) { |
| 2785 | size_t alen = 0; |
| 2786 | const char *args = bfs_edge_args_for_hop(tr, tr->visited[i].node.id, &alen); |
| 2787 | if (args && alen > 0) { |
| 2788 | yyjson_mut_val *av = yyjson_mut_rawn(doc, args, alen); |
| 2789 | if (av) { |
| 2790 | yyjson_mut_obj_add_val(doc, item, "args", av); |
| 2791 | } |
| 2792 | } |
| 2793 | } |
| 2794 | yyjson_mut_arr_add_val(arr, item); |
| 2795 | } |
| 2796 | return arr; |
| 2797 | } |
| 2798 | |
| 2799 | static char *snippet_suggestions(const char *input, cbm_node_t *nodes, int count); |
| 2800 |
no test coverage detected