You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2020/11/15 16:49:16 UTC
[commons-lang] branch master updated: [LANG-1420]
TypeUtils.isAssignable returns wrong result for GenericArrayType and
ParameterizedType.
This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-lang.git
The following commit(s) were added to refs/heads/master by this push:
new 35799d0 [LANG-1420] TypeUtils.isAssignable returns wrong result for GenericArrayType and ParameterizedType.
35799d0 is described below
commit 35799d095886243ad32f46c81a77f85743d5fb05
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Sun Nov 15 11:49:11 2020 -0500
[LANG-1420] TypeUtils.isAssignable returns wrong result for
GenericArrayType and ParameterizedType.
---
src/changes/changes.xml | 13 +-
.../apache/commons/lang3/reflect/TypeUtils.java | 11 +-
.../commons/lang3/reflect/TypeUtilsTest.java | 863 +++++++++++----------
3 files changed, 487 insertions(+), 400 deletions(-)
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 300ee63..9d070a5 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -52,12 +52,13 @@ The <action> type attribute can be add,update,fix,remove.
<action type="fix" dev="ggregory" due-to="iamchao1129">ContextedException Javadoc add missing semicolon #581.</action>
<action issue="LANG-1608" type="fix" dev="aherbert" due-to="Edgar Asatryan">Resolve JUnit pioneer transitive dependencies using JUnit BOM.</action>
<action type="fix" dev="aherbert" due-to="HubertWo, Gary Gregory">NumberUtilsTest - incorrect types in min/max tests #634.</action>
- <action issue="LANG-1579" type="update" dev="aherbert" due-to="XenoAmess">Improve StringUtils.stripAccents conversion of remaining accents.</action>
- <action issue="LANG-1606" type="update" dev="sebb" due-to="Rustem Galiev">StringUtils.countMatches - clarify Javadoc.</action>
- <action issue="LANG-1591" type="update" dev="kinow" due-to="bhawna94">Remove redundant argument from substring call.</action>
- <action issue="LANG-1613" type="update" dev="ggregory" due-to="Arturo Bernal, Gary Gregory">BigDecimal is created when you pass it the min and max values, #642.</action>
- <action issue="LANG-1541" type="update" dev="ggregory" due-to="Arturo Bernal, Gary Gregory">ArrayUtils.contains() and indexOf() fails to handle Double.NaN #647.</action>
- <action issue="LANG-1541" type="update" dev="ggregory" due-to="Gary Gregory">Fix potential NPE in TypeUtils.isAssignable(Type, ParameterizedType, Map, Type>).</action>
+ <action issue="LANG-1579" type="fix" dev="aherbert" due-to="XenoAmess">Improve StringUtils.stripAccents conversion of remaining accents.</action>
+ <action issue="LANG-1606" type="fix" dev="sebb" due-to="Rustem Galiev">StringUtils.countMatches - clarify Javadoc.</action>
+ <action issue="LANG-1591" type="fix" dev="kinow" due-to="bhawna94">Remove redundant argument from substring call.</action>
+ <action issue="LANG-1613" type="fix" dev="ggregory" due-to="Arturo Bernal, Gary Gregory">BigDecimal is created when you pass it the min and max values, #642.</action>
+ <action issue="LANG-1541" type="fix" dev="ggregory" due-to="Arturo Bernal, Gary Gregory">ArrayUtils.contains() and indexOf() fails to handle Double.NaN #647.</action>
+ <action type="fix" dev="ggregory" due-to="Gary Gregory">Fix potential NPE in TypeUtils.isAssignable(Type, ParameterizedType, Map, Type>).</action>
+ <action issue="LANG-1420" type="fix" dev="ggregory" due-to="Gordon Fraser, Rostislav Krasny, Arturo Bernal, Gary Gregory">TypeUtils.isAssignable returns wrong result for GenericArrayType and ParameterizedType, #643.</action>
<!-- ADDS -->
<action type="add" dev="ggregory" due-to="Gary Gregory">Add BooleanUtils.booleanValues().</action>
diff --git a/src/main/java/org/apache/commons/lang3/reflect/TypeUtils.java b/src/main/java/org/apache/commons/lang3/reflect/TypeUtils.java
index c28d3bd..d9659fe 100644
--- a/src/main/java/org/apache/commons/lang3/reflect/TypeUtils.java
+++ b/src/main/java/org/apache/commons/lang3/reflect/TypeUtils.java
@@ -388,7 +388,7 @@ public class TypeUtils {
* the type arguments for the subject class's type variables in that it can
* only determine those parameters that map from the subject {@link Class}
* object to the supertype.
- *
+ *
* <p>
* Example: {@link java.util.TreeSet
* TreeSet} sets its parameter as the parameter for
@@ -924,7 +924,7 @@ public class TypeUtils {
* interface {@link Map} are {@link Object} for the subtype
* {@link java.util.Properties Properties} even though the subtype does not
* directly implement the {@code Map} interface.
- *
+ *
* <p>
* This method returns {@code null} if {@code type} is not assignable to
* {@code toClass}. It returns an empty map if none of the classes or
@@ -1182,6 +1182,11 @@ public class TypeUtils {
return false;
}
+ // cannot cast an array type to a parameterized type.
+ if (type instanceof GenericArrayType) {
+ return false;
+ }
+
// all types are assignable to themselves
if (toParameterizedType.equals(type)) {
return true;
@@ -1482,7 +1487,7 @@ public class TypeUtils {
* Strips out the redundant upper bound types in type
* variable types and wildcard types (or it would with wildcard types if
* multiple upper bounds were allowed).
- *
+ *
* <p>
* Example, with the variable type declaration:
* </p>
diff --git a/src/test/java/org/apache/commons/lang3/reflect/TypeUtilsTest.java b/src/test/java/org/apache/commons/lang3/reflect/TypeUtilsTest.java
index d029c08..8cdce0b 100644
--- a/src/test/java/org/apache/commons/lang3/reflect/TypeUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/reflect/TypeUtilsTest.java
@@ -22,7 +22,9 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import java.awt.Insets;
import java.io.Serializable;
+import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Method;
@@ -43,8 +45,62 @@ import org.apache.commons.lang3.reflect.testbed.Foo;
import org.apache.commons.lang3.reflect.testbed.GenericParent;
import org.apache.commons.lang3.reflect.testbed.GenericTypeHolder;
import org.apache.commons.lang3.reflect.testbed.StringParameterizedChild;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
+class AAAClass extends AAClass<String> {
+ public class BBBClass extends BBClass<String> {
+ }
+}
+
+class AAClass<T> {
+
+ public class BBClass<S> {
+ }
+}
+
+@SuppressWarnings("rawtypes")
+//raw types, where used, are used purposely
+class AClass extends AAClass<String>.BBClass<Number> {
+
+ public interface AInterface<T> {
+ }
+
+ public class BClass<T> {
+ }
+
+ public class CClass<T> extends BClass {
+ }
+
+ public class DClass<T> extends CClass<T> {
+ }
+
+ public class EClass<T> extends DClass {
+ }
+
+ public class FClass extends EClass<String> {
+ }
+
+ public class GClass<T extends BClass<? extends T> & AInterface<AInterface<? super T>>> {
+ }
+
+ public BClass<Number> bClass;
+
+ public CClass<? extends String> cClass;
+
+ public DClass<String> dClass;
+
+ public EClass<String> eClass;
+
+ public FClass fClass;
+
+ public GClass gClass;
+
+ AClass(final AAClass<String> enclosingInstance) {
+ enclosingInstance.super();
+ }
+}
+
/**
* Test TypeUtils
*/
@@ -52,25 +108,59 @@ import org.junit.jupiter.api.Test;
//raw types, where used, are used purposely
public class TypeUtilsTest<B> {
- public interface This<K, V> {
+ public interface And<K, V> extends This<Number, Number> {
}
- public class That<K, V> implements This<K, V> {
+ public static class ClassWithSuperClassWithGenericType extends ArrayList<Object> {
+ private static final long serialVersionUID = 1L;
+
+ public static <U> Iterable<U> methodWithGenericReturnType() {
+ return null;
+ }
}
- public interface And<K, V> extends This<Number, Number> {
+ public class Other<T> implements This<String, T> {
}
- public class The<K, V> extends That<Number, Number> implements And<String, String> {
+ public class Tester implements This<String, B> {
}
- public class Other<T> implements This<String, T> {
+ public class That<K, V> implements This<K, V> {
+ }
+
+ public class The<K, V> extends That<Number, Number> implements And<String, String> {
}
public class Thing<Q> extends Other<B> {
}
- public class Tester implements This<String, B> {
+ public interface This<K, V> {
+ }
+
+ public static Comparable<String> stringComparable;
+
+ public static Comparable<URI> uriComparable;
+
+ public static Comparable<Integer> intComparable;
+
+ public static Comparable<Long> longComparable;
+
+ public static Comparable<?> wildcardComparable;
+
+ public static URI uri;
+
+ public static List<String>[] stringListArray;
+
+ public static <G extends Comparable<G>> G stub() {
+ return null;
+ }
+
+ public static <G extends Comparable<? super G>> G stub2() {
+ return null;
+ }
+
+ public static <T extends Comparable<? extends T>> T stub3() {
+ return null;
}
public This<String, String> dis;
@@ -93,25 +183,222 @@ public class TypeUtilsTest<B> {
public Comparable<? extends Integer>[] intWildcardComparable;
- public static Comparable<String> stringComparable;
+ public Iterable<? extends Map<Integer, ? extends Collection<?>>> iterable;
- public static Comparable<URI> uriComparable;
+ public void delegateBooleanAssertion(final Type[] types, final int i2, final int i1, final boolean expected) {
+ final Type type1 = types[i1];
+ final Type type2 = types[i2];
+ final boolean isAssignable = TypeUtils.isAssignable(type2, type1);
- public static Comparable<Integer> intComparable;
+ if (expected) {
+ assertTrue(isAssignable,
+ "[" + i1 + ", " + i2 + "]: From "
+ + String.valueOf(type2) + " to "
+ + String.valueOf(type1));
+ } else {
+ assertFalse(isAssignable,
+ "[" + i1 + ", " + i2 + "]: From "
+ + String.valueOf(type2) + " to "
+ + String.valueOf(type1));
+ }
+ }
- public static Comparable<Long> longComparable;
+ public void dummyMethod(final List list0, final List<Object> list1, final List<?> list2,
+ final List<? super Object> list3, final List<String> list4, final List<? extends String> list5,
+ final List<? super String> list6, final List[] list7, final List<Object>[] list8, final List<?>[] list9,
+ final List<? super Object>[] list10, final List<String>[] list11, final List<? extends String>[] list12,
+ final List<? super String>[] list13) {
+ }
- public static Comparable<?> wildcardComparable;
+ @Test
+ public void testDetermineTypeVariableAssignments() throws SecurityException,
+ NoSuchFieldException {
+ final ParameterizedType iterableType = (ParameterizedType) getClass().getField("iterable")
+ .getGenericType();
+ final Map<TypeVariable<?>, Type> typeVarAssigns = TypeUtils.determineTypeArguments(TreeSet.class,
+ iterableType);
+ final TypeVariable<?> treeSetTypeVar = TreeSet.class.getTypeParameters()[0];
+ assertTrue(typeVarAssigns.containsKey(treeSetTypeVar));
+ assertEquals(iterableType.getActualTypeArguments()[0], typeVarAssigns
+ .get(treeSetTypeVar));
+ }
- public static URI uri;
+ @Test
+ public void testGenericArrayType() throws Exception {
+ final Type expected = getClass().getField("intWildcardComparable").getGenericType();
+ final GenericArrayType actual =
+ TypeUtils.genericArrayType(TypeUtils.parameterize(Comparable.class, TypeUtils.wildcardType()
+ .withUpperBounds(Integer.class).build()));
+ assertTrue(TypeUtils.equals(expected, actual));
+ assertEquals("java.lang.Comparable<? extends java.lang.Integer>[]", actual.toString());
+ }
+
+ @Test
+ public void testGetArrayComponentType() throws Exception {
+ final Method method = getClass().getMethod("dummyMethod", List.class, List.class, List.class,
+ List.class, List.class, List.class, List.class, List[].class, List[].class,
+ List[].class, List[].class, List[].class, List[].class, List[].class);
+
+ final Type[] types = method.getGenericParameterTypes();
+
+ assertNull(TypeUtils.getArrayComponentType(types[0]));
+ assertNull(TypeUtils.getArrayComponentType(types[1]));
+ assertNull(TypeUtils.getArrayComponentType(types[2]));
+ assertNull(TypeUtils.getArrayComponentType(types[3]));
+ assertNull(TypeUtils.getArrayComponentType(types[4]));
+ assertNull(TypeUtils.getArrayComponentType(types[5]));
+ assertNull(TypeUtils.getArrayComponentType(types[6]));
+ assertEquals(types[0], TypeUtils.getArrayComponentType(types[7]));
+ assertEquals(types[1], TypeUtils.getArrayComponentType(types[8]));
+ assertEquals(types[2], TypeUtils.getArrayComponentType(types[9]));
+ assertEquals(types[3], TypeUtils.getArrayComponentType(types[10]));
+ assertEquals(types[4], TypeUtils.getArrayComponentType(types[11]));
+ assertEquals(types[5], TypeUtils.getArrayComponentType(types[12]));
+ assertEquals(types[6], TypeUtils.getArrayComponentType(types[13]));
+ }
+
+ @Test
+ public void testGetPrimitiveArrayComponentType() {
+ assertEquals(boolean.class, TypeUtils.getArrayComponentType(boolean[].class));
+ assertEquals(byte.class, TypeUtils.getArrayComponentType(byte[].class));
+ assertEquals(short.class, TypeUtils.getArrayComponentType(short[].class));
+ assertEquals(int.class, TypeUtils.getArrayComponentType(int[].class));
+ assertEquals(char.class, TypeUtils.getArrayComponentType(char[].class));
+ assertEquals(long.class, TypeUtils.getArrayComponentType(long[].class));
+ assertEquals(float.class, TypeUtils.getArrayComponentType(float[].class));
+ assertEquals(double.class, TypeUtils.getArrayComponentType(double[].class));
+
+ assertNull(TypeUtils.getArrayComponentType(boolean.class));
+ assertNull(TypeUtils.getArrayComponentType(byte.class));
+ assertNull(TypeUtils.getArrayComponentType(short.class));
+ assertNull(TypeUtils.getArrayComponentType(int.class));
+ assertNull(TypeUtils.getArrayComponentType(char.class));
+ assertNull(TypeUtils.getArrayComponentType(long.class));
+ assertNull(TypeUtils.getArrayComponentType(float.class));
+ assertNull(TypeUtils.getArrayComponentType(double.class));
+ }
+
+ @Test
+ public void testGetRawType() throws SecurityException, NoSuchFieldException {
+ final Type stringParentFieldType = GenericTypeHolder.class.getDeclaredField("stringParent")
+ .getGenericType();
+ final Type integerParentFieldType = GenericTypeHolder.class.getDeclaredField("integerParent")
+ .getGenericType();
+ final Type foosFieldType = GenericTypeHolder.class.getDeclaredField("foos").getGenericType();
+ final Type genericParentT = GenericParent.class.getTypeParameters()[0];
+ assertEquals(GenericParent.class, TypeUtils.getRawType(stringParentFieldType, null));
+ assertEquals(GenericParent.class, TypeUtils.getRawType(integerParentFieldType,
+ null));
+ assertEquals(List.class, TypeUtils.getRawType(foosFieldType, null));
+ assertEquals(String.class, TypeUtils.getRawType(genericParentT,
+ StringParameterizedChild.class));
+ assertEquals(String.class, TypeUtils.getRawType(genericParentT,
+ stringParentFieldType));
+ assertEquals(Foo.class, TypeUtils.getRawType(Iterable.class.getTypeParameters()[0],
+ foosFieldType));
+ assertEquals(Foo.class, TypeUtils.getRawType(List.class.getTypeParameters()[0],
+ foosFieldType));
+ assertNull(TypeUtils.getRawType(genericParentT, GenericParent.class));
+ assertEquals(GenericParent[].class, TypeUtils.getRawType(GenericTypeHolder.class
+ .getDeclaredField("barParents").getGenericType(), null));
+ }
+
+ @Test
+ public void testGetTypeArguments() {
+ Map<TypeVariable<?>, Type> typeVarAssigns;
+ TypeVariable<?> treeSetTypeVar;
+ Type typeArg;
+
+ typeVarAssigns = TypeUtils.getTypeArguments(Integer.class, Comparable.class);
+ treeSetTypeVar = Comparable.class.getTypeParameters()[0];
+ assertTrue(typeVarAssigns.containsKey(treeSetTypeVar),
+ "Type var assigns for Comparable from Integer: " + typeVarAssigns);
+ typeArg = typeVarAssigns.get(treeSetTypeVar);
+ assertEquals(Integer.class, typeVarAssigns.get(treeSetTypeVar),
+ "Type argument of Comparable from Integer: " + typeArg);
+
+ typeVarAssigns = TypeUtils.getTypeArguments(int.class, Comparable.class);
+ treeSetTypeVar = Comparable.class.getTypeParameters()[0];
+ assertTrue(typeVarAssigns.containsKey(treeSetTypeVar),
+ "Type var assigns for Comparable from int: " + typeVarAssigns);
+ typeArg = typeVarAssigns.get(treeSetTypeVar);
+ assertEquals(Integer.class, typeVarAssigns.get(treeSetTypeVar),
+ "Type argument of Comparable from int: " + typeArg);
+
+ final Collection<Integer> col = Collections.emptyList();
+ typeVarAssigns = TypeUtils.getTypeArguments(List.class, Collection.class);
+ treeSetTypeVar = Comparable.class.getTypeParameters()[0];
+ assertFalse(typeVarAssigns.containsKey(treeSetTypeVar),
+ "Type var assigns for Collection from List: " + typeVarAssigns);
+
+ typeVarAssigns = TypeUtils.getTypeArguments(AAAClass.BBBClass.class, AAClass.BBClass.class);
+ assertEquals(2, typeVarAssigns.size());
+ assertEquals(String.class, typeVarAssigns.get(AAClass.class.getTypeParameters()[0]));
+ assertEquals(String.class, typeVarAssigns.get(AAClass.BBClass.class.getTypeParameters()[0]));
+
+ typeVarAssigns = TypeUtils.getTypeArguments(Other.class, This.class);
+ assertEquals(2, typeVarAssigns.size());
+ assertEquals(String.class, typeVarAssigns.get(This.class.getTypeParameters()[0]));
+ assertEquals(Other.class.getTypeParameters()[0], typeVarAssigns.get(This.class.getTypeParameters()[1]));
+
+ typeVarAssigns = TypeUtils.getTypeArguments(And.class, This.class);
+ assertEquals(2, typeVarAssigns.size());
+ assertEquals(Number.class, typeVarAssigns.get(This.class.getTypeParameters()[0]));
+ assertEquals(Number.class, typeVarAssigns.get(This.class.getTypeParameters()[1]));
+
+ typeVarAssigns = TypeUtils.getTypeArguments(Thing.class, Other.class);
+ assertEquals(2, typeVarAssigns.size());
+ assertEquals(getClass().getTypeParameters()[0], typeVarAssigns.get(getClass().getTypeParameters()[0]));
+ assertEquals(getClass().getTypeParameters()[0], typeVarAssigns.get(Other.class.getTypeParameters()[0]));
+ }
+
+ @Test
+ public void testIsArrayGenericTypes() throws Exception {
+ final Method method = getClass().getMethod("dummyMethod", List.class, List.class, List.class,
+ List.class, List.class, List.class, List.class, List[].class, List[].class,
+ List[].class, List[].class, List[].class, List[].class, List[].class);
+
+ final Type[] types = method.getGenericParameterTypes();
+
+ assertFalse(TypeUtils.isArrayType(types[0]));
+ assertFalse(TypeUtils.isArrayType(types[1]));
+ assertFalse(TypeUtils.isArrayType(types[2]));
+ assertFalse(TypeUtils.isArrayType(types[3]));
+ assertFalse(TypeUtils.isArrayType(types[4]));
+ assertFalse(TypeUtils.isArrayType(types[5]));
+ assertFalse(TypeUtils.isArrayType(types[6]));
+ assertTrue(TypeUtils.isArrayType(types[7]));
+ assertTrue(TypeUtils.isArrayType(types[8]));
+ assertTrue(TypeUtils.isArrayType(types[9]));
+ assertTrue(TypeUtils.isArrayType(types[10]));
+ assertTrue(TypeUtils.isArrayType(types[11]));
+ assertTrue(TypeUtils.isArrayType(types[12]));
+ assertTrue(TypeUtils.isArrayType(types[13]));
+ }
- public static List<String>[] stringListArray;
+ @Test
+ public void testIsArrayTypeClasses() {
+ assertTrue(TypeUtils.isArrayType(boolean[].class));
+ assertTrue(TypeUtils.isArrayType(byte[].class));
+ assertTrue(TypeUtils.isArrayType(short[].class));
+ assertTrue(TypeUtils.isArrayType(int[].class));
+ assertTrue(TypeUtils.isArrayType(char[].class));
+ assertTrue(TypeUtils.isArrayType(long[].class));
+ assertTrue(TypeUtils.isArrayType(float[].class));
+ assertTrue(TypeUtils.isArrayType(double[].class));
+ assertTrue(TypeUtils.isArrayType(Object[].class));
+ assertTrue(TypeUtils.isArrayType(String[].class));
- public void dummyMethod(final List list0, final List<Object> list1, final List<?> list2,
- final List<? super Object> list3, final List<String> list4, final List<? extends String> list5,
- final List<? super String> list6, final List[] list7, final List<Object>[] list8, final List<?>[] list9,
- final List<? super Object>[] list10, final List<String>[] list11, final List<? extends String>[] list12,
- final List<? super String>[] list13) {
+ assertFalse(TypeUtils.isArrayType(boolean.class));
+ assertFalse(TypeUtils.isArrayType(byte.class));
+ assertFalse(TypeUtils.isArrayType(short.class));
+ assertFalse(TypeUtils.isArrayType(int.class));
+ assertFalse(TypeUtils.isArrayType(char.class));
+ assertFalse(TypeUtils.isArrayType(long.class));
+ assertFalse(TypeUtils.isArrayType(float.class));
+ assertFalse(TypeUtils.isArrayType(double.class));
+ assertFalse(TypeUtils.isArrayType(Object.class));
+ assertFalse(TypeUtils.isArrayType(String.class));
}
@SuppressWarnings("boxing") // deliberately used here
@@ -428,316 +715,117 @@ public class TypeUtilsTest<B> {
final Type cClassType = AClass.class.getField("cClass").getGenericType();
final Type dClassType = AClass.class.getField("dClass").getGenericType();
final Type eClassType = AClass.class.getField("eClass").getGenericType();
- final Type fClassType = AClass.class.getField("fClass").getGenericType();
- final AClass aClass = new AClass(new AAClass<>());
- aClass.bClass = aClass.cClass;
- assertTrue(TypeUtils.isAssignable(cClassType, bClassType));
- aClass.bClass = aClass.dClass;
- assertTrue(TypeUtils.isAssignable(dClassType, bClassType));
- aClass.bClass = aClass.eClass;
- assertTrue(TypeUtils.isAssignable(eClassType, bClassType));
- aClass.bClass = aClass.fClass;
- assertTrue(TypeUtils.isAssignable(fClassType, bClassType));
- aClass.cClass = aClass.dClass;
- assertTrue(TypeUtils.isAssignable(dClassType, cClassType));
- aClass.cClass = aClass.eClass;
- assertTrue(TypeUtils.isAssignable(eClassType, cClassType));
- aClass.cClass = aClass.fClass;
- assertTrue(TypeUtils.isAssignable(fClassType, cClassType));
- aClass.dClass = aClass.eClass;
- assertTrue(TypeUtils.isAssignable(eClassType, dClassType));
- aClass.dClass = aClass.fClass;
- assertTrue(TypeUtils.isAssignable(fClassType, dClassType));
- aClass.eClass = aClass.fClass;
- assertTrue(TypeUtils.isAssignable(fClassType, eClassType));
- }
-
- public void delegateBooleanAssertion(final Type[] types, final int i2, final int i1, final boolean expected) {
- final Type type1 = types[i1];
- final Type type2 = types[i2];
- final boolean isAssignable = TypeUtils.isAssignable(type2, type1);
-
- if (expected) {
- assertTrue(isAssignable,
- "[" + i1 + ", " + i2 + "]: From "
- + String.valueOf(type2) + " to "
- + String.valueOf(type1));
- } else {
- assertFalse(isAssignable,
- "[" + i1 + ", " + i2 + "]: From "
- + String.valueOf(type2) + " to "
- + String.valueOf(type1));
- }
- }
-
- @SuppressWarnings("boxing") // boxing is deliberate here
- @Test
- public void testIsInstance() throws SecurityException, NoSuchFieldException {
- final Type intComparableType = getClass().getField("intComparable").getGenericType();
- final Type uriComparableType = getClass().getField("uriComparable").getGenericType();
- intComparable = 1;
- assertTrue(TypeUtils.isInstance(1, intComparableType));
- // uriComparable = 1;
- assertFalse(TypeUtils.isInstance(1, uriComparableType));
- }
-
- @Test
- public void testGetTypeArguments() {
- Map<TypeVariable<?>, Type> typeVarAssigns;
- TypeVariable<?> treeSetTypeVar;
- Type typeArg;
-
- typeVarAssigns = TypeUtils.getTypeArguments(Integer.class, Comparable.class);
- treeSetTypeVar = Comparable.class.getTypeParameters()[0];
- assertTrue(typeVarAssigns.containsKey(treeSetTypeVar),
- "Type var assigns for Comparable from Integer: " + typeVarAssigns);
- typeArg = typeVarAssigns.get(treeSetTypeVar);
- assertEquals(Integer.class, typeVarAssigns.get(treeSetTypeVar),
- "Type argument of Comparable from Integer: " + typeArg);
-
- typeVarAssigns = TypeUtils.getTypeArguments(int.class, Comparable.class);
- treeSetTypeVar = Comparable.class.getTypeParameters()[0];
- assertTrue(typeVarAssigns.containsKey(treeSetTypeVar),
- "Type var assigns for Comparable from int: " + typeVarAssigns);
- typeArg = typeVarAssigns.get(treeSetTypeVar);
- assertEquals(Integer.class, typeVarAssigns.get(treeSetTypeVar),
- "Type argument of Comparable from int: " + typeArg);
-
- final Collection<Integer> col = Collections.emptyList();
- typeVarAssigns = TypeUtils.getTypeArguments(List.class, Collection.class);
- treeSetTypeVar = Comparable.class.getTypeParameters()[0];
- assertFalse(typeVarAssigns.containsKey(treeSetTypeVar),
- "Type var assigns for Collection from List: " + typeVarAssigns);
-
- typeVarAssigns = TypeUtils.getTypeArguments(AAAClass.BBBClass.class, AAClass.BBClass.class);
- assertEquals(2, typeVarAssigns.size());
- assertEquals(String.class, typeVarAssigns.get(AAClass.class.getTypeParameters()[0]));
- assertEquals(String.class, typeVarAssigns.get(AAClass.BBClass.class.getTypeParameters()[0]));
-
- typeVarAssigns = TypeUtils.getTypeArguments(Other.class, This.class);
- assertEquals(2, typeVarAssigns.size());
- assertEquals(String.class, typeVarAssigns.get(This.class.getTypeParameters()[0]));
- assertEquals(Other.class.getTypeParameters()[0], typeVarAssigns.get(This.class.getTypeParameters()[1]));
-
- typeVarAssigns = TypeUtils.getTypeArguments(And.class, This.class);
- assertEquals(2, typeVarAssigns.size());
- assertEquals(Number.class, typeVarAssigns.get(This.class.getTypeParameters()[0]));
- assertEquals(Number.class, typeVarAssigns.get(This.class.getTypeParameters()[1]));
-
- typeVarAssigns = TypeUtils.getTypeArguments(Thing.class, Other.class);
- assertEquals(2, typeVarAssigns.size());
- assertEquals(getClass().getTypeParameters()[0], typeVarAssigns.get(getClass().getTypeParameters()[0]));
- assertEquals(getClass().getTypeParameters()[0], typeVarAssigns.get(Other.class.getTypeParameters()[0]));
- }
-
- @Test
- public void testTypesSatisfyVariables() throws SecurityException,
- NoSuchMethodException {
- final Map<TypeVariable<?>, Type> typeVarAssigns = new HashMap<>();
- final Integer max = TypeUtilsTest.<Integer>stub();
- typeVarAssigns.put(getClass().getMethod("stub").getTypeParameters()[0], Integer.class);
- assertTrue(TypeUtils.typesSatisfyVariables(typeVarAssigns));
- typeVarAssigns.clear();
- typeVarAssigns.put(getClass().getMethod("stub2").getTypeParameters()[0], Integer.class);
- assertTrue(TypeUtils.typesSatisfyVariables(typeVarAssigns));
- typeVarAssigns.clear();
- typeVarAssigns.put(getClass().getMethod("stub3").getTypeParameters()[0], Integer.class);
- assertTrue(TypeUtils.typesSatisfyVariables(typeVarAssigns));
- }
-
- @Test
- public void testDetermineTypeVariableAssignments() throws SecurityException,
- NoSuchFieldException {
- final ParameterizedType iterableType = (ParameterizedType) getClass().getField("iterable")
- .getGenericType();
- final Map<TypeVariable<?>, Type> typeVarAssigns = TypeUtils.determineTypeArguments(TreeSet.class,
- iterableType);
- final TypeVariable<?> treeSetTypeVar = TreeSet.class.getTypeParameters()[0];
- assertTrue(typeVarAssigns.containsKey(treeSetTypeVar));
- assertEquals(iterableType.getActualTypeArguments()[0], typeVarAssigns
- .get(treeSetTypeVar));
- }
-
- @Test
- public void testGetRawType() throws SecurityException, NoSuchFieldException {
- final Type stringParentFieldType = GenericTypeHolder.class.getDeclaredField("stringParent")
- .getGenericType();
- final Type integerParentFieldType = GenericTypeHolder.class.getDeclaredField("integerParent")
- .getGenericType();
- final Type foosFieldType = GenericTypeHolder.class.getDeclaredField("foos").getGenericType();
- final Type genericParentT = GenericParent.class.getTypeParameters()[0];
- assertEquals(GenericParent.class, TypeUtils.getRawType(stringParentFieldType, null));
- assertEquals(GenericParent.class, TypeUtils.getRawType(integerParentFieldType,
- null));
- assertEquals(List.class, TypeUtils.getRawType(foosFieldType, null));
- assertEquals(String.class, TypeUtils.getRawType(genericParentT,
- StringParameterizedChild.class));
- assertEquals(String.class, TypeUtils.getRawType(genericParentT,
- stringParentFieldType));
- assertEquals(Foo.class, TypeUtils.getRawType(Iterable.class.getTypeParameters()[0],
- foosFieldType));
- assertEquals(Foo.class, TypeUtils.getRawType(List.class.getTypeParameters()[0],
- foosFieldType));
- assertNull(TypeUtils.getRawType(genericParentT, GenericParent.class));
- assertEquals(GenericParent[].class, TypeUtils.getRawType(GenericTypeHolder.class
- .getDeclaredField("barParents").getGenericType(), null));
- }
-
- @Test
- public void testIsArrayTypeClasses() {
- assertTrue(TypeUtils.isArrayType(boolean[].class));
- assertTrue(TypeUtils.isArrayType(byte[].class));
- assertTrue(TypeUtils.isArrayType(short[].class));
- assertTrue(TypeUtils.isArrayType(int[].class));
- assertTrue(TypeUtils.isArrayType(char[].class));
- assertTrue(TypeUtils.isArrayType(long[].class));
- assertTrue(TypeUtils.isArrayType(float[].class));
- assertTrue(TypeUtils.isArrayType(double[].class));
- assertTrue(TypeUtils.isArrayType(Object[].class));
- assertTrue(TypeUtils.isArrayType(String[].class));
-
- assertFalse(TypeUtils.isArrayType(boolean.class));
- assertFalse(TypeUtils.isArrayType(byte.class));
- assertFalse(TypeUtils.isArrayType(short.class));
- assertFalse(TypeUtils.isArrayType(int.class));
- assertFalse(TypeUtils.isArrayType(char.class));
- assertFalse(TypeUtils.isArrayType(long.class));
- assertFalse(TypeUtils.isArrayType(float.class));
- assertFalse(TypeUtils.isArrayType(double.class));
- assertFalse(TypeUtils.isArrayType(Object.class));
- assertFalse(TypeUtils.isArrayType(String.class));
- }
-
- @Test
- public void testIsArrayGenericTypes() throws Exception {
- final Method method = getClass().getMethod("dummyMethod", List.class, List.class, List.class,
- List.class, List.class, List.class, List.class, List[].class, List[].class,
- List[].class, List[].class, List[].class, List[].class, List[].class);
-
- final Type[] types = method.getGenericParameterTypes();
-
- assertFalse(TypeUtils.isArrayType(types[0]));
- assertFalse(TypeUtils.isArrayType(types[1]));
- assertFalse(TypeUtils.isArrayType(types[2]));
- assertFalse(TypeUtils.isArrayType(types[3]));
- assertFalse(TypeUtils.isArrayType(types[4]));
- assertFalse(TypeUtils.isArrayType(types[5]));
- assertFalse(TypeUtils.isArrayType(types[6]));
- assertTrue(TypeUtils.isArrayType(types[7]));
- assertTrue(TypeUtils.isArrayType(types[8]));
- assertTrue(TypeUtils.isArrayType(types[9]));
- assertTrue(TypeUtils.isArrayType(types[10]));
- assertTrue(TypeUtils.isArrayType(types[11]));
- assertTrue(TypeUtils.isArrayType(types[12]));
- assertTrue(TypeUtils.isArrayType(types[13]));
- }
-
- @Test
- public void testGetPrimitiveArrayComponentType() {
- assertEquals(boolean.class, TypeUtils.getArrayComponentType(boolean[].class));
- assertEquals(byte.class, TypeUtils.getArrayComponentType(byte[].class));
- assertEquals(short.class, TypeUtils.getArrayComponentType(short[].class));
- assertEquals(int.class, TypeUtils.getArrayComponentType(int[].class));
- assertEquals(char.class, TypeUtils.getArrayComponentType(char[].class));
- assertEquals(long.class, TypeUtils.getArrayComponentType(long[].class));
- assertEquals(float.class, TypeUtils.getArrayComponentType(float[].class));
- assertEquals(double.class, TypeUtils.getArrayComponentType(double[].class));
-
- assertNull(TypeUtils.getArrayComponentType(boolean.class));
- assertNull(TypeUtils.getArrayComponentType(byte.class));
- assertNull(TypeUtils.getArrayComponentType(short.class));
- assertNull(TypeUtils.getArrayComponentType(int.class));
- assertNull(TypeUtils.getArrayComponentType(char.class));
- assertNull(TypeUtils.getArrayComponentType(long.class));
- assertNull(TypeUtils.getArrayComponentType(float.class));
- assertNull(TypeUtils.getArrayComponentType(double.class));
+ final Type fClassType = AClass.class.getField("fClass").getGenericType();
+ final AClass aClass = new AClass(new AAClass<>());
+ aClass.bClass = aClass.cClass;
+ assertTrue(TypeUtils.isAssignable(cClassType, bClassType));
+ aClass.bClass = aClass.dClass;
+ assertTrue(TypeUtils.isAssignable(dClassType, bClassType));
+ aClass.bClass = aClass.eClass;
+ assertTrue(TypeUtils.isAssignable(eClassType, bClassType));
+ aClass.bClass = aClass.fClass;
+ assertTrue(TypeUtils.isAssignable(fClassType, bClassType));
+ aClass.cClass = aClass.dClass;
+ assertTrue(TypeUtils.isAssignable(dClassType, cClassType));
+ aClass.cClass = aClass.eClass;
+ assertTrue(TypeUtils.isAssignable(eClassType, cClassType));
+ aClass.cClass = aClass.fClass;
+ assertTrue(TypeUtils.isAssignable(fClassType, cClassType));
+ aClass.dClass = aClass.eClass;
+ assertTrue(TypeUtils.isAssignable(eClassType, dClassType));
+ aClass.dClass = aClass.fClass;
+ assertTrue(TypeUtils.isAssignable(fClassType, dClassType));
+ aClass.eClass = aClass.fClass;
+ assertTrue(TypeUtils.isAssignable(fClassType, eClassType));
}
- @Test
- public void testGetArrayComponentType() throws Exception {
- final Method method = getClass().getMethod("dummyMethod", List.class, List.class, List.class,
- List.class, List.class, List.class, List.class, List[].class, List[].class,
- List[].class, List[].class, List[].class, List[].class, List[].class);
+ private void testIsAssignable(Class testUnassignableClass) {
+ final Class<Constructor> rawClass = Constructor.class;
+ final Class<Insets> typeArgClass = Insets.class;
+ // Builds a ParameterizedType for Constructor<Insets>
+ ParameterizedType paramType = TypeUtils.parameterize(rawClass, typeArgClass);
+ assertEquals(rawClass, paramType.getRawType());
+ assertEquals(typeArgClass, paramType.getActualTypeArguments()[0]);
- final Type[] types = method.getGenericParameterTypes();
+ assertFalse(testUnassignableClass.isAssignableFrom(paramType.getClass()));
+ assertFalse(paramType.getClass().isAssignableFrom(testUnassignableClass));
- assertNull(TypeUtils.getArrayComponentType(types[0]));
- assertNull(TypeUtils.getArrayComponentType(types[1]));
- assertNull(TypeUtils.getArrayComponentType(types[2]));
- assertNull(TypeUtils.getArrayComponentType(types[3]));
- assertNull(TypeUtils.getArrayComponentType(types[4]));
- assertNull(TypeUtils.getArrayComponentType(types[5]));
- assertNull(TypeUtils.getArrayComponentType(types[6]));
- assertEquals(types[0], TypeUtils.getArrayComponentType(types[7]));
- assertEquals(types[1], TypeUtils.getArrayComponentType(types[8]));
- assertEquals(types[2], TypeUtils.getArrayComponentType(types[9]));
- assertEquals(types[3], TypeUtils.getArrayComponentType(types[10]));
- assertEquals(types[4], TypeUtils.getArrayComponentType(types[11]));
- assertEquals(types[5], TypeUtils.getArrayComponentType(types[12]));
- assertEquals(types[6], TypeUtils.getArrayComponentType(types[13]));
+ GenericArrayType arrayType = TypeUtils.genericArrayType(paramType);
+ assertFalse(TypeUtils.isAssignable(arrayType, paramType),
+ () -> String.format("TypeUtils.isAssignable(%s, %s)", arrayType, paramType));
+ assertFalse(TypeUtils.isAssignable(paramType, arrayType),
+ () -> String.format("TypeUtils.isAssignable(%s, %s)", paramType, arrayType));
}
@Test
- public void testLang820() {
- final Type[] typeArray = {String.class, String.class};
- final Type[] expectedArray = {String.class};
- assertArrayEquals(expectedArray, TypeUtils.normalizeUpperBounds(typeArray));
- }
+ public void testIsAssignableGenericArrayTypeToParameterizedType() {
+ final Class<Constructor> rawClass = Constructor.class;
+ final Class<Insets> typeArgClass = Insets.class;
+ // Builds a ParameterizedType for Constructor<Insets>
+ ParameterizedType paramType = TypeUtils.parameterize(rawClass, typeArgClass);
+ assertEquals(rawClass, paramType.getRawType());
+ assertEquals(typeArgClass, paramType.getActualTypeArguments()[0]);
- @Test
- public void testParameterize() throws Exception {
- final ParameterizedType stringComparableType = TypeUtils.parameterize(Comparable.class, String.class);
- assertTrue(TypeUtils.equals(getClass().getField("stringComparable").getGenericType(),
- stringComparableType));
- assertEquals("java.lang.Comparable<java.lang.String>", stringComparableType.toString());
- }
+ assertFalse(GenericArrayType.class.isAssignableFrom(paramType.getClass()));
+ assertFalse(paramType.getClass().isAssignableFrom(GenericArrayType.class));
- @Test
- public void testParameterizeNarrowerTypeArray() {
- final TypeVariable<?>[] variables = ArrayList.class.getTypeParameters();
- final ParameterizedType parameterizedType = TypeUtils.parameterize(ArrayList.class, variables);
- final Map<TypeVariable<?>, Type> mapping = Collections.<TypeVariable<?>, Type>singletonMap(variables[0], String.class);
- final Type unrolled = TypeUtils.unrollVariables(mapping, parameterizedType);
- assertEquals(TypeUtils.parameterize(ArrayList.class, String.class), unrolled);
+ GenericArrayType testType = TypeUtils.genericArrayType(paramType);
+ assertFalse(TypeUtils.isAssignable(paramType, testType),
+ () -> String.format("TypeUtils.isAssignable(%s, %s)", paramType, testType));
+ assertFalse(TypeUtils.isAssignable(testType, paramType),
+ () -> String.format("TypeUtils.isAssignable(%s, %s)", testType, paramType));
}
@Test
- public void testParameterizeWithOwner() throws Exception {
- final Type owner = TypeUtils.parameterize(TypeUtilsTest.class, String.class);
- final ParameterizedType dat2Type = TypeUtils.parameterizeWithOwner(owner, That.class, String.class, String.class);
- assertTrue(TypeUtils.equals(getClass().getField("dat2").getGenericType(), dat2Type));
+ @Disabled("TODO")
+ public void testIsAssignableGenericArrayTypeToWildercardType() {
+ final Class<Constructor> rawClass = Constructor.class;
+ final Class<Insets> typeArgClass = Insets.class;
+ // Builds a ParameterizedType for Constructor<Insets>
+ ParameterizedType paramType = TypeUtils.parameterize(rawClass, typeArgClass);
+ assertEquals(rawClass, paramType.getRawType());
+ assertEquals(typeArgClass, paramType.getActualTypeArguments()[0]);
+
+ assertFalse(WildcardType.class.isAssignableFrom(paramType.getClass()));
+ assertFalse(paramType.getClass().isAssignableFrom(WildcardType.class));
+
+ WildcardType testType = TypeUtils.WILDCARD_ALL;
+ // TODO This test returns true unlike the test above.
+ // Is this a bug in this test or in the main code?
+ assertFalse(TypeUtils.isAssignable(paramType, testType),
+ () -> String.format("TypeUtils.isAssignable(%s, %s)", paramType, testType));
+ assertFalse(TypeUtils.isAssignable(testType, paramType),
+ () -> String.format("TypeUtils.isAssignable(%s, %s)", testType, paramType));
}
@Test
- public void testWildcardType() throws Exception {
- final WildcardType simpleWildcard = TypeUtils.wildcardType().withUpperBounds(String.class).build();
- final Field cClass = AClass.class.getField("cClass");
- assertTrue(TypeUtils.equals(((ParameterizedType) cClass.getGenericType()).getActualTypeArguments()[0],
- simpleWildcard));
- assertEquals(String.format("? extends %s", String.class.getName()), TypeUtils.toString(simpleWildcard));
- assertEquals(String.format("? extends %s", String.class.getName()), simpleWildcard.toString());
- }
+ public void testIsAssignableGenericArrayTypeToObject() {
+ final Class<Constructor> rawClass = Constructor.class;
+ final Class<Insets> typeArgClass = Insets.class;
+ // Builds a ParameterizedType for Constructor<Insets>
+ ParameterizedType paramType = TypeUtils.parameterize(rawClass, typeArgClass);
+ assertEquals(rawClass, paramType.getRawType());
+ assertEquals(typeArgClass, paramType.getActualTypeArguments()[0]);
- @Test
- public void testUnboundedWildcardType() {
- final WildcardType unbounded = TypeUtils.wildcardType().withLowerBounds((Type) null).withUpperBounds().build();
- assertTrue(TypeUtils.equals(TypeUtils.WILDCARD_ALL, unbounded));
- assertArrayEquals(new Type[] { Object.class }, TypeUtils.getImplicitUpperBounds(unbounded));
- assertArrayEquals(new Type[] { null }, TypeUtils.getImplicitLowerBounds(unbounded));
- assertEquals("?", TypeUtils.toString(unbounded));
- assertEquals("?", unbounded.toString());
+ assertTrue(Object.class.isAssignableFrom(paramType.getClass()));
+ assertFalse(paramType.getClass().isAssignableFrom(Object.class));
+
+ Type testType = Object.class;
+ assertTrue(TypeUtils.isAssignable(paramType, testType),
+ () -> String.format("TypeUtils.isAssignable(%s, %s)", paramType, testType));
+ assertFalse(TypeUtils.isAssignable(testType, paramType),
+ () -> String.format("TypeUtils.isAssignable(%s, %s)", testType, paramType));
}
+ @SuppressWarnings("boxing") // boxing is deliberate here
@Test
- public void testLowerBoundedWildcardType() {
- final WildcardType lowerBounded = TypeUtils.wildcardType().withLowerBounds(java.sql.Date.class).build();
- assertEquals(String.format("? super %s", java.sql.Date.class.getName()), TypeUtils.toString(lowerBounded));
- assertEquals(String.format("? super %s", java.sql.Date.class.getName()), lowerBounded.toString());
-
- final TypeVariable<Class<Iterable>> iterableT0 = Iterable.class.getTypeParameters()[0];
- final WildcardType lowerTypeVariable = TypeUtils.wildcardType().withLowerBounds(iterableT0).build();
- assertEquals(String.format("? super %s", iterableT0.getName()), TypeUtils.toString(lowerTypeVariable));
- assertEquals(String.format("? super %s", iterableT0.getName()), lowerTypeVariable.toString());
+ public void testIsInstance() throws SecurityException, NoSuchFieldException {
+ final Type intComparableType = getClass().getField("intComparable").getGenericType();
+ final Type uriComparableType = getClass().getField("uriComparable").getGenericType();
+ intComparable = 1;
+ assertTrue(TypeUtils.isInstance(1, intComparableType));
+ // uriComparable = 1;
+ assertFalse(TypeUtils.isInstance(1, uriComparableType));
}
@Test
@@ -750,45 +838,6 @@ public class TypeUtilsTest<B> {
}
@Test
- public void testGenericArrayType() throws Exception {
- final Type expected = getClass().getField("intWildcardComparable").getGenericType();
- final GenericArrayType actual =
- TypeUtils.genericArrayType(TypeUtils.parameterize(Comparable.class, TypeUtils.wildcardType()
- .withUpperBounds(Integer.class).build()));
- assertTrue(TypeUtils.equals(expected, actual));
- assertEquals("java.lang.Comparable<? extends java.lang.Integer>[]", actual.toString());
- }
-
- @Test
- public void testToStringLang1311() {
- assertEquals("int[]", TypeUtils.toString(int[].class));
- assertEquals("java.lang.Integer[]", TypeUtils.toString(Integer[].class));
- final Field stringListField = FieldUtils.getDeclaredField(getClass(), "stringListArray");
- assertEquals("java.util.List<java.lang.String>[]", TypeUtils.toString(stringListField.getGenericType()));
- }
-
- @Test
- public void testToLongString() {
- assertEquals(getClass().getName() + ":B", TypeUtils.toLongString(getClass().getTypeParameters()[0]));
- }
-
- @Test
- public void testWrap() {
- final Type t = getClass().getTypeParameters()[0];
- assertTrue(TypeUtils.equals(t, TypeUtils.wrap(t).getType()));
-
- assertEquals(String.class, TypeUtils.wrap(String.class).getType());
- }
-
- public static class ClassWithSuperClassWithGenericType extends ArrayList<Object> {
- private static final long serialVersionUID = 1L;
-
- public static <U> Iterable<U> methodWithGenericReturnType() {
- return null;
- }
- }
-
- @Test
public void testLANG1190() throws Exception {
final Type fromType = ClassWithSuperClassWithGenericType.class.getDeclaredMethod("methodWithGenericReturnType").getGenericReturnType();
final Type failingToType = TypeUtils.wildcardType().withLowerBounds(ClassWithSuperClassWithGenericType.class).build();
@@ -802,70 +851,102 @@ public class TypeUtilsTest<B> {
assertEquals("T extends java.lang.Enum<T>", TypeUtils.toString(method.getGenericReturnType()));
}
- public Iterable<? extends Map<Integer, ? extends Collection<?>>> iterable;
-
- public static <G extends Comparable<G>> G stub() {
- return null;
- }
-
- public static <G extends Comparable<? super G>> G stub2() {
- return null;
- }
-
- public static <T extends Comparable<? extends T>> T stub3() {
- return null;
+ @Test
+ public void testLang820() {
+ final Type[] typeArray = {String.class, String.class};
+ final Type[] expectedArray = {String.class};
+ assertArrayEquals(expectedArray, TypeUtils.normalizeUpperBounds(typeArray));
}
-}
-class AAClass<T> {
+ @Test
+ public void testLowerBoundedWildcardType() {
+ final WildcardType lowerBounded = TypeUtils.wildcardType().withLowerBounds(java.sql.Date.class).build();
+ assertEquals(String.format("? super %s", java.sql.Date.class.getName()), TypeUtils.toString(lowerBounded));
+ assertEquals(String.format("? super %s", java.sql.Date.class.getName()), lowerBounded.toString());
- public class BBClass<S> {
+ final TypeVariable<Class<Iterable>> iterableT0 = Iterable.class.getTypeParameters()[0];
+ final WildcardType lowerTypeVariable = TypeUtils.wildcardType().withLowerBounds(iterableT0).build();
+ assertEquals(String.format("? super %s", iterableT0.getName()), TypeUtils.toString(lowerTypeVariable));
+ assertEquals(String.format("? super %s", iterableT0.getName()), lowerTypeVariable.toString());
}
-}
-class AAAClass extends AAClass<String> {
- public class BBBClass extends BBClass<String> {
+ @Test
+ public void testParameterize() throws Exception {
+ final ParameterizedType stringComparableType = TypeUtils.parameterize(Comparable.class, String.class);
+ assertTrue(TypeUtils.equals(getClass().getField("stringComparable").getGenericType(),
+ stringComparableType));
+ assertEquals("java.lang.Comparable<java.lang.String>", stringComparableType.toString());
}
-}
-
-@SuppressWarnings("rawtypes")
-//raw types, where used, are used purposely
-class AClass extends AAClass<String>.BBClass<Number> {
- AClass(final AAClass<String> enclosingInstance) {
- enclosingInstance.super();
+ @Test
+ public void testParameterizeNarrowerTypeArray() {
+ final TypeVariable<?>[] variables = ArrayList.class.getTypeParameters();
+ final ParameterizedType parameterizedType = TypeUtils.parameterize(ArrayList.class, variables);
+ final Map<TypeVariable<?>, Type> mapping = Collections.<TypeVariable<?>, Type>singletonMap(variables[0], String.class);
+ final Type unrolled = TypeUtils.unrollVariables(mapping, parameterizedType);
+ assertEquals(TypeUtils.parameterize(ArrayList.class, String.class), unrolled);
}
- public class BClass<T> {
+ @Test
+ public void testParameterizeWithOwner() throws Exception {
+ final Type owner = TypeUtils.parameterize(TypeUtilsTest.class, String.class);
+ final ParameterizedType dat2Type = TypeUtils.parameterizeWithOwner(owner, That.class, String.class, String.class);
+ assertTrue(TypeUtils.equals(getClass().getField("dat2").getGenericType(), dat2Type));
}
- public class CClass<T> extends BClass {
+ @Test
+ public void testToLongString() {
+ assertEquals(getClass().getName() + ":B", TypeUtils.toLongString(getClass().getTypeParameters()[0]));
}
- public class DClass<T> extends CClass<T> {
+ @Test
+ public void testToStringLang1311() {
+ assertEquals("int[]", TypeUtils.toString(int[].class));
+ assertEquals("java.lang.Integer[]", TypeUtils.toString(Integer[].class));
+ final Field stringListField = FieldUtils.getDeclaredField(getClass(), "stringListArray");
+ assertEquals("java.util.List<java.lang.String>[]", TypeUtils.toString(stringListField.getGenericType()));
}
- public class EClass<T> extends DClass {
+ @Test
+ public void testTypesSatisfyVariables() throws SecurityException,
+ NoSuchMethodException {
+ final Map<TypeVariable<?>, Type> typeVarAssigns = new HashMap<>();
+ final Integer max = TypeUtilsTest.<Integer>stub();
+ typeVarAssigns.put(getClass().getMethod("stub").getTypeParameters()[0], Integer.class);
+ assertTrue(TypeUtils.typesSatisfyVariables(typeVarAssigns));
+ typeVarAssigns.clear();
+ typeVarAssigns.put(getClass().getMethod("stub2").getTypeParameters()[0], Integer.class);
+ assertTrue(TypeUtils.typesSatisfyVariables(typeVarAssigns));
+ typeVarAssigns.clear();
+ typeVarAssigns.put(getClass().getMethod("stub3").getTypeParameters()[0], Integer.class);
+ assertTrue(TypeUtils.typesSatisfyVariables(typeVarAssigns));
}
- public class FClass extends EClass<String> {
+ @Test
+ public void testUnboundedWildcardType() {
+ final WildcardType unbounded = TypeUtils.wildcardType().withLowerBounds((Type) null).withUpperBounds().build();
+ assertTrue(TypeUtils.equals(TypeUtils.WILDCARD_ALL, unbounded));
+ assertArrayEquals(new Type[] { Object.class }, TypeUtils.getImplicitUpperBounds(unbounded));
+ assertArrayEquals(new Type[] { null }, TypeUtils.getImplicitLowerBounds(unbounded));
+ assertEquals("?", TypeUtils.toString(unbounded));
+ assertEquals("?", unbounded.toString());
}
- public class GClass<T extends BClass<? extends T> & AInterface<AInterface<? super T>>> {
+ @Test
+ public void testWildcardType() throws Exception {
+ final WildcardType simpleWildcard = TypeUtils.wildcardType().withUpperBounds(String.class).build();
+ final Field cClass = AClass.class.getField("cClass");
+ assertTrue(TypeUtils.equals(((ParameterizedType) cClass.getGenericType()).getActualTypeArguments()[0],
+ simpleWildcard));
+ assertEquals(String.format("? extends %s", String.class.getName()), TypeUtils.toString(simpleWildcard));
+ assertEquals(String.format("? extends %s", String.class.getName()), simpleWildcard.toString());
}
- public BClass<Number> bClass;
-
- public CClass<? extends String> cClass;
-
- public DClass<String> dClass;
-
- public EClass<String> eClass;
-
- public FClass fClass;
-
- public GClass gClass;
+ @Test
+ public void testWrap() {
+ final Type t = getClass().getTypeParameters()[0];
+ assertTrue(TypeUtils.equals(t, TypeUtils.wrap(t).getType()));
- public interface AInterface<T> {
+ assertEquals(String.class, TypeUtils.wrap(String.class).getType());
}
}