MethodHandlesTest.java revision 4183
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @summary unit tests for java.lang.invoke.MethodHandles
* @compile -source 7 -target 7 MethodHandlesTest.java
*/
/**
*
* @author jrose
*/
public class MethodHandlesTest {
// How much output?
static int verbosity = 0;
static {
}
// Set this true during development if you want to fast-forward to
// a particular new, non-working test. Tests which are known to
// work (or have recently worked) test this flag and return on true.
static boolean CAN_SKIP_WORKING = false;
//static { CAN_SKIP_WORKING = true; }
// Set true to test more calls. If false, some tests are just
// lookups, without exercising the actual method handle.
static boolean DO_MORE_CALLS = true;
@Test
verbosity += 9; try {
// left blank for debugging
}
// current failures
public void testFail_1() throws Throwable {
// AMH.<init>: IllegalArgumentException: bad adapter (conversion=0xfffab300): adapter pushes too many parameters
}
public void testFail_2() throws Throwable {
// if CONV_OP_IMPLEMENTED_MASK includes OP_SPREAD_ARGS, this crashes:
}
public void testFail_3() throws Throwable {
// ToGeneric.<init>: UnsupportedOperationException: NYI: primitive parameters must follow references; entryType = (int,java.lang.Object)java.lang.Object
}
public void testFail_4() throws Throwable {
// ToGeneric.<init>: UnsupportedOperationException: NYI: primitive parameters must follow references; entryType = (int,java.lang.Object)java.lang.Object
}
public void testFail_5() throws Throwable {
// ToGeneric.<init>: UnsupportedOperationException: NYI: primitive parameters must follow references; entryType = (int,java.lang.Object)java.lang.Object
}
public void testFail_6() throws Throwable {
// ValueConversions.varargsArray: UnsupportedOperationException: NYI: cannot form a varargs array of length 13
}
static final int MAX_ARG_INCREASE = 3;
public MethodHandlesTest() {
}
static int allPosTests, allNegTests;
public void printCounts() {
allPosTests += posTests;
allNegTests += negTests;
}
}
else ++negTests;
}
if (verbosity >= 1)
}
public static void setUpClass() throws Exception {
}
public static void tearDownClass() throws Exception {
}
}
}
return entry;
}
}
if (verbosity >= 3)
}
}
return (int)(value);
return (long)(value);
return (char)(value);
return (short)(value);
return (float)(value);
return (double)(value);
return (byte)(value);
return null;
}
static long nextArgVal;
long val = nextArgVal++;
val >>= 1;
if (moreBits)
// Guarantee some bits in the high word.
// In any case keep the decimal representation simple-looking,
// with lots of zeroes, so as not to make the printed decimal
// strings unnecessarily noisy.
}
static int nextArg() {
// Produce a 32-bit result something like ONE_MILLION+(smallint).
// Example: 1_000_042.
return (int) nextArg(false);
}
// produce a 64-bit result something like
// ((TEN_BILLION+1) * (ONE_MILLION+(smallint)))
// Example: 10_000_420_001_000_042.
return nextArg(true);
return (long) nextArg();
}
return wrap;
}
// import sun.invoke.util.Wrapper;
// Wrapper wrap = Wrapper.forBasicType(dst);
// if (wrap == Wrapper.OBJECT && Wrapper.isWrapperType(dst))
// wrap = Wrapper.forWrapperType(dst);
// if (wrap != Wrapper.OBJECT)
// return wrap.wrap(nextArg++);
if (param.isInterface()) {
{ param = c; break; }
}
}
return "#"+nextArg();
else
try {
return param.newInstance();
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
}
return null; // random class not Object, String, Integer, etc.
}
return args;
}
return args;
}
}
static <T> T[] cat(T[] a, T... b) {
if (blen == 0) return a;
return c;
}
}
return res;
}
if (x == null) return x;
if (x instanceof String) return x; // keep the name
if (x instanceof List) {
// recursively report classes of the list elements
}
return x.getClass().getSimpleName();
}
/** Return lambda(arg...[arity]) { new Object[]{ arg... } } */
}
/** Return lambda(arg...[arity]) { Arrays.asList(arg...) } */
}
}
/** Variation of varargsList, but with the given rtype. */
// OK
if (LIST_TO_STRING == null)
try {
} else if (rtype.isPrimitive()) {
if (LIST_TO_INT == null)
try {
} else {
}
}
}
}
// This lookup is good for all members in and under MethodHandlesTest.
// This lookup is good for package-private members but not private ones.
// This lookup is good only for public members.
// Subject methods...
static class Example implements IntExample {
}
public static class PubExample extends Example {
}
static class SubExample extends Example {
}
public static interface IntExample {
public void v0();
public static class Impl implements IntExample {
}
}
static final Object[][][] ACCESS_CASES = {
{ { false, PUBLIC }, { false, PACKAGE }, { true, PRIVATE }, { true, EXAMPLE } }, //[1]: only PRIVATE
};
} else {
if (pubc)
else
}
return cases;
}
}
@Test
public void testFindStatic() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("findStatic");
}
void testFindStatic(Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
}
}
void testFindStatic(Lookup lookup, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
}
void testFindStatic(boolean positive, Lookup lookup, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
try {
} catch (ReflectiveOperationException ex) {
else
}
if (verbosity >= 3)
assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
if (!positive) return; // negative test failed as expected
if (verbosity >= 1)
}
// rough check of name string
assertEquals(s, x);
}
@Test
public void testFindVirtual() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("findVirtual");
// test dispatch
}
void testFindVirtual(Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
}
void testFindVirtual(Class<?> rcvc, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
}
}
void testFindVirtual(Lookup lookup, Class<?> rcvc, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
}
void testFindVirtual(boolean positive, Lookup lookup, Class<?> rcvc, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
try {
} catch (ReflectiveOperationException ex) {
else
}
if (verbosity >= 3)
assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
if (!positive) return; // negative test failed as expected
if (verbosity >= 1)
}
@Test
public void testFindSpecial() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("findSpecial");
// Do some negative testing:
}
}
}
try {
} catch (ReflectiveOperationException ex) {
else
}
if (verbosity >= 3)
System.out.println("findSpecial from "+specialCaller.getName()+" to "+defc.getName()+"."+name+"/"+type+" => "+target
assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
if (!positive) return; // negative test failed as expected
}
@Test
if (CAN_SKIP_WORKING) return;
startTest("bind");
}
}
}
void testBind(boolean positive, Lookup lookup, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
try {
} catch (ReflectiveOperationException ex) {
else
}
if (verbosity >= 3)
assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
if (!positive) return; // negative test failed as expected
if (verbosity >= 1)
}
@Test
public void testUnreflect() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("unreflect");
}
void testUnreflect(Class<?> defc, boolean isStatic, Class<?> ret, String name, Class<?>... params) throws Throwable {
testUnreflectMaybeSpecial(null, (Boolean)ac[0], (Lookup)ac[1], defc, (isStatic ? null : defc), ret, name, params);
}
}
void testUnreflect(Class<?> defc, Class<?> rcvc, Class<?> ret, String name, Class<?>... params) throws Throwable {
}
}
try {
if (isSpecial)
else
} catch (ReflectiveOperationException ex) {
else
}
if (verbosity >= 3)
+" => "+target
assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
if (!positive) return; // negative test failed as expected
if (!isStatic) {
}
if (isStatic) {
} else {
if (isSpecial)
else
}
if (verbosity >= 1)
}
void testUnreflectSpecial(Class<?> defc, Class<?> rcvc, Class<?> ret, String name, Class<?>... params) throws Throwable {
testUnreflectMaybeSpecial(specialCaller, (Boolean)ac[0], (Lookup)ac[1], defc, rcvc, ret, name, params);
}
}
@Test
public void testUnreflectSpecial() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("unreflectSpecial");
testUnreflectMaybeSpecial(Example.class, false, PRIVATE, Example.class, Example.class, void.class, "s0");
}
public static class HasFields {
boolean fZ = false;
byte fB = (byte)'B';
short fS = (short)'S';
char fC = 'C';
int fI = 'I';
long fJ = 'J';
float fF = 'F';
double fD = 'D';
static boolean sZ = true;
static {
{'I',int.class}, {'J',long.class},
{'F',float.class}, {'D',double.class},
{'Z',boolean.class}, {'B',byte.class},
{'S',short.class}, {'C',char.class},
};
try {
}
try {
}
if (type == float.class) {
float v = 'F';
if (isStatic) v++;
}
}
}
cases.add(new Object[]{ new Object[]{ false, HasFields.class, "bogus_fD", double.class }, Error.class });
cases.add(new Object[]{ new Object[]{ true, HasFields.class, "bogus_sL", Object.class }, Error.class });
}
}
switch (testMode) {
case TEST_FIND_STATIC: return isStatic;
case TEST_FIND_FIELD: return !isStatic;
case TEST_UNREFLECT: return true; // unreflect matches both
}
}
@Test
public void testUnreflectGetter() throws Throwable {
startTest("unreflectGetter");
}
@Test
public void testFindGetter() throws Throwable {
startTest("findGetter");
}
@Test
public void testFindStaticGetter() throws Throwable {
startTest("findStaticGetter");
}
}
testGetter(true, lookup,
testGetter(false, lookup,
}
}
}
boolean isStatic;
if (f != null) {
fclass = f.getDeclaringClass();
} else {
try {
} catch (ReflectiveOperationException ex) {
f = null;
}
}
if (isGetter)
else
try {
switch (testMode0) {
case TEST_SETTER|
case TEST_SETTER|
case TEST_SETTER|
default:
}
} catch (ReflectiveOperationException ex) {
else
}
if (verbosity >= 3)
System.out.println("find"+(isStatic?"Static":"")+(isGetter?"Getter":"Setter")+" "+fclass.getName()+"."+fname+"/"+ftype
+" => "+mh
assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, mh != null);
if (!positive) return; // negative test failed as expected
if (isGetter) {
} else {
.changeReturnType(void.class)
}
}
if (isGetter) {
for (int i = 0; i <= 1; i++) {
if (isStatic) {
if (ftype == int.class)
else
} else {
if (ftype == int.class)
else
}
} else {
break;
}
}
} else {
for (int i = 0; i <= 1; i++) {
if (isStatic) {
if (ftype == int.class)
else
} else {
if (ftype == int.class)
else
}
}
}
}
}
}
@Test
public void testUnreflectSetter() throws Throwable {
startTest("unreflectSetter");
}
@Test
public void testFindSetter() throws Throwable {
startTest("findSetter");
}
@Test
public void testFindStaticSetter() throws Throwable {
startTest("findStaticSetter");
}
startTest("unreflectSetter");
}
testSetter(false, lookup,
}
}
}
@Test
public void testArrayElementGetter() throws Throwable {
startTest("arrayElementGetter");
testArrayElementGetterSetter(false);
}
@Test
public void testArrayElementSetter() throws Throwable {
startTest("arrayElementSetter");
testArrayElementGetterSetter(true);
}
}
countTest(true);
if (verbosity >= 2) System.out.println("array type = "+array.getClass().getComponentType().getName()+"["+Array.getLength(array)+"]");
// FIXME: change Integer.class and (Integer) below to int.class and (int) below.
}
for (int i = 0; i < length; i++) {
// update array element
if (testSetter) {
if (elemType == int.class)
else if (elemType == boolean.class)
else
} else {
}
if (verbosity >= 5) {
}
// observe array element
if (!testSetter) {
if (elemType == int.class)
else if (elemType == boolean.class)
else
}
}
}
for (int i = 0; i < length; i++)
return model;
}
static class Callee {
static MethodHandle ofType(int n) {
}
if (n == -1)
}
}
try {
throw new RuntimeException(ex);
}
}
}
@Test
public void testConvertArguments() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("convertArguments");
}
void testConvert(MethodHandle id, Class<?> rtype, String name, Class<?>... params) throws Throwable {
}
}
// simulate the pairwise conversion
}
{
}
try {
if (useAsType)
else
} catch (RuntimeException ex) {
}
if (verbosity >= 3)
assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
if (!positive) return; // negative test failed as expected
if (verbosity >= 1)
}
@Test
public void testVarargsCollector() throws Throwable {
}
}
@Test
public void testPermuteArguments() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("permuteArguments");
//testPermuteArguments(6, Integer.class, 0, null, 30);
//testPermuteArguments(4, Integer.class, 1, int.class, 6);
}
public void testPermuteArguments(int max, Class<?> type1, int t2c, Class<?> type2, int dilution) throws Throwable {
if (verbosity >= 2)
if (t2c != 0) {
// Fill in a middle range with type2:
}
int numcases = 1;
// Avoid some common factors:
casStep++;
// Do some special patterns, which we probably missed.
// Replication of a single argument or argument pair.
for (int i = 0; i < inargs; i++) {
for (int d = 1; d <= 2; d++) {
if (i + d >= inargs) continue;
reorder[j] += 1;
}
}
// Repetition of a sequence of 3 or more arguments.
for (int i = 1; i < inargs; i++) {
for (int j = 0; j < outargs; j++)
}
}
}
}
}
}
c /= inargs;
}
}
}
}
return reorder;
}
countTest();
int max = 0;
for (int j : reorder) {
}
}
}
}
if (verbosity >= 3)
for (int i = 0; i < outargs; i++) {
}
if (verbosity >= 4) {
}
System.out.println("*** failed permuteArguments "+Arrays.toString(reorder)+" types="+Arrays.asList(types));
}
}
@Test
public void testSpreadArguments() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("spreadArguments");
if (verbosity >= 3)
// FIXME: enable _adapter_spread_args and fix Fail_2
}
}
}
}
countTest();
if (verbosity >= 3)
// make sure the target does what we think it does:
switch (nargs) {
case 0:
break;
case 1:
break;
case 2:
break;
}
}
{ // modify newParams in place
}
if (pos == 0) {
Object args2 = ValueConversions.changeArrayType(arrayType, Arrays.copyOfRange(args, pos, args.length));
} else {
args1[pos] = ValueConversions.changeArrayType(arrayType, Arrays.copyOfRange(args, pos, args.length));
}
if (!argType.isPrimitive()) {
}
} else if (argType == int.class) {
}
} else if (argType == long.class) {
}
} else {
// cannot test...
}
}
@Test
public void testCollectArguments() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("collectArguments");
if (verbosity >= 3)
if (argType == int.class) continue; // FIXME Fail_4
}
}
}
}
countTest();
// fake up a MH with the same type as the desired adapter:
// here is what should happen:
// here is the MH which will witness the collected argument tail:
if (verbosity >= 3)
// assertTrue(returnValue.length == pos+1 && returnValue[pos] instanceof Object[]);
// returnValue[pos] = Arrays.asList((Object[]) returnValue[pos]);
// collectedArgs[pos] = Arrays.asList((Object[]) collectedArgs[pos]);
}
@Test
public void testInsertArguments() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("insertArguments");
}
}
}
}
countTest();
if (verbosity >= 3)
if (verbosity >= 3)
//if (!resList.equals(res2List))
// System.out.println("*** fail at n/p/i = "+nargs+"/"+pos+"/"+ins+": "+resList+" => "+res2List);
}
@Test
public void testFilterReturnValue() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("filterReturnValue");
List.class,
int.class,
//byte.class, //FIXME: add this
//long.class, //FIXME: add this
CharSequence.class,
String.class }) {
}
}
}
countTest();
else
if (verbosity >= 3)
if (verbosity >= 4)
// Simulate expected effect of filter on return value:
if (verbosity >= 4)
if (verbosity >= 4)
if (verbosity >= 3)
System.out.println("*** fail at n/rt = "+nargs+"/"+rtype.getSimpleName()+": "+Arrays.asList(argsToPass)+" => "+result+" != "+expected);
}
@Test
public void testFilterArguments() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("filterArguments");
}
}
}
countTest();
if (verbosity >= 3)
// Simulate expected effect of filter on arglist:
if (verbosity >= 3)
System.out.println("*** fail at n/p = "+nargs+"/"+pos+": "+Arrays.asList(argsToPass)+" => "+result+" != "+expected);
}
@Test
public void testFoldArguments() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("foldArguments");
}
}
}
}
countTest();
if (verbosity >= 3)
// Simulate expected effect of combiner on arglist:
if (verbosity >= 3)
if (verbosity >= 3)
System.out.println("*** fail at n/p/f = "+nargs+"/"+pos+"/"+fold+": "+argsToPass+" => "+result+" != "+expected);
}
@Test
public void testDropArguments() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("dropArguments");
}
}
}
}
countTest();
for (int i = drop; i > 0; i--) {
}
//if (!resList.equals(res2List))
// System.out.println("*** fail at n/p/d = "+nargs+"/"+pos+"/"+drop+": "+argsToDrop+" => "+res2List);
}
@Test
public void testInvokers() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("exactInvoker, genericInvoker, varargsInvoker, dynamicInvoker");
// exactInvoker, genericInvoker, varargsInvoker[0..N], dynamicInvoker
for (int i = 0; i <= 6; i++) {
for (int j = -1; j < i; j++) {
if (j < 0)
else if (argType == void.class)
continue;
else
}
}
}
}
if (verbosity >= 3)
// exact invoker
countTest();
// generic invoker
countTest();
if (nargs <= 3) {
switch (nargs) {
case 0:
break;
case 1:
break;
case 2:
break;
case 3:
break;
}
}
// varargs invoker #0
if (nargs >= 1) {
// varargs invoker #1
}
if (nargs >= 2) {
// varargs invoker #2
}
if (nargs >= 3) {
// varargs invoker #3
}
for (int k = 0; k <= nargs; k++) {
// varargs invoker #0..N
countTest();
}
// dynamic invoker
countTest();
// see if we get the result of the original target:
try {
assertTrue("should not reach here", false);
} catch (IllegalStateException ex) {
}
// set new target after invoker is created, to make sure we track target
}
}
static Object targetIfEquals() {
return called("targetIfEquals");
}
static Object fallbackIfNotEquals() {
return called("fallbackIfNotEquals");
}
assertEquals(x, MISSING_ARG);
return called("targetIfEquals", x);
}
return called("fallbackIfNotEquals", x);
}
assertEquals(x, y);
return called("targetIfEquals", x, y);
}
return called("fallbackIfNotEquals", x, y);
}
assertEquals(x, y);
return called("targetIfEquals", x, y, z);
}
return called("fallbackIfNotEquals", x, y, z);
}
@Test
public void testGuardWithTest() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("guardWithTest");
}
}
countTest();
MethodHandle test = PRIVATE.findVirtual(Object.class, "equals", MethodType.methodType(boolean.class, Object.class));
MethodHandle target = PRIVATE.findStatic(MethodHandlesTest.class, "targetIfEquals", MethodType.genericMethodType(nargs));
MethodHandle fallback = PRIVATE.findStatic(MethodHandlesTest.class, "fallbackIfNotEquals", MethodType.genericMethodType(nargs));
}
{ },
{ "foo" }, { MISSING_ARG },
{ "foo", "foo" }, { "foo", "bar" },
{ "foo", "foo", "baz" }, { "foo", "bar", "baz" }
};
boolean equals;
switch (nargs) {
case 0: equals = true; break;
}
if (verbosity >= 3)
}
}
@Test
public void testCatchException() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("catchException");
}
}
}
private static <T extends Throwable>
return normal;
}
void testCatchException(Class<?> returnType, Throwable thrown, boolean throwIt, int nargs) throws Throwable {
countTest();
if (verbosity >= 3)
//System.out.println("catching with "+target+" : "+throwOrReturn);
//System.out.println("return from "+target+" : "+returned);
if (!throwIt) {
} else {
}
}
@Test
public void testThrowException() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("throwException");
}
countTest();
//System.out.println("throwing with "+target+" : "+thrown);
try {
}
}
}
@Test
public void testCastFailure() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("testCastFailure");
}
static class Surprise {
public MethodHandle asMethodHandle() {
}
trace("value", x);
return x;
}
}
static {
try {
Surprise.class, "value",
Surprise.class, "refIdentity",
Surprise.class, "boxIdentity",
Surprise.class, "intIdentity",
MethodType.methodType(int.class, int.class));
throw new RuntimeException(ex);
}
}
}
countTest(false);
MethodHandle identity = Surprise.REF_IDENTITY, surprise0 = boo.asMethodHandle(), surprise = surprise0;
// fail on return to ((Integer)surprise).intValue
surprise = MethodHandles.convertArguments(surprise, MethodType.methodType(int.class, Object.class));
identity = MethodHandles.convertArguments(identity, MethodType.methodType(int.class, Object.class));
// fail on return to (Integer)surprise
surprise = MethodHandles.convertArguments(surprise, MethodType.methodType(Integer.class, Object.class));
identity = MethodHandles.convertArguments(identity, MethodType.methodType(Integer.class, Object.class));
}
// fail on handing surprise to int argument
// fail on handing surprise to Integer argument
}
}
}
Object x = 42;
for (int i = 0; i < okCount; i++) {
assertEquals(x, y);
assertEquals(x, z);
}
assertEquals(x, y);
try {
assertTrue(false);
} catch (ClassCastException ex) {
if (verbosity > 2)
if (verbosity > 3)
assertTrue(true); // all is well
}
}
called("userMethod", o, s, i);
return null;
}
@Test
public void testUserClassInSignature() throws Throwable {
if (CAN_SKIP_WORKING) return;
startTest("testUserClassInSignature");
// Try a static method.
name = "userMethod";
// Try a virtual method.
name = "v2";
}
static void runForRunnable() {
called("runForRunnable");
}
private interface Fooable {
// this is for randomArg:
throw new RuntimeException("do not call");
}
}
}
return called("fooForFooable", x, y);
}
private static class MyCheckedException extends Exception {
}
private interface WillThrow {
void willThrow() throws MyCheckedException;
}
@Test
public void testAsInstance() throws Throwable {
if (CAN_SKIP_WORKING) return;
{
assertCalled("runForRunnable");
}
{
}
new InternalError("ok"),
new Throwable("fail"),
new Exception("fail"),
new MyCheckedException()
}) {
try {
assertTrue(false);
if (verbosity > 2) {
}
if (ex instanceof RuntimeException ||
} else if (ex instanceof MyCheckedException) {
} else {
}
}
}
// Test error checking:
String.class,
CharSequence.class,
Example.class }) {
try {
assertTrue(false);
} catch (IllegalArgumentException ex) {
}
}
}
}
// Local abbreviated copy of sun.invoke.util.ValueConversions
class ValueConversions {
private static final Object[] NO_ARGS_ARRAY = {};
static MethodHandle[] makeArrays() {
for (;;) {
try {
} catch (ReflectiveOperationException ex) {
// break from loop!
}
}
}
/** Return a method handle that takes the indicated number of Object
* arguments and returns an Object array of them, as if for varargs.
*/
// else need to spin bytecode or do something else fancy
}
MethodType vaType = MethodType.methodType(arrayType, Collections.<Class<?>>nCopies(nargs, elemType));
}
if (!elemType.isPrimitive())
for (int i = 0; i < a.length; i++)
return b;
}
private static final MethodHandle CHANGE_ARRAY_TYPE;
static {
try {
throw err;
}
}
static MethodHandle[] makeLists() {
for (;;) {
try {
} catch (ReflectiveOperationException ex) {
// break from loop!
}
}
}
/** Return a method handle that takes the indicated number of Object
* arguments and returns List.
*/
// else need to spin bytecode or do something else fancy
throw new UnsupportedOperationException("NYI");
}
}
// This guy tests access from outside the same package member, but inside
// the package itself.
class PackageSibling {
return MethodHandles.lookup();
}
}