Restore lenient match against unresolvable wildcard
Closes gh-33982
This commit is contained in:
parent
e618f922c2
commit
b5dd0a60f8
|
@ -334,19 +334,19 @@ public class ResolvableType implements Serializable {
|
||||||
|
|
||||||
// Deal with wildcard bounds
|
// Deal with wildcard bounds
|
||||||
WildcardBounds ourBounds = WildcardBounds.get(this);
|
WildcardBounds ourBounds = WildcardBounds.get(this);
|
||||||
WildcardBounds typeBounds = WildcardBounds.get(other);
|
WildcardBounds otherBounds = WildcardBounds.get(other);
|
||||||
|
|
||||||
// In the form X is assignable to <? extends Number>
|
// In the form X is assignable to <? extends Number>
|
||||||
if (typeBounds != null) {
|
if (otherBounds != null) {
|
||||||
if (ourBounds != null) {
|
if (ourBounds != null) {
|
||||||
return (ourBounds.isSameKind(typeBounds) &&
|
return (ourBounds.isSameKind(otherBounds) &&
|
||||||
ourBounds.isAssignableFrom(typeBounds.getBounds(), matchedBefore));
|
ourBounds.isAssignableFrom(otherBounds.getBounds(), matchedBefore));
|
||||||
}
|
}
|
||||||
else if (upUntilUnresolvable) {
|
else if (upUntilUnresolvable) {
|
||||||
return typeBounds.isAssignableFrom(this, matchedBefore);
|
return otherBounds.isAssignableFrom(this, matchedBefore);
|
||||||
}
|
}
|
||||||
else if (!exactMatch) {
|
else if (!exactMatch) {
|
||||||
return typeBounds.isAssignableTo(this, matchedBefore);
|
return otherBounds.isAssignableTo(this, matchedBefore);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -400,8 +400,8 @@ public class ResolvableType implements Serializable {
|
||||||
if (checkGenerics) {
|
if (checkGenerics) {
|
||||||
// Recursively check each generic
|
// Recursively check each generic
|
||||||
ResolvableType[] ourGenerics = getGenerics();
|
ResolvableType[] ourGenerics = getGenerics();
|
||||||
ResolvableType[] typeGenerics = other.as(ourResolved).getGenerics();
|
ResolvableType[] otherGenerics = other.as(ourResolved).getGenerics();
|
||||||
if (ourGenerics.length != typeGenerics.length) {
|
if (ourGenerics.length != otherGenerics.length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (ourGenerics.length > 0) {
|
if (ourGenerics.length > 0) {
|
||||||
|
@ -410,7 +410,8 @@ public class ResolvableType implements Serializable {
|
||||||
}
|
}
|
||||||
matchedBefore.put(this.type, other.type);
|
matchedBefore.put(this.type, other.type);
|
||||||
for (int i = 0; i < ourGenerics.length; i++) {
|
for (int i = 0; i < ourGenerics.length; i++) {
|
||||||
if (!ourGenerics[i].isAssignableFrom(typeGenerics[i], true, matchedBefore, upUntilUnresolvable)) {
|
if (!ourGenerics[i].isAssignableFrom(otherGenerics[i],
|
||||||
|
!other.hasUnresolvableGenerics(), matchedBefore, upUntilUnresolvable)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1188,6 +1188,26 @@ class ResolvableTypeTests {
|
||||||
assertThatResolvableType(complex4).isNotAssignableFrom(complex3);
|
assertThatResolvableType(complex4).isNotAssignableFrom(complex3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void isAssignableFromForUnresolvedWildcards() {
|
||||||
|
ResolvableType wildcard = ResolvableType.forInstance(new Wildcard<>());
|
||||||
|
ResolvableType wildcardFixed = ResolvableType.forInstance(new WildcardFixed());
|
||||||
|
ResolvableType wildcardConcrete = ResolvableType.forClassWithGenerics(Wildcard.class, Number.class);
|
||||||
|
|
||||||
|
assertThat(wildcard.isAssignableFrom(wildcardFixed)).isTrue();
|
||||||
|
assertThat(wildcard.isAssignableFromResolvedPart(wildcardFixed)).isTrue();
|
||||||
|
assertThat(wildcard.isAssignableFrom(wildcardConcrete)).isTrue();
|
||||||
|
assertThat(wildcard.isAssignableFromResolvedPart(wildcardConcrete)).isTrue();
|
||||||
|
assertThat(wildcardFixed.isAssignableFrom(wildcard)).isFalse();
|
||||||
|
assertThat(wildcardFixed.isAssignableFromResolvedPart(wildcard)).isFalse();
|
||||||
|
assertThat(wildcardFixed.isAssignableFrom(wildcardConcrete)).isFalse();
|
||||||
|
assertThat(wildcardFixed.isAssignableFromResolvedPart(wildcardConcrete)).isFalse();
|
||||||
|
assertThat(wildcardConcrete.isAssignableFrom(wildcard)).isTrue();
|
||||||
|
assertThat(wildcardConcrete.isAssignableFromResolvedPart(wildcard)).isTrue();
|
||||||
|
assertThat(wildcardConcrete.isAssignableFrom(wildcardFixed)).isFalse();
|
||||||
|
assertThat(wildcardConcrete.isAssignableFromResolvedPart(wildcardFixed)).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void identifyTypeVariable() throws Exception {
|
void identifyTypeVariable() throws Exception {
|
||||||
Method method = ClassArguments.class.getMethod("typedArgumentFirst", Class.class, Class.class, Class.class);
|
Method method = ClassArguments.class.getMethod("typedArgumentFirst", Class.class, Class.class, Class.class);
|
||||||
|
@ -1685,7 +1705,6 @@ class ResolvableTypeTests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class MySimpleInterfaceType implements MyInterfaceType<String> {
|
public class MySimpleInterfaceType implements MyInterfaceType<String> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1695,7 +1714,6 @@ class ResolvableTypeTests {
|
||||||
public abstract class ExtendsMySimpleInterfaceTypeWithImplementsRaw extends MySimpleInterfaceTypeWithImplementsRaw {
|
public abstract class ExtendsMySimpleInterfaceTypeWithImplementsRaw extends MySimpleInterfaceTypeWithImplementsRaw {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class MyCollectionInterfaceType implements MyInterfaceType<Collection<String>> {
|
public class MyCollectionInterfaceType implements MyInterfaceType<Collection<String>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1703,20 +1721,17 @@ class ResolvableTypeTests {
|
||||||
public abstract class MySuperclassType<T> {
|
public abstract class MySuperclassType<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class MySimpleSuperclassType extends MySuperclassType<String> {
|
public class MySimpleSuperclassType extends MySuperclassType<String> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class MyCollectionSuperclassType extends MySuperclassType<Collection<String>> {
|
public class MyCollectionSuperclassType extends MySuperclassType<Collection<String>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
interface Wildcard<T extends Number> extends List<T> {
|
public class Wildcard<T extends Number> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class WildcardFixed extends Wildcard<Integer> {
|
||||||
interface RawExtendsWildcard extends Wildcard {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue