Skip to content

Commit

Permalink
Remove TypeToken check for type variable
Browse files Browse the repository at this point in the history
As mentioned in review comments, there are cases during serialization where
usage of the type variable is not so problematic (but still not ideal).
  • Loading branch information
Marcono1234 committed Feb 15, 2022
1 parent 446bf92 commit b9436ed
Show file tree
Hide file tree
Showing 2 changed files with 1 addition and 82 deletions.
27 changes: 1 addition & 26 deletions gson/src/main/java/com/google/gson/reflect/TypeToken.java
Expand Up @@ -22,7 +22,6 @@
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.HashMap;
import java.util.Map;

Expand Down Expand Up @@ -89,9 +88,7 @@ private Type getTypeTokenTypeArgument() {
if (superclass instanceof ParameterizedType) {
ParameterizedType parameterized = (ParameterizedType) superclass;
if (parameterized.getRawType() == TypeToken.class) {
Type typeArgument = $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);
verifyNoTypeVariable(typeArgument);
return typeArgument;
return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);
}
}
// Check for raw TypeToken as superclass
Expand All @@ -104,28 +101,6 @@ else if (superclass == TypeToken.class) {
throw new IllegalStateException("Must only create direct subclasses of TypeToken");
}

private static void verifyNoTypeVariable(Type type) {
if (type instanceof TypeVariable) {
TypeVariable<?> typeVariable = (TypeVariable<?>) type;
throw new IllegalArgumentException("TypeToken type argument must not contain a type variable; captured type variable "
+ typeVariable.getName() + " declared by " + typeVariable.getGenericDeclaration());
} else if (type instanceof GenericArrayType) {
verifyNoTypeVariable(((GenericArrayType) type).getGenericComponentType());
} else if (type instanceof ParameterizedType) {
for (Type typeArgument : ((ParameterizedType) type).getActualTypeArguments()) {
verifyNoTypeVariable(typeArgument);
}
} else if (type instanceof WildcardType) {
WildcardType wildcardType = (WildcardType) type;
for (Type bound : wildcardType.getLowerBounds()) {
verifyNoTypeVariable(bound);
}
for (Type bound : wildcardType.getUpperBounds()) {
verifyNoTypeVariable(bound);
}
}
}

/**
* Returns the raw (non-generic) type for this type.
*/
Expand Down
56 changes: 0 additions & 56 deletions gson/src/test/java/com/google/gson/reflect/TypeTokenTest.java
Expand Up @@ -146,62 +146,6 @@ class SubSubTypeToken2 extends SubTypeToken<Integer> {}
}
}

/**
* TypeToken type argument must not contain a type variable because, due to
* type erasure, at runtime only the bound of the type variable is available
* which is likely not what the user wanted.
*
* <p>Note that type variables are allowed for the methods calling {@code TypeToken(Type)}
* because there the return type is {@code TypeToken<?>} which does not give
* a false sense of type-safety.
*/
public <T> void testTypeTokenTypeVariable() {
try {
new TypeToken<T>() {};
fail();
} catch (IllegalArgumentException expected) {
assertEquals("TypeToken type argument must not contain a type variable; captured type variable T "
+ "declared by public void com.google.gson.reflect.TypeTokenTest.testTypeTokenTypeVariable()",
expected.getMessage());
}

try {
new TypeToken<List<List<T>>>() {};
fail();
} catch (IllegalArgumentException expected) {
assertEquals("TypeToken type argument must not contain a type variable; captured type variable T "
+ "declared by public void com.google.gson.reflect.TypeTokenTest.testTypeTokenTypeVariable()",
expected.getMessage());
}

try {
new TypeToken<List<? extends List<T>>>() {};
fail();
} catch (IllegalArgumentException expected) {
assertEquals("TypeToken type argument must not contain a type variable; captured type variable T "
+ "declared by public void com.google.gson.reflect.TypeTokenTest.testTypeTokenTypeVariable()",
expected.getMessage());
}

try {
new TypeToken<List<? super List<T>>>() {};
fail();
} catch (IllegalArgumentException expected) {
assertEquals("TypeToken type argument must not contain a type variable; captured type variable T "
+ "declared by public void com.google.gson.reflect.TypeTokenTest.testTypeTokenTypeVariable()",
expected.getMessage());
}

try {
new TypeToken<List<T>[]>() {};
fail();
} catch (IllegalArgumentException expected) {
assertEquals("TypeToken type argument must not contain a type variable; captured type variable T "
+ "declared by public void com.google.gson.reflect.TypeTokenTest.testTypeTokenTypeVariable()",
expected.getMessage());
}
}

@SuppressWarnings("rawtypes")
public void testTypeTokenRaw() {
try {
Expand Down

0 comments on commit b9436ed

Please sign in to comment.