Add support for resolving multiple bounds in type variables

Closes gh-22902
See gh-32327
This commit is contained in:
Juergen Hoeller
2024-03-02 11:30:17 +01:00
parent ac1a030c35
commit 390fe0fe78
2 changed files with 128 additions and 32 deletions

View File

@@ -1023,11 +1023,21 @@ class ResolvableTypeTests {
@Test
void isAssignableFromCannotBeResolved() throws Exception {
ResolvableType objectType = ResolvableType.forClass(Object.class);
ResolvableType unresolvableVariable = ResolvableType.forField(AssignmentBase.class.getField("o"));
ResolvableType unresolvableVariable1 = ResolvableType.forField(AssignmentBase.class.getField("o"));
ResolvableType unresolvableVariable2 = ResolvableType.forField(AssignmentBase.class.getField("c"));
ResolvableType unresolvableVariable3 = ResolvableType.forField(AssignmentBase.class.getField("s"));
assertThat(unresolvableVariable.resolve()).isNull();
assertThatResolvableType(objectType).isAssignableFrom(unresolvableVariable);
assertThatResolvableType(unresolvableVariable).isAssignableFrom(objectType);
assertThat(unresolvableVariable1.resolve()).isNull();
assertThatResolvableType(objectType).isAssignableFrom(unresolvableVariable1);
assertThatResolvableType(unresolvableVariable1).isAssignableFrom(objectType);
assertThat(unresolvableVariable2.resolve()).isNull();
assertThatResolvableType(objectType).isAssignableFrom(unresolvableVariable2);
assertThatResolvableType(unresolvableVariable2).isAssignableFrom(objectType);
assertThat(unresolvableVariable3.resolve()).isEqualTo(Serializable.class);
assertThatResolvableType(objectType).isAssignableFrom(unresolvableVariable3);
assertThatResolvableType(unresolvableVariable3).isNotAssignableFrom(objectType);
}
@Test
@@ -1157,7 +1167,7 @@ class ResolvableTypeTests {
// T <= ? extends T
assertThatResolvableType(extendsCharSequence).isAssignableFrom(charSequence, string).isNotAssignableFrom(object);
assertThatResolvableType(charSequence).isNotAssignableFrom(extendsObject, extendsCharSequence, extendsString);
assertThatResolvableType(charSequence).isAssignableFrom(extendsCharSequence, extendsString).isNotAssignableFrom(extendsObject);
assertThatResolvableType(extendsAnon).isAssignableFrom(object, charSequence, string);
// T <= ? super T
@@ -1367,6 +1377,14 @@ class ResolvableTypeTests {
assertThat(type.resolveGeneric()).isEqualTo(Integer.class);
}
@Test
void gh22902() throws Exception {
ResolvableType ab = ResolvableType.forField(ABClient.class.getField("field"));
assertThat(ab.isAssignableFrom(Object.class)).isFalse();
assertThat(ab.isAssignableFrom(AwithB.class)).isTrue();
assertThat(ab.isAssignableFrom(AwithoutB.class)).isFalse();
}
@Test
void gh32327() throws Exception {
ResolvableType repository1 = ResolvableType.forField(Fields.class.getField("repository"));
@@ -1375,7 +1393,7 @@ class ResolvableTypeTests {
assertThat(repository1.hasUnresolvableGenerics()).isFalse();
assertThat(repository1.isAssignableFrom(repository2)).isFalse();
assertThat(repository1.isAssignableFromResolvedPart(repository2)).isTrue();
assertThat(repository1.isAssignableFrom(repository3)).isFalse();
assertThat(repository1.isAssignableFrom(repository3)).isTrue();
assertThat(repository1.isAssignableFromResolvedPart(repository3)).isTrue();
assertThat(repository2.hasUnresolvableGenerics()).isTrue();
assertThat(repository2.isAssignableFrom(repository1)).isTrue();
@@ -1520,7 +1538,7 @@ class ResolvableTypeTests {
}
static class AssignmentBase<O, C, S> {
static class AssignmentBase<O, C, S extends Serializable> {
public O o;
@@ -1722,6 +1740,40 @@ class ResolvableTypeTests {
}
interface A {
void doA();
}
interface B {
void doB();
}
static class ABClient<T extends A & B> {
public T field;
}
static class AwithB implements A, B {
@Override
public void doA() {
}
@Override
public void doB() {
}
}
static class AwithoutB implements A {
@Override
public void doA() {
}
}
private static class ResolvableTypeAssert extends AbstractAssert<ResolvableTypeAssert, ResolvableType>{
public ResolvableTypeAssert(ResolvableType actual) {