1/*
2 * Copyright (c) 2013, 2014, 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 * @bug 8024915 8044629
27 */
28
29import java.lang.reflect.AnnotatedType;
30import java.lang.reflect.Executable;
31import java.util.Arrays;
32
33public class GetAnnotatedReceiverType {
34    public void method() {}
35    public void method0(GetAnnotatedReceiverType this) {}
36    public static void method4() {}
37
38    class Inner0 {
39        public Inner0() {}
40    }
41
42    class Inner1 {
43        public Inner1(GetAnnotatedReceiverType GetAnnotatedReceiverType.this) {}
44    }
45
46    public static class Nested {
47        public Nested() {}
48
49        public class NestedInner {
50            public NestedInner() { }
51
52            public Class<?> getLocalClass () {
53                class NestedInnerLocal { public NestedInnerLocal() {} }
54                return NestedInnerLocal.class;
55            }
56
57            public Class<?> getAnonymousClass() {
58                return new Object() {}.getClass();
59            }
60        }
61    }
62
63    public class Inner2 {
64        public Inner2() { }
65
66        public class Inner3 {
67            public Inner3() { }
68
69            public Class<?> getLocalClass () {
70                class InnerLocal { public InnerLocal() {} }
71                return InnerLocal.class;
72            }
73
74            public Class<?> getAnonymousClass() {
75                return new Object() {}.getClass();
76            }
77        }
78
79        public Class<?> getLocalClass () {
80            class InnerLocal { public InnerLocal() {} }
81                return InnerLocal.class;
82        }
83
84        public Class<?> getAnonymousClass() {
85            return new Object() {}.getClass();
86        }
87    }
88
89    private static int failures = 0;
90    private static int tests = 0;
91
92    public static void main(String[] args) throws NoSuchMethodException {
93        checkEmptyAT(GetAnnotatedReceiverType.class.getMethod("method"),
94                "getAnnotatedReceiverType for \"method\" should return an empty AnnotatedType");
95        checkEmptyAT(Inner0.class.getConstructor(GetAnnotatedReceiverType.class),
96                "getAnnotatedReceiverType for a ctor without a \"this\" should return an empty AnnotatedType");
97
98        checkEmptyAT(GetAnnotatedReceiverType.class.getMethod("method0"),
99                "getAnnotatedReceiverType for \"method0\" should return an empty AnnotatedType");
100        checkEmptyAT(Inner1.class.getConstructor(GetAnnotatedReceiverType.class),
101                "getAnnotatedReceiverType for a ctor with a \"this\" should return an empty AnnotatedType");
102
103        checkNull(GetAnnotatedReceiverType.class.getMethod("method4"),
104                "getAnnotatedReceiverType() on a static method should return null");
105
106        // More nested, inner, local and anonymous classes
107        Nested nested = new Nested();
108        Nested.NestedInner instance = nested.new NestedInner();
109        checkNull(nested.getClass().getConstructors()[0],
110                "getAnnotatedReceiverType() on a constructor for a static class should return null");
111        checkEmptyAT(instance.getClass().getConstructors()[0],
112                "getAnnotatedReceiverType for a ctor without a \"this\" should return an empty AnnotatedType");
113        checkNull(instance.getLocalClass().getConstructors()[0],
114                "getAnnotatedReceiverType() on a constructor for a local class should return null");
115        checkNull(instance.getAnonymousClass().getDeclaredConstructors()[0],
116                "getAnnotatedReceiverType() on a constructor for an anonymous class should return null");
117
118        GetAnnotatedReceiverType outer = new GetAnnotatedReceiverType();
119        Inner2 instance2 = outer.new Inner2();
120        checkEmptyAT(instance2.getClass().getConstructors()[0],
121                "getAnnotatedReceiverType for a ctor without a \"this\" should return an empty AnnotatedType");
122        checkNull(instance2.getLocalClass().getConstructors()[0],
123                "getAnnotatedReceiverType() on a constructor for a local class should return null");
124        checkNull(instance2.getAnonymousClass().getDeclaredConstructors()[0],
125                "getAnnotatedReceiverType() on a constructor for an anonymous class should return null");
126
127        Inner2.Inner3 instance3 = instance2.new Inner3();
128        checkEmptyAT(instance3.getClass().getConstructors()[0],
129                "getAnnotatedReceiverType for a ctor without a \"this\" should return an empty AnnotatedType");
130        checkNull(instance3.getLocalClass().getConstructors()[0],
131                "getAnnotatedReceiverType() on a constructor for a local class should return null");
132        checkNull(instance3.getAnonymousClass().getDeclaredConstructors()[0],
133                "getAnnotatedReceiverType() on a constructor for an anonymous class should return null");
134
135        if (failures != 0)
136            throw new RuntimeException("Test failed, see log for details");
137        else if (tests != 15)
138            throw new RuntimeException("Not all cases ran, failing");
139    }
140
141    private static void checkNull(Executable e, String msg) {
142        AnnotatedType a = e.getAnnotatedReceiverType();
143        if (a != null) {
144            failures++;
145            System.err.println(msg + ": " + e);
146        }
147        tests++;
148    }
149
150    private static void checkEmptyAT(Executable e, String msg) {
151        AnnotatedType a = e.getAnnotatedReceiverType();
152        if (a.getAnnotations().length != 0) {
153            failures++;
154            System.err.print(msg + ": " + e);
155        }
156        tests++;
157    }
158}
159