Skip to content

Commit 545c832

Browse files
committed
simplification
1 parent ef75bbd commit 545c832

File tree

2 files changed

+30
-54
lines changed

2 files changed

+30
-54
lines changed

src/main/java/com/fasterxml/jackson/databind/introspect/MethodGenericTypeResolver.java

Lines changed: 25 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
import java.lang.reflect.Type;
1010
import java.lang.reflect.TypeVariable;
1111
import java.lang.reflect.WildcardType;
12-
import java.util.HashMap;
13-
import java.util.Map;
12+
import java.util.ArrayList;
1413
import java.util.Objects;
1514

1615
/**
@@ -57,12 +56,13 @@ static TypeResolutionContext narrowMethodTypeParameters(
5756
return emptyTypeResCtxt;
5857
}
5958

60-
// Construct a mapping from the method type variable names to the types requested by requestedType
59+
// Construct TypeBindings based on the requested type, and type variables that occur in the generic return type.
6160
// For example given requestedType: Foo<String, Int>
62-
// and method static <T, U> Foo<T, U> func(Object in)
63-
// This produces {T=String, U=Int}.
61+
// and method static <T, U> Foo<T, U> func(Bar<T, U> in)
62+
// Produces TypeBindings{T=String, U=Int}.
6463
Type[] methodReturnTypeArguments = parameterizedGenericReturnType.getActualTypeArguments();
65-
Map<String, JavaType> bindTargetsByName = new HashMap<>(methodReturnTypeArguments.length);
64+
ArrayList<String> names = new ArrayList<>(methodTypeParameters.length);
65+
ArrayList<JavaType> types = new ArrayList<>(methodTypeParameters.length);
6666
for (int j = 0; j < methodReturnTypeArguments.length; j++) {
6767
Type methodReturnTypeArgument = methodReturnTypeArguments[j];
6868
// Note: This strictly supports only TypeVariables, not wildcards with nested type variables
@@ -72,43 +72,33 @@ static TypeResolutionContext narrowMethodTypeParameters(
7272
if (typeParameterName == null) {
7373
return emptyTypeResCtxt;
7474
}
75-
// If the type parameter name is not present in the method type parameters we
76-
// fall back to default type handling.
77-
if (!containsName(methodTypeParameters, typeParameterName)) {
78-
return emptyTypeResCtxt;
75+
76+
// Avoid duplicates
77+
if (names.contains(typeParameterName)) {
78+
continue;
7979
}
80+
8081
JavaType bindTarget = requestedType.getBindings().getBoundType(j);
8182
if (bindTarget == null) {
8283
return emptyTypeResCtxt;
8384
}
84-
bindTargetsByName.put(typeParameterName, bindTarget);
85-
}
86-
}
87-
boolean appliedAtLeastOneBinding = false;
88-
JavaType[] bindings = new JavaType[methodTypeParameters.length];
89-
for (int j = 0; j < methodTypeParameters.length; j++) {
90-
TypeVariable<Method> methodTypeVariable = methodTypeParameters[j];
91-
JavaType typeBindingBasedOnRequest = bindTargetsByName.get(methodTypeVariable.getName());
92-
Type[] bounds = methodTypeVariable.getBounds();
93-
// Use the propagated type information if it exists, otherwise fall back to bounds provided by the method.
94-
if (typeBindingBasedOnRequest == null
95-
// The method level bindings are used if they're narrower than the requested type
96-
|| !pessimisticallyValidateBounds(emptyTypeResCtxt, typeBindingBasedOnRequest, bounds)) {
97-
if (bounds.length == 1) {
98-
typeBindingBasedOnRequest = emptyTypeResCtxt.resolveType(bounds[0]);
99-
} else {
85+
// If the type parameter name is not present in the method type parameters we
86+
// fall back to default type handling.
87+
TypeVariable<?> methodTypeVariable = findByName(methodTypeParameters, typeParameterName);
88+
if (methodTypeVariable == null) {
10089
return emptyTypeResCtxt;
10190
}
102-
} else {
103-
appliedAtLeastOneBinding = true;
91+
if (pessimisticallyValidateBounds(emptyTypeResCtxt, bindTarget, methodTypeVariable.getBounds())) {
92+
names.add(methodTypeVariable.getName());
93+
types.add(bindTarget);
94+
}
10495
}
105-
bindings[j] = typeBindingBasedOnRequest;
10696
}
10797
// Fall back to default handling if no specific types from the requestedType are used
108-
if (!appliedAtLeastOneBinding) {
98+
if (names.isEmpty()) {
10999
return emptyTypeResCtxt;
110100
}
111-
TypeBindings newTypeBindings = TypeBindings.create(candidate, bindings);
101+
TypeBindings newTypeBindings = TypeBindings.create(names, types);
112102
return new TypeResolutionContext.Basic(typeFactory, newTypeBindings);
113103
}
114104

@@ -185,16 +175,16 @@ private static boolean pessimisticallyValidateBound(
185175
return true;
186176
}
187177

188-
private static boolean containsName(TypeVariable<?>[] typeVariables, String name) {
178+
private static TypeVariable<?> findByName(TypeVariable<?>[] typeVariables, String name) {
189179
if (typeVariables == null || name == null) {
190-
return false;
180+
return null;
191181
}
192182
for (TypeVariable<?> typeVariable : typeVariables) {
193183
if (name.equals(typeVariable.getName())) {
194-
return true;
184+
return typeVariable;
195185
}
196186
}
197-
return false;
187+
return null;
198188
}
199189

200190
private MethodGenericTypeResolver() {

src/main/java/com/fasterxml/jackson/databind/type/TypeBindings.java

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -142,28 +142,14 @@ public static TypeBindings create(Class<?> erasedType, JavaType typeArg1, JavaTy
142142
}
143143

144144
/**
145-
* Factory method for constructing bindings for given method using specified type parameters.
145+
* Factory method for constructing bindings given names and associated types.
146146
*/
147-
public static TypeBindings create(Method method, JavaType[] types)
147+
public static TypeBindings create(List<String> names, List<JavaType> types)
148148
{
149-
TypeVariable<?>[] vars = method.getTypeParameters();
150-
String[] names;
151-
if (vars == null || vars.length == 0) {
152-
names = NO_STRINGS;
153-
} else {
154-
int len = vars.length;
155-
names = new String[len];
156-
for (int i = 0; i < len; ++i) {
157-
names[i] = vars[i].getName();
158-
}
159-
}
160-
// Check here to provide a better error message
161-
if (names.length != types.length) {
162-
throw new IllegalArgumentException("Cannot create TypeBindings for method "
163-
+ method.getName() + " with " + types.length + " type parameter"
164-
+ ((types.length == 1) ? "" : "s") + ": method expects " + names.length);
149+
if (names == null || names.isEmpty() || types == null || types.isEmpty()) {
150+
return EMPTY;
165151
}
166-
return new TypeBindings(names, types, null);
152+
return new TypeBindings(names.toArray(NO_STRINGS), types.toArray(NO_TYPES), null);
167153
}
168154

169155
/**

0 commit comments

Comments
 (0)