1/*
2 * Copyright (c) 2004, 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 *
26 * @summary Check getEnclosingClass and other methods
27 * @author Peter von der Ah\u00e9
28 *
29 * a) Top level classes
30 * b) Nested classes (static member classes)
31 * c) Inner classes (non-static member classes)
32 * d) Local classes (named classes declared within a method)
33 * e) Anonymous classes
34 */
35
36/*
37 * TODO:
38 * Test annotations
39 * Test Locals in static initializers
40 * Test Locals in methods
41 * Test Locals in constructors
42 * Test interfaces
43 * Test enums
44 * Test method with a String[] argument
45 */
46
47//package
48
49import common.TestMe;
50
51interface MakeClass {
52    Class<?> make();
53}
54
55public class EnclosingClass {
56    public EnclosingClass() {
57        aec = (new Object() {}).getClass();
58    }
59    static class Nested {
60        static class NestedNested {
61        }
62        class NestedInner {
63        }
64        Class<?> nestedLocal0;
65        Class<?> nestedLocal1;
66        Class<?> nestedLocal2;
67        {
68            class NestedLocal0 {};
69            nestedLocal0 = NestedLocal0.class;
70            nestedMethod1();
71            nestedMethod2(null);
72        }
73        void nestedMethod1() {
74            class NestedLocal1 {}
75            nestedLocal1 = NestedLocal1.class;
76        }
77        void nestedMethod2(String[] args) {
78            class NestedLocal2 {}
79            nestedLocal2 = NestedLocal2.class;
80        }
81        Class<?> nestedAnonymous = (new Object() {}).getClass();
82        static enum NestedNestedEnum {
83        }
84        enum NestedInnerEnum {
85        }
86    }
87
88    class Inner {
89        class InnerInner {
90        }
91        Class<?> innerLocal0;
92        Class<?> innerLocal1;
93        Class<?> innerLocal2;
94        {
95            class InnerLocal0 {
96            };
97            innerLocal0 = InnerLocal0.class;
98            innerMethod1();
99            innerMethod2(null);
100        }
101        void innerMethod1() {
102            class InnerLocal1 {}
103            innerLocal1 = InnerLocal1.class;
104        }
105        void innerMethod2(String[] args) {
106            class InnerLocal2 {}
107            innerLocal2 = InnerLocal2.class;
108        }
109        Class<?> innerAnonymous = (new Object() {}).getClass();
110    }
111
112    @TestMe(desc="top level class",
113            encl="null",
114            simple="EnclosingClass",
115            canonical="EnclosingClass")
116        public Class<?> a = EnclosingClass.class;
117
118    @TestMe(desc="nested class within top level class",
119            encl="class EnclosingClass",
120            simple="Nested",
121            canonical="EnclosingClass.Nested")
122        public Class<?> ab = Nested.class;
123    @TestMe(desc="inner class within top level class",
124            encl="class EnclosingClass",
125            simple="Inner",
126            canonical="EnclosingClass.Inner")
127        public Class<?> ac = Inner.class;
128    @TestMe(desc="local class within top level class",
129            encl="class EnclosingClass",
130            simple="Local0",
131            hasCanonical=false)
132        public Class<?> ad0;
133    @TestMe(desc="local class within top level class",
134            encl="class EnclosingClass",
135            simple="Local1",
136            hasCanonical=false)
137        public Class<?> ad1;
138    @TestMe(desc="local class within top level class",
139            encl="class EnclosingClass",
140            simple="Local2",
141            hasCanonical=false)
142        public Class<?> ad2;
143    @TestMe(desc="local class within a top level class static initializer" ,
144            encl="class EnclosingClass",
145            simple="StaticLocal0",
146            hasCanonical=false)
147        public Class<?> sad0;
148    @TestMe(desc="local class within a top level class static method" ,
149            encl="class EnclosingClass",
150            simple="StaticLocal1",
151            hasCanonical=false)
152        public Class<?> sad1;
153    @TestMe(desc="local class within a top level class static method",
154            encl="class EnclosingClass",
155            simple="StaticLocal2",
156            hasCanonical=false)
157        public Class<?> sad2;
158    {
159        class Local0 {
160            class LocalInner {}
161            {
162                class LocalLocal {};
163                dd = LocalLocal.class;
164                de = (new Object() {}).getClass();
165            }
166        };
167        ad0 = Local0.class;
168        dc = Local0.LocalInner.class;
169        new Local0();
170        method1();
171        method2(null);
172        sad0 = staticLocal0;
173        sad1 = staticMethod1();
174        sad2 = staticMethod2(null);
175    }
176    static Class<?> staticLocal0;
177    static {
178        class StaticLocal0 {};
179        staticLocal0 = StaticLocal0.class;
180    }
181    static Class<?> staticMethod1() {
182        class StaticLocal1 {};
183        return StaticLocal1.class;
184    }
185    static Class<?> staticMethod2(String[] args) {
186        class StaticLocal2 {};
187        return StaticLocal2.class;
188    }
189    void method1() {
190        class Local1 {};
191        ad1 = Local1.class;
192    }
193    void method2(String[] args) {
194        class Local2 {};
195        ad2 = Local2.class;
196    }
197    @TestMe(desc="anonymous class within top level class",
198            encl="class EnclosingClass",
199            simple="",
200            hasCanonical=false)
201        public Class<?> ae = (new Object() {}).getClass();
202    @TestMe(desc="anonymous class within top level class constructor",
203            encl="class EnclosingClass",
204            simple="",
205            hasCanonical=false)
206        public Class<?> aec;
207
208    @TestMe(desc="nested class within nested class",
209            encl="class EnclosingClass$Nested",
210            simple="NestedNested",
211            canonical="EnclosingClass.Nested.NestedNested")
212        public Class<?> bb = Nested.NestedNested.class;
213    @TestMe(desc="inner class within nested class",
214            encl="class EnclosingClass$Nested",
215            simple="NestedInner",
216            canonical="EnclosingClass.Nested.NestedInner")
217        public Class<?> bc = Nested.NestedInner.class;
218    @TestMe(desc="local class within nested class",
219            encl="class EnclosingClass$Nested",
220            simple="NestedLocal0",
221            hasCanonical=false)
222        public Class<?> bd0 = (new Nested()).nestedLocal0;
223    @TestMe(desc="local class within nested class",
224            encl="class EnclosingClass$Nested",
225            simple="NestedLocal1",
226            hasCanonical=false)
227        public Class<?> bd1 = (new Nested()).nestedLocal1;
228    @TestMe(desc="local class within nested class",
229            encl="class EnclosingClass$Nested",
230            simple="NestedLocal2",
231            hasCanonical=false)
232        public Class<?> bd2 = (new Nested()).nestedLocal2;
233    @TestMe(desc="anonymous class within nested class",
234            encl="class EnclosingClass$Nested",
235            simple="",
236            hasCanonical=false)
237        public Class<?> be = (new Nested()).nestedAnonymous;
238
239    @TestMe(desc="nested class within an inner class", encl="", simple="")
240        public Class<?> cb = Void.class; // not legal
241    @TestMe(desc="inner class within an inner class",
242            encl="class EnclosingClass$Inner",
243            simple="InnerInner",
244            canonical="EnclosingClass.Inner.InnerInner")
245        public Class<?> cc = ((new Inner()).new InnerInner()).getClass();
246    @TestMe(desc="local class within an inner class",
247            encl="class EnclosingClass$Inner",
248            simple="InnerLocal0",
249            hasCanonical=false)
250        public Class<?> cd = (new Inner()).innerLocal0;
251    @TestMe(desc="anonymous class within an inner class",
252            encl="class EnclosingClass$Inner",
253            simple="",
254            hasCanonical=false)
255        public Class<?> ce = (new Inner()).innerAnonymous;
256
257    @TestMe(desc="nested class within a local class", encl="", simple="")
258        public Class<?> db = Void.class; // not legal
259    @TestMe(desc="inner class within a local class",
260            encl="class EnclosingClass$1Local0",
261            simple="LocalInner",
262            hasCanonical=false)
263        public Class<?> dc; // initialized above
264    @TestMe(desc="local class within a local class",
265            encl="class EnclosingClass$1Local0",
266            simple="LocalLocal",
267            hasCanonical=false)
268        public Class<?> dd; // initialized above
269    @TestMe(desc="anonymous class within a local class",
270            encl="class EnclosingClass$1Local0",
271            simple="",
272            hasCanonical=false)
273        public Class<?> de; // initialized above
274
275    @TestMe(desc="nested class within an anonymous class", encl="", simple="")
276        public Class<?> eb = Void.class; // not legal
277    @TestMe(desc="inner class within an anonymous class",
278            encl="class EnclosingClass$3",
279            simple="AnonymousInner",
280            hasCanonical=false)
281        public Class<?> ec = new MakeClass() {
282                class AnonymousInner {}
283                public Class<?> make() { return AnonymousInner.class; }
284            }.make();
285    @TestMe(desc="local class within an anonymous class",
286            encl="class EnclosingClass$4",
287            simple="AnonymousLocal",
288            hasCanonical=false)
289        public Class<?> ed = new MakeClass() {
290                Class<?> c;
291                {
292                    class AnonymousLocal {}
293                    c = AnonymousLocal.class;
294                }
295                public Class<?> make() { return c; }
296            }.make();
297    @TestMe(desc="anonymous class within an anonymous class",
298            encl="class EnclosingClass$5",
299            simple="",
300            hasCanonical=false)
301        public Class<?> ee = new MakeClass() {
302                Class<?> c;
303                {
304                    c = new Object() {}.getClass();
305                }
306                public Class<?> make() { return c; }
307            }.make();
308
309    @TestMe(desc="the primitive boolean type",
310            encl="null",
311            simple="boolean",
312            canonical="boolean")
313        public Class<?> booleanClass = boolean.class;
314
315    @TestMe(desc="the primitive char type",
316            encl="null",
317            simple="char",
318            canonical="char")
319        public Class<?> charClass = char.class;
320
321    @TestMe(desc="the primitive byte type",
322            encl="null",
323            simple="byte",
324            canonical="byte")
325        public Class<?> byteClass = byte.class;
326
327    @TestMe(desc="the primitive short type",
328            encl="null",
329            simple="short",
330            canonical="short")
331        public Class<?> shortClass = short.class;
332
333    @TestMe(desc="the primitive int type",
334            encl="null",
335            simple="int",
336            canonical="int")
337        public Class<?> intClass = int.class;
338
339    @TestMe(desc="the primitive long type",
340            encl="null",
341            simple="long",
342            canonical="long")
343        public Class<?> longClass = long.class;
344
345    @TestMe(desc="the primitive float type",
346            encl="null",
347            simple="float",
348            canonical="float")
349        public Class<?> floatClass = float.class;
350
351    @TestMe(desc="the primitive double type",
352            encl="null",
353            simple="double",
354            canonical="double")
355        public Class<?> doubleClass = double.class;
356
357    @TestMe(desc="the primitive void type",
358            encl="null",
359            simple="void",
360            canonical="void")
361        public Class<?> voidClass = void.class;
362
363}
364