8255449: Improve the exception message of MethodHandles::permuteArguments

Reviewed-by: chegar, mchung
This commit is contained in:
Jorn Vernee 2020-10-29 18:32:48 +00:00
parent 2a50c3f810
commit 2a2fa134c3
2 changed files with 75 additions and 16 deletions
src/java.base/share/classes/java/lang/invoke
test/jdk/java/lang/invoke

@ -4739,23 +4739,24 @@ assert((int)twice.invokeExact(21) == 42);
if (newType.returnType() != oldType.returnType())
throw newIllegalArgumentException("return types do not match",
oldType, newType);
if (reorder.length == oldType.parameterCount()) {
int limit = newType.parameterCount();
boolean bad = false;
for (int j = 0; j < reorder.length; j++) {
int i = reorder[j];
if (i < 0 || i >= limit) {
bad = true; break;
}
Class<?> src = newType.parameterType(i);
Class<?> dst = oldType.parameterType(j);
if (src != dst)
throw newIllegalArgumentException("parameter types do not match after reorder",
oldType, newType);
if (reorder.length != oldType.parameterCount())
throw newIllegalArgumentException("old type parameter count and reorder array length do not match",
oldType, Arrays.toString(reorder));
int limit = newType.parameterCount();
for (int j = 0; j < reorder.length; j++) {
int i = reorder[j];
if (i < 0 || i >= limit) {
throw newIllegalArgumentException("index is out of bounds for new type",
i, newType);
}
if (!bad) return true;
Class<?> src = newType.parameterType(i);
Class<?> dst = oldType.parameterType(j);
if (src != dst)
throw newIllegalArgumentException("parameter types do not match after reorder",
oldType, newType);
}
throw newIllegalArgumentException("bad reorder array: "+Arrays.toString(reorder));
return true;
}
/**

@ -44,7 +44,7 @@ import java.util.Arrays;
import static org.junit.Assert.*;
public class MethodHandlesPermuteArgumentsTest extends MethodHandlesTest {
public class MethodHandlesPermuteArgumentsTest extends test.java.lang.invoke.MethodHandlesTest {
@Test // SLOW
public void testPermuteArguments() throws Throwable {
@ -58,6 +58,11 @@ public class MethodHandlesPermuteArgumentsTest extends MethodHandlesTest {
if (CAN_TEST_LIGHTLY) return;
testPermuteArguments(4, Integer.class, 2, String.class, 0);
testPermuteArguments(6, Integer.class, 0, null, 30);
testBadReorderArrayLength();
testBadReorderIndex();
testReturnTypeMismatch();
testReorderTypeMismatch();
}
public void testPermuteArguments(int max, Class<?> type1, int t2c, Class<?> type2, int dilution) throws Throwable {
@ -191,4 +196,57 @@ public class MethodHandlesPermuteArgumentsTest extends MethodHandlesTest {
}
assertEquals(expected, result);
}
public void testBadReorderArrayLength() throws Throwable {
MethodHandle mh = MethodHandles.empty(MethodType.methodType(void.class, int.class, int.class, String.class));
MethodType newType = MethodType.methodType(void.class, int.class, String.class);
assertThrows(() -> MethodHandles.permuteArguments(mh, newType, 0, 1),
IllegalArgumentException.class, ".*old type parameter count and reorder array length do not match.*");
}
public void testBadReorderIndex() throws Throwable {
MethodHandle mh = MethodHandles.empty(MethodType.methodType(void.class, int.class, int.class, String.class));
MethodType newType = MethodType.methodType(void.class, int.class, String.class);
assertThrows(() -> MethodHandles.permuteArguments(mh, newType, 0, 0, 2),
IllegalArgumentException.class, ".*index is out of bounds for new type.*");
assertThrows(() -> MethodHandles.permuteArguments(mh, newType, 0, 0, -1),
IllegalArgumentException.class, ".*index is out of bounds for new type.*");
}
public void testReturnTypeMismatch() throws Throwable {
MethodHandle mh = MethodHandles.empty(MethodType.methodType(void.class, int.class, int.class, String.class));
MethodType newType = MethodType.methodType(int.class, int.class, String.class);
assertThrows(() -> MethodHandles.permuteArguments(mh, newType, 0, 0, 1),
IllegalArgumentException.class, ".*return types do not match.*");
}
public void testReorderTypeMismatch() throws Throwable {
MethodHandle mh = MethodHandles.empty(MethodType.methodType(void.class, int.class, int.class, String.class));
MethodType newType = MethodType.methodType(void.class, double.class, String.class);
assertThrows(() -> MethodHandles.permuteArguments(mh, newType, 0, 0, 1),
IllegalArgumentException.class, ".*parameter types do not match after reorder.*");
}
private interface RunnableX {
void run() throws Throwable;
}
private static void assertThrows(RunnableX r, Class<?> exceptionClass, String messagePattern) throws Throwable {
try {
r.run();
fail("Exception expected");
} catch (Throwable e) {
if (exceptionClass.isInstance(e)) {
assertMatches(e.getMessage(), messagePattern);
} else {
throw e;
}
}
}
private static void assertMatches(String str, String pattern) {
if (!str.matches(pattern)) {
throw new AssertionError("'" + str + "' did not match the pattern '" + pattern + "'.");
}
}
}