1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package libcore.java.lang.reflect;
18
19import java.lang.reflect.Method;
20import java.lang.reflect.ParameterizedType;
21import java.lang.reflect.Type;
22import java.lang.reflect.TypeVariable;
23import java.lang.reflect.WildcardType;
24import tests.api.java.lang.reflect.GenericReflectionTestsBase;
25
26/**
27 * Tests generic reflection in more complicated cases. In particular: Scoping of
28 * type parameters, equality of type parameters, wildcard types, parameterized
29 * types and multiple bounds.
30 */
31public class OldGenericReflectionCornerCases extends GenericReflectionTestsBase {
32
33    static class Pair<T, S> {}
34
35    static class WildcardEquality<T> {
36        void wildcardEquality(Pair<? extends T, ? extends T> param) {}
37    }
38    @SuppressWarnings("unchecked")
39    public void testWildcardEquality() throws Exception {
40        Class<? extends WildcardEquality> clazz = WildcardEquality.class;
41
42        Method method = clazz.getDeclaredMethod("wildcardEquality", Pair.class);
43        TypeVariable<?>[] typeParameters = clazz.getTypeParameters();
44        assertLenghtOne(typeParameters);
45        TypeVariable<?> typeParameter = typeParameters[0];
46
47        Type[] parameterTypes = method.getGenericParameterTypes();
48        assertLenghtOne(parameterTypes);
49        Type parameter = parameterTypes[0];
50        assertInstanceOf(ParameterizedType.class, parameter);
51        ParameterizedType paramType = (ParameterizedType) parameter;
52        Type[] actualTypeArguments = paramType.getActualTypeArguments();
53        assertEquals(2, actualTypeArguments.length);
54
55        Type firstArgument = actualTypeArguments[0];
56        assertInstanceOf(WildcardType.class, firstArgument);
57        WildcardType firstWildcardArgument = (WildcardType) firstArgument;
58        Type secondArgument = actualTypeArguments[1];
59        assertInstanceOf(WildcardType.class, secondArgument);
60        WildcardType secondWildcardArgument = (WildcardType) secondArgument;
61
62        assertEquals(firstWildcardArgument, secondWildcardArgument);
63
64        Type[] firstWildcardArgumentUpperBounds = firstWildcardArgument.getUpperBounds();
65        assertLenghtOne(firstWildcardArgumentUpperBounds);
66        Type firstWildcardArgumentUpperBoundsType = firstWildcardArgumentUpperBounds[0];
67
68        Type[] secondWildcardArgumentUpperBounds = secondWildcardArgument.getUpperBounds();
69        assertLenghtOne(secondWildcardArgumentUpperBounds);
70        Type secondWildcardArgumentUpperBoundsType = secondWildcardArgumentUpperBounds[0];
71
72        assertEquals(firstWildcardArgumentUpperBoundsType, secondWildcardArgumentUpperBoundsType);
73
74        assertEquals(typeParameter, firstWildcardArgumentUpperBoundsType);
75        assertEquals(typeParameter, secondWildcardArgumentUpperBoundsType);
76    }
77
78    static class WildcardUnEquality<T> {
79        void wildcardUnEquality(Pair<? extends T, ? super T> param) {}
80    }
81    @SuppressWarnings("unchecked")
82    public void testWildcardUnEquality() throws Exception {
83        Class<? extends WildcardUnEquality> clazz = WildcardUnEquality.class;
84
85        Method method = clazz.getDeclaredMethod("wildcardUnEquality", Pair.class);
86        TypeVariable<?>[] typeParameters = clazz.getTypeParameters();
87        assertLenghtOne(typeParameters);
88        TypeVariable<?> typeParameter = typeParameters[0];
89
90        Type[] parameterTypes = method.getGenericParameterTypes();
91        assertLenghtOne(parameterTypes);
92        Type parameter = parameterTypes[0];
93        assertInstanceOf(ParameterizedType.class, parameter);
94        ParameterizedType paramType = (ParameterizedType) parameter;
95        Type[] actualTypeArguments = paramType.getActualTypeArguments();
96        assertEquals(2, actualTypeArguments.length);
97
98        Type firstArgument = actualTypeArguments[0];
99        assertInstanceOf(WildcardType.class, firstArgument);
100        WildcardType firstWildcardArgument = (WildcardType) firstArgument;
101        Type secondArgument = actualTypeArguments[1];
102        assertInstanceOf(WildcardType.class, secondArgument);
103        WildcardType secondWildcardArgument = (WildcardType) secondArgument;
104
105        assertNotEquals(firstWildcardArgument, secondWildcardArgument);
106
107        Type[] firstWildcardArgumentUpperBounds = firstWildcardArgument.getUpperBounds();
108        assertLenghtOne(firstWildcardArgumentUpperBounds);
109        Type firstWildcardArgumentUpperBoundsType = firstWildcardArgumentUpperBounds[0];
110
111        Type[] secondWildcardArgumentLowerBounds = secondWildcardArgument.getLowerBounds();
112        assertLenghtOne(secondWildcardArgumentLowerBounds);
113        Type secondWildcardArgumentLoweroundsType = secondWildcardArgumentLowerBounds[0];
114
115        assertEquals(firstWildcardArgumentUpperBoundsType, secondWildcardArgumentLoweroundsType);
116        assertEquals(typeParameter, firstWildcardArgumentUpperBoundsType);
117        assertEquals(typeParameter, secondWildcardArgumentLoweroundsType);
118    }
119
120    static class MultipleBoundedWildcardUnEquality<T extends Object & Comparable<MultipleBoundedWildcardUnEquality<T>>> {
121        void multipleBoundedWildcardUnEquality(Pair<? extends T, ? super T> param) {}
122    }
123    @SuppressWarnings("unchecked")
124    public void testMultipleBoundedWildcardUnEquality() throws Exception {
125        Class<? extends MultipleBoundedWildcardUnEquality> clazz = MultipleBoundedWildcardUnEquality.class;
126
127        // new WildcardEquality<Object>().wildcardEquality(new Pair<String,
128        // Integer>());
129
130        Method method = clazz.getDeclaredMethod("multipleBoundedWildcardUnEquality", Pair.class);
131        TypeVariable<?>[] typeParameters = clazz.getTypeParameters();
132        assertLenghtOne(typeParameters);
133        TypeVariable<?> typeParameter = typeParameters[0];
134        Type[] typeParameterBounds = typeParameter.getBounds();
135        assertEquals(2, typeParameterBounds.length);
136        assertEquals(Object.class, typeParameterBounds[0]);
137        assertInstanceOf(ParameterizedType.class, typeParameterBounds[1]);
138        ParameterizedType parameterizedType = (ParameterizedType) typeParameterBounds[1];
139        assertEquals(Comparable.class, parameterizedType.getRawType());
140        Type[] typeArguments = parameterizedType.getActualTypeArguments();
141        assertLenghtOne(typeArguments);
142        assertInstanceOf(ParameterizedType.class, typeArguments[0]);
143        ParameterizedType type = (ParameterizedType) typeArguments[0];
144        assertEquals(typeParameter, type.getActualTypeArguments()[0]);
145        assertEquals(MultipleBoundedWildcardUnEquality.class, type.getRawType());
146
147        Type[] parameterTypes = method.getGenericParameterTypes();
148        assertLenghtOne(parameterTypes);
149        Type parameter = parameterTypes[0];
150        assertInstanceOf(ParameterizedType.class, parameter);
151        ParameterizedType paramType = (ParameterizedType) parameter;
152        Type[] actualTypeArguments = paramType.getActualTypeArguments();
153        assertEquals(2, actualTypeArguments.length);
154
155        Type firstArgument = actualTypeArguments[0];
156        assertInstanceOf(WildcardType.class, firstArgument);
157        WildcardType firstWildcardArgument = (WildcardType) firstArgument;
158        Type secondArgument = actualTypeArguments[1];
159        assertInstanceOf(WildcardType.class, secondArgument);
160        WildcardType secondWildcardArgument = (WildcardType) secondArgument;
161
162        assertNotEquals(firstWildcardArgument, secondWildcardArgument);
163
164        Type[] firstWildcardArgumentUpperBounds = firstWildcardArgument.getUpperBounds();
165        assertLenghtOne(firstWildcardArgumentUpperBounds);
166        Type firstWildcardArgumentUpperBoundsType = firstWildcardArgumentUpperBounds[0];
167
168        Type[] secondWildcardArgumentLowerBounds = secondWildcardArgument.getLowerBounds();
169        assertLenghtOne(secondWildcardArgumentLowerBounds);
170        Type secondWildcardArgumentLoweroundsType = secondWildcardArgumentLowerBounds[0];
171
172        assertEquals(firstWildcardArgumentUpperBoundsType, secondWildcardArgumentLoweroundsType);
173    }
174
175    static class MultipleBoundedWildcardEquality<T extends Object & Comparable<MultipleBoundedWildcardEquality<T>>> {
176        void multipleBoundedWildcardEquality(Pair<? extends T, ? extends T> param) {}
177    }
178    @SuppressWarnings("unchecked")
179    public void testMultipleBoundedWildcard() throws Exception {
180        Class<? extends MultipleBoundedWildcardEquality> clazz = MultipleBoundedWildcardEquality.class;
181
182        Method method = clazz.getDeclaredMethod("multipleBoundedWildcardEquality", Pair.class);
183        TypeVariable<?>[] typeParameters = clazz.getTypeParameters();
184        assertLenghtOne(typeParameters);
185        TypeVariable<?> typeParameter = typeParameters[0];
186        Type[] typeParameterBounds = typeParameter.getBounds();
187        assertEquals(2, typeParameterBounds.length);
188        assertEquals(Object.class, typeParameterBounds[0]);
189        assertInstanceOf(ParameterizedType.class, typeParameterBounds[1]);
190        ParameterizedType parameterizedType = (ParameterizedType) typeParameterBounds[1];
191        assertEquals(Comparable.class, parameterizedType.getRawType());
192        Type[] typeArguments = parameterizedType.getActualTypeArguments();
193        assertLenghtOne(typeArguments);
194        assertInstanceOf(ParameterizedType.class, typeArguments[0]);
195        ParameterizedType type = (ParameterizedType) typeArguments[0];
196        assertEquals(typeParameter, type.getActualTypeArguments()[0]);
197        assertEquals(MultipleBoundedWildcardEquality.class, type.getRawType());
198
199        Type[] parameterTypes = method.getGenericParameterTypes();
200        assertLenghtOne(parameterTypes);
201        Type parameter = parameterTypes[0];
202        assertInstanceOf(ParameterizedType.class, parameter);
203        ParameterizedType paramType = (ParameterizedType) parameter;
204        Type[] actualTypeArguments = paramType.getActualTypeArguments();
205        assertEquals(2, actualTypeArguments.length);
206
207        Type firstArgument = actualTypeArguments[0];
208        assertInstanceOf(WildcardType.class, firstArgument);
209        WildcardType firstWildcardArgument = (WildcardType) firstArgument;
210        Type secondArgument = actualTypeArguments[1];
211        assertInstanceOf(WildcardType.class, secondArgument);
212        WildcardType secondWildcardArgument = (WildcardType) secondArgument;
213
214        assertEquals(firstWildcardArgument, secondWildcardArgument);
215
216        Type[] firstWildcardArgumentUpperBounds = firstWildcardArgument.getUpperBounds();
217        assertLenghtOne(firstWildcardArgumentUpperBounds);
218        Type firstWildcardArgumentUpperBoundsType = firstWildcardArgumentUpperBounds[0];
219
220        Type[] secondWildcardArgumentUpperBounds = secondWildcardArgument.getUpperBounds();
221        assertLenghtOne(secondWildcardArgumentUpperBounds);
222        Type secondWildcardArgumentLoweroundsType = secondWildcardArgumentUpperBounds[0];
223
224        assertEquals(firstWildcardArgumentUpperBoundsType, secondWildcardArgumentLoweroundsType);
225    }
226}
227