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

Function bind_lambda_args

internal/cbm/lsp/java_lsp.c:2415–2634  ·  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

2413 * Returns a bitmask of arg indices that were handled here so the generic
2414 * walker can skip them. */
2415static uint32_t bind_lambda_args(JavaLSPContext *ctx, TSNode call_node,
2416 const CBMRegisteredFunc *resolved, const CBMType *recv_type) {
2417 uint32_t handled_mask = 0;
2418 TSNode args_node = ts_node_child_by_field_name(call_node, "arguments", 9);
2419 if (ts_node_is_null(args_node))
2420 return handled_mask;
2421 const CBMType *const *param_types = NULL;
2422 if (resolved && resolved->signature && resolved->signature->kind == CBM_TYPE_FUNC) {
2423 param_types = resolved->signature->data.func.param_types;
2424 }
2425 /* param_types is NULL-terminated with the DECLARED param count — the call
2426 * site may pass MORE arguments (overload mismatch, varargs). Indexing by
2427 * the raw argument index read past the terminator and dereferenced
2428 * whatever followed in the arena (elasticsearch SIGSEGV; same OOB family
2429 * as #427). Bound every access by the array's own length. */
2430 int param_type_count = 0;
2431 if (param_types) {
2432 while (param_types[param_type_count]) {
2433 param_type_count++;
2434 }
2435 }
2436 /* Even without registry param_types, the heuristic (recv_qn + method_name
2437 * → arg shape) often pins the lambda type — that's the path that
2438 * handles `xs.forEach(x -> ...)` and `xs.stream().filter(x -> ...)`
2439 * given that stdlib registrations don't model arg types. */
2440
2441 /* Gather receiver template args for substitution. */
2442 const CBMType *const *recv_targs = NULL;
2443 int recv_targ_count = 0;
2444 const char *recv_qn = NULL;
2445 if (recv_type && recv_type->kind == CBM_TYPE_TEMPLATE) {
2446 recv_targs = recv_type->data.template_type.template_args;
2447 recv_targ_count = recv_type->data.template_type.arg_count;
2448 recv_qn = recv_type->data.template_type.template_name;
2449 } else if (recv_type && recv_type->kind == CBM_TYPE_NAMED) {
2450 recv_qn = recv_type->data.named.qualified_name;
2451 }
2452
2453 /* Method name (for heuristic). */
2454 TSNode mname_node = ts_node_child_by_field_name(call_node, "name", 4);
2455 char *mname = ts_node_is_null(mname_node) ? NULL : java_node_text(ctx, mname_node);
2456
2457 uint32_t n = ts_node_named_child_count(args_node);
2458 for (uint32_t i = 0; i < n && i < 32; i++) {
2459 TSNode arg = ts_node_named_child(args_node, i);
2460 const char *kind = ts_node_type(arg);
2461 if (strcmp(kind, "lambda_expression") != 0)
2462 continue;
2463
2464 /* First try registry-driven SAM inference. */
2465 const CBMType *expected =
2466 (param_types && i < (uint32_t)param_type_count) ? param_types[i] : NULL;
2467 if (!expected && recv_qn && mname && recv_targ_count > 0) {
2468 /* Heuristic path: bind lambda directly using receiver template
2469 * args + recognized method name, skipping the SAM table. */
2470 int h_arity = 0;
2471 const CBMType *h_p0 = NULL;
2472 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