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.JvmClassName;
|
||||
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.scopes.receivers.*;
|
||||
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(
|
||||
JetCallExpression expression,
|
||||
ResolvedCall<? extends CallableDescriptor> resolvedCall,
|
||||
@@ -1967,7 +1977,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
callableMethod = typeMapper.asCallableMethod(invoke);
|
||||
}
|
||||
else {
|
||||
callableMethod = typeMapper.mapToCallableMethod(fd, superCall,
|
||||
SimpleFunctionDescriptor originalOfSamAdapter = getOriginalIfSamAdapter(fd);
|
||||
callableMethod = typeMapper.mapToCallableMethod(originalOfSamAdapter != null ? originalOfSamAdapter : fd, superCall,
|
||||
isCallInsideSameClassAsDeclared(fd, context),
|
||||
isCallInsideSameModuleAsDeclared(fd, context),
|
||||
OwnerKind.IMPLEMENTATION);
|
||||
@@ -2214,12 +2225,27 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
|
||||
int mask = 0;
|
||||
|
||||
SimpleFunctionDescriptor originalOfSamAdapter = getOriginalIfSamAdapter(fd);
|
||||
|
||||
for (ValueParameterDescriptor valueParameter : fd.getValueParameters()) {
|
||||
ResolvedValueArgument resolvedValueArgument = valueArguments.get(valueParameter.getIndex());
|
||||
if (resolvedValueArgument instanceof ExpressionValueArgument) {
|
||||
ExpressionValueArgument valueArgument = (ExpressionValueArgument) resolvedValueArgument;
|
||||
//noinspection ConstantConditions
|
||||
gen(valueArgument.getValueArgument().getArgumentExpression(), valueParameterTypes.get(valueParameter.getIndex()));
|
||||
ValueArgument valueArgument = ((ExpressionValueArgument) resolvedValueArgument).getValueArgument();
|
||||
assert valueArgument != null;
|
||||
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) {
|
||||
Type type = valueParameterTypes.get(valueParameter.getIndex());
|
||||
|
||||
+1
-1
@@ -134,7 +134,7 @@ public class SingleAbstractMethodUtils {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean isSamType(@NotNull JetType type) {
|
||||
public static boolean isSamType(@NotNull JetType type) {
|
||||
ClassifierDescriptor classifier = type.getConstructor().getDeclarationDescriptor();
|
||||
return classifier instanceof ClassDescriptorFromJvmBytecode &&
|
||||
((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 */
|
||||
@SuppressWarnings("all")
|
||||
@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 void testAllFilesPresentInBoxWithJava() throws Exception {
|
||||
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")
|
||||
public static class StaticFun extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInStaticFun() throws Exception {
|
||||
@@ -271,6 +294,7 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege
|
||||
suite.addTestSuite(Enum.class);
|
||||
suite.addTestSuite(Functions.class);
|
||||
suite.addTestSuite(Property.class);
|
||||
suite.addTestSuite(SamAdapters.class);
|
||||
suite.addTestSuite(StaticFun.class);
|
||||
suite.addTest(Visibility.innerSuite());
|
||||
return suite;
|
||||
|
||||
Reference in New Issue
Block a user