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
| 2231 | * matches. The lambda binder then uses these directly without going |
| 2232 | * through the SAM-spec table. */ |
| 2233 | static bool method_implies_lambda_args(const char *recv_qn, const char *method_name, |
| 2234 | const CBMType *const *targs, int targ_count, int *out_arity, |
| 2235 | const CBMType **out_param0, const CBMType **out_param1) { |
| 2236 | *out_arity = 0; |
| 2237 | *out_param0 = NULL; |
| 2238 | *out_param1 = NULL; |
| 2239 | if (!recv_qn || !method_name || !targs || targ_count <= 0) |
| 2240 | return false; |
| 2241 | |
| 2242 | /* 1-param lambdas over T0 — Predicate / Consumer / Function shapes. */ |
| 2243 | static const char *one_arg_methods[] = { |
| 2244 | "forEach", "filter", "map", "flatMap", "peek", "removeIf", |
| 2245 | "anyMatch", "allMatch", "noneMatch", "takeWhile", "dropWhile", "ifPresent", |
| 2246 | "ifPresentOrElse", "mapToInt", "mapToLong", "mapToDouble", "filter", NULL, |
| 2247 | }; |
| 2248 | for (int i = 0; one_arg_methods[i]; i++) { |
| 2249 | if (strcmp(method_name, one_arg_methods[i]) == 0) { |
| 2250 | *out_arity = 1; |
| 2251 | *out_param0 = targs[0]; |
| 2252 | return true; |
| 2253 | } |
| 2254 | } |
| 2255 | /* Map<K,V>.forEach takes BiConsumer<K, V> (2 params). */ |
| 2256 | if (is_map_like(recv_qn) && targ_count >= 2) { |
| 2257 | if (strcmp(method_name, "forEach") == 0 || strcmp(method_name, "replaceAll") == 0 || |
| 2258 | strcmp(method_name, "compute") == 0 || strcmp(method_name, "computeIfPresent") == 0 || |
| 2259 | strcmp(method_name, "merge") == 0) { |
| 2260 | *out_arity = 2; |
| 2261 | *out_param0 = targs[0]; |
| 2262 | *out_param1 = targs[1]; |
| 2263 | return true; |
| 2264 | } |
| 2265 | if (strcmp(method_name, "computeIfAbsent") == 0) { |
| 2266 | /* Function<K, V> — 1-arg of K. */ |
| 2267 | *out_arity = 1; |
| 2268 | *out_param0 = targs[0]; |
| 2269 | return true; |
| 2270 | } |
| 2271 | } |
| 2272 | /* Comparator-typed args — keep simple: Comparator<T0>.compare(T0, T0). */ |
| 2273 | if (strcmp(method_name, "sort") == 0 && targ_count >= 1) { |
| 2274 | *out_arity = 2; |
| 2275 | *out_param0 = targs[0]; |
| 2276 | *out_param1 = targs[0]; |
| 2277 | return true; |
| 2278 | } |
| 2279 | return false; |
| 2280 | } |
| 2281 | |
| 2282 | /* When a method on a TEMPLATE receiver returns a NAMED type that is itself |
| 2283 | * a parametric "carrier" (Stream, Iterator, Optional, …), preserve the |
no test coverage detected