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