Skip to content

Commit

Permalink
Revert "Support WildcardType resolution in GenericTypeResolver"
Browse files Browse the repository at this point in the history
  • Loading branch information
sdeleuze committed Nov 29, 2023
1 parent c8e6315 commit b842509
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 107 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
* @author Rob Harrop
* @author Sam Brannen
* @author Phillip Webb
* @author Sebastien Deleuze
* @since 2.5.2
*/
public final class GenericTypeResolver {
Expand Down Expand Up @@ -167,30 +166,29 @@ public static Type resolveType(Type genericType, @Nullable Class<?> contextClass
}
else if (genericType instanceof ParameterizedType parameterizedType) {
ResolvableType resolvedType = ResolvableType.forType(genericType);
Class<?>[] generics = new Class<?>[parameterizedType.getActualTypeArguments().length];
Type[] typeArguments = parameterizedType.getActualTypeArguments();
ResolvableType contextType = ResolvableType.forClass(contextClass);
for (int i = 0; i < typeArguments.length; i++) {
Type typeArgument = typeArguments[i];
if (typeArgument instanceof TypeVariable<?> typeVariable) {
ResolvableType resolvedTypeArgument = resolveVariable(typeVariable, contextType);
if (resolvedTypeArgument != ResolvableType.NONE) {
generics[i] = resolvedTypeArgument.resolve();
if (resolvedType.hasUnresolvableGenerics()) {
Class<?>[] generics = new Class<?>[parameterizedType.getActualTypeArguments().length];
Type[] typeArguments = parameterizedType.getActualTypeArguments();
ResolvableType contextType = ResolvableType.forClass(contextClass);
for (int i = 0; i < typeArguments.length; i++) {
Type typeArgument = typeArguments[i];
if (typeArgument instanceof TypeVariable<?> typeVariable) {
ResolvableType resolvedTypeArgument = resolveVariable(typeVariable, contextType);
if (resolvedTypeArgument != ResolvableType.NONE) {
generics[i] = resolvedTypeArgument.resolve();
}
else {
generics[i] = ResolvableType.forType(typeArgument).resolve();
}
}
else {
generics[i] = ResolvableType.forType(typeArgument).resolve();
}
}
else if (typeArgument instanceof WildcardType wildcardType) {
generics[i] = resolveWildcard(wildcardType, contextType).resolve();
Class<?> rawClass = resolvedType.getRawClass();
if (rawClass != null) {
return ResolvableType.forClassWithGenerics(rawClass, generics).getType();
}
else {
generics[i] = ResolvableType.forType(typeArgument).resolve();
}
}
Class<?> rawClass = resolvedType.getRawClass();
if (rawClass != null) {
return ResolvableType.forClassWithGenerics(rawClass, generics).getType();
}
}
}
Expand Down Expand Up @@ -226,26 +224,6 @@ private static ResolvableType resolveVariable(TypeVariable<?> typeVariable, Reso
return ResolvableType.NONE;
}

private static ResolvableType resolveWildcard(WildcardType wildcardType, ResolvableType contextType) {
for (Type bound : wildcardType.getUpperBounds()) {
if (bound instanceof TypeVariable<?> typeVariable) {
ResolvableType resolvedTypeArgument = resolveVariable(typeVariable, contextType);
if (resolvedTypeArgument != ResolvableType.NONE) {
return resolvedTypeArgument;
}
}
}
for (Type bound : wildcardType.getLowerBounds()) {
if (bound instanceof TypeVariable<?> typeVariable) {
ResolvableType resolvedTypeArgument = resolveVariable(typeVariable, contextType);
if (resolvedTypeArgument != ResolvableType.NONE) {
return resolvedTypeArgument;
}
}
}
return ResolvableType.forType(wildcardType);
}

/**
* Resolve the specified generic type against the given TypeVariable map.
* <p>Used by Spring Data.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -194,58 +194,6 @@ public void resolveTransitiveTypeVariableWithDifferentName() {
assertThat(resolved).isEqualTo(E.class);
}

@Test
void resolveWildcardTypeWithUpperBound() {
Method method = method(MySimpleSuperclassType.class, "upperBound", List.class);
Type resolved = resolveType(method.getGenericParameterTypes()[0], MySimpleSuperclassType.class);
ResolvableType resolvableType = ResolvableType.forType(resolved);
assertThat(resolvableType.hasUnresolvableGenerics()).isFalse();
assertThat(resolvableType.resolveGenerics()).containsExactly(String.class);
}

@Test
void resolveWildcardTypeWithUpperBoundWithResolvedType() {
Method method = method(MySimpleSuperclassType.class, "upperBoundWithResolvedType", List.class);
Type resolved = resolveType(method.getGenericParameterTypes()[0], MySimpleSuperclassType.class);
ResolvableType resolvableType = ResolvableType.forType(resolved);
assertThat(resolvableType.hasUnresolvableGenerics()).isFalse();
assertThat(resolvableType.resolveGenerics()).containsExactly(Integer.class);
}

@Test
void resolveWildcardTypeWithLowerBound() {
Method method = method(MySimpleSuperclassType.class, "lowerBound", List.class);
Type resolved = resolveType(method.getGenericParameterTypes()[0], MySimpleSuperclassType.class);
ResolvableType resolvableType = ResolvableType.forType(resolved);
assertThat(resolvableType.hasUnresolvableGenerics()).isFalse();
assertThat(resolvableType.resolveGenerics()).containsExactly(String.class);
}

@Test
void resolveWildcardTypeWithLowerBoundWithResolvedType() {
Method method = method(MySimpleSuperclassType.class, "lowerBoundWithResolvedType", List.class);
Type resolved = resolveType(method.getGenericParameterTypes()[0], MySimpleSuperclassType.class);
ResolvableType resolvableType = ResolvableType.forType(resolved);
assertThat(resolvableType.hasUnresolvableGenerics()).isFalse();
assertThat(resolvableType.resolveGenerics()).containsExactly(Integer.class);
}

@Test
void resolveWildcardTypeWithUnbounded() {
Method method = method(MySimpleSuperclassType.class, "unbounded", List.class);
Type resolved = resolveType(method.getGenericParameterTypes()[0], MySimpleSuperclassType.class);
ResolvableType resolvableType = ResolvableType.forType(resolved);
assertThat(resolvableType.hasUnresolvableGenerics()).isFalse();
assertThat(resolvableType.resolveGenerics()).containsExactly(Object.class);
}

@Test // gh-28904
void resolveGenericWithDifferentInterfaceOrder() {
Type f = First.class.getTypeParameters()[0];
assertThat(resolveType(f, FirstSecondService.class)).isEqualTo(Integer.class);
assertThat(resolveType(f, SecondFirstService.class)).isEqualTo(Integer.class);
}

private static Method method(Class<?> target, String methodName, Class<?>... parameterTypes) {
Method method = findMethod(target, methodName, parameterTypes);
assertThat(method).describedAs(target.getName() + "#" + methodName).isNotNull();
Expand All @@ -268,21 +216,6 @@ public class MyConcreteType extends MyAbstractType<Character> {
}

public abstract class MySuperclassType<T> {

public void upperBound(List<? extends T> list) {
}

public void upperBoundWithResolvedType(List<? extends Integer> list) {
}

public void lowerBound(List<? extends T> list) {
}

public void lowerBoundWithResolvedType(List<? super Integer> list) {
}

public void unbounded(List<?> list) {
}
}

public class MySimpleSuperclassType extends MySuperclassType<String> {
Expand Down

0 comments on commit b842509

Please sign in to comment.