| 1493 | } |
| 1494 | |
| 1495 | static void process_method_decl(JavaLSPContext *ctx, TSNode node, const char *class_qn, |
| 1496 | const char *super_qn) { |
| 1497 | /* Compute method QN. */ |
| 1498 | TSNode name_node = ts_node_child_by_field_name(node, "name", 4); |
| 1499 | if (ts_node_is_null(name_node)) |
| 1500 | return; |
| 1501 | char *mname = java_node_text(ctx, name_node); |
| 1502 | if (!mname) |
| 1503 | return; |
| 1504 | char *method_qn = cbm_arena_sprintf(ctx->arena, "%s.%s", class_qn, mname); |
| 1505 | |
| 1506 | /* Save context. */ |
| 1507 | const char *saved_method = ctx->enclosing_method_qn; |
| 1508 | const char *saved_class = ctx->enclosing_class_qn; |
| 1509 | const char *saved_super = ctx->enclosing_super_qn; |
| 1510 | CBMScope *saved_scope = ctx->current_scope; |
| 1511 | |
| 1512 | ctx->enclosing_method_qn = method_qn; |
| 1513 | ctx->enclosing_class_qn = class_qn; |
| 1514 | ctx->enclosing_super_qn = super_qn; |
| 1515 | ctx->current_scope = cbm_scope_push(ctx->arena, saved_scope); |
| 1516 | |
| 1517 | /* Bind formal parameters into scope. */ |
| 1518 | TSNode params = ts_node_child_by_field_name(node, "parameters", 10); |
| 1519 | if (!ts_node_is_null(params)) { |
| 1520 | uint32_t n = ts_node_named_child_count(params); |
| 1521 | for (uint32_t i = 0; i < n; i++) { |
| 1522 | TSNode p = ts_node_named_child(params, i); |
| 1523 | const char *pk = ts_node_type(p); |
| 1524 | if (strcmp(pk, "formal_parameter") != 0 && strcmp(pk, "spread_parameter") != 0 && |
| 1525 | strcmp(pk, "receiver_parameter") != 0) { |
| 1526 | continue; |
| 1527 | } |
| 1528 | TSNode pname = ts_node_child_by_field_name(p, "name", 4); |
| 1529 | TSNode ptype = ts_node_child_by_field_name(p, "type", 4); |
| 1530 | if (ts_node_is_null(pname)) |
| 1531 | continue; |
| 1532 | char *pn = java_node_text(ctx, pname); |
| 1533 | if (!pn) |
| 1534 | continue; |
| 1535 | const CBMType *pt = |
| 1536 | ts_node_is_null(ptype) ? cbm_type_unknown() : java_parse_type_node(ctx, ptype); |
| 1537 | if (strcmp(pk, "spread_parameter") == 0 && pt) { |
| 1538 | pt = cbm_type_slice(ctx->arena, pt); |
| 1539 | } |
| 1540 | cbm_scope_bind(ctx->current_scope, pn, pt); |
| 1541 | } |
| 1542 | } |
| 1543 | |
| 1544 | /* Bind `this` (only matters indirectly — `this` is a syntactic node, not |
| 1545 | * an identifier). */ |
| 1546 | |
| 1547 | /* Walk method body. */ |
| 1548 | TSNode body = ts_node_child_by_field_name(node, "body", 4); |
| 1549 | if (!ts_node_is_null(body)) { |
| 1550 | process_block(ctx, body); |
| 1551 | } |
| 1552 |
no test coverage detected