diff --git a/compiler/testData/diagnostics/tests/j+k/overrideRawType.kt b/compiler/testData/diagnostics/tests/j+k/overrideRawType.kt new file mode 100644 index 00000000000..b2b58c6cf3d --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/overrideRawType.kt @@ -0,0 +1,15 @@ +//FILE: Foo.java +public class Foo { +} + +//FILE: Bar.java +public interface Bar { + void f(Foo f); +} + +//FILE: a.kt +class BarImpl: Bar { + override fun f(f: Foo?) { + throw UnsupportedOperationException() + } +} diff --git a/compiler/testData/loadJava/compiledJava/RawTypeWithUpperBound.java b/compiler/testData/loadJava/compiledJava/RawTypeWithUpperBound.java new file mode 100644 index 00000000000..e53bf24de83 --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/RawTypeWithUpperBound.java @@ -0,0 +1,11 @@ +package test; + +public interface RawTypeWithUpperBound { + + public interface Foo { + } + + interface Bar { + void f(Foo f); + } +} diff --git a/compiler/testData/loadJava/compiledJava/RawTypeWithUpperBound.txt b/compiler/testData/loadJava/compiledJava/RawTypeWithUpperBound.txt new file mode 100644 index 00000000000..0d0e3d1f4a1 --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/RawTypeWithUpperBound.txt @@ -0,0 +1,15 @@ +package test + +public trait RawTypeWithUpperBound : java.lang.Object { + + public trait Bar : java.lang.Object { + public abstract fun f(/*0*/ p0: test.RawTypeWithUpperBound.Foo?): jet.Unit + } + + public trait Foo : java.lang.Object { + } +} + +package test.RawTypeWithUpperBound { + public /*synthesized*/ fun Bar(/*0*/ function: (test.RawTypeWithUpperBound.Foo?) -> jet.Unit): test.RawTypeWithUpperBound.Bar +} diff --git a/compiler/testData/loadJava/compiledJava/RawUpperBound.java b/compiler/testData/loadJava/compiledJava/RawUpperBound.java new file mode 100644 index 00000000000..3475c6c1358 --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/RawUpperBound.java @@ -0,0 +1,4 @@ +package test; + +public interface RawUpperBound { +} diff --git a/compiler/testData/loadJava/compiledJava/RawUpperBound.txt b/compiler/testData/loadJava/compiledJava/RawUpperBound.txt new file mode 100644 index 00000000000..296cd9b27bf --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/RawUpperBound.txt @@ -0,0 +1,4 @@ +package test + +public trait RawUpperBound?> : java.lang.Object { +} diff --git a/compiler/testData/loadJava/compiledJava/RecursiveRawUpperBound.java b/compiler/testData/loadJava/compiledJava/RecursiveRawUpperBound.java new file mode 100644 index 00000000000..dfdd83407d7 --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/RecursiveRawUpperBound.java @@ -0,0 +1,4 @@ +package test; + +public interface RecursiveRawUpperBound { +} diff --git a/compiler/testData/loadJava/compiledJava/RecursiveRawUpperBound.txt b/compiler/testData/loadJava/compiledJava/RecursiveRawUpperBound.txt new file mode 100644 index 00000000000..d4e8e21760b --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/RecursiveRawUpperBound.txt @@ -0,0 +1,4 @@ +package test + +public trait RecursiveRawUpperBound?> : java.lang.Object { +} diff --git a/compiler/testData/loadJava/compiledJava/RecursiveWildcardUpperBound.java b/compiler/testData/loadJava/compiledJava/RecursiveWildcardUpperBound.java new file mode 100644 index 00000000000..e50ea04a8ea --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/RecursiveWildcardUpperBound.java @@ -0,0 +1,4 @@ +package test; + +public interface RecursiveWildcardUpperBound { +} diff --git a/compiler/testData/loadJava/compiledJava/RecursiveWildcardUpperBound.txt b/compiler/testData/loadJava/compiledJava/RecursiveWildcardUpperBound.txt new file mode 100644 index 00000000000..6201f964299 --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/RecursiveWildcardUpperBound.txt @@ -0,0 +1,4 @@ +package test + +public trait RecursiveWildcardUpperBound?> : java.lang.Object { +} diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index bd792ca3efe..1f8227a5c4d 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -4558,6 +4558,11 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest("compiler/testData/diagnostics/tests/j+k/mutableIterator.kt"); } + @TestMetadata("overrideRawType.kt") + public void testOverrideRawType() throws Exception { + doTest("compiler/testData/diagnostics/tests/j+k/overrideRawType.kt"); + } + @TestMetadata("OverrideVararg.kt") public void testOverrideVararg() throws Exception { doTest("compiler/testData/diagnostics/tests/j+k/OverrideVararg.kt"); diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java index b39add6f8ef..bd6e11ff109 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java @@ -59,6 +59,26 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest { doTestCompiledJava("compiler/testData/loadJava/compiledJava/PackageLocalVisibility.java"); } + @TestMetadata("RawTypeWithUpperBound.java") + public void testRawTypeWithUpperBound() throws Exception { + doTestCompiledJava("compiler/testData/loadJava/compiledJava/RawTypeWithUpperBound.java"); + } + + @TestMetadata("RawUpperBound.java") + public void testRawUpperBound() throws Exception { + doTestCompiledJava("compiler/testData/loadJava/compiledJava/RawUpperBound.java"); + } + + @TestMetadata("RecursiveRawUpperBound.java") + public void testRecursiveRawUpperBound() throws Exception { + doTestCompiledJava("compiler/testData/loadJava/compiledJava/RecursiveRawUpperBound.java"); + } + + @TestMetadata("RecursiveWildcardUpperBound.java") + public void testRecursiveWildcardUpperBound() throws Exception { + doTestCompiledJava("compiler/testData/loadJava/compiledJava/RecursiveWildcardUpperBound.java"); + } + @TestMetadata("SubclassFromNested.java") public void testSubclassFromNested() throws Exception { doTestCompiledJava("compiler/testData/loadJava/compiledJava/SubclassFromNested.java"); diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/types/LazyJavaTypeResolver.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/types/LazyJavaTypeResolver.kt index 0cd379c3a96..0fa9b038148 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/types/LazyJavaTypeResolver.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/types/LazyJavaTypeResolver.kt @@ -79,9 +79,12 @@ class LazyJavaTypeResolver( private class LazyStarProjection( c: LazyJavaResolverContext, - val typeParameter: TypeParameterDescriptor + val typeParameter: TypeParameterDescriptor, + val attr: JavaTypeAttributes ) : TypeProjectionBase() { - override fun getProjectionKind() = if (typeParameter.getVariance() == OUT_VARIANCE) INVARIANT else OUT_VARIANCE + override fun getProjectionKind() = + // projections are not allowed in immediate arguments of supertypes + if (typeParameter.getVariance() == OUT_VARIANCE || attr.howThisTypeIsUsed == SUPERTYPE) INVARIANT else OUT_VARIANCE override fun getType() = typeParameter.getUpperBoundsAsType() } @@ -167,18 +170,19 @@ class LazyJavaTypeResolver( if (isRaw()) { return typeParameters.map { parameter -> - // not making a star projection because of this case: - // Java: - // class C {} - // The upper bound is raw here, and we can't compute the projection: it would be infinite: - // C<*> = C>> - // this way we loose some type information, even when the case is not so bad, but it doesn't seem to matter - // projections are not allowed in immediate arguments of supertypes - val projectionKind = if (parameter.getVariance() == OUT_VARIANCE || attr.howThisTypeIsUsed == SUPERTYPE) - INVARIANT - else OUT_VARIANCE - TypeProjectionImpl(projectionKind, KotlinBuiltIns.getInstance().getNullableAnyType()) + if (attr.howThisTypeIsUsed == UPPER_BOUND) { + // not making a star projection because of this case: + // Java: + // class C {} + // The upper bound is raw here, and we can't compute the projection: it would be infinite: + // C<*> = C>> + // this way we lose some type information, even when the case is not so bad, but it doesn't seem to matter + val projectionKind = if (parameter.getVariance() == OUT_VARIANCE) INVARIANT else OUT_VARIANCE + TypeProjectionImpl(projectionKind, KotlinBuiltIns.getInstance().getNullableAnyType()) + } + else + LazyStarProjection(c, parameter, attr) } } if (isConstructorTypeParameter()) { @@ -209,7 +213,7 @@ class LazyJavaTypeResolver( is JavaWildcardType -> { val bound = javaType.getBound() if (bound == null) - LazyStarProjection(c, typeParameter) + LazyStarProjection(c, typeParameter, attr) else { var projectionKind = if (javaType.isExtends()) OUT_VARIANCE else IN_VARIANCE if (projectionKind == typeParameter.getVariance()) { @@ -263,11 +267,11 @@ class LazyJavaTypeAttributes( c: LazyJavaResolverContext, val annotationOwner: JavaAnnotationOwner, override val howThisTypeIsUsed: TypeUsage, - computeHowThisTypeIsUsedAccrodingToAnnotations: () -> TypeUsage = {howThisTypeIsUsed} + computeHowThisTypeIsUsedAccordingToAnnotations: () -> TypeUsage = {howThisTypeIsUsed} ): JavaTypeAttributes { override val howThisTypeIsUsedAccordingToAnnotations: TypeUsage by c.storageManager.createLazyValue( - computeHowThisTypeIsUsedAccrodingToAnnotations + computeHowThisTypeIsUsedAccordingToAnnotations ) override val isMarkedNotNull: Boolean by c.storageManager.createLazyValue { c.hasNotNullAnnotation(annotationOwner) }