Heuristic table mapping (receiver kind, method name) → lambda arg shape. * * Used when the registry's CBMRegisteredFunc lacks param-type metadata * (most stdlib registrations are return-only) but the receiver's template * args make the SAM-arg type unambiguous. * * Returns true and fills out_arity + out_param[0..1] when a heuristic * matches. The lambda binder then uses these directly witho
| 2296 | * matches. The lambda binder then uses these directly without going |
| 2297 | * through the SAM-spec table. */ |
| 2298 | static bool method_implies_lambda_args(const char *recv_qn, const char *method_name, |
| 2299 | const CBMType *const *targs, int targ_count, int *out_arity, |
| 2300 | const CBMType **out_param0, const CBMType **out_param1) { |
| 2301 | *out_arity = 0; |
| 2302 | *out_param0 = NULL; |
| 2303 | *out_param1 = NULL; |
| 2304 | if (!recv_qn || !method_name || !targs || targ_count <= 0) |
| 2305 | return false; |
| 2306 | |
| 2307 | /* 1-param lambdas over T0 — Predicate / Consumer / Function shapes. */ |
| 2308 | static const char *one_arg_methods[] = { |
| 2309 | "forEach", "filter", "map", "flatMap", "peek", "removeIf", |
| 2310 | "anyMatch", "allMatch", "noneMatch", "takeWhile", "dropWhile", "ifPresent", |
| 2311 | "ifPresentOrElse", "mapToInt", "mapToLong", "mapToDouble", "filter", NULL, |
| 2312 | }; |
| 2313 | for (int i = 0; one_arg_methods[i]; i++) { |
| 2314 | if (strcmp(method_name, one_arg_methods[i]) == 0) { |
| 2315 | *out_arity = 1; |
| 2316 | *out_param0 = targs[0]; |
| 2317 | return true; |
| 2318 | } |
| 2319 | } |
| 2320 | /* Map<K,V>.forEach takes BiConsumer<K, V> (2 params). */ |
| 2321 | if (is_map_like(recv_qn) && targ_count >= 2) { |
| 2322 | if (strcmp(method_name, "forEach") == 0 || strcmp(method_name, "replaceAll") == 0 || |
| 2323 | strcmp(method_name, "compute") == 0 || strcmp(method_name, "computeIfPresent") == 0 || |
| 2324 | strcmp(method_name, "merge") == 0) { |
| 2325 | *out_arity = 2; |
| 2326 | *out_param0 = targs[0]; |
| 2327 | *out_param1 = targs[1]; |
| 2328 | return true; |
| 2329 | } |
| 2330 | if (strcmp(method_name, "computeIfAbsent") == 0) { |
| 2331 | /* Function<K, V> — 1-arg of K. */ |
| 2332 | *out_arity = 1; |
| 2333 | *out_param0 = targs[0]; |
| 2334 | return true; |
| 2335 | } |
| 2336 | } |
| 2337 | /* Comparator-typed args — keep simple: Comparator<T0>.compare(T0, T0). */ |
| 2338 | if (strcmp(method_name, "sort") == 0 && targ_count >= 1) { |
| 2339 | *out_arity = 2; |
| 2340 | *out_param0 = targs[0]; |
| 2341 | *out_param1 = targs[0]; |
| 2342 | return true; |
| 2343 | } |
| 2344 | return false; |
| 2345 | } |
| 2346 | |
| 2347 | /* When a method on a TEMPLATE receiver returns a NAMED type that is itself |
| 2348 | * a parametric "carrier" (Stream, Iterator, Optional, …), preserve the |
no test coverage detected