1 /* 2 * Copyright (c) 2003, 2018, 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 package nsk.jdi.Method.isBridge; 25 26 import com.sun.jdi.*; 27 28 import java.io.*; 29 import java.util.*; 30 31 import nsk.share.*; 32 import nsk.share.jpda.*; 33 import nsk.share.jdi.*; 34 35 /** 36 * The test exercises the JDI method<br> 37 * <b>com.sun.jdi.Method.isBridge()</b></br> 38 * It verifies that 'bridge methods' generated during translation of 39 * generic classes are determinated properly by the method. 40 * Here are the rules from the spec "Adding Generics to the Java 41 * Programming Language: Public Draft Specification, Version 2.0" 42 * followed by the test:<br><pre> 43 * 44 * 6.2 Translation of Methods 45 * ... 46 * <li> If C.m is directly overridden by a method D.m in D, and the 47 * erasure of the return type or argument types of D.m differs from 48 * the erasure of the corresponding types in C.m, a bridge method 49 * needs to be generated. 50 * 51 * <li> A bridge method also needs to be generated if C.m is not 52 * directly overridden in D, unless C.m is abstract. 53 * </pre><br> 54 * The test works as follows. Debuggee contains several dummy superclasses 55 * and subclasses. Some of their methods fall under the rules above. 56 * Debugger verifies that the JDI Method.isBridge() returns true for all 57 * generated bridge methods and false for the non-bridge ones. 58 * The list of the class methods is obtained through the JDI 59 * ReferenceType.methods() which must return each method declared directly 60 * in this type including any synthetic methods created by the compiler. 61 */ 62 public class isbridge001 { 63 static final String DEBUGGEE_CLASS = 64 "nsk.jdi.Method.isBridge.isbridge001t"; 65 66 static final String COMMAND_READY = "ready"; 67 static final String COMMAND_QUIT = "quit"; 68 69 static final String[][][] methods = { 70 // nsk.jdi.Method.isBridge.isbridge001aa 71 {{"<init>", 72 "()V", 73 "false", 74 "0"}, 75 {"isbridge001aMeth", 76 "(Ljava/lang/Double;)V", 77 "false", 78 "0"}}, 79 80 // nsk.jdi.Method.isBridge.isbridge001bb 81 {{"<init>", 82 "()V", 83 "false", 84 "0"}, 85 {"isbridge001bMeth", 86 "(Ljava/lang/Number;)Ljava/lang/Number;", 87 "false", 88 "0"}, 89 {"isbridge001bMeth2", 90 "(Ljava/lang/Number;I)V", 91 "false", 92 "0"}}, 93 94 // nsk.jdi.Method.isBridge.isbridge001bb2 95 {{"<init>", 96 "()V", 97 "false", 98 "0"}, 99 {"isbridge001bMeth", 100 "(Ljava/lang/Byte;)Ljava/lang/Byte;", 101 "false", 102 "0"}, 103 {"isbridge001bMeth2", 104 "(Ljava/lang/Byte;I)V", 105 "false", 106 "0"}, 107 {"isbridge001bMeth", 108 "(Ljava/lang/Number;)Ljava/lang/Number;", 109 "true", 110 "0"}, 111 {"isbridge001bMeth2", 112 "(Ljava/lang/Number;I)V", 113 "true", 114 "0"}}, 115 116 // nsk.jdi.Method.isBridge.isbridge001dd 117 {{"<init>", 118 "()V", 119 "false", 120 "0"}}, 121 122 // nsk.jdi.Method.isBridge.isbridge001dd2 123 {{"<init>", 124 "()V", 125 "false", 126 "0"}, 127 {"isbridge001dMeth", 128 "(Ljava/lang/Boolean;Ljava/lang/Character;)Ljava/lang/String;", 129 "false", 130 "0"}, 131 {"isbridge001dMeth", 132 "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 133 "true", 134 "0"}} 135 }; 136 137 static final String[] classes = { 138 "nsk.jdi.Method.isBridge.isbridge001aa", 139 "nsk.jdi.Method.isBridge.isbridge001bb", 140 "nsk.jdi.Method.isBridge.isbridge001bb2", 141 "nsk.jdi.Method.isBridge.isbridge001dd", 142 "nsk.jdi.Method.isBridge.isbridge001dd2", 143 }; 144 145 static final int CLS_NUM = classes.length; 146 147 private IOPipe pipe; 148 private Log log; 149 private Debugee debuggee; 150 private int tot_res = Consts.TEST_PASSED; 151 main(String argv[])152 public static void main (String argv[]) { 153 System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE); 154 } 155 run(String argv[], PrintStream out)156 public static int run(String argv[], PrintStream out) { 157 return new isbridge001().runThis(argv, out); 158 } 159 runThis(String args[], PrintStream out)160 private int runThis(String args[], PrintStream out) { 161 ArgumentHandler argHandler = new ArgumentHandler(args); 162 log = new Log(out, argHandler); 163 Binder binder = new Binder(argHandler, log); 164 165 debuggee = binder.bindToDebugee(DEBUGGEE_CLASS); 166 pipe = debuggee.createIOPipe(); 167 debuggee.redirectStderr(log, "isbridge001t.err> "); 168 debuggee.resume(); 169 String cmd = pipe.readln(); 170 if (!cmd.equals(COMMAND_READY)) { 171 tot_res = Consts.TEST_FAILED; 172 log.complain("TEST BUG: unknown debuggee's command: " 173 + cmd); 174 return quitDebuggee(); 175 } 176 177 for (int i=0; i<CLS_NUM; i++) { 178 ReferenceType rType; 179 List clsMethods; 180 181 log.display("\n>>>>>> Class " + classes[i]); 182 if ((rType = debuggee.classByName(classes[i])) == null) { 183 tot_res = Consts.TEST_FAILED; 184 log.complain("TEST FAILURE: Method Debugee.classByName() returned null for " 185 + classes[i] + "\n"); 186 return quitDebuggee(); 187 } 188 try { 189 clsMethods = rType.methods(); 190 } catch (Exception e) { 191 tot_res = Consts.TEST_FAILED; 192 log.complain("TEST FAILURE: ReferenceType.methods: caught " + e 193 + "\n"); 194 return quitDebuggee(); 195 } 196 197 Iterator iterator = clsMethods.iterator(); 198 while(iterator.hasNext()) { 199 Method meth = (Method) iterator.next(); 200 log.display("\t--> method " + meth 201 + "\n\t\tname " + meth.name() 202 + "\n\t\treturn type " + meth.returnTypeName() 203 + "\n\t\tsignature " + meth.signature()); 204 205 int idx = findMethod(i, meth.signature()); 206 if (idx != -1) { 207 try { 208 int methCounter = Integer.parseInt(methods[i][idx][3]); 209 methCounter++; 210 methods[i][idx][3] = String.valueOf(methCounter); 211 } catch (NumberFormatException e) { 212 tot_res = Consts.TEST_FAILED; 213 log.complain("TEST BUG: Integer.parseInt: caught " + e); 214 return quitDebuggee(); 215 } 216 boolean bridge = new Boolean(methods[i][idx][2]); 217 if (bridge == meth.isBridge()) 218 log.display("\tCHECK PASSED: Method.isBridge() returns " 219 + meth.isBridge() + " as expected\n"); 220 else { 221 tot_res = Consts.TEST_FAILED; 222 log.complain("TEST FAILED: Method.isBridge() returns " 223 + meth.isBridge() 224 + "\n\tfor the method: " + meth.name() 225 + " " + meth.signature() 226 + "\n\tExpected: "+ methods[i][idx][2] + "\n"); 227 } 228 } 229 } 230 231 log.display("<<<<<<"); 232 } 233 234 for (int i=0; i<CLS_NUM; i++) { 235 int j = 0; 236 237 while(true) { 238 try { 239 if (methods[i][j][3].equals("0")) { 240 tot_res = Consts.TEST_FAILED; 241 log.complain("TEST FAILED: Method " + methods[i][j][0] 242 + " " + methods[i][j][1] 243 + "\n\tfrom the class " + classes[i] 244 + "\n\twas not returned by the ReferenceType.methods()\n"); 245 } 246 247 j++; 248 } catch(ArrayIndexOutOfBoundsException e) { 249 break; 250 } 251 } 252 } 253 254 return quitDebuggee(); 255 } 256 quitDebuggee()257 private int quitDebuggee() { 258 pipe.println(COMMAND_QUIT); 259 debuggee.waitFor(); 260 int debStat = debuggee.getStatus(); 261 if (debStat != (Consts.JCK_STATUS_BASE + Consts.TEST_PASSED)) { 262 tot_res = Consts.TEST_FAILED; 263 log.complain("TEST FAILED: debuggee's process finished with status: " 264 + debStat); 265 } else 266 log.display("Debuggee's process finished with status: " 267 + debStat); 268 269 return tot_res; 270 } 271 findMethod(int clsIdx, String signature)272 private int findMethod(int clsIdx, String signature) { 273 int i=0; 274 275 while(true) { 276 try { 277 if (signature.equals(methods[clsIdx][i][1])) 278 return i; // the tested method found 279 280 i++; 281 } catch(ArrayIndexOutOfBoundsException e) { 282 break; 283 } 284 } 285 286 return -1; // the tested method not found 287 } 288 } 289