| 981 | * ══════════════════════════════════════════════════════════════════ */ |
| 982 | |
| 983 | static void rust_process_call(CBMExtractCtx *ctx, TSNode call) { |
| 984 | TSNode func = ts_node_child_by_field_name(call, TS_FIELD("function")); |
| 985 | if (ts_node_is_null(func)) { |
| 986 | return; |
| 987 | } |
| 988 | const char *fk = ts_node_type(func); |
| 989 | if (strcmp(fk, "field_expression") != 0) { |
| 990 | return; |
| 991 | } |
| 992 | TSNode field = ts_node_child_by_field_name(func, TS_FIELD("field")); |
| 993 | TSNode value = ts_node_child_by_field_name(func, TS_FIELD("value")); |
| 994 | if (ts_node_is_null(field) || ts_node_is_null(value)) { |
| 995 | return; |
| 996 | } |
| 997 | |
| 998 | char *method = cbm_node_text(ctx->arena, field, ctx->source); |
| 999 | if (!method) { |
| 1000 | return; |
| 1001 | } |
| 1002 | |
| 1003 | CBMChannelDirection direction; |
| 1004 | if (strcmp(method, "send") == 0 || strcmp(method, "send_all") == 0 || |
| 1005 | strcmp(method, "feed") == 0) { |
| 1006 | direction = CBM_CHANNEL_EMIT; |
| 1007 | } else if (strcmp(method, "next") == 0 || strcmp(method, "try_next") == 0) { |
| 1008 | direction = CBM_CHANNEL_LISTEN; |
| 1009 | } else { |
| 1010 | return; |
| 1011 | } |
| 1012 | |
| 1013 | /* Verify receiver looks like a websocket sink/stream */ |
| 1014 | char *recv = cbm_node_text(ctx->arena, value, ctx->source); |
| 1015 | if (!recv) { |
| 1016 | return; |
| 1017 | } |
| 1018 | const char *tail = recv; |
| 1019 | const char *dot = strrchr(tail, '.'); |
| 1020 | if (dot) { |
| 1021 | tail = dot + SKIP_ONE; |
| 1022 | } |
| 1023 | if (strcmp(tail, "sink") != 0 && strcmp(tail, "ws_sender") != 0 && |
| 1024 | strcmp(tail, "writer") != 0 && strcmp(tail, "write") != 0 && strcmp(tail, "stream") != 0 && |
| 1025 | strcmp(tail, "ws_receiver") != 0 && strcmp(tail, "reader") != 0 && |
| 1026 | strcmp(tail, "read") != 0 && strcmp(tail, "ws_stream") != 0 && strcmp(tail, "ws") != 0) { |
| 1027 | return; |
| 1028 | } |
| 1029 | |
| 1030 | const char *func_name = enclosing_function_qn(ctx, call); |
| 1031 | const char *channel_name = func_name ? func_name : "(websocket)"; |
| 1032 | push_channel(ctx, channel_name, "websocket", direction, call); |
| 1033 | } |
| 1034 | |
| 1035 | static void extract_channels_rust(CBMExtractCtx *ctx) { |
| 1036 | TSNodeStack stack; |
no test coverage detected