Extract all arguments from a call expression into call->args[]. */
| 1835 | |
| 1836 | /* Extract all arguments from a call expression into call->args[]. */ |
| 1837 | static void extract_call_args(CBMExtractCtx *ctx, TSNode args, CBMCall *call) { |
| 1838 | uint32_t argc = ts_node_named_child_count(args); |
| 1839 | int positional_idx = 0; |
| 1840 | for (uint32_t ai = 0; ai < argc && call->arg_count < CBM_MAX_CALL_ARGS; ai++) { |
| 1841 | TSNode arg_node = ts_node_named_child(args, ai); |
| 1842 | const char *ak = ts_node_type(arg_node); |
| 1843 | CBMCallArg *ca = &call->args[call->arg_count]; |
| 1844 | memset(ca, 0, sizeof(*ca)); |
| 1845 | |
| 1846 | if (strcmp(ak, "keyword_argument") == 0 || strcmp(ak, "pair") == 0) { |
| 1847 | process_keyword_arg(ctx, arg_node, ca); |
| 1848 | ca->index = positional_idx++; |
| 1849 | call->arg_count++; |
| 1850 | } else if (strcmp(ak, "list_splat") == 0 || strcmp(ak, "dictionary_splat") == 0 || |
| 1851 | strcmp(ak, "spread_element") == 0) { |
| 1852 | positional_idx++; |
| 1853 | } else { |
| 1854 | ca->expr = cbm_node_text(ctx->arena, arg_node, ctx->source); |
| 1855 | ca->index = positional_idx++; |
| 1856 | if (is_string_like(ak) && ca->expr) { |
| 1857 | ca->value = strip_quotes(ctx->arena, ca->expr); |
| 1858 | } else if (strcmp(ak, "identifier") == 0 && ca->expr) { |
| 1859 | ca->value = lookup_string_constant(ctx, ca->expr); |
| 1860 | } |
| 1861 | call->arg_count++; |
| 1862 | } |
| 1863 | } |
| 1864 | } |
| 1865 | |
| 1866 | // Check if a keyword name matches URL or topic patterns. |
| 1867 | static bool is_url_or_topic_keyword(const char *key) { |
no test coverage detected