From c3e44ec1994e7a8fd351241cf2e1f797c7991417 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Fri, 18 Mar 2016 14:53:25 +0300 Subject: [PATCH] Fix loading Java type arguments Type arguments with use variance in java contradicting to Kotlin declaration-site variance should be loaded as star-projections #KT-11492 Fixed --- .../tests/j+k/wrongVarianceInJava.kt | 23 ++++++++++++++ .../tests/j+k/wrongVarianceInJava.txt | 30 +++++++++++++++++++ .../checkers/DiagnosticsTestGenerated.java | 6 ++++ .../java/lazy/types/LazyJavaTypeResolver.kt | 10 +++++-- 4 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/j+k/wrongVarianceInJava.kt create mode 100644 compiler/testData/diagnostics/tests/j+k/wrongVarianceInJava.txt diff --git a/compiler/testData/diagnostics/tests/j+k/wrongVarianceInJava.kt b/compiler/testData/diagnostics/tests/j+k/wrongVarianceInJava.kt new file mode 100644 index 00000000000..bd1c004e9a9 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/wrongVarianceInJava.kt @@ -0,0 +1,23 @@ +// !CHECK_TYPE +// !DIAGNOSTICS: -UNUSED_PARAMETER +// FILE: A.java + +public class A { + public static Out foo() { return null; } + public static In bar() { return null; } +} + +// FILE: main.kt + +class Out { + fun x(): E = null!! +} + +class In { + fun y(f: F) {} +} + +fun test() { + A.foo().x() checkType { _() } + A.bar().y(null) +} diff --git a/compiler/testData/diagnostics/tests/j+k/wrongVarianceInJava.txt b/compiler/testData/diagnostics/tests/j+k/wrongVarianceInJava.txt new file mode 100644 index 00000000000..3680462e699 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/wrongVarianceInJava.txt @@ -0,0 +1,30 @@ +package + +public fun test(): kotlin.Unit + +public open class A { + public constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public open fun bar(): In<*>! + public open fun foo(): Out<*>! +} + +public final class In { + public constructor In() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + public final fun y(/*0*/ f: F): kotlin.Unit +} + +public final class Out { + public constructor Out() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + public final fun x(): E +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index a72407035a0..5255320d8cd 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -10323,6 +10323,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("wrongVarianceInJava.kt") + public void testWrongVarianceInJava() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/wrongVarianceInJava.kt"); + doTest(fileName); + } + @TestMetadata("compiler/testData/diagnostics/tests/j+k/brokenCode") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt index 8839ec9b55e..b602ba37137 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt @@ -224,12 +224,13 @@ class LazyJavaTypeResolver( return when (javaType) { is JavaWildcardType -> { val bound = javaType.bound - if (bound == null) + val projectionKind = if (javaType.isExtends) OUT_VARIANCE else IN_VARIANCE + if (bound == null || projectionKind.isConflictingArgumentFor(typeParameter)) makeStarProjection(typeParameter, attr) else { createProjection( type = transformJavaType(bound, UPPER_BOUND.toAttributes()), - projectionKind = if (javaType.isExtends) OUT_VARIANCE else IN_VARIANCE, + projectionKind = projectionKind, typeParameterDescriptor = typeParameter ) } @@ -238,6 +239,11 @@ class LazyJavaTypeResolver( } } + private fun Variance.isConflictingArgumentFor(typeParameter: TypeParameterDescriptor): Boolean { + if (typeParameter.variance == INVARIANT) return false + return this != typeParameter.variance + } + override fun getCapabilities(): TypeCapabilities = if (isRaw()) RawTypeCapabilities else TypeCapabilities.NONE private val nullable = c.storageManager.createLazyValue l@ {