|
68 | 68 | import org.springframework.messaging.Message; |
69 | 69 | import org.springframework.util.Assert; |
70 | 70 | import org.springframework.util.CollectionUtils; |
| 71 | +import org.springframework.util.ObjectUtils; |
71 | 72 | import org.springframework.util.ReflectionUtils; |
72 | 73 | import org.springframework.util.StringUtils; |
73 | 74 |
|
@@ -166,10 +167,13 @@ public static Type getGenericType(Type type) { |
166 | 167 | * @return instance of {@link Class} as raw representation of the provided {@link Type} |
167 | 168 | */ |
168 | 169 | public static Class<?> getRawType(Type type) { |
169 | | -// ((WildcardType) type).getUpperBounds(); |
170 | | -// Class cazz = ResolvableType.forType(type).getRawClass(); |
171 | 170 | if (type instanceof WildcardType) { |
172 | | - return Object.class; |
| 171 | + Type[] upperbounds = ((WildcardType) type).getUpperBounds(); |
| 172 | + /* |
| 173 | + * Kotlin may have something like this <? extends Message> which is technically a whildcard yet it has upper/lower types. |
| 174 | + * See GH-1260 |
| 175 | + */ |
| 176 | + return ObjectUtils.isEmpty(upperbounds) ? Object.class : getRawType(upperbounds[0]); |
173 | 177 | } |
174 | 178 | return ResolvableType.forType(type).getRawClass(); |
175 | 179 | } |
@@ -392,7 +396,12 @@ public static Type getInputType(Type functionType) { |
392 | 396 | resolvableInputType = resolvableFunctionType.as(Function.class); |
393 | 397 | } |
394 | 398 | else { |
395 | | - resolvableInputType = resolvableFunctionType.as(Consumer.class); |
| 399 | + if (KotlinDetector.isKotlinPresent() && Function1.class.isAssignableFrom(getRawType(functionType))) { // Kotlin |
| 400 | + return ResolvableType.forType(getImmediateGenericType(functionType, 1)).getType(); |
| 401 | + } |
| 402 | + else { |
| 403 | + resolvableInputType = resolvableFunctionType.as(Consumer.class); |
| 404 | + } |
396 | 405 | } |
397 | 406 | if (resolvableInputType.getType() instanceof ParameterizedType) { |
398 | 407 | return resolvableInputType.getGeneric(0).getType(); |
@@ -477,7 +486,12 @@ public static Type getOutputType(Type functionType) { |
477 | 486 | resolvableOutputType = resolvableFunctionType.as(Function.class); |
478 | 487 | } |
479 | 488 | else { |
480 | | - resolvableOutputType = resolvableFunctionType.as(Supplier.class); |
| 489 | + if (KotlinDetector.isKotlinPresent() && Function1.class.isAssignableFrom(getRawType(functionType))) { // Kotlin |
| 490 | + return ResolvableType.forType(getImmediateGenericType(functionType, 1)).getType(); |
| 491 | + } |
| 492 | + else { |
| 493 | + resolvableOutputType = resolvableFunctionType.as(Supplier.class); |
| 494 | + } |
481 | 495 | } |
482 | 496 |
|
483 | 497 | Type outputType; |
@@ -629,6 +643,7 @@ private static void assertSupportedTypes(Type type) { |
629 | 643 | Class<?> candidateType = (Class<?>) type; |
630 | 644 |
|
631 | 645 | Assert.isTrue(Supplier.class.isAssignableFrom(candidateType) |
| 646 | + || (KotlinDetector.isKotlinPresent() && (Function0.class.isAssignableFrom(candidateType) || Function1.class.isAssignableFrom(candidateType))) |
632 | 647 | || Function.class.isAssignableFrom(candidateType) |
633 | 648 | || Consumer.class.isAssignableFrom(candidateType) |
634 | 649 | || FunctionRegistration.class.isAssignableFrom(candidateType) |
|
0 commit comments