blob: a4a03a348986e118b99eb5b4e5a6b6ed13c947b7 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2000-2002 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 4326648 4768329
27 * @summary Test to verify that table entries are generated for all final
28 * locals when a class is built for debug, even if they could be
29 * inlined otherwise.
30 *
31 * @author Tim Bell
32 *
33 * @run build TestScaffold VMConnection TargetListener TargetAdapter
34 * @run compile -g FinalLocalsTest.java
35 * @run main FinalLocalsTest
36 */
37import com.sun.jdi.*;
38import com.sun.jdi.event.*;
39import com.sun.jdi.request.*;
40
41import java.util.*;
42
43 /********** target program **********/
44
45class FinalLocalsTarg {
46 public void test1 (final int t, int k){
47 String s1 = "first";
48 final int z = 0;
49 if (true) {
50 final float r = 10.00f;
51 boolean b = true;
52 System.out.println(r);
53 }
54 }
55 public void hi(){
56 return;
57 }
58 public static void main(String[] args) {
59 System.out.print("in FinalLocalsTarg:");
60 new FinalLocalsTarg().hi();
61 return;
62 }
63}
64
65 /********** test program **********/
66
67public class FinalLocalsTest extends TestScaffold {
68 ReferenceType targetClass;
69 ThreadReference mainThread;
70
71 FinalLocalsTest (String args[]) {
72 super(args);
73 }
74
75 public static void main(String[] args) throws Exception {
76 new FinalLocalsTest(args).startTests();
77 }
78
79 /********** test core **********/
80 static final int VARIABLES = 1;
81 static final int BYNAME = 2;
82 static final int ARGUMENTS = 3;
83 /*
84 * Take a String containing comma separated values
85 * and return those values in a TreeSet.
86 */
87 private TreeSet buildSet(String in) {
88 TreeSet result = new TreeSet();
89 StringTokenizer tt = new StringTokenizer(in, ",");
90 while (tt.hasMoreTokens()) {
91 String ss = tt.nextToken();
92 if (! result.add(ss)) {
93 failure ("Duplicate entry \"" + ss + "\" in string: " +
94 in + " is not allowed");
95 }
96 }
97 return result;
98 }
99
100 private void test(Method method, int which, String name, String expected) {
101 String got = testCase(method, which);
102 System.out.println(" test() comparing expected = " + expected +
103 " to got = " + got);
104 TreeSet expectedSet = buildSet(expected);
105 TreeSet gotSet = buildSet(got);
106
107 while (! expectedSet.isEmpty()) {
108 String ee = (String)expectedSet.first();
109 expectedSet.remove(ee);
110 if (gotSet.contains(ee)) {
111 gotSet.remove(ee);
112 } else {
113 failure (name + " Expected entry \"" + ee + "\" not found");
114 }
115 }
116
117 //assert expectedSet.isEmpty() : name + " expected set should have been emptied";
118
119 if (! gotSet.isEmpty()) {
120 StringBuffer sb = new StringBuffer();
121 Iterator it = gotSet.iterator();
122 while (it.hasNext()) {
123 sb.append(it.next());
124 if (it.hasNext()) {
125 sb.append(",");
126 }
127 }
128 failure (name + " Unexpected entries found: " + sb.toString());
129 }
130 }
131
132 String testCase(Method method, int which) {
133 try {
134 List vars;
135 switch (which) {
136 case VARIABLES:
137 vars = method.variables();
138 break;
139 case BYNAME:
140 vars = method.variablesByName("s1");
141 break;
142 case ARGUMENTS:
143 vars = method.arguments();
144 break;
145 default:
146 throw new InternalException("should not happen");
147 }
148 StringBuffer sb = new StringBuffer();
149 for (Iterator it = vars.iterator(); it.hasNext(); ) {
150 LocalVariable lv = (LocalVariable)it.next();
151 if (sb.length() > 0) {
152 sb.append(",");
153 }
154 sb.append(lv.name());
155 }
156 return sb.toString();
157 } catch (Exception exc) {
158 String st = exc.getClass().getName();
159 int inx = st.lastIndexOf('.');
160 return st.substring(inx+1);
161 }
162 }
163
164 protected void runTests() throws Exception {
165 /*
166 * Get to the top of main()
167 * to determine targetClass and mainThread
168 */
169 BreakpointEvent bpe = startToMain("FinalLocalsTarg");
170 targetClass = bpe.location().declaringType();
171 mainThread = bpe.thread();
172 EventRequestManager erm = vm().eventRequestManager();
173
174 /*
175 * Get to a point where the classes are loaded.
176 */
177 BreakpointEvent bp = resumeTo("FinalLocalsTarg", "hi", "()V");
178
179 ReferenceType rt = findReferenceType("FinalLocalsTarg");
180 if (rt == null) {
181 throw new Exception("FinalLocalsTarg: not loaded");
182 }
183
184 /*
185 * Inspect the LocalVariableTable attributes for method "test1"
186 * NOTE: .class files compiled with some versions of javac will
187 * give results listed in different order. That's OK.
188 */
189 Method method = findMethod(rt, "test1", "(II)V");
190 if (method == null) {
191 throw new Exception("Method not found");
192 }
193 test(method, VARIABLES, "VARIABLES",
194 "t,k,s1,z,r,b");
195 test(method, BYNAME, "BYNAME",
196 "s1");
197 test(method, ARGUMENTS, "ARGUMENTS",
198 "t,k");
199
200 /*
201 * All Done. Resume the target listening for events
202 */
203 listenUntilVMDisconnect();
204
205 /*
206 * deal with results of test
207 * if anything has called failure("foo") testFailed will be true
208 */
209 if (!testFailed) {
210 println("FinalLocalsTest: passed");
211 } else {
212 throw new Exception("FinalLocalsTest: failed");
213 }
214 }
215}