| 2452 | } |
| 2453 | |
| 2454 | static void process_class_decl(PHPLSPContext *ctx, TSNode node) { |
| 2455 | TSNode name_node = ts_node_child_by_field_name(node, "name", 4); |
| 2456 | if (ts_node_is_null(name_node)) |
| 2457 | return; |
| 2458 | char *cname = php_node_text(ctx, name_node); |
| 2459 | if (!cname) |
| 2460 | return; |
| 2461 | |
| 2462 | const char *saved_class = ctx->enclosing_class_qn; |
| 2463 | const char *saved_parent = ctx->enclosing_parent_qn; |
| 2464 | |
| 2465 | /* enclosing_class_qn must match what the unified extractor records, |
| 2466 | * which uses module_qn (file-path-based), NOT the PHP `namespace` |
| 2467 | * declaration. */ |
| 2468 | if (ctx->module_qn) { |
| 2469 | ctx->enclosing_class_qn = cbm_arena_sprintf(ctx->arena, "%s.%s", ctx->module_qn, cname); |
| 2470 | } else { |
| 2471 | ctx->enclosing_class_qn = cbm_arena_strdup(ctx->arena, cname); |
| 2472 | } |
| 2473 | ctx->enclosing_parent_qn = find_extends_qn(ctx, node); |
| 2474 | |
| 2475 | /* Walk class body — pick out method_declaration nodes. */ |
| 2476 | TSNode body = ts_node_child_by_field_name(node, "body", 4); |
| 2477 | if (ts_node_is_null(body)) |
| 2478 | body = child_named(node, "declaration_list"); |
| 2479 | if (!ts_node_is_null(body)) { |
| 2480 | uint32_t nc = ts_node_child_count(body); |
| 2481 | for (uint32_t i = 0; i < nc; i++) { |
| 2482 | TSNode c = ts_node_child(body, i); |
| 2483 | if (ts_node_is_null(c)) |
| 2484 | continue; |
| 2485 | const char *k = ts_node_type(c); |
| 2486 | if (strcmp(k, "method_declaration") == 0) { |
| 2487 | process_function_like(ctx, c); |
| 2488 | } |
| 2489 | } |
| 2490 | } |
| 2491 | |
| 2492 | ctx->enclosing_class_qn = saved_class; |
| 2493 | ctx->enclosing_parent_qn = saved_parent; |
| 2494 | } |
| 2495 | |
| 2496 | /* ── top-level pass ─────────────────────────────────────────────── */ |
| 2497 |
no test coverage detected