Use representative upper bound in JetTypeMapper instead of just the first

This commit is contained in:
Alexander Udalov
2015-10-22 21:00:05 +03:00
parent 3918005364
commit 996c14d071
4 changed files with 50 additions and 3 deletions
@@ -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<KotlinType> 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();
@@ -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 <T> c1(t: T) where T : C, T : I1, T : I2
fun <T> c2(t: T) where T : I1, T : C, T : I2
fun <T> c3(t: T) where T : I2, T : C, T : I1
fun <T> c4(t: T) where T : I2, T : I1, T : C
fun <T> i1(t: T) where T : I1, T : I2
fun <T> 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"
}
@@ -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")
@@ -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;