Skip to content

Commit

Permalink
Add isSubtypeOf() "pre"-condition check before getSubtype() returns.
Browse files Browse the repository at this point in the history
We have to call it before return because before type variable substitution, isSubtypeOf() can't apply.

See #3048

RELNOTES=Validate `TypeToken.getSubtype()`.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=187777105
  • Loading branch information
benyu authored and ronshapiro committed Mar 6, 2018
1 parent d710bd8 commit e47fc16
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,15 @@ public void testSubtypeOfNonStaticAnonymousClass() {
.isSubtypeOf(superclass));
}

public void testGetSubtypeOf_impossibleWildcard() {
TypeToken<List<? extends Number>> numberList = new TypeToken<List<? extends Number>>() {};
abstract class StringList implements List<String> {}
try {
numberList.getSubtype(StringList.class);
fail();
} catch (IllegalArgumentException expected) {}
}

private static class OwnerTypeSubtypingTests extends SubtypeTester {
@TestSubtype
public Mall<Outdoor>.Shop<Electronics> innerTypeIsSubtype(
Expand Down
2 changes: 2 additions & 0 deletions android/guava/src/com/google/common/reflect/TypeToken.java
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,8 @@ public final TypeToken<? extends T> getSubtype(Class<?> subclass) {
Type resolvedTypeArgs = resolveTypeArgsForSubclass(subclass);
@SuppressWarnings("unchecked") // guarded by the isAssignableFrom() statement above
TypeToken<? extends T> subtype = (TypeToken<? extends T>) of(resolvedTypeArgs);
checkArgument(
subtype.isSubtypeOf(this), "%s does not appear to be a subtype of %s", subtype, this);
return subtype;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,15 @@ public void testSubtypeOfNonStaticAnonymousClass() {
.isSubtypeOf(superclass));
}

public void testGetSubtypeOf_impossibleWildcard() {
TypeToken<List<? extends Number>> numberList = new TypeToken<List<? extends Number>>() {};
abstract class StringList implements List<String> {}
try {
numberList.getSubtype(StringList.class);
fail();
} catch (IllegalArgumentException expected) {}
}

private static class OwnerTypeSubtypingTests extends SubtypeTester {
@TestSubtype
public Mall<Outdoor>.Shop<Electronics> innerTypeIsSubtype(
Expand Down
2 changes: 2 additions & 0 deletions guava/src/com/google/common/reflect/TypeToken.java
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,8 @@ public final TypeToken<? extends T> getSubtype(Class<?> subclass) {
Type resolvedTypeArgs = resolveTypeArgsForSubclass(subclass);
@SuppressWarnings("unchecked") // guarded by the isAssignableFrom() statement above
TypeToken<? extends T> subtype = (TypeToken<? extends T>) of(resolvedTypeArgs);
checkArgument(
subtype.isSubtypeOf(this), "%s does not appear to be a subtype of %s", subtype, this);
return subtype;
}

Expand Down

0 comments on commit e47fc16

Please sign in to comment.