1 /*
2  * Copyright (c) 2014, 2016, 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  * @summary local variable table attribute test.
27  * @bug 8040097
28  * @library /tools/lib /tools/javac/lib ../lib
29  * @modules jdk.compiler/com.sun.tools.javac.api
30  *          jdk.compiler/com.sun.tools.javac.main
31  *          jdk.compiler/com.sun.tools.javac.util
32  *          jdk.jdeps/com.sun.tools.classfile
33  * @build toolbox.ToolBox InMemoryFileManager TestBase
34  * @build LocalVariableTestBase
35  * @compile -g LocalVariableTableTest.java
36  * @run main LocalVariableTableTest
37  */
38 
39 import com.sun.tools.classfile.Code_attribute;
40 import com.sun.tools.classfile.LocalVariableTable_attribute;
41 
42 import java.io.IOException;
43 import java.util.Arrays;
44 import java.util.List;
45 import java.util.stream.Stream;
46 
47 import static java.util.stream.Collectors.toList;
48 
49 public class LocalVariableTableTest extends LocalVariableTestBase {
50 
LocalVariableTableTest(Class<?> clazz)51     public LocalVariableTableTest(Class<?> clazz) {
52         super(clazz);
53     }
54 
main(String[] args)55     public static void main(String[] args) throws IOException {
56         new LocalVariableTableTest(LocalVariableTableTest.class).test();
57     }
58 
59     @ExpectedLocals(name = "l", type = "D")
60     @ExpectedLocals(name = "i", type = "J")
onlyTwoCellParameters(double l, long i)61     public static void onlyTwoCellParameters(double l, long i) {
62     }
63 
64     @ExpectedLocals(name = "l", type = "D")
65     @ExpectedLocals(name = "dl", type = "D")
66     @ExpectedLocals(name = "i", type = "J")
67     @ExpectedLocals(name = "il", type = "J")
68     @ExpectedLocals(name = "d", type = "J")
69     @ExpectedLocals(name = "ll", type = "J")
onlyTwoCellLocals(double l, long i, long d)70     public static void onlyTwoCellLocals(double l, long i, long d) {
71         double dl = 1.1;
72         long il = 1;
73         long ll = 1;
74     }
75 
76     @Override
getVariableTables(Code_attribute codeAttribute)77     protected List<VariableTable> getVariableTables(Code_attribute codeAttribute) {
78         return Stream.of(codeAttribute.attributes.attrs)
79                 .filter(at -> at instanceof LocalVariableTable_attribute)
80                 .map(at -> (LocalVariableTable_attribute) at)
81                 .map((t) -> new LocalVariableTable(t)).collect(toList());
82     }
83 
84     @ExpectedLocals(name = "l", type = "J")
85     @ExpectedLocals(name = "i", type = "I")
86     @ExpectedLocals(name = "d", type = "D")
87     @ExpectedLocals(name = "ll", type = "J")
88     @ExpectedLocals(name = "obj", type = "Ljava/lang/Object;")
89     @ExpectedLocals(name = "dd", type = "D")
90     @ExpectedLocals(name = "bb", type = "B")
91     @ExpectedLocals(name = "this", type = "LLocalVariableTableTest;")
longDoubleOverlap(long l, int i, double d)92     public double longDoubleOverlap(long l, int i, double d) {
93         long ll = 1L;
94         Object obj = 2;
95         double dd = 3.0;
96         byte bb = 0;
97         return l + i + d + ll + Integer.valueOf(obj.toString()) + dd + bb;
98     }
99 
100     @ExpectedLocals(name = "bool", type = "Z")
101     @ExpectedLocals(name = "b", type = "B")
102     @ExpectedLocals(name = "ch", type = "C")
103     @ExpectedLocals(name = "sh", type = "S")
104     @ExpectedLocals(name = "i", type = "I")
105     @ExpectedLocals(name = "l", type = "J")
106     @ExpectedLocals(name = "d", type = "D")
107     @ExpectedLocals(name = "f", type = "F")
108     @ExpectedLocals(name = "ref", type = "Ljava/lang/Integer;")
109     @ExpectedLocals(name = "arr", type = "[Ljava/lang/Integer;")
110     @ExpectedLocals(name = "this", type = "LLocalVariableTableTest;")
allTypesWithoutParameters()111     public void allTypesWithoutParameters() {
112         boolean bool = true;
113         byte b = 0x1;
114         char ch = 'a';
115         short sh = 1_1;
116         int i = -2;
117         long l = 1L;
118         float f = 1.1f;
119         double d = 0.1;
120         Integer ref = 2;
121         Integer[] arr = null;
122     }
123 
124     @ExpectedLocals(name = "bool", type = "Z")
125     @ExpectedLocals(name = "b", type = "B")
126     @ExpectedLocals(name = "ch", type = "C")
127     @ExpectedLocals(name = "sh", type = "S")
128     @ExpectedLocals(name = "i", type = "I")
129     @ExpectedLocals(name = "l", type = "J")
130     @ExpectedLocals(name = "d", type = "D")
131     @ExpectedLocals(name = "f", type = "F")
132     @ExpectedLocals(name = "ref", type = "Ljava/lang/Integer;")
133     @ExpectedLocals(name = "this", type = "LLocalVariableTableTest;")
allTypesWithParameters(boolean bool, byte b, char ch)134     public void allTypesWithParameters(boolean bool, byte b, char ch) {
135         short sh = 1_1;
136         int i = -2;
137         long l = 1L;
138         float f = 1.1f;
139         double d = 0.1;
140         Integer ref = 2;
141     }
142 
143     @ExpectedLocals(name = "list", type = "Ljava/util/List;")
144     @ExpectedLocals(name = "list2", type = "[Ljava/util/List;")
145     @ExpectedLocals(name = "p", type = "Ljava/lang/Object;")
146     @ExpectedLocals(name = "k", type = "Ljava/lang/Integer;")
147     @ExpectedLocals(name = "i", type = "I")
148     @ExpectedLocals(name = "this", type = "LLocalVariableTableTest;")
genericType(K k)149     public <T extends List<Integer>, P, K extends Integer> void genericType(K k) {
150         T list = null;
151         int i = 0;
152         P p = null;
153         List<T>[] list2 = null;
154     }
155 
156     @ExpectedLocals(name = "this", type = "LLocalVariableTableTest;")
157     @ExpectedLocals(name = "inWhile", type = "I")
158     @ExpectedLocals(name = "inTry", type = "D")
159     @ExpectedLocals(name = "inSync", type = "F")
160     @ExpectedLocals(name = "inDo", type = "B")
161     @ExpectedLocals(name = "inFor", type = "J")
162     @ExpectedLocals(name = "s", type = "Ljava/util/stream/Stream;")
deepScope()163     public void deepScope() {
164         {
165             while (true) {
166                 int inWhile = 0;
167                 for (long inFor : Arrays.asList(0)) {
168                     try (Stream<? extends Integer> s = Stream.of(0)) {
169                         double inTry = 0.0;
170                         synchronized (this) {
171                             float inSync = -1.0f;
172                             do {
173                                 byte inDo = 0;
174                                 switch (1) {
175                                     default:
176                                         short inSwitch = 100;
177                                 }
178                             } while (true);
179                         }
180                     }
181                 }
182             }
183         }
184     }
185 
186     class LocalVariableTable implements VariableTable {
187 
188         final LocalVariableTable_attribute att;
189 
LocalVariableTable(LocalVariableTable_attribute att)190         public LocalVariableTable(LocalVariableTable_attribute att) {
191             this.att = att;
192         }
193 
194         @Override
localVariableTableLength()195         public int localVariableTableLength() {
196             return att.local_variable_table_length;
197         }
198 
199         @Override
entries()200         public List<Entry> entries() {
201             return Stream.of(att.local_variable_table).map(LocalVariableTableEntry::new).collect(toList());
202         }
203 
204         @Override
attributeLength()205         public int attributeLength() {
206             return att.attribute_length;
207         }
208 
209         private class LocalVariableTableEntry implements Entry {
210 
211             final LocalVariableTable_attribute.Entry entry;
212 
LocalVariableTableEntry(LocalVariableTable_attribute.Entry entry)213             private LocalVariableTableEntry(LocalVariableTable_attribute.Entry entry) {
214                 this.entry = entry;
215             }
216 
217             @Override
index()218             public int index() {
219                 return entry.index;
220             }
221 
222             @Override
startPC()223             public int startPC() {
224                 return entry.start_pc;
225             }
226 
227             @Override
length()228             public int length() {
229                 return entry.length;
230             }
231 
232             @Override
name()233             public String name() {
234                 return getString(entry.name_index);
235             }
236 
237             @Override
type()238             public String type() {
239                 return getString(entry.descriptor_index);
240             }
241 
242             @Override
toString()243             public String toString() {
244                 return dump();
245             }
246         }
247     }
248 }
249