Fix wildcards for invariant arguments

See test with Java, we want preserve the invariant that if return type and
value parameter types are same in Kotlin, than we can use such return-value
as argument for that parameter
This commit is contained in:
Denis Zharkov
2015-12-14 16:49:53 +03:00
parent 5df2a58003
commit 154657a374
7 changed files with 48 additions and 4 deletions
@@ -26,7 +26,8 @@ internal class TypeMappingMode private constructor(
val skipDeclarationSiteWildcards: Boolean = false,
val skipDeclarationSiteWildcardsIfPossible: Boolean = false,
private val genericArgumentMode: TypeMappingMode? = null,
private val genericContravariantArgumentMode: TypeMappingMode? = genericArgumentMode
private val genericContravariantArgumentMode: TypeMappingMode? = genericArgumentMode,
private val genericInvariantArgumentMode: TypeMappingMode? = genericArgumentMode
) {
companion object {
/**
@@ -86,11 +87,18 @@ internal class TypeMappingMode private constructor(
else
null
val invariantArgumentMode =
if (canBeUsedInSupertypePosition)
getOptimalModeForSignaturePart(type, isForAnnotationParameter, canBeUsedInSupertypePosition = false)
else
null
return TypeMappingMode(
isForAnnotationParameter = isForAnnotationParameter,
skipDeclarationSiteWildcards = !canBeUsedInSupertypePosition,
skipDeclarationSiteWildcardsIfPossible = true,
genericContravariantArgumentMode = contravariantArgumentMode)
genericContravariantArgumentMode = contravariantArgumentMode,
genericInvariantArgumentMode = invariantArgumentMode)
}
@JvmStatic
@@ -107,6 +115,7 @@ internal class TypeMappingMode private constructor(
fun toGenericArgumentMode(effectiveVariance: Variance): TypeMappingMode =
when (effectiveVariance) {
Variance.IN_VARIANCE -> genericContravariantArgumentMode ?: this
Variance.INVARIANT -> genericInvariantArgumentMode ?: this
else -> genericArgumentMode ?: this
}
}
@@ -0,0 +1,5 @@
public class JavaClass {
public static String test() {
return MainKt.bar(MainKt.foo());
}
}
@@ -0,0 +1,11 @@
class Pair<out X, out Y>(val x: X, val y: Y)
class Inv<T>(val x: T)
fun foo(): Inv<Pair<CharSequence, CharSequence>> = Inv(Pair("O", "K"))
fun bar(inv: Inv<Pair<CharSequence, CharSequence>>) = inv.x.x.toString() + inv.x.y
fun box(): String {
return JavaClass.test();
}
@@ -8,7 +8,7 @@ open class Open
fun arrayOfOutOpen(x: Array<Out<Open>>) {}
// method: ArraysKt::arrayOfOutOpen
// generic signature: ([LOut<+LOpen;>;)V
// generic signature: ([LOut<LOpen;>;)V
fun arrayOfOutFinal(x: Array<Out<Final>>) {}
// method: ArraysKt::arrayOfOutFinal
@@ -10,6 +10,10 @@ fun skipAllOutInvWildcards(): Inv<OutPair<Open, Out<Out<Open>>>> = null!!
// method: FinalReturnTypeKt::skipAllOutInvWildcards
// generic signature: ()LInv<LOutPair<LOpen;LOut<LOut<LOpen;>;>;>;>;
fun skipAllInvWildcards(): Inv<In<Out<Open>>> = null!!
// method: FinalReturnTypeKt::skipAllInvWildcards
// generic signature: ()LInv<LIn<LOut<+LOpen;>;>;>;
fun notDeepIn(): In<Final> = null!!
// method: FinalReturnTypeKt::notDeepIn
// generic signature: ()LIn<LFinal;>;
@@ -1,4 +1,5 @@
class Inv<X>
class In<in E>
class Out<out T>
class Final
open class Open
@@ -13,12 +14,20 @@ fun invFinal(x: Inv<Final>) {}
fun invOutOpen(x: Inv<Out<Open>>) {}
// method: TopLevelInvKt::invOutOpen
// generic signature: (LInv<LOut<+LOpen;>;>;)V
// generic signature: (LInv<LOut<LOpen;>;>;)V
fun invOutFinal(x: Inv<Out<Final>>) {}
// method: TopLevelInvKt::invOutFinal
// generic signature: (LInv<LOut<LFinal;>;>;)V
fun invInOutOpen(x: Inv<In<Out<Open>>>) {}
// method: TopLevelInvKt::invInOutOpen
// generic signature: (LInv<LIn<LOut<+LOpen;>;>;>;)V
fun invInOutFinal(x: Inv<In<Out<Final>>>) {}
// method: TopLevelInvKt::invInOutFinal
// generic signature: (LInv<LIn<LOut<LFinal;>;>;>;)V
fun invOutProjectedOutFinal(x: Inv<out Out<Final>>) {}
// method: TopLevelInvKt::invOutProjectedOutFinal
// generic signature: (LInv<+LOut<LFinal;>;>;)V
@@ -107,6 +107,12 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege
doTestWithJava(fileName);
}
@TestMetadata("invariantArgumentsNoWildcard")
public void testInvariantArgumentsNoWildcard() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/invariantArgumentsNoWildcard/");
doTestWithJava(fileName);
}
@TestMetadata("jvmName")
public void testJvmName() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/jvmName/");