45 * @author jrose |
45 * @author jrose |
46 */ |
46 */ |
47 public class MethodHandlesTest { |
47 public class MethodHandlesTest { |
48 // How much output? |
48 // How much output? |
49 static int verbosity = 0; |
49 static int verbosity = 0; |
|
50 static { |
|
51 String vstr = System.getProperty("test.java.dyn.MethodHandlesTest.verbosity"); |
|
52 if (vstr != null) verbosity = Integer.parseInt(vstr); |
|
53 } |
50 |
54 |
51 // Set this true during development if you want to fast-forward to |
55 // Set this true during development if you want to fast-forward to |
52 // a particular new, non-working test. Tests which are known to |
56 // a particular new, non-working test. Tests which are known to |
53 // work (or have recently worked) test this flag and return on true. |
57 // work (or have recently worked) test this flag and return on true. |
54 static boolean CAN_SKIP_WORKING = false; |
58 static boolean CAN_SKIP_WORKING = false; |
107 boolean platformOK = false; |
111 boolean platformOK = false; |
108 Properties properties = System.getProperties(); |
112 Properties properties = System.getProperties(); |
109 String vers = properties.getProperty("java.vm.version"); |
113 String vers = properties.getProperty("java.vm.version"); |
110 String name = properties.getProperty("java.vm.name"); |
114 String name = properties.getProperty("java.vm.name"); |
111 String arch = properties.getProperty("os.arch"); |
115 String arch = properties.getProperty("os.arch"); |
112 if ((arch.equals("i386") || arch.equals("amd64") || |
116 if ((arch.equals("amd64") || arch.equals("i386") || arch.equals("x86") || |
113 arch.equals("sparc") || arch.equals("sparcv9")) && |
117 arch.equals("sparc") || arch.equals("sparcv9")) && |
114 (name.contains("Client") || name.contains("Server")) |
118 (name.contains("Client") || name.contains("Server")) |
115 ) { |
119 ) { |
116 platformOK = true; |
120 platformOK = true; |
117 } else { |
121 } else { |
119 } |
123 } |
120 assumeTrue(platformOK); |
124 assumeTrue(platformOK); |
121 } |
125 } |
122 |
126 |
123 String testName; |
127 String testName; |
|
128 static int allPosTests, allNegTests; |
124 int posTests, negTests; |
129 int posTests, negTests; |
125 @After |
130 @After |
126 public void printCounts() { |
131 public void printCounts() { |
127 if (verbosity >= 2 && (posTests | negTests) != 0) { |
132 if (verbosity >= 2 && (posTests | negTests) != 0) { |
128 System.out.println(); |
133 System.out.println(); |
129 if (posTests != 0) System.out.println("=== "+testName+": "+posTests+" positive test cases run"); |
134 if (posTests != 0) System.out.println("=== "+testName+": "+posTests+" positive test cases run"); |
130 if (negTests != 0) System.out.println("=== "+testName+": "+negTests+" negative test cases run"); |
135 if (negTests != 0) System.out.println("=== "+testName+": "+negTests+" negative test cases run"); |
|
136 allPosTests += posTests; |
|
137 allNegTests += negTests; |
131 posTests = negTests = 0; |
138 posTests = negTests = 0; |
132 } |
139 } |
133 } |
140 } |
134 void countTest(boolean positive) { |
141 void countTest(boolean positive) { |
135 if (positive) ++posTests; |
142 if (positive) ++posTests; |
151 nextArgVal = INITIAL_ARG_VAL; |
158 nextArgVal = INITIAL_ARG_VAL; |
152 } |
159 } |
153 |
160 |
154 @AfterClass |
161 @AfterClass |
155 public static void tearDownClass() throws Exception { |
162 public static void tearDownClass() throws Exception { |
|
163 int posTests = allPosTests, negTests = allNegTests; |
|
164 if (verbosity >= 2 && (posTests | negTests) != 0) { |
|
165 System.out.println(); |
|
166 if (posTests != 0) System.out.println("=== "+posTests+" total positive test cases"); |
|
167 if (negTests != 0) System.out.println("=== "+negTests+" total negative test cases"); |
|
168 } |
156 } |
169 } |
157 |
170 |
158 static List<Object> calledLog = new ArrayList<Object>(); |
171 static List<Object> calledLog = new ArrayList<Object>(); |
159 static Object logEntry(String name, Object... args) { |
172 static Object logEntry(String name, Object... args) { |
160 return Arrays.asList(name, Arrays.asList(args)); |
173 return Arrays.asList(name, Arrays.asList(args)); |
809 } |
822 } |
810 CASES = cases.toArray(new Object[0][]); |
823 CASES = cases.toArray(new Object[0][]); |
811 } |
824 } |
812 } |
825 } |
813 |
826 |
|
827 static final int TEST_UNREFLECT = 1, TEST_FIND_FIELD = 2, TEST_FIND_STATIC_FIELD = 3; |
|
828 static boolean testModeMatches(int testMode, boolean isStatic) { |
|
829 switch (testMode) { |
|
830 case TEST_FIND_STATIC_FIELD: return isStatic; |
|
831 case TEST_FIND_FIELD: return !isStatic; |
|
832 default: return true; // unreflect matches both |
|
833 } |
|
834 } |
|
835 |
814 @Test |
836 @Test |
815 public void testUnreflectGetter() throws Throwable { |
837 public void testUnreflectGetter() throws Throwable { |
|
838 startTest("unreflectGetter"); |
|
839 testGetter(TEST_UNREFLECT); |
|
840 } |
|
841 @Test |
|
842 public void testFindGetter() throws Throwable { |
|
843 startTest("findGetter"); |
|
844 testGetter(TEST_FIND_FIELD); |
|
845 } |
|
846 @Test |
|
847 public void testFindStaticGetter() throws Throwable { |
|
848 startTest("findStaticGetter"); |
|
849 testGetter(TEST_FIND_STATIC_FIELD); |
|
850 } |
|
851 public void testGetter(int testMode) throws Throwable { |
816 Lookup lookup = PRIVATE; // FIXME: test more lookups than this one |
852 Lookup lookup = PRIVATE; // FIXME: test more lookups than this one |
817 startTest("unreflectGetter"); |
|
818 for (Object[] c : HasFields.CASES) { |
853 for (Object[] c : HasFields.CASES) { |
819 Field f = (Field)c[0]; |
854 Field f = (Field)c[0]; |
820 Object value = c[1]; |
855 Object value = c[1]; |
821 Class<?> type = f.getType(); |
856 Class<?> type = f.getType(); |
822 if (type.isPrimitive() && type != int.class) |
857 testGetter(lookup, f, type, value, testMode); |
823 continue; //FIXME |
858 } |
824 testUnreflectGetter(lookup, f, type, value); |
859 } |
825 } |
860 public void testGetter(MethodHandles.Lookup lookup, |
826 } |
861 Field f, Class<?> type, Object value, int testMode) throws Throwable { |
827 public void testUnreflectGetter(MethodHandles.Lookup lookup, |
862 boolean isStatic = Modifier.isStatic(f.getModifiers()); |
828 Field f, Class<?> type, Object value) throws Throwable { |
863 Class<?> fclass = f.getDeclaringClass(); |
|
864 String fname = f.getName(); |
|
865 Class<?> ftype = f.getType(); |
|
866 if (!testModeMatches(testMode, isStatic)) return; |
829 countTest(true); |
867 countTest(true); |
830 boolean isStatic = Modifier.isStatic(f.getModifiers()); |
|
831 MethodType expType = MethodType.methodType(type, HasFields.class); |
868 MethodType expType = MethodType.methodType(type, HasFields.class); |
832 if (isStatic) expType = expType.dropParameterTypes(0, 1); |
869 if (isStatic) expType = expType.dropParameterTypes(0, 1); |
833 MethodHandle mh = lookup.unreflectGetter(f); |
870 MethodHandle mh = lookup.unreflectGetter(f); |
834 assertSame(mh.type(), expType); |
871 assertSame(mh.type(), expType); |
835 assertEquals(mh.toString(), f.getName()); |
872 assertEquals(mh.toString(), fname); |
836 HasFields fields = new HasFields(); |
873 HasFields fields = new HasFields(); |
837 Object sawValue; |
874 Object sawValue; |
838 Class<?> rtype = type; |
875 Class<?> rtype = type; |
839 if (type != int.class) rtype = Object.class; |
876 if (type != int.class) rtype = Object.class; |
840 mh = MethodHandles.convertArguments(mh, mh.type().generic().changeReturnType(rtype)); |
877 mh = MethodHandles.convertArguments(mh, mh.type().generic().changeReturnType(rtype)); |
860 } |
897 } |
861 |
898 |
862 |
899 |
863 @Test |
900 @Test |
864 public void testUnreflectSetter() throws Throwable { |
901 public void testUnreflectSetter() throws Throwable { |
|
902 startTest("unreflectSetter"); |
|
903 testSetter(TEST_UNREFLECT); |
|
904 } |
|
905 @Test |
|
906 public void testFindSetter() throws Throwable { |
|
907 startTest("findSetter"); |
|
908 testSetter(TEST_FIND_FIELD); |
|
909 } |
|
910 @Test |
|
911 public void testFindStaticSetter() throws Throwable { |
|
912 startTest("findStaticSetter"); |
|
913 testSetter(TEST_FIND_STATIC_FIELD); |
|
914 } |
|
915 public void testSetter(int testMode) throws Throwable { |
865 Lookup lookup = PRIVATE; // FIXME: test more lookups than this one |
916 Lookup lookup = PRIVATE; // FIXME: test more lookups than this one |
866 startTest("unreflectSetter"); |
917 startTest("unreflectSetter"); |
867 for (Object[] c : HasFields.CASES) { |
918 for (Object[] c : HasFields.CASES) { |
868 Field f = (Field)c[0]; |
919 Field f = (Field)c[0]; |
869 Object value = c[1]; |
920 Object value = c[1]; |
870 Class<?> type = f.getType(); |
921 Class<?> type = f.getType(); |
871 if (type.isPrimitive() && type != int.class) |
922 testSetter(lookup, f, type, value, testMode); |
872 continue; //FIXME |
923 } |
873 testUnreflectSetter(lookup, f, type, value); |
924 } |
874 } |
925 public void testSetter(MethodHandles.Lookup lookup, |
875 } |
926 Field f, Class<?> type, Object value, int testMode) throws Throwable { |
876 public void testUnreflectSetter(MethodHandles.Lookup lookup, |
927 boolean isStatic = Modifier.isStatic(f.getModifiers()); |
877 Field f, Class<?> type, Object value) throws Throwable { |
928 Class<?> fclass = f.getDeclaringClass(); |
|
929 String fname = f.getName(); |
|
930 Class<?> ftype = f.getType(); |
|
931 if (!testModeMatches(testMode, isStatic)) return; |
878 countTest(true); |
932 countTest(true); |
879 boolean isStatic = Modifier.isStatic(f.getModifiers()); |
|
880 MethodType expType = MethodType.methodType(void.class, HasFields.class, type); |
933 MethodType expType = MethodType.methodType(void.class, HasFields.class, type); |
881 if (isStatic) expType = expType.dropParameterTypes(0, 1); |
934 if (isStatic) expType = expType.dropParameterTypes(0, 1); |
882 MethodHandle mh = lookup.unreflectSetter(f); |
935 MethodHandle mh; |
|
936 if (testMode == TEST_UNREFLECT) |
|
937 mh = lookup.unreflectSetter(f); |
|
938 else if (testMode == TEST_FIND_FIELD) |
|
939 mh = lookup.findSetter(fclass, fname, ftype); |
|
940 else if (testMode == TEST_FIND_STATIC_FIELD) |
|
941 mh = lookup.findStaticSetter(fclass, fname, ftype); |
|
942 else throw new InternalError(); |
883 assertSame(mh.type(), expType); |
943 assertSame(mh.type(), expType); |
884 assertEquals(mh.toString(), f.getName()); |
944 assertEquals(mh.toString(), fname); |
885 HasFields fields = new HasFields(); |
945 HasFields fields = new HasFields(); |
886 Object sawValue; |
946 Object sawValue; |
887 Class<?> vtype = type; |
947 Class<?> vtype = type; |
888 if (type != int.class) vtype = Object.class; |
948 if (type != int.class) vtype = Object.class; |
889 int last = mh.type().parameterCount() - 1; |
949 int last = mh.type().parameterCount() - 1; |