From 67336653e0d78728f8daf07cc2d0fd4f35f87794 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Thu, 27 Jul 2017 16:40:22 +0300 Subject: [PATCH] Generate SAM wrappers only if they are required for a given argument SAM interface wrapper for an argument is required, if in the function descriptor for SAM adapter type for the corresponding value parameter doesn't match type of the corresponding value parameter in the original (Java) descriptor. #KT-19251 Fixed Target versions 1.1.5 --- .../binding/CodegenAnnotatingVisitor.java | 4 ++++ .../codegen/box/sam/constructors/kt19251.kt | 14 ++++++++++++++ .../box/sam/constructors/kt19251_child.kt | 17 +++++++++++++++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 12 ++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 12 ++++++++++++ .../codegen/LightAnalysisModeTestGenerated.java | 12 ++++++++++++ 6 files changed, 71 insertions(+) create mode 100644 compiler/testData/codegen/box/sam/constructors/kt19251.kt create mode 100644 compiler/testData/codegen/box/sam/constructors/kt19251_child.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java index 71a5d283ef1..f8ece668c2a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java @@ -56,6 +56,7 @@ import org.jetbrains.kotlin.resolve.constants.EnumValue; import org.jetbrains.kotlin.resolve.constants.NullValue; import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt; import org.jetbrains.kotlin.types.KotlinType; +import org.jetbrains.kotlin.types.checker.KotlinTypeChecker; import org.jetbrains.org.objectweb.asm.Type; import java.util.*; @@ -559,6 +560,9 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid { if (valueArguments == null) return; for (ValueParameterDescriptor valueParameter : original.getValueParameters()) { + ValueParameterDescriptor adaptedParameter = descriptor.getValueParameters().get(valueParameter.getIndex()); + if (KotlinTypeChecker.DEFAULT.equalTypes(adaptedParameter.getType(), valueParameter.getType())) continue; + SamType samType = SamType.create(TypeMapperUtilsKt.removeExternalProjections(valueParameter.getType())); if (samType == null) continue; diff --git a/compiler/testData/codegen/box/sam/constructors/kt19251.kt b/compiler/testData/codegen/box/sam/constructors/kt19251.kt new file mode 100644 index 00000000000..0b23924234f --- /dev/null +++ b/compiler/testData/codegen/box/sam/constructors/kt19251.kt @@ -0,0 +1,14 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME +// FULL_JDK +// FILE: test.kt +fun box(): String { + val map = mutableMapOf() + val fn = Fun { TODO() } + return map.computeIfAbsent(fn, { "OK" }) +} + +// FILE: Fun.java +public interface Fun { + String invoke(String string); +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/sam/constructors/kt19251_child.kt b/compiler/testData/codegen/box/sam/constructors/kt19251_child.kt new file mode 100644 index 00000000000..68dcd40f89a --- /dev/null +++ b/compiler/testData/codegen/box/sam/constructors/kt19251_child.kt @@ -0,0 +1,17 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME +// FULL_JDK +// FILE: test.kt +fun box(): String { + val map = mutableMapOf() + val fn = DerivedFun { TODO() } + return map.computeIfAbsent(fn, { "OK" }) +} + +// FILE: Fun.java +public interface Fun { + String invoke(String string); +} + +// FILE: DerivedFun.java +public interface DerivedFun extends Fun {} \ No newline at end of file diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 19e28ca14eb..681d109c453 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -17266,6 +17266,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("kt19251.kt") + public void testKt19251() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/sam/constructors/kt19251.kt"); + doTest(fileName); + } + + @TestMetadata("kt19251_child.kt") + public void testKt19251_child() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/sam/constructors/kt19251_child.kt"); + doTest(fileName); + } + @TestMetadata("nonLiteralComparator.kt") public void testNonLiteralComparator() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/sam/constructors/nonLiteralComparator.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 34a6fa678df..a0d93710791 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -17266,6 +17266,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("kt19251.kt") + public void testKt19251() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/sam/constructors/kt19251.kt"); + doTest(fileName); + } + + @TestMetadata("kt19251_child.kt") + public void testKt19251_child() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/sam/constructors/kt19251_child.kt"); + doTest(fileName); + } + @TestMetadata("nonLiteralComparator.kt") public void testNonLiteralComparator() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/sam/constructors/nonLiteralComparator.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index d91f412f796..6463b3b9ab6 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -17266,6 +17266,18 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes doTest(fileName); } + @TestMetadata("kt19251.kt") + public void testKt19251() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/sam/constructors/kt19251.kt"); + doTest(fileName); + } + + @TestMetadata("kt19251_child.kt") + public void testKt19251_child() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/sam/constructors/kt19251_child.kt"); + doTest(fileName); + } + @TestMetadata("nonLiteralComparator.kt") public void testNonLiteralComparator() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/sam/constructors/nonLiteralComparator.kt");