|
1 | 1 | /**
|
2 |
| - * Copyright 2009-2016 the original author or authors. |
| 2 | + * Copyright 2009-2018 the original author or authors. |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
@@ -170,39 +170,48 @@ private static Type resolveTypeVar(TypeVariable<?> typeVar, Type srcType, Class<
|
170 | 170 | }
|
171 | 171 |
|
172 | 172 | private static Type scanSuperTypes(TypeVariable<?> typeVar, Type srcType, Class<?> declaringClass, Class<?> clazz, Type superclass) {
|
173 |
| - Type result = null; |
174 | 173 | if (superclass instanceof ParameterizedType) {
|
175 | 174 | ParameterizedType parentAsType = (ParameterizedType) superclass;
|
176 | 175 | Class<?> parentAsClass = (Class<?>) parentAsType.getRawType();
|
| 176 | + TypeVariable<?>[] parentTypeVars = parentAsClass.getTypeParameters(); |
| 177 | + if (srcType instanceof ParameterizedType) { |
| 178 | + parentAsType = translateParentTypeVars((ParameterizedType) srcType, clazz, parentAsType); |
| 179 | + } |
177 | 180 | if (declaringClass == parentAsClass) {
|
178 |
| - Type[] typeArgs = parentAsType.getActualTypeArguments(); |
179 |
| - TypeVariable<?>[] declaredTypeVars = declaringClass.getTypeParameters(); |
180 |
| - for (int i = 0; i < declaredTypeVars.length; i++) { |
181 |
| - if (declaredTypeVars[i] == typeVar) { |
182 |
| - if (typeArgs[i] instanceof TypeVariable) { |
183 |
| - TypeVariable<?>[] typeParams = clazz.getTypeParameters(); |
184 |
| - for (int j = 0; j < typeParams.length; j++) { |
185 |
| - if (typeParams[j] == typeArgs[i]) { |
186 |
| - if (srcType instanceof ParameterizedType) { |
187 |
| - result = ((ParameterizedType) srcType).getActualTypeArguments()[j]; |
188 |
| - } |
189 |
| - break; |
190 |
| - } |
191 |
| - } |
192 |
| - } else { |
193 |
| - result = typeArgs[i]; |
194 |
| - } |
| 181 | + for (int i = 0; i < parentTypeVars.length; i++) { |
| 182 | + if (typeVar == parentTypeVars[i]) { |
| 183 | + return parentAsType.getActualTypeArguments()[i]; |
195 | 184 | }
|
196 | 185 | }
|
197 |
| - } else if (declaringClass.isAssignableFrom(parentAsClass)) { |
198 |
| - result = resolveTypeVar(typeVar, parentAsType, declaringClass); |
199 | 186 | }
|
200 |
| - } else if (superclass instanceof Class) { |
201 |
| - if (declaringClass.isAssignableFrom((Class<?>) superclass)) { |
202 |
| - result = resolveTypeVar(typeVar, superclass, declaringClass); |
| 187 | + if (declaringClass.isAssignableFrom(parentAsClass)) { |
| 188 | + return resolveTypeVar(typeVar, parentAsType, declaringClass); |
203 | 189 | }
|
| 190 | + } else if (superclass instanceof Class && declaringClass.isAssignableFrom((Class<?>) superclass)) { |
| 191 | + return resolveTypeVar(typeVar, superclass, declaringClass); |
204 | 192 | }
|
205 |
| - return result; |
| 193 | + return null; |
| 194 | + } |
| 195 | + |
| 196 | + private static ParameterizedType translateParentTypeVars(ParameterizedType srcType, Class<?> srcClass, ParameterizedType parentType) { |
| 197 | + Type[] parentTypeArgs = parentType.getActualTypeArguments(); |
| 198 | + Type[] srcTypeArgs = srcType.getActualTypeArguments(); |
| 199 | + TypeVariable<?>[] srcTypeVars = srcClass.getTypeParameters(); |
| 200 | + Type[] newParentArgs = new Type[parentTypeArgs.length]; |
| 201 | + boolean noChange = true; |
| 202 | + for (int i = 0; i < parentTypeArgs.length; i++) { |
| 203 | + if (parentTypeArgs[i] instanceof TypeVariable) { |
| 204 | + for (int j = 0; j < srcTypeVars.length; j++) { |
| 205 | + if (srcTypeVars[j] == parentTypeArgs[i]) { |
| 206 | + noChange = false; |
| 207 | + newParentArgs[i] = srcTypeArgs[j]; |
| 208 | + } |
| 209 | + } |
| 210 | + } else { |
| 211 | + newParentArgs[i] = parentTypeArgs[i]; |
| 212 | + } |
| 213 | + } |
| 214 | + return noChange ? parentType : new ParameterizedTypeImpl((Class<?>)parentType.getRawType(), null, newParentArgs); |
206 | 215 | }
|
207 | 216 |
|
208 | 217 | private TypeParameterResolver() {
|
|
0 commit comments