| 1558 | } |
| 1559 | |
| 1560 | static void process_constructor_decl(JavaLSPContext *ctx, TSNode node, const char *class_qn, |
| 1561 | const char *super_qn) { |
| 1562 | TSNode name_node = ts_node_child_by_field_name(node, "name", 4); |
| 1563 | char *cname = ts_node_is_null(name_node) ? NULL : java_node_text(ctx, name_node); |
| 1564 | /* Constructor QN convention: Class.<init> or Class.ClassShortName. The |
| 1565 | * extractor uses the short class name; mirror that. */ |
| 1566 | char *ctor_qn; |
| 1567 | if (cname) { |
| 1568 | ctor_qn = cbm_arena_sprintf(ctx->arena, "%s.%s", class_qn, cname); |
| 1569 | } else { |
| 1570 | ctor_qn = cbm_arena_sprintf(ctx->arena, "%s.<init>", class_qn); |
| 1571 | } |
| 1572 | |
| 1573 | const char *saved_method = ctx->enclosing_method_qn; |
| 1574 | const char *saved_class = ctx->enclosing_class_qn; |
| 1575 | const char *saved_super = ctx->enclosing_super_qn; |
| 1576 | CBMScope *saved_scope = ctx->current_scope; |
| 1577 | |
| 1578 | ctx->enclosing_method_qn = ctor_qn; |
| 1579 | ctx->enclosing_class_qn = class_qn; |
| 1580 | ctx->enclosing_super_qn = super_qn; |
| 1581 | ctx->current_scope = cbm_scope_push(ctx->arena, saved_scope); |
| 1582 | |
| 1583 | TSNode params = ts_node_child_by_field_name(node, "parameters", 10); |
| 1584 | if (!ts_node_is_null(params)) { |
| 1585 | uint32_t n = ts_node_named_child_count(params); |
| 1586 | for (uint32_t i = 0; i < n; i++) { |
| 1587 | TSNode p = ts_node_named_child(params, i); |
| 1588 | if (strcmp(ts_node_type(p), "formal_parameter") != 0) |
| 1589 | continue; |
| 1590 | TSNode pname = ts_node_child_by_field_name(p, "name", 4); |
| 1591 | TSNode ptype = ts_node_child_by_field_name(p, "type", 4); |
| 1592 | if (ts_node_is_null(pname)) |
| 1593 | continue; |
| 1594 | char *pn = java_node_text(ctx, pname); |
| 1595 | if (!pn) |
| 1596 | continue; |
| 1597 | const CBMType *pt = |
| 1598 | ts_node_is_null(ptype) ? cbm_type_unknown() : java_parse_type_node(ctx, ptype); |
| 1599 | cbm_scope_bind(ctx->current_scope, pn, pt); |
| 1600 | } |
| 1601 | } |
| 1602 | |
| 1603 | TSNode body = ts_node_child_by_field_name(node, "body", 4); |
| 1604 | if (!ts_node_is_null(body)) |
| 1605 | process_block(ctx, body); |
| 1606 | |
| 1607 | ctx->current_scope = saved_scope; |
| 1608 | ctx->enclosing_method_qn = saved_method; |
| 1609 | ctx->enclosing_class_qn = saved_class; |
| 1610 | ctx->enclosing_super_qn = saved_super; |
| 1611 | } |
| 1612 | |
| 1613 | /* Determine the class's super QN from the AST node. */ |
| 1614 | static const char *class_super_qn(JavaLSPContext *ctx, TSNode class_node) { |
no test coverage detected