Supported non-literal arguments for SAM adapters.
This commit is contained in:
@@ -1884,8 +1884,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
BindingContext.SAM_CONSTRUCTOR_TO_INTERFACE, ((SimpleFunctionDescriptor) funDescriptor).getOriginal());
|
BindingContext.SAM_CONSTRUCTOR_TO_INTERFACE, ((SimpleFunctionDescriptor) funDescriptor).getOriginal());
|
||||||
|
|
||||||
if (samInterface != null) {
|
if (samInterface != null) {
|
||||||
return invokeSamConstructor(expression, resolvedCall, (SimpleFunctionDescriptor) funDescriptor,
|
return invokeSamConstructor(expression, resolvedCall, (ClassDescriptorFromJvmBytecode) samInterface);
|
||||||
(ClassDescriptorFromJvmBytecode) samInterface);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1915,7 +1914,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
private StackValue invokeSamConstructor(
|
private StackValue invokeSamConstructor(
|
||||||
JetCallExpression expression,
|
JetCallExpression expression,
|
||||||
ResolvedCall<? extends CallableDescriptor> resolvedCall,
|
ResolvedCall<? extends CallableDescriptor> resolvedCall,
|
||||||
SimpleFunctionDescriptor funDescriptor,
|
|
||||||
ClassDescriptorFromJvmBytecode samInterface
|
ClassDescriptorFromJvmBytecode samInterface
|
||||||
) {
|
) {
|
||||||
ResolvedValueArgument argument = resolvedCall.getValueArgumentsByIndex().get(0);
|
ResolvedValueArgument argument = resolvedCall.getValueArgumentsByIndex().get(0);
|
||||||
@@ -1926,18 +1924,26 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
ValueArgument valueArgument = ((ExpressionValueArgument) argument).getValueArgument();
|
ValueArgument valueArgument = ((ExpressionValueArgument) argument).getValueArgument();
|
||||||
assert valueArgument != null : "getValueArgument() is null for " + expression.getText();
|
assert valueArgument != null : "getValueArgument() is null for " + expression.getText();
|
||||||
JetExpression argumentExpression = valueArgument.getArgumentExpression();
|
JetExpression argumentExpression = valueArgument.getArgumentExpression();
|
||||||
|
assert argumentExpression != null : "getArgumentExpression() is null for " + expression.getText();
|
||||||
|
|
||||||
|
return genSamInterfaceValue(argumentExpression, samInterface);
|
||||||
|
}
|
||||||
|
|
||||||
|
private StackValue genSamInterfaceValue(
|
||||||
|
@NotNull JetExpression argumentExpression,
|
||||||
|
@NotNull ClassDescriptorFromJvmBytecode samInterface
|
||||||
|
) {
|
||||||
if (argumentExpression instanceof JetFunctionLiteralExpression) {
|
if (argumentExpression instanceof JetFunctionLiteralExpression) {
|
||||||
return genClosure(((JetFunctionLiteralExpression) argumentExpression).getFunctionLiteral(), samInterface);
|
return genClosure(((JetFunctionLiteralExpression) argumentExpression).getFunctionLiteral(), samInterface);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
JvmClassName className =
|
JvmClassName className =
|
||||||
state.getSamWrapperClasses().getSamWrapperClass(samInterface, (JetFile) expression.getContainingFile());
|
state.getSamWrapperClasses().getSamWrapperClass(samInterface, (JetFile) argumentExpression.getContainingFile());
|
||||||
|
|
||||||
v.anew(className.getAsmType());
|
v.anew(className.getAsmType());
|
||||||
v.dup();
|
v.dup();
|
||||||
|
|
||||||
JetType functionType = funDescriptor.getValueParameters().get(0).getType();
|
JetType functionType = samInterface.getFunctionTypeForSamInterface();
|
||||||
gen(argumentExpression, typeMapper.mapType(functionType));
|
gen(argumentExpression, typeMapper.mapType(functionType));
|
||||||
|
|
||||||
v.invokespecial(className.getInternalName(), "<init>",
|
v.invokespecial(className.getInternalName(), "<init>",
|
||||||
@@ -2309,10 +2315,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
if (originalOfSamAdapter != null) {
|
if (originalOfSamAdapter != null) {
|
||||||
JetType samAdapterType = originalOfSamAdapter.getValueParameters().get(valueParameter.getIndex()).getType();
|
JetType samAdapterType = originalOfSamAdapter.getValueParameters().get(valueParameter.getIndex()).getType();
|
||||||
if (SingleAbstractMethodUtils.isSamType(samAdapterType)) {
|
if (SingleAbstractMethodUtils.isSamType(samAdapterType)) {
|
||||||
ClassDescriptor samInterface = (ClassDescriptor) samAdapterType.getConstructor().getDeclarationDescriptor();
|
ClassDescriptorFromJvmBytecode samInterface = (ClassDescriptorFromJvmBytecode) samAdapterType.getConstructor().getDeclarationDescriptor();
|
||||||
|
|
||||||
// TODO support not literals
|
genSamInterfaceValue(argumentExpression, samInterface);
|
||||||
genClosure(((JetFunctionLiteralExpression) argumentExpression).getFunctionLiteral(), samInterface);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
class JavaClass {
|
||||||
|
public static void run(Runnable r1, Runnable r2) {
|
||||||
|
r1.run();
|
||||||
|
r2.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
fun box(): String {
|
||||||
|
var v = "FAIL"
|
||||||
|
val f = { v = "O" }
|
||||||
|
JavaClass.run(f, { v += "K" })
|
||||||
|
return v
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
class JavaClass {
|
||||||
|
public static void sortIntList(List<Integer> list, Comparator<Integer> comparator) {
|
||||||
|
Collections.sort(list, comparator);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import java.util.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val list = ArrayList(Arrays.asList(3, 2, 4, 8, 1, 5))
|
||||||
|
val expected = ArrayList(Arrays.asList(8, 5, 4, 3, 2, 1))
|
||||||
|
|
||||||
|
val f = { (a: Int, b: Int) -> b - a }
|
||||||
|
JavaClass.sortIntList(list, f)
|
||||||
|
return if (list == expected) "OK" else list.toString()
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
class JavaClass {
|
||||||
|
private Runnable r;
|
||||||
|
|
||||||
|
public JavaClass(Runnable r) {
|
||||||
|
this.r = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
r.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
fun box(): String {
|
||||||
|
var v = "FAIL"
|
||||||
|
val f = { v = "OK" }
|
||||||
|
JavaClass(f).run()
|
||||||
|
return v
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
class JavaClass {
|
||||||
|
public static void run(Runnable r) {
|
||||||
|
r.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
fun box(): String {
|
||||||
|
var v = "FAIL"
|
||||||
|
val f = { v = "OK" }
|
||||||
|
JavaClass.run(f)
|
||||||
|
return v
|
||||||
|
}
|
||||||
+20
@@ -155,6 +155,26 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege
|
|||||||
doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/fileFilter.kt");
|
doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/fileFilter.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nonLiteralAndLiteralRunnable.kt")
|
||||||
|
public void testNonLiteralAndLiteralRunnable() throws Exception {
|
||||||
|
doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralAndLiteralRunnable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nonLiteralComparator.kt")
|
||||||
|
public void testNonLiteralComparator() throws Exception {
|
||||||
|
doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralComparator.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nonLiteralInConstructor.kt")
|
||||||
|
public void testNonLiteralInConstructor() throws Exception {
|
||||||
|
doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralInConstructor.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nonLiteralRunnable.kt")
|
||||||
|
public void testNonLiteralRunnable() throws Exception {
|
||||||
|
doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralRunnable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("severalSamParameters.kt")
|
@TestMetadata("severalSamParameters.kt")
|
||||||
public void testSeveralSamParameters() throws Exception {
|
public void testSeveralSamParameters() throws Exception {
|
||||||
doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/severalSamParameters.kt");
|
doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/severalSamParameters.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user