(Class<?> cls, String name, int argCount)
| 834 | // --------- helpers --------- |
| 835 | |
| 836 | private static Method findMethod(Class<?> cls, String name, int argCount) { |
| 837 | // Search child-first (normal Java resolution order) but collect candidates. |
| 838 | // Prefer varargs methods over non-varargs when both match — varargs methods |
| 839 | // are the untyped transpiled methods (Object... params, CompletableFuture returns) |
| 840 | // while non-varargs are typed overloads (String/Long/Map params, sync returns) |
| 841 | // that don't work with callDynamically's Object[] args. |
| 842 | Method nonVarArgsMatch = null; |
| 843 | |
| 844 | Class<?> cur = cls; |
| 845 | while (cur != null) { |
| 846 | for (Method m : cur.getDeclaredMethods()) { |
| 847 | if (!m.getName().equals(name)) continue; |
| 848 | |
| 849 | // Varargs method that can accept this arg count: return immediately |
| 850 | if (m.isVarArgs() && argCount >= m.getParameterCount() - 1) { |
| 851 | return m; |
| 852 | } |
| 853 | |
| 854 | // Exact arg count match: save as fallback (typed overload) |
| 855 | if (m.getParameterCount() == argCount && nonVarArgsMatch == null) { |
| 856 | nonVarArgsMatch = m; |
| 857 | } |
| 858 | } |
| 859 | cur = cur.getSuperclass(); |
| 860 | } |
| 861 | |
| 862 | if (nonVarArgsMatch != null) return nonVarArgsMatch; |
| 863 | |
| 864 | // last resort: first by name |
| 865 | for (Method m : cls.getMethods()) { |
| 866 | if (m.getName().equals(name)) return m; |
| 867 | } |
| 868 | throw new RuntimeException("Method not found: " + name + " with " + argCount + " args on " + cls.getName()); |
| 869 | } |
| 870 | |
| 871 | private static Long toLong(Object o) { |
| 872 | if (o instanceof Long) return (Long) o; |
no test coverage detected