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

Function process_node

internal/cbm/lsp/ts_lsp.c:2729–3055  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2727}
2728
2729static void process_node(TSLSPContext *ctx, TSNode node) {
2730 if (!ctx || ts_node_is_null(node))
2731 return;
2732 const char *kind = ts_node_type(node);
2733
2734 // Scope-affecting statements bind first, then we recurse.
2735 ts_process_statement(ctx, node);
2736
2737 if (strcmp(kind, "call_expression") == 0) {
2738 resolve_call_at(ctx, node);
2739
2740 // Contextual callback typing: when an arg is an arrow_function and the
2741 // corresponding param of the called function is itself a FUNC, propagate the
2742 // expected callback param types into the arrow's body before walking it.
2743 // Handle arg processing manually for this path to avoid double-walking via
2744 // default recurse below.
2745 do {
2746 TSNode fn_node =
2747 ts_node_child_by_field_name(node, "function", TS_LSP_FIELD_LEN("function"));
2748 if (ts_node_is_null(fn_node))
2749 break;
2750 const CBMType *fn_type = ts_eval_expr_type(ctx, fn_node);
2751 if (!fn_type || fn_type->kind != CBM_TYPE_FUNC)
2752 break;
2753 if (!fn_type->data.func.param_types)
2754 break;
2755 TSNode args =
2756 ts_node_child_by_field_name(node, "arguments", TS_LSP_FIELD_LEN("arguments"));
2757 if (ts_node_is_null(args))
2758 break;
2759
2760 // Process the function child for nested call resolution.
2761 process_node(ctx, fn_node);
2762
2763 // param_types is NULL-terminated (no count field). Measure its
2764 // length so we never index past the terminator: a call may pass
2765 // more args than the function declares params (e.g. excess/variadic
2766 // args), and the extra args simply have no expected type. Indexing
2767 // param_types[i] by the raw arg count read out of bounds → garbage
2768 // CBMType* → crash on expected->kind.
2769 uint32_t param_count = 0;
2770 while (fn_type->data.func.param_types[param_count])
2771 param_count++;
2772
2773 uint32_t argc = ts_node_named_child_count(args);
2774 for (uint32_t i = 0; i < argc; i++) {
2775 TSNode arg = ts_node_named_child(args, i);
2776 if (ts_node_is_null(arg))
2777 continue;
2778 const char *ak = ts_node_type(arg);
2779 const CBMType *expected =
2780 (i < param_count) ? fn_type->data.func.param_types[i] : NULL;
2781 if ((strcmp(ak, "arrow_function") == 0 || strcmp(ak, "function_expression") == 0) &&
2782 expected && expected->kind == CBM_TYPE_FUNC) {
2783 process_callback_arrow(ctx, arg, expected);
2784 } else {
2785 process_node(ctx, arg);
2786 }

Callers 3

process_callback_arrowFunction · 0.85
process_function_bodyFunction · 0.85
ts_lsp_process_fileFunction · 0.85

Calls 15

ts_process_statementFunction · 0.85
resolve_call_atFunction · 0.85
ts_eval_expr_typeFunction · 0.85
process_callback_arrowFunction · 0.85
resolve_jsx_elementFunction · 0.85
node_textFunction · 0.85
cbm_scope_lookupFunction · 0.85
cbm_registry_lookup_typeFunction · 0.85
cbm_scope_pushFunction · 0.85
cbm_scope_bindFunction · 0.85
extract_narrowingFunction · 0.85

Tested by

no test coverage detected