1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * you may not use this file except in compliance with the License.
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * You may obtain a copy of the License at
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License.
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage tests.api.java.lang.reflect;
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.Method;
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.ParameterizedType;
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.Type;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.TypeVariable;
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.WildcardType;
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Tests bounded type parameters declared on methods and bounded wildcards.
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class WildcardTypeTest extends GenericReflectionTestsBase {
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @SuppressWarnings({"unchecked", "hiding"})
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static class BoundedWildcardsGenericMethods<T> {
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public <T extends BoundedWildcardsGenericMethods> void lowerBoundedParamNoReturn( BoundedWildcardsGenericMethods<? super T> param) {}
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public <T extends BoundedWildcardsGenericMethods> void upperBoundedParamNoReturn( BoundedWildcardsGenericMethods<? extends T> param) {}
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public <T extends BoundedWildcardsGenericMethods> T lowerBoundedParamReturn(BoundedWildcardsGenericMethods<? super T> param) { return (T) new Object(); }
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        public <T extends BoundedWildcardsGenericMethods> T upperBoundedParamReturn(BoundedWildcardsGenericMethods<? extends T> param) { return (T) new Object();}
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
41f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @SuppressWarnings("unchecked")
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static Class<? extends BoundedWildcardsGenericMethods> clazz = BoundedWildcardsGenericMethods.class;
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
45229e34b182b98e1dba15d3dc6341954986ae2b7aBrian Carlstrom    /**
46229e34b182b98e1dba15d3dc6341954986ae2b7aBrian Carlstrom     * Tests that there are is one Type Parameter on the Class itself.
47229e34b182b98e1dba15d3dc6341954986ae2b7aBrian Carlstrom     */
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void testBoundedGenericMethods() {
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertLenghtOne(clazz.getTypeParameters());
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Tests whether the type parameter is bounded by BoundedGenericMethods like:
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <T extends BoundedGenericMethods>.
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param method the declaring method
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void checkBoundedTypeParameter(Method method) {
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        TypeVariable<Method> typeParameter = getTypeParameter(method);
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertEquals("T", typeParameter.getName());
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertEquals(method, typeParameter.getGenericDeclaration());
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Type[] bounds = typeParameter.getBounds();
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertLenghtOne(bounds);
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Type bound = bounds[0];
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertEquals(BoundedWildcardsGenericMethods.class, bound);
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void checkLowerBoundedParameter(Method method) {
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Type genericParameterType = method.getGenericParameterTypes()[0];
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertInstanceOf(ParameterizedType.class, genericParameterType);
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ParameterizedType parameterizedType = (ParameterizedType) genericParameterType;
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertLenghtOne(actualTypeArguments);
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertInstanceOf(WildcardType.class, actualTypeArguments[0]);
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        WildcardType wildcardType = (WildcardType) actualTypeArguments[0];
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Type[] lowerBounds = wildcardType.getLowerBounds();
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertLenghtOne(lowerBounds);
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Type lowerBound = lowerBounds[0];
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertEquals(getTypeParameter(method), lowerBound);
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Type[] upperBounds = wildcardType.getUpperBounds();
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertEquals(Object.class, upperBounds[0]);
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void checkUpperBoundedParameter(Method method) {
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertLenghtOne(method.getGenericParameterTypes());
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Type genericParameterType = method.getGenericParameterTypes()[0];
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertInstanceOf(ParameterizedType.class, genericParameterType);
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ParameterizedType parameterizedType = (ParameterizedType) genericParameterType;
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertLenghtOne(actualTypeArguments);
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertInstanceOf(WildcardType.class, actualTypeArguments[0]);
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        WildcardType wildcardType = (WildcardType) actualTypeArguments[0];
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertLenghtZero(wildcardType.getLowerBounds());
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Type[] upperBounds = wildcardType.getUpperBounds();
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertLenghtOne(upperBounds);
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Type upperBound = upperBounds[0];
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertEquals(getTypeParameter(method), upperBound);
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
107f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @SuppressWarnings("unchecked")
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void checkReturnType(Method method) {
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Type genericReturnType = method.getGenericReturnType();
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertEquals(getTypeParameter(method), genericReturnType);
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertTrue(genericReturnType instanceof TypeVariable);
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        TypeVariable<Method> returnTypeVariable = (TypeVariable<Method>) genericReturnType;
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertEquals(method, returnTypeVariable.getGenericDeclaration());
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Type[] bounds = returnTypeVariable.getBounds();
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertLenghtOne(bounds);
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Type bound = bounds[0];
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertEquals(BoundedWildcardsGenericMethods.class, bound);
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
123f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void testUpperBoundedParamNoReturn() throws Exception {
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Method method = clazz.getMethod("upperBoundedParamNoReturn", BoundedWildcardsGenericMethods.class);
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkBoundedTypeParameter(method);
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkUpperBoundedParameter(method);
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
129f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void testLowerBoundedParamReturn() throws Exception {
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Method method = clazz.getMethod("lowerBoundedParamReturn", BoundedWildcardsGenericMethods.class);
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkBoundedTypeParameter(method);
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkLowerBoundedParameter(method);
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkReturnType(method);
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
136f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void testUpperBoundedParamReturn() throws Exception {
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Method method = clazz.getMethod("upperBoundedParamReturn", BoundedWildcardsGenericMethods.class);
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkBoundedTypeParameter(method);
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkUpperBoundedParameter(method);
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkReturnType(method);
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
143f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void testLowerBoundedParamNoReturn() throws Exception {
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Method method = clazz.getMethod("lowerBoundedParamNoReturn", BoundedWildcardsGenericMethods.class);
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkBoundedTypeParameter(method);
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        assertLenghtOne(method.getGenericParameterTypes());
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkLowerBoundedParameter(method);
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
152