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

Function process_callback_arrow

internal/cbm/lsp/ts_lsp.c:2406–2495  ·  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

2404// be bound to `arr`'s element type via Array<T>.map's `(x: T) => U` signature). The
2405// caller passes `expected` = the FUNC type the callback must conform to.
2406static void process_callback_arrow(TSLSPContext *ctx, TSNode arrow, const CBMType *expected) {
2407 if (ts_node_is_null(arrow) || !expected || expected->kind != CBM_TYPE_FUNC)
2408 return;
2409
2410 CBMScope *saved = ctx->current_scope;
2411 ctx->current_scope = cbm_scope_push(ctx->arena, saved);
2412
2413 // Tree-sitter typescript shapes for arrow functions:
2414 // `(x, y) => body` → parameters: formal_parameters
2415 // `x => body` → parameter: identifier (singular field)
2416 TSNode params =
2417 ts_node_child_by_field_name(arrow, "parameters", TS_LSP_FIELD_LEN("parameters"));
2418 TSNode bare_param =
2419 ts_node_child_by_field_name(arrow, "parameter", TS_LSP_FIELD_LEN("parameter"));
2420 int idx = 0;
2421 if (!ts_node_is_null(bare_param)) {
2422 // Single bare param: `x => ...`.
2423 const char *pk = ts_node_type(bare_param);
2424 if (strcmp(pk, "identifier") == 0) {
2425 char *nm = node_text(ctx, bare_param);
2426 const CBMType *pt =
2427 (expected->data.func.param_types && expected->data.func.param_types[0])
2428 ? expected->data.func.param_types[0]
2429 : cbm_type_unknown();
2430 if (nm)
2431 cbm_scope_bind(ctx->current_scope, nm, pt);
2432 }
2433 } else if (!ts_node_is_null(params)) {
2434 uint32_t pc = ts_node_named_child_count(params);
2435 for (uint32_t i = 0; i < pc; i++) {
2436 TSNode p = ts_node_named_child(params, i);
2437 if (ts_node_is_null(p))
2438 continue;
2439 const char *pk = ts_node_type(p);
2440 const char *pname = NULL;
2441 const CBMType *expected_pt =
2442 (expected->data.func.param_types && expected->data.func.param_types[idx])
2443 ? expected->data.func.param_types[idx]
2444 : NULL;
2445
2446 if (strcmp(pk, "identifier") == 0) {
2447 pname = node_text(ctx, p);
2448 } else {
2449 // required_parameter / optional_parameter — extract pattern.
2450 TSNode pp = ts_node_child_by_field_name(p, "pattern", TS_LSP_FIELD_LEN("pattern"));
2451 if (ts_node_is_null(pp)) {
2452 pp = ts_node_child_by_field_name(p, "name", TS_LSP_FIELD_LEN("name"));
2453 }
2454 if (!ts_node_is_null(pp) && strcmp(ts_node_type(pp), "identifier") == 0) {
2455 pname = node_text(ctx, pp);
2456 }
2457 // If the param has its own annotation, use that. Otherwise use expected.
2458 TSNode tann = ts_node_child_by_field_name(p, "type", TS_LSP_FIELD_LEN("type"));
2459 if (!ts_node_is_null(tann)) {
2460 TSNode tch = (strcmp(ts_node_type(tann), "type_annotation") == 0)
2461 ? ts_node_named_child(tann, 0)
2462 : tann;
2463 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