blob: 31dfaa5393197875dc0c656eb59d11242953b31f [file] [log] [blame]
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package tests.api.java.lang.reflect;
import dalvik.annotation.KnownFailure;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
/**
* Tests generic reflection in more complicated cases. In particular: Scoping of
* type parameters, equality of type parameters, wildcard types, parameterized
* types and multiple bounds.
*/
@TestTargetClass(Method.class)
public class GenericReflectionCornerCases extends GenericReflectionTestsBase {
static class Pair<T, S> {}
static class WildcardEquality<T> {
void wildcardEquality(Pair<? extends T, ? extends T> param) {}
}
@TestTargets({
@TestTargetNew(
level = TestLevel.PARTIAL,
notes = "Stress test.",
method = "getTypeParameters",
args = {}
),
@TestTargetNew(
level = TestLevel.PARTIAL,
notes = "Stress test.",
method = "getGenericParameterTypes",
args = {}
)
})
@SuppressWarnings("unchecked")
public void testWildcardEquality() throws Exception {
Class<? extends WildcardEquality> clazz = WildcardEquality.class;
Method method = clazz.getDeclaredMethod("wildcardEquality", Pair.class);
TypeVariable<?>[] typeParameters = clazz.getTypeParameters();
assertLenghtOne(typeParameters);
TypeVariable<?> typeParameter = typeParameters[0];
Type[] parameterTypes = method.getGenericParameterTypes();
assertLenghtOne(parameterTypes);
Type parameter = parameterTypes[0];
assertInstanceOf(ParameterizedType.class, parameter);
ParameterizedType paramType = (ParameterizedType) parameter;
Type[] actualTypeArguments = paramType.getActualTypeArguments();
assertEquals(2, actualTypeArguments.length);
Type firstArgument = actualTypeArguments[0];
assertInstanceOf(WildcardType.class, firstArgument);
WildcardType firstWildcardArgument = (WildcardType) firstArgument;
Type secondArgument = actualTypeArguments[1];
assertInstanceOf(WildcardType.class, secondArgument);
WildcardType secondWildcardArgument = (WildcardType) secondArgument;
assertEquals(firstWildcardArgument, secondWildcardArgument);
Type[] firstWildcardArgumentUpperBounds = firstWildcardArgument.getUpperBounds();
assertLenghtOne(firstWildcardArgumentUpperBounds);
Type firstWildcardArgumentUpperBoundsType = firstWildcardArgumentUpperBounds[0];
Type[] secondWildcardArgumentUpperBounds = secondWildcardArgument.getUpperBounds();
assertLenghtOne(secondWildcardArgumentUpperBounds);
Type secondWildcardArgumentUpperBoundsType = secondWildcardArgumentUpperBounds[0];
assertEquals(firstWildcardArgumentUpperBoundsType, secondWildcardArgumentUpperBoundsType);
assertEquals(typeParameter, firstWildcardArgumentUpperBoundsType);
assertEquals(typeParameter, secondWildcardArgumentUpperBoundsType);
}
static class WildcardUnEquality<T> {
void wildcardUnEquality(Pair<? extends T, ? super T> param) {}
}
@TestTargets({
@TestTargetNew(
level = TestLevel.PARTIAL,
notes = "Stress test.",
method = "getTypeParameters",
args = {}
),
@TestTargetNew(
level = TestLevel.PARTIAL,
notes = "Stress test.",
method = "getGenericParameterTypes",
args = {}
)
})
@SuppressWarnings("unchecked")
public void testWildcardUnEquality() throws Exception {
Class<? extends WildcardUnEquality> clazz = WildcardUnEquality.class;
Method method = clazz.getDeclaredMethod("wildcardUnEquality", Pair.class);
TypeVariable<?>[] typeParameters = clazz.getTypeParameters();
assertLenghtOne(typeParameters);
TypeVariable<?> typeParameter = typeParameters[0];
Type[] parameterTypes = method.getGenericParameterTypes();
assertLenghtOne(parameterTypes);
Type parameter = parameterTypes[0];
assertInstanceOf(ParameterizedType.class, parameter);
ParameterizedType paramType = (ParameterizedType) parameter;
Type[] actualTypeArguments = paramType.getActualTypeArguments();
assertEquals(2, actualTypeArguments.length);
Type firstArgument = actualTypeArguments[0];
assertInstanceOf(WildcardType.class, firstArgument);
WildcardType firstWildcardArgument = (WildcardType) firstArgument;
Type secondArgument = actualTypeArguments[1];
assertInstanceOf(WildcardType.class, secondArgument);
WildcardType secondWildcardArgument = (WildcardType) secondArgument;
assertNotEquals(firstWildcardArgument, secondWildcardArgument);
Type[] firstWildcardArgumentUpperBounds = firstWildcardArgument.getUpperBounds();
assertLenghtOne(firstWildcardArgumentUpperBounds);
Type firstWildcardArgumentUpperBoundsType = firstWildcardArgumentUpperBounds[0];
Type[] secondWildcardArgumentLowerBounds = secondWildcardArgument.getLowerBounds();
assertLenghtOne(secondWildcardArgumentLowerBounds);
Type secondWildcardArgumentLoweroundsType = secondWildcardArgumentLowerBounds[0];
assertEquals(firstWildcardArgumentUpperBoundsType, secondWildcardArgumentLoweroundsType);
assertEquals(typeParameter, firstWildcardArgumentUpperBoundsType);
assertEquals(typeParameter, secondWildcardArgumentLoweroundsType);
}
static class MultipleBoundedWildcardUnEquality<T extends Object & Comparable<MultipleBoundedWildcardUnEquality<T>>> {
void multipleBoundedWildcardUnEquality(Pair<? extends T, ? super T> param) {}
}
@TestTargets({
@TestTargetNew(
level = TestLevel.PARTIAL,
notes = "Stress test.",
method = "getTypeParameters",
args = {}
),
@TestTargetNew(
level = TestLevel.PARTIAL,
notes = "Stress test.",
method = "getGenericParameterTypes",
args = {}
)
})
@SuppressWarnings("unchecked")
@KnownFailure("Class MultipleBoundedWildcardUnEquality can not be found, "
+ "maybe the wrong class loader is used to get the raw type?")
public void testMultipleBoundedWildcardUnEquality() throws Exception {
Class<? extends MultipleBoundedWildcardUnEquality> clazz = MultipleBoundedWildcardUnEquality.class;
// new WildcardEquality<Object>().wildcardEquality(new Pair<String,
// Integer>());
Method method = clazz.getDeclaredMethod("multipleBoundedWildcardUnEquality", Pair.class);
TypeVariable<?>[] typeParameters = clazz.getTypeParameters();
assertLenghtOne(typeParameters);
TypeVariable<?> typeParameter = typeParameters[0];
Type[] typeParameterBounds = typeParameter.getBounds();
assertEquals(2, typeParameterBounds.length);
assertEquals(Object.class, typeParameterBounds[0]);
assertInstanceOf(ParameterizedType.class, typeParameterBounds[1]);
ParameterizedType parameterizedType = (ParameterizedType) typeParameterBounds[1];
assertEquals(Comparable.class, parameterizedType.getRawType());
Type[] typeArguments = parameterizedType.getActualTypeArguments();
assertLenghtOne(typeArguments);
assertInstanceOf(ParameterizedType.class, typeArguments[0]);
ParameterizedType type = (ParameterizedType) typeArguments[0];
assertEquals(typeParameter, type.getActualTypeArguments()[0]);
assertEquals(MultipleBoundedWildcardUnEquality.class, type.getRawType());
Type[] parameterTypes = method.getGenericParameterTypes();
assertLenghtOne(parameterTypes);
Type parameter = parameterTypes[0];
assertInstanceOf(ParameterizedType.class, parameter);
ParameterizedType paramType = (ParameterizedType) parameter;
Type[] actualTypeArguments = paramType.getActualTypeArguments();
assertEquals(2, actualTypeArguments.length);
Type firstArgument = actualTypeArguments[0];
assertInstanceOf(WildcardType.class, firstArgument);
WildcardType firstWildcardArgument = (WildcardType) firstArgument;
Type secondArgument = actualTypeArguments[1];
assertInstanceOf(WildcardType.class, secondArgument);
WildcardType secondWildcardArgument = (WildcardType) secondArgument;
assertNotEquals(firstWildcardArgument, secondWildcardArgument);
Type[] firstWildcardArgumentUpperBounds = firstWildcardArgument.getUpperBounds();
assertLenghtOne(firstWildcardArgumentUpperBounds);
Type firstWildcardArgumentUpperBoundsType = firstWildcardArgumentUpperBounds[0];
Type[] secondWildcardArgumentLowerBounds = secondWildcardArgument.getLowerBounds();
assertLenghtOne(secondWildcardArgumentLowerBounds);
Type secondWildcardArgumentLoweroundsType = secondWildcardArgumentLowerBounds[0];
assertEquals(firstWildcardArgumentUpperBoundsType, secondWildcardArgumentLoweroundsType);
}
static class MultipleBoundedWildcardEquality<T extends Object & Comparable<MultipleBoundedWildcardEquality<T>>> {
void multipleBoundedWildcardEquality(Pair<? extends T, ? extends T> param) {}
}
@TestTargets({
@TestTargetNew(
level = TestLevel.PARTIAL,
notes = "Stress test.",
method = "getTypeParameters",
args = {}
),
@TestTargetNew(
level = TestLevel.PARTIAL,
notes = "Stress test.",
method = "getGenericParameterTypes",
args = {}
)
})
@SuppressWarnings("unchecked")
@KnownFailure("Class MultipleBoundedWildcardEquality can not be found, "
+ "maybe the wrong class loader is used to get the raw type?")
public void testMultipleBoundedWildcard() throws Exception {
Class<? extends MultipleBoundedWildcardEquality> clazz = MultipleBoundedWildcardEquality.class;
Method method = clazz.getDeclaredMethod("multipleBoundedWildcardEquality", Pair.class);
TypeVariable<?>[] typeParameters = clazz.getTypeParameters();
assertLenghtOne(typeParameters);
TypeVariable<?> typeParameter = typeParameters[0];
Type[] typeParameterBounds = typeParameter.getBounds();
assertEquals(2, typeParameterBounds.length);
assertEquals(Object.class, typeParameterBounds[0]);
assertInstanceOf(ParameterizedType.class, typeParameterBounds[1]);
ParameterizedType parameterizedType = (ParameterizedType) typeParameterBounds[1];
assertEquals(Comparable.class, parameterizedType.getRawType());
Type[] typeArguments = parameterizedType.getActualTypeArguments();
assertLenghtOne(typeArguments);
assertInstanceOf(ParameterizedType.class, typeArguments[0]);
ParameterizedType type = (ParameterizedType) typeArguments[0];
assertEquals(typeParameter, type.getActualTypeArguments()[0]);
assertEquals(MultipleBoundedWildcardEquality.class, type.getRawType());
Type[] parameterTypes = method.getGenericParameterTypes();
assertLenghtOne(parameterTypes);
Type parameter = parameterTypes[0];
assertInstanceOf(ParameterizedType.class, parameter);
ParameterizedType paramType = (ParameterizedType) parameter;
Type[] actualTypeArguments = paramType.getActualTypeArguments();
assertEquals(2, actualTypeArguments.length);
Type firstArgument = actualTypeArguments[0];
assertInstanceOf(WildcardType.class, firstArgument);
WildcardType firstWildcardArgument = (WildcardType) firstArgument;
Type secondArgument = actualTypeArguments[1];
assertInstanceOf(WildcardType.class, secondArgument);
WildcardType secondWildcardArgument = (WildcardType) secondArgument;
assertEquals(firstWildcardArgument, secondWildcardArgument);
Type[] firstWildcardArgumentUpperBounds = firstWildcardArgument.getUpperBounds();
assertLenghtOne(firstWildcardArgumentUpperBounds);
Type firstWildcardArgumentUpperBoundsType = firstWildcardArgumentUpperBounds[0];
Type[] secondWildcardArgumentUpperBounds = secondWildcardArgument.getUpperBounds();
assertLenghtOne(secondWildcardArgumentUpperBounds);
Type secondWildcardArgumentLoweroundsType = secondWildcardArgumentUpperBounds[0];
assertEquals(firstWildcardArgumentUpperBoundsType, secondWildcardArgumentLoweroundsType);
}
}