GH-699 Fixed a bug where Kotlin Lambda was incorrectly converted to a consumer function
Fixed consumer type Fixed tests Added javadoc @author tag Resolves #699 Resolves #700
This commit is contained in:
committed by
Oleg Zhurakousky
parent
238ac301df
commit
0db0a2f555
@@ -22,6 +22,7 @@ import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function0;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import kotlin.jvm.functions.Function2;
|
||||
@@ -57,6 +58,7 @@ import org.springframework.util.ObjectUtils;
|
||||
*
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Adrien Poupard
|
||||
* @author Dmitriy Tsypov
|
||||
* @since 2.0
|
||||
*/
|
||||
@Configuration
|
||||
@@ -102,7 +104,7 @@ public class KotlinLambdaToFunctionAutoConfiguration {
|
||||
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public static final class KotlinFunctionWrapper implements Function<Object, Object>, Supplier<Object>, Consumer<Object[]>,
|
||||
public static final class KotlinFunctionWrapper implements Function<Object, Object>, Supplier<Object>, Consumer<Object>,
|
||||
Function0<Object>, Function1<Object, Object>, Function2<Object, Object, Object>,
|
||||
Function3<Object, Object, Object, Object>, Function4<Object, Object, Object, Object, Object>,
|
||||
FactoryBean<FunctionRegistration>,
|
||||
@@ -164,7 +166,7 @@ public class KotlinLambdaToFunctionAutoConfiguration {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(Object[] input) {
|
||||
public void accept(Object input) {
|
||||
this.apply(input);
|
||||
}
|
||||
|
||||
@@ -182,10 +184,13 @@ public class KotlinLambdaToFunctionAutoConfiguration {
|
||||
FunctionRegistration<?> registration = new FunctionRegistration<>(this, name);
|
||||
Type[] types = ((ParameterizedType) functionType).getActualTypeArguments();
|
||||
|
||||
if (functionType.getTypeName().contains("Function0")) {
|
||||
if (isValidKotlinSupplier(functionType)) {
|
||||
functionType = ResolvableType.forClassWithGenerics(Supplier.class, ResolvableType.forType(types[0]))
|
||||
.getType();
|
||||
|
||||
}
|
||||
else if (isValidKotlinConsumer(functionType, types)) {
|
||||
functionType = ResolvableType.forClassWithGenerics(Consumer.class, ResolvableType.forType(types[0]))
|
||||
.getType();
|
||||
}
|
||||
else if (isValidKotlinFunction(functionType, types)) {
|
||||
functionType = ResolvableType.forClassWithGenerics(Function.class, ResolvableType.forType(types[0]),
|
||||
@@ -221,20 +226,45 @@ public class KotlinLambdaToFunctionAutoConfiguration {
|
||||
return registration;
|
||||
}
|
||||
|
||||
private boolean isValidKotlinSupplier(Type functionType) {
|
||||
return isTypeRepresentedByClass(functionType, Function0.class);
|
||||
}
|
||||
|
||||
private boolean isValidKotlinConsumer(Type functionType, Type[] type) {
|
||||
return isTypeRepresentedByClass(functionType, Function1.class) &&
|
||||
type.length == 2 &&
|
||||
!CoroutinesUtils.isContinuationType(type[0]) &&
|
||||
isTypeRepresentedByClass(type[1], Unit.class);
|
||||
}
|
||||
|
||||
private boolean isValidKotlinFunction(Type functionType, Type[] type) {
|
||||
return functionType.getTypeName().contains(Function1.class.getName()) && type.length == 2 && !CoroutinesUtils.isContinuationType(type[0]);
|
||||
return isTypeRepresentedByClass(functionType, Function1.class) &&
|
||||
type.length == 2 &&
|
||||
!CoroutinesUtils.isContinuationType(type[0]) &&
|
||||
!isTypeRepresentedByClass(type[1], Unit.class);
|
||||
}
|
||||
|
||||
private boolean isValidKotlinSuspendSupplier(Type functionType, Type[] type) {
|
||||
return functionType.getTypeName().contains(Function1.class.getName()) && type.length == 2 && CoroutinesUtils.isContinuationFlowType(type[0]);
|
||||
return isTypeRepresentedByClass(functionType, Function1.class) &&
|
||||
type.length == 2 &&
|
||||
CoroutinesUtils.isContinuationFlowType(type[0]);
|
||||
}
|
||||
|
||||
private boolean isValidKotlinSuspendConsumer(Type functionType, Type[] type) {
|
||||
return functionType.getTypeName().contains(Function2.class.getName()) && type.length == 3 && CoroutinesUtils.isFlowType(type[0]) && CoroutinesUtils.isContinuationUnitType(type[1]);
|
||||
return isTypeRepresentedByClass(functionType, Function2.class) &&
|
||||
type.length == 3 &&
|
||||
CoroutinesUtils.isFlowType(type[0]) &&
|
||||
CoroutinesUtils.isContinuationUnitType(type[1]);
|
||||
}
|
||||
|
||||
private boolean isValidKotlinSuspendFunction(Type functionType, Type[] type) {
|
||||
return functionType.getTypeName().contains(Function2.class.getName()) && type.length == 3 && CoroutinesUtils.isContinuationFlowType(type[1]);
|
||||
return isTypeRepresentedByClass(functionType, Function2.class) &&
|
||||
type.length == 3 &&
|
||||
CoroutinesUtils.isContinuationFlowType(type[1]);
|
||||
}
|
||||
|
||||
private boolean isTypeRepresentedByClass(Type type, Class<?> clazz) {
|
||||
return type.getTypeName().contains(clazz.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.cloud.function.kotlin;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@@ -67,10 +68,9 @@ public class ContextFunctionCatalogAutoConfigurationKotlinTests {
|
||||
|
||||
function = this.context.getBean("kotlinConsumer");
|
||||
functionType = (ParameterizedType) FunctionTypeUtils.discoverFunctionType(function, "kotlinConsumer", this.context);
|
||||
assertThat(functionType.getRawType().getTypeName()).isEqualTo(Function.class.getName());
|
||||
assertThat(functionType.getActualTypeArguments().length).isEqualTo(2);
|
||||
assertThat(functionType.getRawType().getTypeName()).isEqualTo(Consumer.class.getName());
|
||||
assertThat(functionType.getActualTypeArguments().length).isEqualTo(1);
|
||||
assertThat(functionType.getActualTypeArguments()[0].getTypeName()).isEqualTo(String.class.getName());
|
||||
assertThat(functionType.getActualTypeArguments()[1].getTypeName()).isEqualTo("kotlin.Unit");
|
||||
|
||||
function = this.context.getBean("kotlinSupplier");
|
||||
functionType = (ParameterizedType) FunctionTypeUtils.discoverFunctionType(function, "kotlinSupplier", this.context);
|
||||
|
||||
Reference in New Issue
Block a user