/** * Returns a class which has a static method with the same name as 'method', whose body creates an * new instance of 'specimen' and invokes 'method' upon it via an invokevirtual instruction with * 'args' as function call parameters. * * <p>'returns' is a dummy return value that need only match 'methods' return type (it is only * used in the dummy class when compiling IV). */ private Class invokeVirtualHarness( Class specimen, ConcreteMethod method, String returns, String... args) { Method cm = new ConcreteMethod( method.getReturnType(), method.getName(), "return " + returns + ";", method.getElements()); Class stub = new Class(specimen.getName(), cm); String params = toJoinedString(args, ", "); ConcreteMethod sm = new ConcreteMethod( method.getReturnType(), method.getName(), String.format( "return (new %s()).%s(%s);", specimen.getName(), method.getName(), params), new AccessFlag("public"), new AccessFlag("static")); Class iv = new Class("IV_" + specimen.getName(), sm); iv.addCompilationDependency(stub); iv.addCompilationDependency(cm); return iv; }
/** * Creates a class which calls target::method(args) via invokevirtual, compiles and loads both the * new class and 'target', and then invokes the method. If the returned value does not match * 'value' then a test failure is indicated. */ public void assertInvokeVirtualEquals( Object value, Class target, ConcreteMethod method, String returns, String... args) { Compiler compiler = compilerLocal.get(); compiler.setFlags(compilerFlags()); Class iv = invokeVirtualHarness(target, method, returns, args); ClassLoader loader = compiler.compile(iv, target); assertStaticCallEquals(loader, iv, method.getName(), value); compiler.cleanup(); }
/** * Creates a class which calls target::method(args) via invokevirtual, compiles and loads both the * new class and 'target', and then invokes the method. If an exception of type 'exceptionType' is * not thrown, then a test failure is indicated. */ public void assertThrows( java.lang.Class<?> exceptionType, Class target, ConcreteMethod method, String returns, String... args) { Compiler compiler = compilerLocal.get(); compiler.setFlags(compilerFlags()); Class iv = invokeVirtualHarness(target, method, returns, args); ClassLoader loader = compiler.compile(iv, target); java.lang.Class<?> cls = null; try { cls = java.lang.Class.forName(iv.getName(), true, loader); } catch (ClassNotFoundException e) { } assertNotNull(cls); java.lang.reflect.Method m = null; try { m = cls.getMethod(method.getName()); } catch (NoSuchMethodException e) { } assertNotNull(m); try { m.invoke(null); fail("Exception should have been thrown"); } catch (InvocationTargetException | IllegalAccessException e) { if (verboseLocal.get() == Boolean.TRUE) { System.out.println(e.getCause()); } assertTrue(exceptionType.isAssignableFrom(e.getCause().getClass())); } compiler.cleanup(); }