| 2658 | } |
| 2659 | |
| 2660 | static void process_class_decl(PHPLSPContext *ctx, TSNode node) { |
| 2661 | TSNode name_node = ts_node_child_by_field_name(node, "name", 4); |
| 2662 | if (ts_node_is_null(name_node)) |
| 2663 | return; |
| 2664 | char *cname = php_node_text(ctx, name_node); |
| 2665 | if (!cname) |
| 2666 | return; |
| 2667 | |
| 2668 | const char *saved_class = ctx->enclosing_class_qn; |
| 2669 | const char *saved_parent = ctx->enclosing_parent_qn; |
| 2670 | |
| 2671 | /* enclosing_class_qn must match what the unified extractor records, |
| 2672 | * which uses module_qn (file-path-based), NOT the PHP `namespace` |
| 2673 | * declaration. */ |
| 2674 | if (ctx->module_qn) { |
| 2675 | ctx->enclosing_class_qn = cbm_arena_sprintf(ctx->arena, "%s.%s", ctx->module_qn, cname); |
| 2676 | } else { |
| 2677 | ctx->enclosing_class_qn = cbm_arena_strdup(ctx->arena, cname); |
| 2678 | } |
| 2679 | ctx->enclosing_parent_qn = find_extends_qn(ctx, node); |
| 2680 | |
| 2681 | /* Walk class body — pick out method_declaration nodes. */ |
| 2682 | TSNode body = ts_node_child_by_field_name(node, "body", 4); |
| 2683 | if (ts_node_is_null(body)) |
| 2684 | body = child_named(node, "declaration_list"); |
| 2685 | if (!ts_node_is_null(body)) { |
| 2686 | uint32_t nc = ts_node_child_count(body); |
| 2687 | for (uint32_t i = 0; i < nc; i++) { |
| 2688 | TSNode c = ts_node_child(body, i); |
| 2689 | if (ts_node_is_null(c)) |
| 2690 | continue; |
| 2691 | const char *k = ts_node_type(c); |
| 2692 | if (strcmp(k, "method_declaration") == 0) { |
| 2693 | process_function_like(ctx, c); |
| 2694 | } |
| 2695 | } |
| 2696 | } |
| 2697 | |
| 2698 | ctx->enclosing_class_qn = saved_class; |
| 2699 | ctx->enclosing_parent_qn = saved_parent; |
| 2700 | } |
| 2701 | |
| 2702 | /* ── top-level pass ─────────────────────────────────────────────── */ |
| 2703 |
no test coverage detected