author | mikejwre |
Thu, 25 Mar 2010 15:05:15 -0700 | |
changeset 5074 | 9c9bfe8f3a47 |
parent 3432 | 8acd97c69118 |
child 5506 | 202f599c92aa |
permissions | -rw-r--r-- |
2 | 1 |
/* |
2 |
* Copyright 2003 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
|
20 |
* CA 95054 USA or visit www.sun.com if you need additional information or |
|
21 |
* have any questions. |
|
22 |
*/ |
|
23 |
||
24 |
/** |
|
25 |
* @test |
|
26 |
* @bug 4870984 |
|
27 |
* @summary JPDA: Add support for RFE 4856541 - varargs |
|
28 |
* |
|
29 |
* @author jjh |
|
30 |
* |
|
31 |
* @run build TestScaffold VMConnection TargetListener TargetAdapter |
|
3432
8acd97c69118
6868533: 3/4 JDI: remove '-source 1.5' and '-target 1.5' options from com.sun.jdi tests
dcubed
parents:
2
diff
changeset
|
32 |
* @run compile -g VarargsTest.java |
2 | 33 |
* @run main VarargsTest |
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 VarargsTarg { |
|
44 |
||
45 |
// These are args that will get passed |
|
46 |
static String[] strArray = new String[] {"a", "b"}; |
|
47 |
static int[] intArray = new int[] {1, 2}; |
|
48 |
||
49 |
// We will pass these to a varargs instance method |
|
50 |
static VarargsTarg vt1 = new VarargsTarg("vt1", ""); |
|
51 |
static VarargsTarg vt2 = new VarargsTarg("vt2", ""); |
|
52 |
||
53 |
String iname; |
|
54 |
||
55 |
VarargsTarg(String ... name) { |
|
56 |
iname = ""; |
|
57 |
for (int ii = 0; ii < name.length; ii++) { |
|
58 |
iname += name[ii]; |
|
59 |
} |
|
60 |
} |
|
61 |
||
62 |
public static void main(String[] args){ |
|
63 |
System.out.println("Howdy!"); |
|
64 |
/* |
|
65 |
* This isn't really part of the test, it just shows |
|
66 |
* the kinds of calls the debugger test will do and lets |
|
67 |
* you verify how javac handles these calls. |
|
68 |
*/ |
|
69 |
System.out.println("debuggee: " + varString()); |
|
70 |
System.out.println("debuggee: " + varString(null)); |
|
71 |
System.out.println("debuggee: " + varString("a")); |
|
72 |
System.out.println("debuggee: " + varString("b", "c")); |
|
73 |
System.out.println("debuggee: " + fixedString(null)); |
|
74 |
System.out.println("debuggee: " + vt1.varStringInstance(vt1, vt2)); |
|
75 |
System.out.println("debuggge: " + varInt(1, 2, 3)); |
|
76 |
System.out.println("debuggee: " + varInteger( new Integer(89))); |
|
77 |
||
78 |
// Should be autoboxed: javac converts the ints to Integers |
|
79 |
// Needs a new method in java.lang.Integer which is only |
|
80 |
// in the generics workspace. |
|
81 |
System.out.println("debugggee: " + varInteger(3, 5, 6)); |
|
82 |
||
83 |
System.out.println("Goodbye from VarargsTarg!"); |
|
84 |
bkpt(); |
|
85 |
} |
|
86 |
static void bkpt() { |
|
87 |
} |
|
88 |
||
89 |
/* |
|
90 |
* Define the methods to be called from the debugger |
|
91 |
*/ |
|
92 |
static String fixedInt(int p1) { |
|
93 |
return "" + p1; |
|
94 |
} |
|
95 |
||
96 |
static String fixedInteger(Integer p1) { |
|
97 |
return "" + p1; |
|
98 |
} |
|
99 |
||
100 |
static String varInt(int... ss) { |
|
101 |
String retVal = ""; |
|
102 |
for (int ii = 0; ii < ss.length; ii++) { |
|
103 |
retVal += ss[ii]; |
|
104 |
} |
|
105 |
return retVal; |
|
106 |
} |
|
107 |
||
108 |
static String varInteger(Integer... ss) { |
|
109 |
String retVal = ""; |
|
110 |
for (int ii = 0; ii < ss.length; ii++) { |
|
111 |
retVal += ss[ii]; |
|
112 |
} |
|
113 |
return retVal; |
|
114 |
} |
|
115 |
||
116 |
static String varString(String... ss) { |
|
117 |
if (ss == null) { |
|
118 |
return "-null-"; |
|
119 |
} |
|
120 |
||
121 |
String retVal = ""; |
|
122 |
for (int ii = 0; ii < ss.length; ii++) { |
|
123 |
retVal += ss[ii]; |
|
124 |
} |
|
125 |
return retVal; |
|
126 |
} |
|
127 |
||
128 |
static String varString2(int p1, String... ss) { |
|
129 |
return p1 + varString(ss); |
|
130 |
} |
|
131 |
||
132 |
static String fixedString(String ss) { |
|
133 |
return "-fixed-"; |
|
134 |
} |
|
135 |
||
136 |
String varStringInstance(VarargsTarg... args) { |
|
137 |
if (args == null) { |
|
138 |
return "-null-"; |
|
139 |
} |
|
140 |
//System.out.println("debugee: ss length = " + ss.length); |
|
141 |
String retVal = iname + ": "; |
|
142 |
for (int ii = 0; ii < args.length; ii++) { |
|
143 |
retVal += args[ii].iname; |
|
144 |
} |
|
145 |
return retVal; |
|
146 |
} |
|
147 |
||
148 |
} |
|
149 |
||
150 |
/********** test program **********/ |
|
151 |
||
152 |
public class VarargsTest extends TestScaffold { |
|
153 |
ClassType targetClass; |
|
154 |
ThreadReference mainThread; |
|
155 |
||
156 |
VarargsTest (String args[]) { |
|
157 |
super(args); |
|
158 |
} |
|
159 |
||
160 |
public static void main(String[] args) throws Exception { |
|
161 |
new VarargsTest(args).startTests(); |
|
162 |
} |
|
163 |
||
164 |
void fail(String reason) { |
|
165 |
failure(reason); |
|
166 |
} |
|
167 |
||
168 |
/* |
|
169 |
* Call a method in the debuggee and verify the return value. |
|
170 |
*/ |
|
171 |
void doInvoke(Object ct, Method mm, List args, Object expected) { |
|
172 |
StringReference returnValue = null; |
|
173 |
try { |
|
174 |
returnValue = doInvokeNoVerify(ct, mm, args); |
|
175 |
} catch (Exception ee) { |
|
176 |
fail("failure: invokeMethod got exception : " + ee); |
|
177 |
ee.printStackTrace(); |
|
178 |
return; |
|
179 |
} |
|
180 |
if (!returnValue.value().equals(expected)) { |
|
181 |
fail("failure: expected \"" + expected + "\", got \"" + |
|
182 |
returnValue.value() + "\""); |
|
183 |
} |
|
184 |
} |
|
185 |
||
186 |
/* |
|
187 |
* Call a method in the debuggee. |
|
188 |
*/ |
|
189 |
StringReference doInvokeNoVerify(Object ct, Method mm, List args) |
|
190 |
throws Exception { |
|
191 |
StringReference returnValue = null; |
|
192 |
if (ct instanceof ClassType) { |
|
193 |
returnValue = (StringReference)((ClassType)ct). |
|
194 |
invokeMethod(mainThread, mm, args, 0); |
|
195 |
} else { |
|
196 |
returnValue = (StringReference)((ObjectReference)ct). |
|
197 |
invokeMethod(mainThread, mm, args, 0); |
|
198 |
} |
|
199 |
return returnValue; |
|
200 |
} |
|
201 |
||
202 |
/********** test core **********/ |
|
203 |
||
204 |
protected void runTests() throws Exception { |
|
205 |
/* |
|
206 |
* Get to the top of main() |
|
207 |
* to determine targetClass and mainThread |
|
208 |
*/ |
|
209 |
BreakpointEvent bpe = startToMain("VarargsTarg"); |
|
210 |
targetClass = (ClassType)bpe.location().declaringType(); |
|
211 |
mainThread = bpe.thread(); |
|
212 |
||
213 |
/* |
|
214 |
* Run past the calls the debuggee makes |
|
215 |
* just to see what they do. |
|
216 |
*/ |
|
217 |
bpe = resumeTo("VarargsTarg", "bkpt", "()V"); |
|
218 |
||
219 |
/* |
|
220 |
* Find Method objects for varString and varString2 |
|
221 |
* Both are tested just to show that the code works |
|
222 |
* if there is just one param or if there is more than one. |
|
223 |
*/ |
|
224 |
ReferenceType rt = findReferenceType("VarargsTarg"); |
|
225 |
||
226 |
List mList; |
|
227 |
||
228 |
/* |
|
229 |
* The test consists of calling the varargs static and instance methods |
|
230 |
* (and constructor) passing primitives, Strings, and Objects, and also |
|
231 |
* passing arrays of the above instead of individual args. |
|
232 |
* The same code is used in the underlying JDI implementations |
|
233 |
* for calling instance methods, static methods, and constructors |
|
234 |
* so this test doesn't have to try all possible argument configurations |
|
235 |
* with each type of method. |
|
236 |
*/ |
|
237 |
||
238 |
mList = rt.methodsByName("varString"); |
|
239 |
Method varString = (Method)mList.get(0); |
|
240 |
||
241 |
mList = rt.methodsByName("varString2"); |
|
242 |
Method varString2 = (Method)mList.get(0); |
|
243 |
||
244 |
if (!varString.isVarArgs()) { |
|
245 |
fail("failure: varString is not flagged as being var args"); |
|
246 |
} |
|
247 |
if (!varString2.isVarArgs()) { |
|
248 |
fail("failure: varString2 is not flagged as being var args"); |
|
249 |
} |
|
250 |
||
251 |
/* |
|
252 |
* Setup arg lists for both varString and varString2 that |
|
253 |
* have null in the varargs position. |
|
254 |
*/ |
|
255 |
||
256 |
{ |
|
257 |
// call varString() |
|
258 |
ArrayList nullArg1 = new ArrayList(0); |
|
259 |
doInvoke(targetClass, varString, nullArg1, ""); |
|
260 |
} |
|
261 |
{ |
|
262 |
// call varString(null) |
|
263 |
ArrayList nullArg1 = new ArrayList(1); |
|
264 |
nullArg1.add(null); |
|
265 |
doInvoke(targetClass, varString, nullArg1, "-null-"); |
|
266 |
} |
|
267 |
{ |
|
268 |
// call varString(9) |
|
269 |
ArrayList nullArg2 = new ArrayList(1); |
|
270 |
nullArg2.add(vm().mirrorOf(9)); |
|
271 |
doInvoke(targetClass, varString2, nullArg2, "9"); |
|
272 |
} |
|
273 |
{ |
|
274 |
// call varString(9, null) |
|
275 |
ArrayList nullArg2 = new ArrayList(2); |
|
276 |
nullArg2.add(vm().mirrorOf(9)); |
|
277 |
nullArg2.add(null); |
|
278 |
doInvoke(targetClass, varString2, nullArg2, "9-null-"); |
|
279 |
} |
|
280 |
{ |
|
281 |
ArrayList args1 = new ArrayList(4); |
|
282 |
args1.add(vm().mirrorOf("1")); |
|
283 |
||
284 |
// call varString("1") |
|
285 |
doInvoke(targetClass, varString, args1, "1"); |
|
286 |
||
287 |
// call varString("1", "2") |
|
288 |
args1.add(vm().mirrorOf("2")); |
|
289 |
args1.add(vm().mirrorOf("3")); |
|
290 |
args1.add(vm().mirrorOf("4")); |
|
291 |
doInvoke(targetClass, varString, args1, "1234"); |
|
292 |
} |
|
293 |
{ |
|
294 |
ArrayList args2 = new ArrayList(2); |
|
295 |
args2.add(vm().mirrorOf(9)); |
|
296 |
args2.add(vm().mirrorOf("1")); |
|
297 |
||
298 |
// call varString2(9, "1"); |
|
299 |
doInvoke(targetClass, varString2, args2, "91"); |
|
300 |
||
301 |
// call varString2(9, "1", "2"); |
|
302 |
args2.add(vm().mirrorOf("2")); |
|
303 |
doInvoke(targetClass, varString2, args2, "912"); |
|
304 |
} |
|
305 |
||
306 |
{ |
|
307 |
/* |
|
308 |
* Passing an array of Strings should work too. |
|
309 |
*/ |
|
310 |
Field ff = targetClass.fieldByName("strArray"); |
|
311 |
Value vv1 = targetClass.getValue(ff); |
|
312 |
||
313 |
// call varString(new String[] {"a", "b"}) |
|
314 |
ArrayList argsArray = new ArrayList(1); |
|
315 |
argsArray.add(vv1); |
|
316 |
doInvoke(targetClass, varString, argsArray, "ab"); |
|
317 |
||
318 |
/* |
|
319 |
* But passing an array of Strings and another String |
|
320 |
* should fail |
|
321 |
*/ |
|
322 |
argsArray.add(vm().mirrorOf("x")); |
|
323 |
boolean isOk = false; |
|
324 |
try { |
|
325 |
// call varString(new String[] {"a", "b"}, "x") |
|
326 |
doInvokeNoVerify(targetClass, varString, argsArray); |
|
327 |
} catch (Exception ee) { |
|
328 |
/* |
|
329 |
* Since the number of args passed is > than |
|
330 |
* the number of params, JDI assumes they are var args |
|
331 |
* and tries to put the array containing the "a" and |
|
332 |
* "be" elements into a the first element of an array |
|
333 |
* of Strings. This fails because you can't store |
|
334 |
* an array into a String |
|
335 |
*/ |
|
336 |
isOk = true; |
|
337 |
//ee.printStackTrace(); |
|
338 |
} |
|
339 |
if (!isOk) { |
|
340 |
fail("failure: an array and a String didn't cause an exception"); |
|
341 |
} |
|
342 |
} |
|
343 |
||
344 |
{ |
|
345 |
/* |
|
346 |
* Test calling instance method instead of static method, |
|
347 |
* and passing non-String objects |
|
348 |
*/ |
|
349 |
Field vtField = targetClass.fieldByName("vt1"); |
|
350 |
Value vv1 = targetClass.getValue(vtField); |
|
351 |
||
352 |
vtField = targetClass.fieldByName("vt2"); |
|
353 |
Value vv2 = targetClass.getValue(vtField); |
|
354 |
||
355 |
/* Create a new instance by calling the varargs |
|
356 |
* ctor. |
|
357 |
* call new VarargsTarg("vt3", "xx"); |
|
358 |
*/ |
|
359 |
Value vv3; |
|
360 |
{ |
|
361 |
mList = rt.methodsByName("<init>"); |
|
362 |
Method ctor = (Method)mList.get(0); |
|
363 |
if (!ctor.isVarArgs()) { |
|
364 |
fail("failure: Constructor is not varargs"); |
|
365 |
} |
|
366 |
ArrayList argsArray = new ArrayList(2); |
|
367 |
argsArray.add(vm().mirrorOf("vt3")); |
|
368 |
argsArray.add(vm().mirrorOf("xx")); |
|
369 |
vv3 = targetClass.newInstance(mainThread, ctor, argsArray, 0); |
|
370 |
} |
|
371 |
// call vt1.varStringInstance(vv1, vv2, vv3) |
|
372 |
mList = rt.methodsByName("varStringInstance"); |
|
373 |
Method varStringInstance = (Method)mList.get(0); |
|
374 |
||
375 |
ArrayList argsArray = new ArrayList(3); |
|
376 |
argsArray.add(vv1); |
|
377 |
argsArray.add(vv2); |
|
378 |
argsArray.add(vv3); |
|
379 |
doInvoke(vv1, varStringInstance, argsArray, "vt1: vt1vt2vt3xx"); |
|
380 |
} |
|
381 |
{ |
|
382 |
/* |
|
383 |
* tests with primitive types |
|
384 |
*/ |
|
385 |
List mlist; |
|
386 |
Method mm; |
|
387 |
ArrayList ll = new ArrayList(2); |
|
388 |
||
389 |
// call fixedInt(21) |
|
390 |
mlist = rt.methodsByName("fixedInt"); |
|
391 |
mm = (Method)mlist.get(0); |
|
392 |
ll.add(vm().mirrorOf(21)); |
|
393 |
doInvoke(targetClass, mm, ll, "21"); |
|
394 |
||
395 |
// autoboxing is not implemented in JDI. |
|
396 |
// call fixedInteger(21) |
|
397 |
//mlist = rt.methodsByName("fixedInteger"); |
|
398 |
//mm = (Method)mlist.get(0); |
|
399 |
//doInvoke(targetClass, mm, ll, "21"); |
|
400 |
||
401 |
mlist = rt.methodsByName("varInt"); |
|
402 |
mm = (Method)mlist.get(0); |
|
403 |
||
404 |
// call varInt( new int[] {1, 2}); |
|
405 |
Field ff = targetClass.fieldByName("intArray"); |
|
406 |
Value vv1 = targetClass.getValue(ff); |
|
407 |
ll.set(0, vv1); |
|
408 |
doInvoke(targetClass, mm, ll, "12"); |
|
409 |
||
410 |
// call varInt(21, 22) |
|
411 |
ll.set(0, vm().mirrorOf(21)); |
|
412 |
ll.add(vm().mirrorOf(22)); |
|
413 |
doInvoke(targetClass, mm, ll, "2122"); |
|
414 |
||
415 |
mlist = rt.methodsByName("varInteger"); |
|
416 |
mm = (Method)mlist.get(0); |
|
417 |
||
418 |
// call varInteger(1, 2) |
|
419 |
// autoboxing is not implemented. |
|
420 |
//doInvoke(targetClass, mm, ll, "2122"); |
|
421 |
} |
|
422 |
||
423 |
/* |
|
424 |
* We don't really need this for the test, but |
|
425 |
* but without it, we sometimes hit 4728096. |
|
426 |
*/ |
|
427 |
listenUntilVMDisconnect(); |
|
428 |
/* |
|
429 |
* deal with results of test |
|
430 |
* if anything has called failure("foo") testFailed will be true |
|
431 |
*/ |
|
432 |
if (!testFailed) { |
|
433 |
println("VarargsTest: passed"); |
|
434 |
} else { |
|
435 |
throw new Exception("VarargsTest: failed"); |
|
436 |
} |
|
437 |
} |
|
438 |
} |