From 996c14d071cabe84f71e7e02b42d90e14f25cee1 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 22 Oct 2015 21:00:05 +0300 Subject: [PATCH] Use representative upper bound in JetTypeMapper instead of just the first --- .../kotlin/codegen/state/JetTypeMapper.java | 17 +++++++++-- .../typeParameterMultipleBounds.kt | 29 +++++++++++++++++++ ...lackBoxWithStdlibCodegenTestGenerated.java | 6 ++++ .../kotlin/resolve/DescriptorUtils.java | 1 + 4 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/codegen/boxWithStdlib/typeMapping/typeParameterMultipleBounds.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java index 26b165cbd94..8e81c1c1e5d 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java @@ -509,10 +509,9 @@ public class JetTypeMapper { } if (descriptor instanceof TypeParameterDescriptor) { - TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) descriptor; - Type type = mapType(typeParameterDescriptor.getUpperBounds().iterator().next(), kind); + Type type = mapType(getRepresentativeUpperBound((TypeParameterDescriptor) descriptor), kind); if (signatureVisitor != null) { - signatureVisitor.writeTypeVariable(typeParameterDescriptor.getName(), type); + signatureVisitor.writeTypeVariable(descriptor.getName(), type); } return type; } @@ -520,6 +519,18 @@ public class JetTypeMapper { throw new UnsupportedOperationException("Unknown type " + jetType); } + @NotNull + private static KotlinType getRepresentativeUpperBound(@NotNull TypeParameterDescriptor descriptor) { + List upperBounds = descriptor.getUpperBounds(); + assert !upperBounds.isEmpty() : "Upper bounds should not be empty: " + descriptor; + for (KotlinType upperBound : upperBounds) { + if (!isJvmInterface(upperBound)) { + return upperBound; + } + } + return CollectionsKt.first(upperBounds); + } + @Nullable private static Type mapBuiltinType(@NotNull KotlinType type) { DeclarationDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); diff --git a/compiler/testData/codegen/boxWithStdlib/typeMapping/typeParameterMultipleBounds.kt b/compiler/testData/codegen/boxWithStdlib/typeMapping/typeParameterMultipleBounds.kt new file mode 100644 index 00000000000..25034a7014f --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/typeMapping/typeParameterMultipleBounds.kt @@ -0,0 +1,29 @@ +interface I1 +interface I2 +open class C + +interface K { + // Erasure of a type parameter with multiple bounds should be the class bound, or the first bound if there's no class bound + + fun c1(t: T) where T : C, T : I1, T : I2 + fun c2(t: T) where T : I1, T : C, T : I2 + fun c3(t: T) where T : I2, T : C, T : I1 + fun c4(t: T) where T : I2, T : I1, T : C + + fun i1(t: T) where T : I1, T : I2 + fun i2(t: T) where T : I2, T : I1 +} + +fun box(): String { + val k = K::class.java + + k.getDeclaredMethod("c1", C::class.java) + k.getDeclaredMethod("c2", C::class.java) + k.getDeclaredMethod("c3", C::class.java) + k.getDeclaredMethod("c4", C::class.java) + + k.getDeclaredMethod("i1", I1::class.java) + k.getDeclaredMethod("i2", I2::class.java) + + return "OK" +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index 575d452ac22..867468e39c9 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -4740,6 +4740,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/typeMapping/genericTypeWithNothing.kt"); doTestWithStdlib(fileName); } + + @TestMetadata("typeParameterMultipleBounds.kt") + public void testTypeParameterMultipleBounds() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/typeMapping/typeParameterMultipleBounds.kt"); + doTestWithStdlib(fileName); + } } @TestMetadata("compiler/testData/codegen/boxWithStdlib/vararg") diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java index f12823affc6..d31ab0f5064 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.resolve; +import kotlin.CollectionsKt; import kotlin.jvm.functions.Function1; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable;