Try to emit a usage for a reference node. Returns early if the node should be skipped.
| 2427 | |
| 2428 | // Try to emit a usage for a reference node. Returns early if the node should be skipped. |
| 2429 | static void try_emit_usage(CBMExtractCtx *ctx, TSNode node, const CBMLangSpec *spec) { |
| 2430 | if (emit_direct_perl_coderef_usage(ctx, node, cbm_enclosing_func_qn_cached(ctx, node), 0)) { |
| 2431 | return; |
| 2432 | } |
| 2433 | if (inside_direct_perl_coderef(ctx, node)) { |
| 2434 | return; |
| 2435 | } |
| 2436 | if (!is_reference_node(node, ctx->language)) { |
| 2437 | return; |
| 2438 | } |
| 2439 | if (is_call_argument_label(node)) { |
| 2440 | return; |
| 2441 | } |
| 2442 | if (is_inside_call(node, spec) || is_inside_import(node, spec)) { |
| 2443 | return; |
| 2444 | } |
| 2445 | if (is_binding_occurrence(ctx, node, spec, NULL) || |
| 2446 | is_write_occurrence(ctx, node, spec, NULL)) { |
| 2447 | return; |
| 2448 | } |
| 2449 | char *name = reference_name(ctx, node); |
| 2450 | if (name && name[0] && !cbm_is_keyword(name, ctx->language)) { |
| 2451 | CBMUsage usage = {0}; |
| 2452 | usage.ref_name = name; |
| 2453 | usage.enclosing_func_qn = cbm_enclosing_func_qn_cached(ctx, node); |
| 2454 | stamp_usage_site(ctx, &usage, node, name, NULL); |
| 2455 | cbm_usages_push(&ctx->result->usages, ctx->arena, usage); |
| 2456 | } |
| 2457 | } |
| 2458 | |
| 2459 | // Iterative usage walker — explicit stack |
| 2460 | static void walk_usages(CBMExtractCtx *ctx, TSNode root, const CBMLangSpec *spec) { |
no test coverage detected