@Override public Object coerceArgument(Object argument) { if (argument instanceof Closure) { Class clazz = getTheClass(); return coerceToSAM((Closure) argument, method, clazz); } else { return argument; } }
private static void getAbstractMethods(Class c, List<Method> current) { if (c==null || !Modifier.isAbstract(c.getModifiers())) return; getAbstractMethods(c.getSuperclass(), current); for (Class ci : c.getInterfaces()) { getAbstractMethods(ci, current); } for (Method m : getDeclaredMethods(c)) { if (Modifier.isPrivate(m.getModifiers())) continue; if (Modifier.isAbstract(m.getModifiers())) current.add(m); } }
private static boolean isSAM(Class<?> c) { return CachedSAMClass.getSAMMethod(c) !=null; }
getAbstractMethods(c, methods); if (methods.isEmpty()) return null; ListIterator<Method> it = methods.listIterator(); while (it.hasNext()) { Method m = it.next(); if (hasUsableImplementation(c, m)) it.remove(); return getSingleNonDuplicateMethod(methods);
private static Object continueCastOnSAM(Object object, Class type) { if (object instanceof Closure) { Method m = CachedSAMClass.getSAMMethod(type); if (m != null) { return CachedSAMClass.coerceToSAM((Closure) object, m, type);
/** * returns the abstract method from a SAM type, if it is a SAM type. * @param c the SAM class * @return null if nothing was found, the method otherwise */ public static Method getSAMMethod(Class<?> c) { try { return getSAMMethodImpl(c); } catch (NoClassDefFoundError ignore) { return null; } }
public static Object coerceToSAM(Closure argument, Method method, Class clazz) { return coerceToSAM(argument, method, clazz, clazz.isInterface()); }
private static boolean hasUsableImplementation(Class c, Method m) { if (c==m.getDeclaringClass()) return false; Method found; try { found = c.getMethod(m.getName(), m.getParameterTypes()); int asp = found.getModifiers() & ABSTRACT_STATIC_PRIVATE; int visible = found.getModifiers() & VISIBILITY; if (visible !=0 && asp == 0) return true; } catch (NoSuchMethodException e) {/*ignore*/} if (c==Object.class) return false; return hasUsableImplementation(c.getSuperclass(), m); }
@Override public boolean isAssignableFrom(Class argument) { return argument == null || Closure.class.isAssignableFrom(argument) || ReflectionCache.isAssignableFrom(getTheClass(), argument); }
cachedClass = new CachedClosureClass (klazz, classInfo); } else if (isSAM(klazz)) { cachedClass = new CachedSAMClass(klazz, classInfo); } else { cachedClass = new CachedClass(klazz, classInfo);
private void handleSAM() { if (handle!=null) return; if (!(args[0] instanceof Closure)) return; Method m = CachedSAMClass.getSAMMethod(staticTargetType); if (m==null) return; //TODO: optimize: add guard based on type Closure handle = MethodHandles.insertArguments(SAM_CONVERSION, 1, m, staticTargetType); }
public CachedSAMClass(Class klazz, ClassInfo classInfo) { super(klazz, classInfo); method = getSAMMethod(klazz); if (method==null) throw new GroovyBugError("assigned method should not have been null!"); }
if (clazz.isInterface() && !(clazz.isInstance(cl))) { if (Traits.isTrait(clazz)) { Method samMethod = CachedSAMClass.getSAMMethod(clazz); if (samMethod!=null) { Map impl = Collections.singletonMap(samMethod.getName(),cl);
Method method = CachedSAMClass.getSAMMethod(parameter); if (method == null) return null;