MCPcopy Create free account
hub / github.com/DeusData/codebase-memory-mcp / process_callback_arrow

Function process_callback_arrow

internal/cbm/lsp/ts_lsp.c:2756–2845  ·  view source on GitHub ↗

Process an arrow_function or function_expression as a callback whose param types are contextually typed by the enclosing call (e.g. `arr.map(x => x.length)` — `x` should be bound to `arr`'s element type via Array .map's `(x: T) => U` signature). The caller passes `expected` = the FUNC type the callback must conform to.

Source from the content-addressed store, hash-verified

2754// be bound to `arr`'s element type via Array<T>.map's `(x: T) => U` signature). The
2755// caller passes `expected` = the FUNC type the callback must conform to.
2756static void process_callback_arrow(TSLSPContext *ctx, TSNode arrow, const CBMType *expected) {
2757 if (ts_node_is_null(arrow) || !expected || expected->kind != CBM_TYPE_FUNC)
2758 return;
2759
2760 CBMScope *saved = ctx->current_scope;
2761 ctx->current_scope = cbm_scope_push(ctx->arena, saved);
2762
2763 // Tree-sitter typescript shapes for arrow functions:
2764 // `(x, y) => body` → parameters: formal_parameters
2765 // `x => body` → parameter: identifier (singular field)
2766 TSNode params =
2767 ts_node_child_by_field_name(arrow, "parameters", TS_LSP_FIELD_LEN("parameters"));
2768 TSNode bare_param =
2769 ts_node_child_by_field_name(arrow, "parameter", TS_LSP_FIELD_LEN("parameter"));
2770 int idx = 0;
2771 if (!ts_node_is_null(bare_param)) {
2772 // Single bare param: `x => ...`.
2773 const char *pk = ts_node_type(bare_param);
2774 if (strcmp(pk, "identifier") == 0) {
2775 char *nm = node_text(ctx, bare_param);
2776 const CBMType *pt =
2777 (expected->data.func.param_types && expected->data.func.param_types[0])
2778 ? expected->data.func.param_types[0]
2779 : cbm_type_unknown();
2780 if (nm)
2781 cbm_scope_bind(ctx->current_scope, nm, pt);
2782 }
2783 } else if (!ts_node_is_null(params)) {
2784 uint32_t pc = ts_node_named_child_count(params);
2785 for (uint32_t i = 0; i < pc; i++) {
2786 TSNode p = ts_node_named_child(params, i);
2787 if (ts_node_is_null(p))
2788 continue;
2789 const char *pk = ts_node_type(p);
2790 const char *pname = NULL;
2791 const CBMType *expected_pt =
2792 (expected->data.func.param_types && expected->data.func.param_types[idx])
2793 ? expected->data.func.param_types[idx]
2794 : NULL;
2795
2796 if (strcmp(pk, "identifier") == 0) {
2797 pname = node_text(ctx, p);
2798 } else {
2799 // required_parameter / optional_parameter — extract pattern.
2800 TSNode pp = ts_node_child_by_field_name(p, "pattern", TS_LSP_FIELD_LEN("pattern"));
2801 if (ts_node_is_null(pp)) {
2802 pp = ts_node_child_by_field_name(p, "name", TS_LSP_FIELD_LEN("name"));
2803 }
2804 if (!ts_node_is_null(pp) && strcmp(ts_node_type(pp), "identifier") == 0) {
2805 pname = node_text(ctx, pp);
2806 }
2807 // If the param has its own annotation, use that. Otherwise use expected.
2808 TSNode tann = ts_node_child_by_field_name(p, "type", TS_LSP_FIELD_LEN("type"));
2809 if (!ts_node_is_null(tann)) {
2810 TSNode tch = (strcmp(ts_node_type(tann), "type_annotation") == 0)
2811 ? ts_node_named_child(tann, 0)
2812 : tann;
2813 if (!ts_node_is_null(tch)) {

Callers 1

process_nodeFunction · 0.85

Calls 7

cbm_scope_pushFunction · 0.85
node_textFunction · 0.85
cbm_type_unknownFunction · 0.85
cbm_scope_bindFunction · 0.85
ts_parse_type_nodeFunction · 0.85
cbm_type_is_unknownFunction · 0.85
process_nodeFunction · 0.85

Tested by

no test coverage detected