< prev index next >
test/jdk/java/lang/invoke/MethodHandlesTest.java
Print this page
*** 1,7 ****
/*
! * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
--- 1,7 ----
/*
! * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*** 36,45 ****
--- 36,46 ----
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+ import java.util.stream.Stream;
import static org.junit.Assert.*;
/**
*
*** 559,632 ****
static char sC = 1+'C';
static int sI = 1+'I';
static long sJ = 1+'J';
static float sF = 1+'F';
static double sD = 1+'D';
final static boolean fsZ = false;
! final static byte fsB = 2+(byte)'B';
! final static short fsS = 2+(short)'S';
! final static char fsC = 2+'C';
! final static int fsI = 2+'I';
! final static long fsJ = 2+'J';
! final static float fsF = 2+'F';
! final static double fsD = 2+'D';
Object iL = 'L';
! String iR = "R";
! static Object sL = 'M';
! static String sR = "S";
! final static Object fsL = 'N';
! final static String fsR = "T";
! static final Object[][] CASES;
static {
- ArrayList<Object[]> cases = new ArrayList<>();
Object types[][] = {
{'L',Object.class}, {'R',String.class},
{'I',int.class}, {'J',long.class},
{'F',float.class}, {'D',double.class},
{'Z',boolean.class}, {'B',byte.class},
{'S',short.class}, {'C',char.class},
};
HasFields fields = new HasFields();
for (Object[] t : types) {
! for (int kind = 0; kind <= 2; kind++) {
boolean isStatic = (kind != 0);
! boolean isFinal = (kind == 2);
char btc = (Character)t[0];
! String name = (isStatic ? "s" : "i") + btc;
! if (isFinal) name = "f" + name;
Class<?> type = (Class<?>) t[1];
! Object value;
! Field field;
try {
! field = HasFields.class.getDeclaredField(name);
} catch (NoSuchFieldException | SecurityException ex) {
throw new InternalError("no field HasFields."+name);
}
try {
! value = field.get(fields);
} catch (IllegalArgumentException | IllegalAccessException ex) {
! throw new InternalError("cannot fetch field HasFields."+name);
}
- if (type == float.class) {
- float v = 'F';
- if (isStatic) v++;
- if (isFinal) v++;
- assertTrue(value.equals(v));
}
! if (isFinal && isStatic) field.setAccessible(true);
! assertTrue(name.equals(field.getName()));
! assertTrue(type.equals(field.getType()));
! assertTrue(isStatic == (Modifier.isStatic(field.getModifiers())));
! assertTrue(isFinal == (Modifier.isFinal(field.getModifiers())));
! cases.add(new Object[]{ field, value });
}
}
- 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 });
- CASES = cases.toArray(new Object[0][]);
}
}
static final int TEST_UNREFLECT = 1, TEST_FIND_FIELD = 2, TEST_FIND_STATIC = 3, TEST_SETTER = 0x10, TEST_BOUND = 0x20, TEST_NPE = 0x40;
--- 560,694 ----
static char sC = 1+'C';
static int sI = 1+'I';
static long sJ = 1+'J';
static float sF = 1+'F';
static double sD = 1+'D';
+
+ // final fields
+ final boolean fiZ = false;
+ final byte fiB = 2+(byte)'B';
+ final short fiS = 2+(short)'S';
+ final char fiC = 2+'C';
+ final int fiI = 2+'I';
+ final long fiJ = 2+'J';
+ final float fiF = 2+'F';
+ final double fiD = 2+'D';
final static boolean fsZ = false;
! final static byte fsB = 3+(byte)'B';
! final static short fsS = 3+(short)'S';
! final static char fsC = 3+'C';
! final static int fsI = 3+'I';
! final static long fsJ = 3+'J';
! final static float fsF = 3+'F';
! final static double fsD = 3+'D';
Object iL = 'L';
! String iR = "iR";
! static Object sL = 1+'L';
! static String sR = "sR";
! final Object fiL = 2+'L';
! final String fiR = "fiR";
! final static Object fsL = 3+'L';
! final static String fsR = "fsR";
! static final ArrayList<Object[]> STATIC_FIELD_CASES = new ArrayList<>();
! static final ArrayList<Object[]> INSTANCE_FIELD_CASES = new ArrayList<>();
static {
Object types[][] = {
{'L',Object.class}, {'R',String.class},
{'I',int.class}, {'J',long.class},
{'F',float.class}, {'D',double.class},
{'Z',boolean.class}, {'B',byte.class},
{'S',short.class}, {'C',char.class},
};
HasFields fields = new HasFields();
for (Object[] t : types) {
! for (int kind = 0; kind <= 1; kind++) {
boolean isStatic = (kind != 0);
! ArrayList<Object[]> cases = isStatic ? STATIC_FIELD_CASES : INSTANCE_FIELD_CASES;
char btc = (Character)t[0];
! String fname = (isStatic ? "s" : "i") + btc;
! String finalFname = (isStatic ? "fs" : "fi") + btc;
Class<?> type = (Class<?>) t[1];
! // non-final field
! Field nonFinalField = getField(fname, type);
! Object value = getValue(fields, nonFinalField);
! if (type == float.class) {
! float v = 'F';
! if (isStatic) v++;
! assertTrue(value.equals(v));
! }
! assertTrue(isStatic == (Modifier.isStatic(nonFinalField.getModifiers())));
! cases.add(new Object[]{ nonFinalField, value });
!
! // setAccessible(true) on final field but static final field only has read access
! Field finalField = getField(finalFname, type);
! Object fvalue = getValue(fields, finalField);
! finalField.setAccessible(true);
! assertTrue(isStatic == (Modifier.isStatic(finalField.getModifiers())));
! cases.add(new Object[]{ finalField, fvalue, Error.class});
! }
! }
! INSTANCE_FIELD_CASES.add(new Object[]{ new Object[]{ false, HasFields.class, "bogus_fD", double.class }, Error.class });
! STATIC_FIELD_CASES.add(new Object[]{ new Object[]{ true, HasFields.class, "bogus_sL", Object.class }, Error.class });
! }
!
! private static Field getField(String name, Class<?> type) {
try {
! Field field = HasFields.class.getDeclaredField(name);
! assertTrue(name.equals(field.getName()));
! assertTrue(type.equals(field.getType()));
! return field;
} catch (NoSuchFieldException | SecurityException ex) {
throw new InternalError("no field HasFields."+name);
}
+ }
+
+ private static Object getValue(Object o, Field field) {
try {
! return field.get(o);
} catch (IllegalArgumentException | IllegalAccessException ex) {
! throw new InternalError("cannot fetch field HasFields."+field.getName());
}
}
!
! static Object[][] testCasesFor(int testMode) {
! Stream<Object[]> cases;
! if ((testMode & TEST_UNREFLECT) != 0) {
! cases = Stream.concat(STATIC_FIELD_CASES.stream(), INSTANCE_FIELD_CASES.stream());
! } else if ((testMode & TEST_FIND_STATIC) != 0) {
! cases = STATIC_FIELD_CASES.stream();
! } else if ((testMode & TEST_FIND_FIELD) != 0) {
! cases = INSTANCE_FIELD_CASES.stream();
! } else {
! throw new InternalError("unexpected test mode: " + testMode);
! }
! return cases.map(c -> mapTestCase(testMode, c)).toArray(Object[][]::new);
!
}
+
+ private static Object[] mapTestCase(int testMode, Object[] c) {
+ // non-final fields (2-element) and final fields (3-element) if not TEST_SETTER
+ if (c.length == 2 || (testMode & TEST_SETTER) == 0)
+ return c;
+
+ // final fields (3-element)
+ assertTrue((testMode & TEST_SETTER) != 0 && c[0] instanceof Field && c[2] == Error.class);
+ if ((testMode & TEST_UNREFLECT) == 0)
+ return new Object[]{ c[0], c[2]}; // negative test case; can't set on final fields
+
+ // unreflectSetter grants write access on instance final field if accessible flag is true
+ // hence promote the negative test case to positive test case
+ Field f = (Field) c[0];
+ int mods = f.getModifiers();
+ if (!Modifier.isFinal(mods) || (!Modifier.isStatic(mods) && f.isAccessible())) {
+ // positive test case
+ return new Object[]{ c[0], c[1] };
+ } else {
+ // otherwise, negative test case
+ return new Object[]{ c[0], c[2]};
}
}
}
static final int TEST_UNREFLECT = 1, TEST_FIND_FIELD = 2, TEST_FIND_STATIC = 3, TEST_SETTER = 0x10, TEST_BOUND = 0x20, TEST_NPE = 0x40;
< prev index next >