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

Function bind_lambda_args

internal/cbm/lsp/java_lsp.c:2350–2569  ·  view source on GitHub ↗

Given a method-invocation node and its resolved CBMRegisteredFunc, walk * each lambda argument: bind its formal_parameters to the SAM's parameter * types (with generic substitution from the receiver's template args), then * resolve calls inside the lambda body against the freshly-bound scope. * * Returns a bitmask of arg indices that were handled here so the generic * walker can skip them. *

Source from the content-addressed store, hash-verified

2348 * Returns a bitmask of arg indices that were handled here so the generic
2349 * walker can skip them. */
2350static uint32_t bind_lambda_args(JavaLSPContext *ctx, TSNode call_node,
2351 const CBMRegisteredFunc *resolved, const CBMType *recv_type) {
2352 uint32_t handled_mask = 0;
2353 TSNode args_node = ts_node_child_by_field_name(call_node, "arguments", 9);
2354 if (ts_node_is_null(args_node))
2355 return handled_mask;
2356 const CBMType *const *param_types = NULL;
2357 if (resolved && resolved->signature && resolved->signature->kind == CBM_TYPE_FUNC) {
2358 param_types = resolved->signature->data.func.param_types;
2359 }
2360 /* param_types is NULL-terminated with the DECLARED param count — the call
2361 * site may pass MORE arguments (overload mismatch, varargs). Indexing by
2362 * the raw argument index read past the terminator and dereferenced
2363 * whatever followed in the arena (elasticsearch SIGSEGV; same OOB family
2364 * as #427). Bound every access by the array's own length. */
2365 int param_type_count = 0;
2366 if (param_types) {
2367 while (param_types[param_type_count]) {
2368 param_type_count++;
2369 }
2370 }
2371 /* Even without registry param_types, the heuristic (recv_qn + method_name
2372 * → arg shape) often pins the lambda type — that's the path that
2373 * handles `xs.forEach(x -> ...)` and `xs.stream().filter(x -> ...)`
2374 * given that stdlib registrations don't model arg types. */
2375
2376 /* Gather receiver template args for substitution. */
2377 const CBMType *const *recv_targs = NULL;
2378 int recv_targ_count = 0;
2379 const char *recv_qn = NULL;
2380 if (recv_type && recv_type->kind == CBM_TYPE_TEMPLATE) {
2381 recv_targs = recv_type->data.template_type.template_args;
2382 recv_targ_count = recv_type->data.template_type.arg_count;
2383 recv_qn = recv_type->data.template_type.template_name;
2384 } else if (recv_type && recv_type->kind == CBM_TYPE_NAMED) {
2385 recv_qn = recv_type->data.named.qualified_name;
2386 }
2387
2388 /* Method name (for heuristic). */
2389 TSNode mname_node = ts_node_child_by_field_name(call_node, "name", 4);
2390 char *mname = ts_node_is_null(mname_node) ? NULL : java_node_text(ctx, mname_node);
2391
2392 uint32_t n = ts_node_named_child_count(args_node);
2393 for (uint32_t i = 0; i < n && i < 32; i++) {
2394 TSNode arg = ts_node_named_child(args_node, i);
2395 const char *kind = ts_node_type(arg);
2396 if (strcmp(kind, "lambda_expression") != 0)
2397 continue;
2398
2399 /* First try registry-driven SAM inference. */
2400 const CBMType *expected =
2401 (param_types && i < (uint32_t)param_type_count) ? param_types[i] : NULL;
2402 if (!expected && recv_qn && mname && recv_targ_count > 0) {
2403 /* Heuristic path: bind lambda directly using receiver template
2404 * args + recognized method name, skipping the SAM table. */
2405 int h_arity = 0;
2406 const CBMType *h_p0 = NULL;
2407 const CBMType *h_p1 = NULL;

Callers 1

Calls 9

java_node_textFunction · 0.85
cbm_scope_pushFunction · 0.85
cbm_scope_bindFunction · 0.85
java_parse_type_nodeFunction · 0.85
cbm_type_unknownFunction · 0.85
find_samFunction · 0.85
sam_param_typeFunction · 0.85

Tested by

no test coverage detected