/** Invokes a given method via {@link Method#invoke(Object, Object...)}. */ default Object invoke(ResolvedJavaMethod method, Object receiver, Object... args) { try { JavaType[] parameterTypes = method.toParameterTypes(); Class<?>[] parameterClasses = new Class<?>[parameterTypes.length]; for (int i = 0; i < parameterClasses.length; ++i) { JavaType type = parameterTypes[i]; if (type.getJavaKind() != JavaKind.Object) { parameterClasses[i] = type.getJavaKind().toJavaClass(); } else { parameterClasses[i] = resolveClassForSnippet(parameterTypes[i]); } } Class<?> c = resolveClassForSnippet(method.getDeclaringClass()); if (method.isConstructor()) { Constructor<?> javaConstructor = c.getDeclaredConstructor(parameterClasses); javaConstructor.setAccessible(true); return javaConstructor.newInstance(args); } else { Method javaMethod = c.getDeclaredMethod(method.getName(), parameterClasses); javaMethod.setAccessible(true); return javaMethod.invoke(receiver, args); } } catch (IllegalAccessException | InstantiationException | InvocationTargetException | ClassNotFoundException | NoSuchMethodException ex) { throw new IllegalArgumentException(ex); } }
@Override public Bytecode getBytecode(ResolvedJavaMethod method) { Classfile classfile = getClassfile(resolveToClass(method.getDeclaringClass().getName())); return classfile.getCode(method.getName(), method.getSignature().toMethodDescriptor()); }