diff --git a/compiler/testData/diagnostics/tests/j+k/overrideRawType.kt b/compiler/testData/diagnostics/tests/j+k/overrideRawType.kt index b2b58c6cf3d..4772e9a77c0 100644 --- a/compiler/testData/diagnostics/tests/j+k/overrideRawType.kt +++ b/compiler/testData/diagnostics/tests/j+k/overrideRawType.kt @@ -9,7 +9,7 @@ public interface Bar { //FILE: a.kt class BarImpl: Bar { - override fun f(f: Foo?) { + override fun f(f: Foo<*>?) { throw UnsupportedOperationException() } } diff --git a/compiler/testData/diagnostics/tests/j+k/overrideRawType.txt b/compiler/testData/diagnostics/tests/j+k/overrideRawType.txt index cafd1d3ea25..c8ca7cfed49 100644 --- a/compiler/testData/diagnostics/tests/j+k/overrideRawType.txt +++ b/compiler/testData/diagnostics/tests/j+k/overrideRawType.txt @@ -12,7 +12,7 @@ public trait Bar { internal final class BarImpl : Bar { public constructor BarImpl() public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean - public open override /*1*/ fun f(/*0*/ f: Foo?): kotlin.Unit + public open override /*1*/ fun f(/*0*/ f: Foo<*>?): kotlin.Unit public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } diff --git a/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperType.txt b/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperType.txt index 35efb4e9903..0f754af9ee5 100644 --- a/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperType.txt +++ b/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperType.txt @@ -3,7 +3,7 @@ package test public open class RawSuperType { public constructor RawSuperType() - public open inner class Derived : test.RawSuperType.Super<*> { + public open inner class Derived : test.RawSuperType.Super { public constructor Derived() public open override /*1*/ fun dummy(): kotlin.Unit public open override /*1*/ fun foo(/*0*/ p0: kotlin.Any!): kotlin.Unit diff --git a/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithBound.java b/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithBound.java new file mode 100644 index 00000000000..c88983b4dd6 --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithBound.java @@ -0,0 +1,31 @@ +package test; + +import java.lang.Object; +import java.lang.Override; +import java.lang.UnsupportedOperationException; + +public class RawSuperTypeWithBound { + + public interface Bound {} + + public interface Super { + void foo(T t); + + void dummy(); // To make it not SAM + } + + public class Derived implements Super { + public void foo(Object o) { + throw new UnsupportedOperationException(); + } + + @Override + public void foo(Bound o) { + throw new UnsupportedOperationException(); + } + + @Override + public void dummy() {} + } + +} \ No newline at end of file diff --git a/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithBound.txt b/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithBound.txt new file mode 100644 index 00000000000..da96738ad0e --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithBound.txt @@ -0,0 +1,20 @@ +package test + +public open class RawSuperTypeWithBound { + public constructor RawSuperTypeWithBound() + + public trait Bound { + } + + public open inner class Derived : test.RawSuperTypeWithBound.Super { + public constructor Derived() + public open override /*1*/ fun dummy(): kotlin.Unit + public open fun foo(/*0*/ p0: kotlin.Any!): kotlin.Unit + public open override /*1*/ fun foo(/*0*/ p0: test.RawSuperTypeWithBound.Bound!): kotlin.Unit + } + + public trait Super { + public abstract fun dummy(): kotlin.Unit + public abstract fun foo(/*0*/ p0: T!): kotlin.Unit + } +} diff --git a/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBound.java b/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBound.java new file mode 100644 index 00000000000..8df385a4211 --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBound.java @@ -0,0 +1,29 @@ +package test; + +import java.lang.Object; +import java.lang.Override; +import java.lang.UnsupportedOperationException; + +public class RawSuperTypeWithRecursiveBound { + + public interface Super> { + void foo(T t); + + void dummy(); // To make it not SAM + } + + public class Derived implements Super { + public void foo(Object o) { + throw new UnsupportedOperationException(); + } + + @Override + public void foo(Super o) { + throw new UnsupportedOperationException(); + } + + @Override + public void dummy() {} + } + +} \ No newline at end of file diff --git a/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBound.txt b/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBound.txt new file mode 100644 index 00000000000..c84a856b2b5 --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBound.txt @@ -0,0 +1,17 @@ +package test + +public open class RawSuperTypeWithRecursiveBound { + public constructor RawSuperTypeWithRecursiveBound() + + public open inner class Derived : test.RawSuperTypeWithRecursiveBound.Super!> { + public constructor Derived() + public open override /*1*/ fun dummy(): kotlin.Unit + public open fun foo(/*0*/ p0: kotlin.Any!): kotlin.Unit + public open override /*1*/ fun foo(/*0*/ p0: test.RawSuperTypeWithRecursiveBound.Super<*>!): kotlin.Unit + } + + public trait Super!> { + public abstract fun dummy(): kotlin.Unit + public abstract fun foo(/*0*/ p0: T!): kotlin.Unit + } +} diff --git a/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBoundMultipleParameters.java b/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBoundMultipleParameters.java new file mode 100644 index 00000000000..5c0a0930b65 --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBoundMultipleParameters.java @@ -0,0 +1,29 @@ +package test; + +import java.lang.Object; +import java.lang.Override; +import java.lang.UnsupportedOperationException; + +public class RawSuperTypeWithRecursiveBoundMultipleParameters { + + public interface Super> { + void foo(R r, T t); + + void dummy(); // To make it not SAM + } + + public class Derived implements Super { + public void foo(Object o, Object o1) { + throw new UnsupportedOperationException(); + } + + @Override + public void foo(Object r, Super t) { + throw new UnsupportedOperationException(); + } + + @Override + public void dummy() {} + } + +} \ No newline at end of file diff --git a/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBoundMultipleParameters.txt b/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBoundMultipleParameters.txt new file mode 100644 index 00000000000..f50cc14528c --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBoundMultipleParameters.txt @@ -0,0 +1,17 @@ +package test + +public open class RawSuperTypeWithRecursiveBoundMultipleParameters { + public constructor RawSuperTypeWithRecursiveBoundMultipleParameters() + + public open inner class Derived : test.RawSuperTypeWithRecursiveBoundMultipleParameters.Super!> { + public constructor Derived() + public open override /*1*/ fun dummy(): kotlin.Unit + public open fun foo(/*0*/ p0: kotlin.Any!, /*1*/ p1: kotlin.Any!): kotlin.Unit + public open override /*1*/ fun foo(/*0*/ p0: kotlin.Any!, /*1*/ p1: test.RawSuperTypeWithRecursiveBoundMultipleParameters.Super<*, *>!): kotlin.Unit + } + + public trait Super!> { + public abstract fun dummy(): kotlin.Unit + public abstract fun foo(/*0*/ p0: R!, /*1*/ p1: T!): kotlin.Unit + } +} diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java index 5bd5bb9ac91..d76544847a8 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/LoadJavaTestGenerated.java @@ -1723,6 +1723,24 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest { doTestCompiledJava(fileName); } + @TestMetadata("RawSuperTypeWithBound.java") + public void testRawSuperTypeWithBound() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithBound.java"); + doTestCompiledJava(fileName); + } + + @TestMetadata("RawSuperTypeWithRecursiveBound.java") + public void testRawSuperTypeWithRecursiveBound() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBound.java"); + doTestCompiledJava(fileName); + } + + @TestMetadata("RawSuperTypeWithRecursiveBoundMultipleParameters.java") + public void testRawSuperTypeWithRecursiveBoundMultipleParameters() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBoundMultipleParameters.java"); + doTestCompiledJava(fileName); + } + @TestMetadata("ReturnInnerSubclassOfSupersInner.java") public void testReturnInnerSubclassOfSupersInner() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/signaturePropagation/ReturnInnerSubclassOfSupersInner.java"); 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 c4cadb8ce4f..e92c4f2625f 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 @@ -37,6 +37,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.load.java.JvmAnnotationNames import kotlin.platform.platformStatic import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations +import kotlin.properties.* class LazyJavaTypeResolver( private val c: LazyJavaResolverContext, @@ -89,17 +90,14 @@ class LazyJavaTypeResolver( }.replaceAnnotations(attr.annotations) } - private class LazyStarProjection( - val typeParameter: TypeParameterDescriptor, - val attr: JavaTypeAttributes - ) : TypeProjectionBase() { - override fun isStarProjection() = true - - 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() + fun makeStarProjection( + typeParameter: TypeParameterDescriptor, + attr: JavaTypeAttributes + ): TypeProjection { + return if (attr.howThisTypeIsUsed == SUPERTYPE) + TypeProjectionImpl(typeParameter.starProjectionType()) + else + StarProjectionImpl(typeParameter) } private inner class LazyJavaClassifierType( @@ -197,7 +195,7 @@ class LazyJavaTypeResolver( TypeProjectionImpl(projectionKind, KotlinBuiltIns.getInstance().getNullableAnyType()) } else - LazyStarProjection(parameter, attr) + makeStarProjection(parameter, attr) } } if (isConstructorTypeParameter()) { @@ -228,7 +226,7 @@ class LazyJavaTypeResolver( is JavaWildcardType -> { val bound = javaType.getBound() if (bound == null) - LazyStarProjection(typeParameter, attr) + makeStarProjection(typeParameter, attr) else { var projectionKind = if (javaType.isExtends()) OUT_VARIANCE else IN_VARIANCE if (projectionKind == typeParameter.getVariance()) { diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/StarProjectionImpl.kt b/core/descriptors/src/org/jetbrains/kotlin/types/StarProjectionImpl.kt index d444567b289..7745bc2ff6d 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/StarProjectionImpl.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/StarProjectionImpl.kt @@ -26,24 +26,28 @@ class StarProjectionImpl( override fun getProjectionKind() = Variance.OUT_VARIANCE + // No synchronization here: there's no problem in accidentally computing this twice private val _type: JetType by Delegates.lazy { - val classDescriptor = typeParameter.getContainingDeclaration() as ClassDescriptor - val typeParameters = classDescriptor.getTypeConstructor().getParameters().map { it.getTypeConstructor() } - TypeSubstitutor.create( - object : TypeSubstitution() { - override fun get(key: TypeConstructor) = when (key) { - typeParameter.getTypeConstructor() -> this@StarProjectionImpl - in typeParameters -> TypeUtils.makeStarProjection(key.getDeclarationDescriptor() as TypeParameterDescriptor) - else -> null - } - - } - ).substitute(typeParameter.getUpperBounds().iterator().next(), Variance.OUT_VARIANCE)!! + typeParameter.starProjectionType() } override fun getType() = _type } +public fun TypeParameterDescriptor.starProjectionType(): JetType { + val classDescriptor = this.getContainingDeclaration() as ClassDescriptor + val typeParameters = classDescriptor.getTypeConstructor().getParameters().map { it.getTypeConstructor() } + return TypeSubstitutor.create( + object : TypeSubstitution() { + override fun get(key: TypeConstructor) = + if (key in typeParameters) + TypeUtils.makeStarProjection(key.getDeclarationDescriptor() as TypeParameterDescriptor) + else null + + } + ).substitute(this.getUpperBounds().first(), Variance.OUT_VARIANCE)!! +} + class TypeBasedStarProjectionImpl( private val _type: JetType ) : TypeProjectionBase() { diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java b/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java index ff6187bd1ed..dad4ac43afb 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java @@ -210,12 +210,12 @@ public class TypeSubstitutor { } JetType substitutedType; CustomTypeVariable typeVariable = TypesPackage.getCustomTypeVariable(type); - if (typeVariable != null) { - substitutedType = typeVariable.substitutionResult(replacement.getType()); - } - else if (replacement.isStarProjection()) { + if (replacement.isStarProjection()) { return replacement; } + else if (typeVariable != null) { + substitutedType = typeVariable.substitutionResult(replacement.getType()); + } else { // this is a simple type T or T?: if it's T, we should just take replacement, if T? - we make replacement nullable substitutedType = TypeUtils.makeNullableIfNeeded(replacement.getType(), type.isMarkedNullable()); diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/render/KotlinClassWithDelegatedPropertyRenderer.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/render/KotlinClassWithDelegatedPropertyRenderer.kt index 159109ccf18..d1217dcf1d0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/render/KotlinClassWithDelegatedPropertyRenderer.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/render/KotlinClassWithDelegatedPropertyRenderer.kt @@ -76,7 +76,7 @@ public class KotlinClassWithDelegatedPropertyRenderer : ClassRenderer() { val threadReference = context.getSuspendContext().getThread()?.getThreadReference() if (method != null && threadReference != null) { val propValue = try { - context.getDebugProcess().invokeInstanceMethod(context, value, method, listOf(), context.getSuspendContext().getSuspendPolicy()) + context.getDebugProcess().invokeInstanceMethod(context, value, method, listOf(), context.getSuspendContext().getSuspendPolicy()) } catch(e: EvaluateException) { e.getExceptionFromTargetVM()