Push a single method definition
| 4645 | |
| 4646 | // Push a single method definition |
| 4647 | static void push_method_def(CBMExtractCtx *ctx, TSNode child, TSNode class_node, |
| 4648 | const char *class_qn, const CBMLangSpec *spec, TSNode name_node) { |
| 4649 | CBMArena *a = ctx->arena; |
| 4650 | |
| 4651 | char *name = cbm_func_name_node_text(a, name_node, ctx->source, ctx->language); |
| 4652 | if (!name || !name[0]) { |
| 4653 | return; |
| 4654 | } |
| 4655 | |
| 4656 | const char *method_qn = cbm_arena_sprintf(a, "%s.%s", class_qn, name); |
| 4657 | |
| 4658 | CBMDefinition def; |
| 4659 | memset(&def, 0, sizeof(def)); |
| 4660 | def.name = name; |
| 4661 | def.qualified_name = method_qn; |
| 4662 | def.label = "Method"; |
| 4663 | def.file_path = ctx->rel_path; |
| 4664 | def.parent_class = class_qn; |
| 4665 | def.start_line = ts_node_start_point(child).row + TS_LINE_OFFSET; |
| 4666 | def.end_line = ts_node_end_point(child).row + TS_LINE_OFFSET; |
| 4667 | def.lines = (int)(def.end_line - def.start_line + TS_LINE_OFFSET); |
| 4668 | def.is_exported = cbm_is_exported(name, ctx->language); |
| 4669 | if (ctx->language == CBM_LANG_RUST && |
| 4670 | strcmp(ts_node_type(child), "function_signature_item") == 0) { |
| 4671 | def.is_abstract = true; |
| 4672 | } |
| 4673 | |
| 4674 | TSNode params = find_function_params(child, ctx->language); |
| 4675 | if (!ts_node_is_null(params)) { |
| 4676 | def.signature = cbm_node_text(a, params, ctx->source); |
| 4677 | def.param_types = extract_param_types(a, params, ctx->source, ctx->language); |
| 4678 | def.signature_param_types = extract_signature_param_types( |
| 4679 | a, params, ctx->source, ctx->language, true, &def.signature_param_count); |
| 4680 | } |
| 4681 | |
| 4682 | // Return type (same fields as extract_func_def) |
| 4683 | { |
| 4684 | static const char *rt_fields[] = {"result", "return_type", "type", NULL}; |
| 4685 | for (const char **f = rt_fields; *f; f++) { |
| 4686 | TSNode rt = ts_node_child_by_field_name(child, *f, (uint32_t)strlen(*f)); |
| 4687 | if (!ts_node_is_null(rt)) { |
| 4688 | def.return_type = cbm_node_text(a, rt, ctx->source); |
| 4689 | break; |
| 4690 | } |
| 4691 | } |
| 4692 | } |
| 4693 | |
| 4694 | // ObjectScript: return type is method_definition -> return_type -> typename. |
| 4695 | if (!def.return_type && (ctx->language == CBM_LANG_OBJECTSCRIPT_UDL || |
| 4696 | ctx->language == CBM_LANG_OBJECTSCRIPT_ROUTINE)) { |
| 4697 | TSNode mdef = cbm_find_child_by_kind(child, "method_definition"); |
| 4698 | if (ts_node_is_null(mdef)) { |
| 4699 | mdef = child; |
| 4700 | } |
| 4701 | TSNode rt_node = cbm_find_child_by_kind(mdef, "return_type"); |
| 4702 | if (!ts_node_is_null(rt_node)) { |
| 4703 | TSNode tname = cbm_find_child_by_kind(rt_node, "typename"); |
| 4704 | if (!ts_node_is_null(tname)) { |
no test coverage detected