}
}
MetaClass metaclass = InvokerHelper.getMetaClass(self);
MetaMethod mm = metaclass.pickMethod(name, types);
// try some simple transformations
// transform a trailing closure to a function
if (mm == null && objects.length > 0) {
Object lastArg = objects[objects.length - 1];
if (lastArg instanceof Closure) {
Class<?>[] at2 = Arrays.copyOf(types, types.length);
at2[objects.length - 1] = Function.class;
mm = metaclass.pickMethod(name, at2);
if (mm != null) {
objects[objects.length - 1] = new ClosureFunction((Closure) lastArg);
}
}
}
// try instantiating a single class
if (mm == null && objects.length == 1 && objects[0] instanceof Class) {
final Class<?> cls = (Class) objects[0];
Class[] at2 = {cls};
final MetaMethod method = metaclass.pickMethod(name, at2);
if (method != null) {
try {
final Constructor ctor = cls.getConstructor();
return new Supplier<Object>() {
@Override
public Object get() {
Object[] objs;
try {
objs = new Object[]{ctor.newInstance()};
} catch (InstantiationException e) {
throw new RuntimeException("cannot instantiate " + cls, e);
} catch (IllegalAccessException e) {
throw new RuntimeException("cannot instantiate " + cls, e);
} catch (InvocationTargetException e) {
throw new RuntimeException("cannot instantiate " + cls, e);
}
return method.doMethodInvoke(self, objs);
}
};
} catch (NoSuchMethodException e) {
/* no constructor avaialble, ignore */
}
}
}
if (mm == null) {
return null;
} else {
final MetaMethod method = mm;
final Object[] finalArgs = objects;
return new Supplier<Object>() {
@Override
public Object get() {
return method.doMethodInvoke(self, finalArgs);
}
};
}
}