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

Function process_node

internal/cbm/lsp/ts_lsp.c:3128–3492  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

3126}
3127
3128static void process_node(TSLSPContext *ctx, TSNode node) {
3129 if (!ctx || ts_node_is_null(node))
3130 return;
3131 const char *kind = ts_node_type(node);
3132
3133 /* A nested statement block owns `let`/`const` declarations. Function-body
3134 * blocks are intentionally unwrapped by process_function_body(), so this
3135 * branch applies only to nested lexical blocks and cannot hide parameters. */
3136 if (strcmp(kind, "statement_block") == 0) {
3137 CBMScope *saved = ctx->current_scope;
3138 ctx->current_scope = cbm_scope_push(ctx->arena, saved);
3139 TSTreeCursor cursor = ts_tree_cursor_new(node);
3140 if (ts_tree_cursor_goto_first_child(&cursor)) {
3141 do {
3142 process_node(ctx, ts_tree_cursor_current_node(&cursor));
3143 } while (ts_tree_cursor_goto_next_sibling(&cursor));
3144 }
3145 ts_tree_cursor_delete(&cursor);
3146 ctx->current_scope = saved;
3147 return;
3148 }
3149
3150 // Scope-affecting statements bind first, then we recurse.
3151 ts_process_statement(ctx, node);
3152
3153 if (strcmp(kind, "call_expression") == 0) {
3154 resolve_call_at(ctx, node);
3155 resolve_value_references_at(ctx, node);
3156
3157 // Contextual callback typing: when an arg is an arrow_function and the
3158 // corresponding param of the called function is itself a FUNC, propagate the
3159 // expected callback param types into the arrow's body before walking it.
3160 // Handle arg processing manually for this path to avoid double-walking via
3161 // default recurse below.
3162 do {
3163 TSNode fn_node =
3164 ts_node_child_by_field_name(node, "function", TS_LSP_FIELD_LEN("function"));
3165 if (ts_node_is_null(fn_node))
3166 break;
3167 TSNode args =
3168 ts_node_child_by_field_name(node, "arguments", TS_LSP_FIELD_LEN("arguments"));
3169 if (ts_node_is_null(args))
3170 break;
3171 const CBMType *fn_type = ts_signature_for_call(ctx, fn_node, args);
3172 if (!fn_type || fn_type->kind != CBM_TYPE_FUNC)
3173 break;
3174 if (!fn_type->data.func.param_types)
3175 break;
3176
3177 // Process the function child for nested call resolution.
3178 process_node(ctx, fn_node);
3179
3180 // param_types is NULL-terminated (no count field). Measure its
3181 // length so we never index past the terminator: a call may pass
3182 // more args than the function declares params (e.g. excess/variadic
3183 // args), and the extra args simply have no expected type. Indexing
3184 // param_types[i] by the raw arg count read out of bounds → garbage
3185 // CBMType* → crash on expected->kind.

Callers 4

process_callback_arrowFunction · 0.85
process_namespace_memberFunction · 0.85
process_function_bodyFunction · 0.85
ts_lsp_process_fileFunction · 0.85

Calls 15

cbm_scope_pushFunction · 0.85
ts_process_statementFunction · 0.85
resolve_call_atFunction · 0.85
ts_signature_for_callFunction · 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_bindFunction · 0.85
extract_narrowingFunction · 0.85

Tested by

no test coverage detected