1 /* 2 * Copyright (c) 2003, 2015, 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 4421040 27 * @summary JPDA: Add support for JSR-014 Generics 28 * @author jjh 29 * 30 * @run build TestScaffold VMConnection TargetListener TargetAdapter 31 * @run compile -g GenericsTest.java 32 * @run driver GenericsTest 33 */ 34 import com.sun.jdi.*; 35 import com.sun.jdi.event.*; 36 import com.sun.jdi.request.*; 37 38 import java.util.*; 39 40 /********** target program **********/ 41 42 class GenericsTarg { 43 static Gen1<String> genField = new Gen1<String>();; 44 static Sub1 sub1Field = new Sub1(); 45 46 String[] strArray = null; 47 int intField = 0; 48 Object objField; main(String[] args)49 public static void main(String[] args){ 50 //genField.print(); 51 System.out.println("Goodbye from GenericsTarg!"); 52 } 53 } 54 class Gen1<tt> { 55 tt field1; Gen1()56 Gen1() { 57 System.out.println("Gen1<tt> ctor called"); 58 } method1(tt p1)59 tt method1(tt p1) { 60 Gen1<String> xxx = null; 61 System.out.println("method1: param is " + p1); 62 return p1; 63 } method2()64 String method2() { 65 String str = "This local variable is not generic"; 66 return str; 67 } 68 } 69 70 class Sub1 extends Gen1<String> { method1(String p1)71 String method1(String p1) { 72 System.out.println("method1 has been overridden: param is " + p1); 73 return "hi"; 74 } 75 } 76 77 /********** test program **********/ 78 79 public class GenericsTest extends TestScaffold { 80 ReferenceType targetClass; 81 ThreadReference mainThread; 82 static boolean useOld; 83 GenericsTest(String args[])84 GenericsTest (String args[]) { 85 super(args); 86 } 87 main(String[] args)88 public static void main(String[] args) throws Exception { 89 /* 90 * The 1.5 FE must be able to talk to a 1.4 BE, ie, JDWP version <= 1.4. 91 * This is hard to test since this test file must be compiled with 92 * -source 1.5 which will cause its class file to be version 49 which 93 * won't run on a pre 1.5 JDK. We can simulate this though 94 * by passing 95 * -xjdk <pathname> 96 * to this test which causes the debuggee to be run on that JDK. 97 * This should be a version of 1.5 that accepts classfile version 49, 98 * but which still contains the 1.4 version of JDWP. 99 * This trick verifies that the calls to genericSignature() methods 100 * in the test do not cause the generic JDWP commands to be issued. 101 * The value to use for this is currently: 102 * /java/re/jdk/1.5/promoted/all/b17/binaries/solaris-sparc 103 */ 104 if (args.length > 1 && args[0].equals("-xjdk")) { 105 System.setProperty("java.home", args[1]); 106 useOld = true; 107 108 // Delete this arg 109 String[] args1 = new String[args.length - 2]; 110 for (int ii = 0; ii < args.length -2; ii++) { 111 args1[ii] = args[ii + 2]; 112 } 113 args = args1; 114 } 115 116 new GenericsTest(args).startTests(); 117 } 118 119 /********** test core **********/ 120 runTests()121 protected void runTests() throws Exception { 122 /* 123 * Get to the top of main() 124 * to determine targetClass and mainThread 125 */ 126 BreakpointEvent bpe = startToMain("GenericsTarg"); 127 targetClass = bpe.location().declaringType(); 128 { 129 /* 130 * Prove that arrays aren't broken and that 131 * null is returned if there is no generic signature 132 */ 133 Field strArray = targetClass.fieldByName("strArray"); 134 ReferenceType fieldType = (ReferenceType)(strArray.type()); 135 String genSig = fieldType.genericSignature(); 136 System.out.println("strArray name = " + strArray); 137 System.out.println(" type = " + fieldType); 138 System.out.println(" sig = " + fieldType.signature()); 139 System.out.println(" genSig = " + genSig); 140 if (!useOld && genSig != null) { 141 failure("FAILED: Expected generic signature = null for " 142 + fieldType.name() + ", received: " + genSig); 143 } 144 } 145 { 146 // prove that primitives aren't broken. 147 Field intField = targetClass.fieldByName("intField"); 148 Type fieldType = (Type)(intField.type()); 149 System.out.println("intField name = " + intField); 150 System.out.println(" type = " + fieldType); 151 System.out.println(" sig = " + fieldType.signature()); 152 } 153 154 Field genField = targetClass.fieldByName("genField"); 155 ReferenceType gen1Class = (ReferenceType)(genField.type()); 156 String genSig; 157 String expected; 158 { 159 // Verify genericSignature for a class 160 expected = "<tt:Ljava/lang/Object;>Ljava/lang/Object;"; 161 genSig = gen1Class.genericSignature(); 162 System.out.println("genField name = " + genField); 163 System.out.println(" type = " + gen1Class); 164 System.out.println(" sig = " + gen1Class.signature()); 165 System.out.println(" genSig = " + genSig); 166 if (!useOld && !expected.equals(genSig)) { 167 failure("FAILED: Expected generic signature for gen1: " + 168 expected + ", received: " + genSig); 169 } 170 } 171 { 172 // Verify genericSignature() for a field 173 List genFields = gen1Class.fields(); 174 Field field1 = (Field)genFields.get(0); 175 // there is only one field 176 expected = "Ttt;"; 177 genSig = field1.genericSignature(); 178 System.out.println("field1 name = " + field1); 179 System.out.println(" type = " + gen1Class.signature()); 180 System.out.println(" sig = " + field1.signature()); 181 System.out.println(" gen sig = " + genSig); 182 if (!useOld && !expected.equals(genSig)) { 183 failure("FAILED: Expected generic signature for field1: " + 184 expected + ", received: " + genSig); 185 } 186 } 187 { 188 // Verify genericSignature() for a method 189 List genMethods = gen1Class.methodsByName("method1"); 190 // There is only uno 191 Method method1 = (Method)genMethods.get(0); 192 expected = "(Ttt;)Ttt;"; 193 genSig = method1.genericSignature(); 194 System.out.println("method1 name = " + method1); 195 System.out.println(" type = " + gen1Class.signature()); 196 System.out.println(" sig = " + method1.signature()); 197 System.out.println(" gen sig = " + genSig); 198 System.out.println(" bridge = " + method1.isBridge()); 199 if (!useOld && !expected.equals(genSig)) { 200 failure("FAILED: Expected generic signature for method1: " + 201 expected + ", received: " + genSig); 202 } 203 204 // Verify this is not a bridge method 205 if (method1.isBridge()) { 206 failure("FAILED: Expected gen1.method1 to not be a bridge" 207 + " method but it is"); 208 } 209 210 // Verify genericSignature for a local var 211 List localVars = method1.variables(); 212 String[] expectedGenSigs = { "Ttt", "Gen1<String>" }; 213 for ( int ii = 0 ; ii < localVars.size(); ii++) { 214 expected = expectedGenSigs[ii]; 215 LocalVariable pp = (LocalVariable)localVars.get(ii); 216 genSig = pp.genericSignature(); 217 System.out.println(" local var " + ii + " = " + pp.name()); 218 System.out.println(" sig = " + pp.signature()); 219 System.out.println(" gen sig = " + genSig); 220 //jjh Uncomment when generics for local vars are available from 221 //jjh javac and hotspot. See: 222 //jjh 4914602 LVT entries for classfile version > 49 must be converted 223 //jjh if (!useOld && !expected.equals(genSig)) { 224 //jjh failure("FAILED: Expected generic signature for local var: " + 225 //jjh expected + ", received: " + genSig); 226 //jjh } 227 } 228 } 229 { 230 // Verify genericSignature() for a method2 231 List genMethods = gen1Class.methodsByName("method2"); 232 // There is only uno 233 Method method2 = (Method)genMethods.get(0); 234 expected = "null"; 235 genSig = method2.genericSignature(); 236 genSig = (genSig == null) ? "null" : genSig; 237 System.out.println("method2 name = " + method2); 238 System.out.println(" type = " + gen1Class.signature()); 239 System.out.println(" sig = " + method2.signature()); 240 System.out.println(" gen sig = " + genSig); 241 System.out.println(" bridge = " + method2.isBridge()); 242 if (!useOld && !expected.equals(genSig)) { 243 failure("FAILED: Expected generic signature for method2: " + 244 expected + ", received: " + genSig); 245 } 246 247 // Verify this is not a bridge method 248 if (method2.isBridge()) { 249 failure("FAILED: Expected gen1.method2 to not be a bridge" 250 + " method but it is"); 251 } 252 253 // Verify genericSignature for a local var 254 List localVars = method2.variables(); 255 expected = "null"; 256 for ( int ii = 0 ; ii < localVars.size(); ii++) { 257 LocalVariable pp = (LocalVariable)localVars.get(ii); 258 genSig = pp.genericSignature(); 259 genSig = (genSig == null) ? "null" : genSig; 260 261 System.out.println(" local var " + ii + " = " + pp.name()); 262 System.out.println(" sig = " + pp.signature()); 263 System.out.println(" gen sig = " + genSig); 264 if (!useOld && !expected.equals(genSig)) { 265 failure("FAILED: Expected generic signature for local var: " + 266 expected + ", received: " + genSig); 267 } 268 } 269 } 270 { 271 Field sub1Field = targetClass.fieldByName("sub1Field"); 272 ReferenceType sub1Class = (ReferenceType)(sub1Field.type()); 273 List<Method> sub1Methods = sub1Class.methodsByName("method1"); 274 for (Method mm: sub1Methods) { 275 System.out.println("method is: " + mm); 276 } 277 /* 278 * There should be two methods - the first is the 279 * method1 defined in Sub1, and the 2nd is a javac generated 280 * bridge method. 281 */ 282 Method method1 = (Method)sub1Methods.get(1); 283 System.out.println("\nmethod1 name = " + method1); 284 System.out.println(" sig = " + method1.signature()); 285 System.out.println(" bridge = " + method1.isBridge()); 286 if (!useOld && !method1.isBridge()) { 287 failure("FAILED: Expected Sub1.method1 to be a bridge method" 288 + " but it isn't"); 289 } 290 291 } 292 { 293 // Verify genericSignature for a non generic class 294 genSig = targetClass.genericSignature(); 295 if (genSig != null) { 296 failure("FAILED: Expected generic signature = null for " 297 + targetClass.name() + ", received: " + genSig); 298 } 299 } 300 { 301 // Verify genericSignature for a non generic field 302 Field objField = targetClass.fieldByName("objField"); 303 genSig = objField.genericSignature(); 304 if (genSig != null) { 305 failure("FAILED: Expected generic signature = null for " 306 + objField.name() + ", received: " + genSig); 307 } 308 } 309 { 310 // Verify genericSignature for a non generic method 311 List methods = targetClass.methodsByName("main"); 312 Method main = (Method)methods.get(0); 313 genSig = main.genericSignature(); 314 if (genSig != null) { 315 failure("FAILED: Expected generic signature = null for " 316 + main.name() + ", received: " + genSig); 317 } 318 } 319 if (0 == 1) { 320 mainThread = bpe.thread(); 321 EventRequestManager erm = vm().eventRequestManager(); 322 StepRequest request = erm.createStepRequest(mainThread, 323 StepRequest.STEP_LINE, 324 StepRequest.STEP_INTO); 325 request.enable(); 326 } 327 328 /* 329 * resume the target listening for events 330 */ 331 listenUntilVMDisconnect(); 332 333 /* 334 * deal with results of test 335 * if anything has called failure("foo") testFailed will be true 336 */ 337 if (!testFailed) { 338 println("GenericsTest: passed"); 339 } else { 340 throw new Exception("GenericsTest: failed"); 341 } 342 } 343 } 344