diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index b7cc9516fc1..32a661118b1 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1884,8 +1884,7 @@ public class ExpressionCodegen extends JetVisitor implem BindingContext.SAM_CONSTRUCTOR_TO_INTERFACE, ((SimpleFunctionDescriptor) funDescriptor).getOriginal()); if (samInterface != null) { - return invokeSamConstructor(expression, resolvedCall, (SimpleFunctionDescriptor) funDescriptor, - (ClassDescriptorFromJvmBytecode) samInterface); + return invokeSamConstructor(expression, resolvedCall, (ClassDescriptorFromJvmBytecode) samInterface); } } @@ -1915,7 +1914,6 @@ public class ExpressionCodegen extends JetVisitor implem private StackValue invokeSamConstructor( JetCallExpression expression, ResolvedCall resolvedCall, - SimpleFunctionDescriptor funDescriptor, ClassDescriptorFromJvmBytecode samInterface ) { ResolvedValueArgument argument = resolvedCall.getValueArgumentsByIndex().get(0); @@ -1926,18 +1924,26 @@ public class ExpressionCodegen extends JetVisitor implem ValueArgument valueArgument = ((ExpressionValueArgument) argument).getValueArgument(); assert valueArgument != null : "getValueArgument() is null for " + expression.getText(); 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) { return genClosure(((JetFunctionLiteralExpression) argumentExpression).getFunctionLiteral(), samInterface); } else { JvmClassName className = - state.getSamWrapperClasses().getSamWrapperClass(samInterface, (JetFile) expression.getContainingFile()); + state.getSamWrapperClasses().getSamWrapperClass(samInterface, (JetFile) argumentExpression.getContainingFile()); v.anew(className.getAsmType()); v.dup(); - JetType functionType = funDescriptor.getValueParameters().get(0).getType(); + JetType functionType = samInterface.getFunctionTypeForSamInterface(); gen(argumentExpression, typeMapper.mapType(functionType)); v.invokespecial(className.getInternalName(), "", @@ -2309,10 +2315,9 @@ public class ExpressionCodegen extends JetVisitor implem if (originalOfSamAdapter != null) { JetType samAdapterType = originalOfSamAdapter.getValueParameters().get(valueParameter.getIndex()).getType(); if (SingleAbstractMethodUtils.isSamType(samAdapterType)) { - ClassDescriptor samInterface = (ClassDescriptor) samAdapterType.getConstructor().getDeclarationDescriptor(); + ClassDescriptorFromJvmBytecode samInterface = (ClassDescriptorFromJvmBytecode) samAdapterType.getConstructor().getDeclarationDescriptor(); - // TODO support not literals - genClosure(((JetFunctionLiteralExpression) argumentExpression).getFunctionLiteral(), samInterface); + genSamInterfaceValue(argumentExpression, samInterface); continue; } } diff --git a/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralAndLiteralRunnable.java b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralAndLiteralRunnable.java new file mode 100644 index 00000000000..b740457a32c --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralAndLiteralRunnable.java @@ -0,0 +1,6 @@ +class JavaClass { + public static void run(Runnable r1, Runnable r2) { + r1.run(); + r2.run(); + } +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralAndLiteralRunnable.kt b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralAndLiteralRunnable.kt new file mode 100644 index 00000000000..433f6d04e4b --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralAndLiteralRunnable.kt @@ -0,0 +1,6 @@ +fun box(): String { + var v = "FAIL" + val f = { v = "O" } + JavaClass.run(f, { v += "K" }) + return v +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralComparator.java b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralComparator.java new file mode 100644 index 00000000000..1d6843c1a82 --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralComparator.java @@ -0,0 +1,7 @@ +import java.util.*; + +class JavaClass { + public static void sortIntList(List list, Comparator comparator) { + Collections.sort(list, comparator); + } +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralComparator.kt b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralComparator.kt new file mode 100644 index 00000000000..084a31ab8f4 --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralComparator.kt @@ -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() +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralInConstructor.java b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralInConstructor.java new file mode 100644 index 00000000000..c47e8ab052e --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralInConstructor.java @@ -0,0 +1,11 @@ +class JavaClass { + private Runnable r; + + public JavaClass(Runnable r) { + this.r = r; + } + + public void run() { + r.run(); + } +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralInConstructor.kt b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralInConstructor.kt new file mode 100644 index 00000000000..9d2e9a4f8b7 --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralInConstructor.kt @@ -0,0 +1,6 @@ +fun box(): String { + var v = "FAIL" + val f = { v = "OK" } + JavaClass(f).run() + return v +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralRunnable.java b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralRunnable.java new file mode 100644 index 00000000000..3860797a795 --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralRunnable.java @@ -0,0 +1,5 @@ +class JavaClass { + public static void run(Runnable r) { + r.run(); + } +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralRunnable.kt b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralRunnable.kt new file mode 100644 index 00000000000..093a7879ce5 --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralRunnable.kt @@ -0,0 +1,6 @@ +fun box(): String { + var v = "FAIL" + val f = { v = "OK" } + JavaClass.run(f) + return v +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java index ad0e4845f5a..7459f66bff5 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java @@ -155,6 +155,26 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege 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") public void testSeveralSamParameters() throws Exception { doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/severalSamParameters.kt");