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

Function process_node

internal/cbm/lsp/ts_lsp.c:3268–3632  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

3266}
3267
3268static void process_node(TSLSPContext *ctx, TSNode node) {
3269 if (!ctx || ts_node_is_null(node))
3270 return;
3271 const char *kind = ts_node_type(node);
3272
3273 /* A nested statement block owns `let`/`const` declarations. Function-body
3274 * blocks are intentionally unwrapped by process_function_body(), so this
3275 * branch applies only to nested lexical blocks and cannot hide parameters. */
3276 if (strcmp(kind, "statement_block") == 0) {
3277 CBMScope *saved = ctx->current_scope;
3278 ctx->current_scope = cbm_scope_push(ctx->arena, saved);
3279 TSTreeCursor cursor = ts_tree_cursor_new(node);
3280 if (ts_tree_cursor_goto_first_child(&cursor)) {
3281 do {
3282 process_node(ctx, ts_tree_cursor_current_node(&cursor));
3283 } while (ts_tree_cursor_goto_next_sibling(&cursor));
3284 }
3285 ts_tree_cursor_delete(&cursor);
3286 ctx->current_scope = saved;
3287 return;
3288 }
3289
3290 // Scope-affecting statements bind first, then we recurse.
3291 ts_process_statement(ctx, node);
3292
3293 if (strcmp(kind, "call_expression") == 0) {
3294 resolve_call_at(ctx, node);
3295 resolve_value_references_at(ctx, node);
3296
3297 // Contextual callback typing: when an arg is an arrow_function and the
3298 // corresponding param of the called function is itself a FUNC, propagate the
3299 // expected callback param types into the arrow's body before walking it.
3300 // Handle arg processing manually for this path to avoid double-walking via
3301 // default recurse below.
3302 do {
3303 TSNode fn_node =
3304 ts_node_child_by_field_name(node, "function", TS_LSP_FIELD_LEN("function"));
3305 if (ts_node_is_null(fn_node))
3306 break;
3307 TSNode args =
3308 ts_node_child_by_field_name(node, "arguments", TS_LSP_FIELD_LEN("arguments"));
3309 if (ts_node_is_null(args))
3310 break;
3311 const CBMType *fn_type = ts_signature_for_call(ctx, fn_node, args);
3312 if (!fn_type || fn_type->kind != CBM_TYPE_FUNC)
3313 break;
3314 if (!fn_type->data.func.param_types)
3315 break;
3316
3317 // Process the function child for nested call resolution.
3318 process_node(ctx, fn_node);
3319
3320 // param_types is NULL-terminated (no count field). Measure its
3321 // length so we never index past the terminator: a call may pass
3322 // more args than the function declares params (e.g. excess/variadic
3323 // args), and the extra args simply have no expected type. Indexing
3324 // param_types[i] by the raw arg count read out of bounds → garbage
3325 // 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