Supported simplest cases of SAM adapter in backend.
This commit is contained in:
@@ -56,6 +56,7 @@ import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants;
|
|||||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType;
|
import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.*;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.*;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
@@ -1790,6 +1791,15 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private SimpleFunctionDescriptor getOriginalIfSamAdapter(@NotNull CallableDescriptor fun) {
|
||||||
|
if (!(fun instanceof SimpleFunctionDescriptor)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
SimpleFunctionDescriptor original = ((SimpleFunctionDescriptor) fun).getOriginal();
|
||||||
|
return bindingContext.get(SAM_ADAPTER_FUNCTION_TO_ORIGINAL, original);
|
||||||
|
}
|
||||||
|
|
||||||
private StackValue invokeSamConstructor(
|
private StackValue invokeSamConstructor(
|
||||||
JetCallExpression expression,
|
JetCallExpression expression,
|
||||||
ResolvedCall<? extends CallableDescriptor> resolvedCall,
|
ResolvedCall<? extends CallableDescriptor> resolvedCall,
|
||||||
@@ -1967,7 +1977,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
callableMethod = typeMapper.asCallableMethod(invoke);
|
callableMethod = typeMapper.asCallableMethod(invoke);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
callableMethod = typeMapper.mapToCallableMethod(fd, superCall,
|
SimpleFunctionDescriptor originalOfSamAdapter = getOriginalIfSamAdapter(fd);
|
||||||
|
callableMethod = typeMapper.mapToCallableMethod(originalOfSamAdapter != null ? originalOfSamAdapter : fd, superCall,
|
||||||
isCallInsideSameClassAsDeclared(fd, context),
|
isCallInsideSameClassAsDeclared(fd, context),
|
||||||
isCallInsideSameModuleAsDeclared(fd, context),
|
isCallInsideSameModuleAsDeclared(fd, context),
|
||||||
OwnerKind.IMPLEMENTATION);
|
OwnerKind.IMPLEMENTATION);
|
||||||
@@ -2214,12 +2225,27 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
|
|
||||||
int mask = 0;
|
int mask = 0;
|
||||||
|
|
||||||
|
SimpleFunctionDescriptor originalOfSamAdapter = getOriginalIfSamAdapter(fd);
|
||||||
|
|
||||||
for (ValueParameterDescriptor valueParameter : fd.getValueParameters()) {
|
for (ValueParameterDescriptor valueParameter : fd.getValueParameters()) {
|
||||||
ResolvedValueArgument resolvedValueArgument = valueArguments.get(valueParameter.getIndex());
|
ResolvedValueArgument resolvedValueArgument = valueArguments.get(valueParameter.getIndex());
|
||||||
if (resolvedValueArgument instanceof ExpressionValueArgument) {
|
if (resolvedValueArgument instanceof ExpressionValueArgument) {
|
||||||
ExpressionValueArgument valueArgument = (ExpressionValueArgument) resolvedValueArgument;
|
ValueArgument valueArgument = ((ExpressionValueArgument) resolvedValueArgument).getValueArgument();
|
||||||
//noinspection ConstantConditions
|
assert valueArgument != null;
|
||||||
gen(valueArgument.getValueArgument().getArgumentExpression(), valueParameterTypes.get(valueParameter.getIndex()));
|
JetExpression argumentExpression = valueArgument.getArgumentExpression();
|
||||||
|
assert argumentExpression != null : valueArgument.asElement().getText();
|
||||||
|
|
||||||
|
if (originalOfSamAdapter != null) {
|
||||||
|
JetType samAdapterType = originalOfSamAdapter.getValueParameters().get(valueParameter.getIndex()).getType();
|
||||||
|
if (SingleAbstractMethodUtils.isSamType(samAdapterType)) {
|
||||||
|
ClassDescriptor samInterface = (ClassDescriptor) samAdapterType.getConstructor().getDeclarationDescriptor();
|
||||||
|
|
||||||
|
// TODO support not literals
|
||||||
|
genClosure(((JetFunctionLiteralExpression) argumentExpression).getFunctionLiteral(), samInterface);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gen(argumentExpression, valueParameterTypes.get(valueParameter.getIndex()));
|
||||||
}
|
}
|
||||||
else if (resolvedValueArgument instanceof DefaultValueArgument) {
|
else if (resolvedValueArgument instanceof DefaultValueArgument) {
|
||||||
Type type = valueParameterTypes.get(valueParameter.getIndex());
|
Type type = valueParameterTypes.get(valueParameter.getIndex());
|
||||||
|
|||||||
+1
-1
@@ -134,7 +134,7 @@ public class SingleAbstractMethodUtils {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isSamType(@NotNull JetType type) {
|
public static boolean isSamType(@NotNull JetType type) {
|
||||||
ClassifierDescriptor classifier = type.getConstructor().getDeclarationDescriptor();
|
ClassifierDescriptor classifier = type.getConstructor().getDeclarationDescriptor();
|
||||||
return classifier instanceof ClassDescriptorFromJvmBytecode &&
|
return classifier instanceof ClassDescriptorFromJvmBytecode &&
|
||||||
((ClassDescriptorFromJvmBytecode) classifier).isSamInterface() &&
|
((ClassDescriptorFromJvmBytecode) classifier).isSamInterface() &&
|
||||||
|
|||||||
@@ -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,8 @@
|
|||||||
|
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))
|
||||||
|
JavaClass.sortIntList(list, { a, b -> b - a })
|
||||||
|
return if (list == expected) "OK" else list.toString()
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
class JavaClass {
|
||||||
|
public static String invokeFilter(FileFilter f, File file1, File file2) {
|
||||||
|
return f.accept(file1) + " " + f.accept(file2);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import java.io.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val ACCEPT_NAME = "test"
|
||||||
|
val WRONG_NAME = "wrong"
|
||||||
|
|
||||||
|
val result = JavaClass.invokeFilter({ file -> ACCEPT_NAME == file?.getName() }, File(ACCEPT_NAME), File(WRONG_NAME))
|
||||||
|
|
||||||
|
if (result != "true false") return "Wrong result: $result"
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
class JavaClass {
|
||||||
|
public static void run(Runnable r) {
|
||||||
|
r.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
fun box(): String {
|
||||||
|
var v = "FAIL"
|
||||||
|
JavaClass.run { v = "OK" }
|
||||||
|
return v
|
||||||
|
}
|
||||||
+25
-1
@@ -31,7 +31,7 @@ import org.jetbrains.jet.codegen.generated.AbstractBlackBoxCodegenTest;
|
|||||||
/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */
|
/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
@TestMetadata("compiler/testData/codegen/boxWithJava")
|
@TestMetadata("compiler/testData/codegen/boxWithJava")
|
||||||
@InnerTestClasses({BlackBoxWithJavaCodegenTestGenerated.Enum.class, BlackBoxWithJavaCodegenTestGenerated.Functions.class, BlackBoxWithJavaCodegenTestGenerated.Property.class, BlackBoxWithJavaCodegenTestGenerated.StaticFun.class, BlackBoxWithJavaCodegenTestGenerated.Visibility.class})
|
@InnerTestClasses({BlackBoxWithJavaCodegenTestGenerated.Enum.class, BlackBoxWithJavaCodegenTestGenerated.Functions.class, BlackBoxWithJavaCodegenTestGenerated.Property.class, BlackBoxWithJavaCodegenTestGenerated.SamAdapters.class, BlackBoxWithJavaCodegenTestGenerated.StaticFun.class, BlackBoxWithJavaCodegenTestGenerated.Visibility.class})
|
||||||
public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||||
public void testAllFilesPresentInBoxWithJava() throws Exception {
|
public void testAllFilesPresentInBoxWithJava() throws Exception {
|
||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/boxWithJava"), Pattern.compile("^(.+)\\.kt$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/boxWithJava"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
@@ -111,6 +111,29 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/boxWithJava/samAdapters")
|
||||||
|
public static class SamAdapters extends AbstractBlackBoxCodegenTest {
|
||||||
|
public void testAllFilesPresentInSamAdapters() throws Exception {
|
||||||
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/boxWithJava/samAdapters"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("comparator.kt")
|
||||||
|
public void testComparator() throws Exception {
|
||||||
|
doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/comparator.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("fileFilter.kt")
|
||||||
|
public void testFileFilter() throws Exception {
|
||||||
|
doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/fileFilter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simplest.kt")
|
||||||
|
public void testSimplest() throws Exception {
|
||||||
|
doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/simplest.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/boxWithJava/staticFun")
|
@TestMetadata("compiler/testData/codegen/boxWithJava/staticFun")
|
||||||
public static class StaticFun extends AbstractBlackBoxCodegenTest {
|
public static class StaticFun extends AbstractBlackBoxCodegenTest {
|
||||||
public void testAllFilesPresentInStaticFun() throws Exception {
|
public void testAllFilesPresentInStaticFun() throws Exception {
|
||||||
@@ -271,6 +294,7 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege
|
|||||||
suite.addTestSuite(Enum.class);
|
suite.addTestSuite(Enum.class);
|
||||||
suite.addTestSuite(Functions.class);
|
suite.addTestSuite(Functions.class);
|
||||||
suite.addTestSuite(Property.class);
|
suite.addTestSuite(Property.class);
|
||||||
|
suite.addTestSuite(SamAdapters.class);
|
||||||
suite.addTestSuite(StaticFun.class);
|
suite.addTestSuite(StaticFun.class);
|
||||||
suite.addTest(Visibility.innerSuite());
|
suite.addTest(Visibility.innerSuite());
|
||||||
return suite;
|
return suite;
|
||||||
|
|||||||
Reference in New Issue
Block a user