blob: ed4323e2d4f2b71c31c6a71cdbeb2afd9dcbb09b [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
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
32 * @run compile -g -source 1.5 -target 1.5 VarargsTest.java
33 * @run main VarargsTest
34 */
35import com.sun.jdi.*;
36import com.sun.jdi.event.*;
37import com.sun.jdi.request.*;
38
39import java.util.*;
40
41 /********** target program **********/
42
43class 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
152public 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}