BoxingConversionTest.java revision 3504:30bfbfa94fad
1/* 2 * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24/* 25 * @test 26 * @bug 7006109 27 * @summary Add test library to simplify the task of writing automated type-system tests 28 * @author mcimadamore 29 * @library /tools/lib/types 30 * @modules jdk.compiler/com.sun.tools.javac.code 31 * jdk.compiler/com.sun.tools.javac.comp 32 * jdk.compiler/com.sun.tools.javac.file 33 * jdk.compiler/com.sun.tools.javac.util 34 * jdk.compiler/com.sun.tools.javac.main 35 * jdk.compiler/com.sun.tools.javac.tree 36 * @build TypeHarness 37 * @run main BoxingConversionTest 38 */ 39 40import com.sun.tools.javac.code.Type; 41import java.lang.reflect.Array; 42import java.util.EnumSet; 43 44/** 45 * Check invariants in assignment/method conversion involving boxing conversions 46 */ 47public class BoxingConversionTest extends TypeHarness { 48 49 Type[] types1; 50 Type[] types2; 51 Type[] types3; 52 53 enum Result { 54 OK_BOTH(true), 55 FAIL_BOTH(false), 56 OK_ASSIGN_ONLY(true); 57 58 boolean value; 59 60 Result(boolean value) { 61 this.value = value; 62 } 63 } 64 65 enum ConversionKind { 66 ASSIGNMENT_CONVERSION(EnumSet.of(Result.OK_BOTH, Result.OK_ASSIGN_ONLY)) { 67 @Override 68 void check(TypeHarness harness, Type from, Type to, Result expected) { 69 harness.assertAssignable(from, to, resSet.contains(expected)); 70 } 71 }, 72 METHOD_CONVERSION(EnumSet.of(Result.OK_BOTH)) { 73 @Override 74 void check(TypeHarness harness, Type from, Type to, Result expected) { 75 harness.assertConvertible(from, to, resSet.contains(expected)); 76 } 77 }; 78 79 EnumSet<Result> resSet; 80 81 private ConversionKind(EnumSet<Result> resSet) { 82 this.resSet = resSet; 83 } 84 85 abstract void check(TypeHarness harness, Type from, Type to, Result expected); 86 } 87 88 enum TestKind { 89 SIMPLE { 90 @Override 91 Type[] getFromTypes(BoxingConversionTest harness) { 92 return harness.types1; 93 } 94 @Override 95 Type[] getToTypes(BoxingConversionTest harness) { 96 return harness.types1; 97 } 98 @Override 99 Result[][] getResults(BoxingConversionTest harness) { 100 return harness.results1; 101 } 102 }, 103 CONSTANT_TYPES { 104 @Override 105 Type[] getFromTypes(BoxingConversionTest harness) { 106 return harness.types2; 107 } 108 @Override 109 Type[] getToTypes(BoxingConversionTest harness) { 110 return harness.types3; 111 } 112 @Override 113 Result[][] getResults(BoxingConversionTest harness) { 114 return harness.results2; 115 } 116 }; 117 118 abstract Type[] getFromTypes(BoxingConversionTest harness); 119 abstract Type[] getToTypes(BoxingConversionTest harness); 120 abstract Result[][] getResults(BoxingConversionTest harness); 121 } 122 123 static final Result T = Result.OK_BOTH; 124 static final Result F = Result.FAIL_BOTH; 125 static final Result A = Result.OK_ASSIGN_ONLY; 126 127 Result[][] results1 = { 128 //byte, short, int, long, float, double, char, bool, Byte, Short, Integer, Long, Float, Double, Character, Boolean 129 /*byte*/ { T , T , T , T , T , T , F , F , T , F , F , F , F , F , F , F }, 130 /*short*/ { F , T , T , T , T , T , F , F , F , T , F , F , F , F , F , F }, 131 /*int*/ { F , F , T , T , T , T , F , F , F , F , T , F , F , F , F , F }, 132 /*long*/ { F , F , F , T , T , T , F , F , F , F , F , T , F , F , F , F }, 133 /*float*/ { F , F , F , F , T , T , F , F , F , F , F , F , T , F , F , F }, 134 /*double*/ { F , F , F , F , F , T , F , F , F , F , F , F , F , T , F , F }, 135 /*char*/ { F , F , T , T , T , T , T , F , F , F , F , F , F , F , T , F }, 136 /*bool*/ { F , F , F , F , F , F , F , T , F , F , F , F , F , F , F , T }, 137 /*Byte*/ { T , T , T , T , T , T , F , F , T , F , F , F , F , F , F , F }, 138 /*Short*/ { F , T , T , T , T , T , F , F , F , T , F , F , F , F , F , F }, 139 /*Integer*/ { F , F , T , T , T , T , F , F , F , F , T , F , F , F , F , F }, 140 /*Long*/ { F , F , F , T , T , T , F , F , F , F , F , T , F , F , F , F }, 141 /*Float*/ { F , F , F , F , T , T , F , F , F , F , F , F , T , F , F , F }, 142 /*Double*/ { F , F , F , F , F , T , F , F , F , F , F , F , F , T , F , F }, 143 /*Character*/ { F , F , T , T , T , T , T , F , F , F , F , F , F , F , T , F }, 144 /*Boolean*/ { F , F , F , F , F , F , F , T , F , F , F , F , F , F , F , T }}; 145 146 Result[][] results2 = { 147 //Byte, Short, Integer, Long, Float, Double, Chararacter, Boolean 148 /*byte*/ { T , F , F , F , F , F , F , F }, 149 /*short*/ { F , T , F , F , F , F , F , F }, 150 /*short1*/ { A , T , F , F , F , F , A , F }, 151 /*short2*/ { F , T , F , F , F , F , A , F }, 152 /*int*/ { F , F , T , F , F , F , F , F }, 153 /*int1*/ { A , A , T , F , F , F , A , F }, 154 /*int2*/ { F , A , T , F , F , F , A , F }, 155 /*int4*/ { F , F , T , F , F , F , F , F }, 156 /*long*/ { F , F , F , T , F , F , F , F }, 157 /*long1*/ { F , F , F , T , F , F , F , F }, 158 /*long2*/ { F , F , F , T , F , F , F , F }, 159 /*long4*/ { F , F , F , T , F , F , F , F }, 160 /*long8*/ { F , F , F , T , F , F , F , F }, 161 /*float*/ { F , F , F , F , T , F , F , F }, 162 /*float1*/ { F , F , F , F , T , F , F , F }, 163 /*float2*/ { F , F , F , F , T , F , F , F }, 164 /*float4*/ { F , F , F , F , T , F , F , F }, 165 /*double*/ { F , F , F , F , F , T , F , F }, 166 /*double1*/ { F , F , F , F , F , T , F , F }, 167 /*double2*/ { F , F , F , F , F , T , F , F }, 168 /*double4*/ { F , F , F , F , F , T , F , F }, 169 /*double8*/ { F , F , F , F , F , T , F , F }, 170 /*char*/ { F , F , F , F , F , F , T , F }, 171 /*char1*/ { A , A , F , F , F , F , T , F }, 172 /*char2*/ { F , A , F , F , F , F , T , F }, 173 /*bool*/ { F , F , F , F , F , F , F , T }}; 174 175 BoxingConversionTest() { 176 Type[] primitiveTypes = new Type[] { 177 predef.byteType, 178 predef.shortType, 179 predef.intType, 180 predef.longType, 181 predef.floatType, 182 predef.doubleType, 183 predef.charType, 184 predef.booleanType }; 185 186 Type[] boxedTypes = new Type[primitiveTypes.length]; 187 for (int i = 0 ; i < primitiveTypes.length ; i++) { 188 boxedTypes[i] = box(primitiveTypes[i]); 189 } 190 191 types1 = join(Type.class, primitiveTypes, boxedTypes); 192 193 types2 = new Type[] { 194 predef.byteType, 195 predef.shortType, 196 fac.Constant((short)0x0001), 197 fac.Constant((short)0x0100), 198 predef.intType, 199 fac.Constant((int)0x0000_0001), 200 fac.Constant((int)0x0000_0100), 201 fac.Constant((int)0x0001_0000), 202 predef.longType, 203 fac.Constant((long)0x0000_0000_0000_0001L), 204 fac.Constant((long)0x0000_0000_0000_0100L), 205 fac.Constant((long)0x0000_0000_0001_0000L), 206 fac.Constant((long)0x0001_0000_0000_0000L), 207 predef.floatType, 208 fac.Constant((float)0x0000_0001), 209 fac.Constant((float)0x0000_0100), 210 fac.Constant((float)0x0001_0000), 211 predef.doubleType, 212 fac.Constant((double)0x0000_0000_0000_0001L), 213 fac.Constant((double)0x0000_0000_0000_0100L), 214 fac.Constant((double)0x0000_0000_0001_0000L), 215 fac.Constant((double)0x0001_0000_0000_0000L), 216 predef.charType, 217 fac.Constant((char)0x0001), 218 fac.Constant((char)0x0100), 219 predef.booleanType 220 }; 221 222 types3 = boxedTypes; 223 } 224 225 void testConversion(ConversionKind convKind, TestKind testKind) { 226 Type[] rows = testKind.getFromTypes(this); 227 Type[] cols = testKind.getToTypes(this); 228 for (int i = 0; i < rows.length ; i++) { 229 for (int j = 0; j < cols.length ; j++) { 230 convKind.check(this, rows[i], cols[j], testKind.getResults(this)[i][j]); 231 } 232 } 233 } 234 235 @SuppressWarnings("unchecked") 236 <T> T[] join(Class<T> type, T[]... args) { 237 int totalLength = 0; 238 for (T[] arr : args) { 239 totalLength += arr.length; 240 } 241 T[] new_arr = (T[])Array.newInstance(type, totalLength); 242 int idx = 0; 243 for (T[] arr : args) { 244 System.arraycopy(arr, 0, new_arr, idx, arr.length); 245 idx += arr.length; 246 } 247 return new_arr; 248 } 249 250 public static void main(String[] args) { 251 BoxingConversionTest harness = new BoxingConversionTest(); 252 for (ConversionKind convKind : ConversionKind.values()) { 253 for (TestKind testKind : TestKind.values()) { 254 harness.testConversion(convKind, testKind); 255 } 256 } 257 } 258} 259