KT-6815 Representing raw types when used as supertypes for Java classes

#KT-6815 Fixed
This commit is contained in:
Andrey Breslav
2015-03-02 19:31:02 +03:00
parent 7c62d8ed83
commit 61989ba245
14 changed files with 196 additions and 33 deletions
@@ -9,7 +9,7 @@ public interface Bar {
//FILE: a.kt
class BarImpl: Bar {
override fun f(f: Foo<out CharSequence?>?) {
override fun f(f: Foo<*>?) {
throw UnsupportedOperationException()
}
}
@@ -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<out kotlin.CharSequence?>?): 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
}
@@ -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<kotlin.Any?> {
public constructor Derived()
public open override /*1*/ fun dummy(): kotlin.Unit
public open override /*1*/ fun foo(/*0*/ p0: kotlin.Any!): kotlin.Unit
@@ -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<T extends Bound> {
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() {}
}
}
@@ -0,0 +1,20 @@
package test
public open class RawSuperTypeWithBound {
public constructor RawSuperTypeWithBound()
public trait Bound {
}
public open inner class Derived : test.RawSuperTypeWithBound.Super<test.RawSuperTypeWithBound.Bound!> {
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</*0*/ T : test.RawSuperTypeWithBound.Bound!> {
public abstract fun dummy(): kotlin.Unit
public abstract fun foo(/*0*/ p0: T!): kotlin.Unit
}
}
@@ -0,0 +1,29 @@
package test;
import java.lang.Object;
import java.lang.Override;
import java.lang.UnsupportedOperationException;
public class RawSuperTypeWithRecursiveBound {
public interface Super<T extends Super<T>> {
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() {}
}
}
@@ -0,0 +1,17 @@
package test
public open class RawSuperTypeWithRecursiveBound {
public constructor RawSuperTypeWithRecursiveBound()
public open inner class Derived : test.RawSuperTypeWithRecursiveBound.Super<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</*0*/ T : test.RawSuperTypeWithRecursiveBound.Super<T!>!> {
public abstract fun dummy(): kotlin.Unit
public abstract fun foo(/*0*/ p0: T!): kotlin.Unit
}
}
@@ -0,0 +1,29 @@
package test;
import java.lang.Object;
import java.lang.Override;
import java.lang.UnsupportedOperationException;
public class RawSuperTypeWithRecursiveBoundMultipleParameters {
public interface Super<R, T extends Super<R, T>> {
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() {}
}
}
@@ -0,0 +1,17 @@
package test
public open class RawSuperTypeWithRecursiveBoundMultipleParameters {
public constructor RawSuperTypeWithRecursiveBoundMultipleParameters()
public open inner class Derived : test.RawSuperTypeWithRecursiveBoundMultipleParameters.Super<kotlin.Any?, 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</*0*/ R, /*1*/ T : test.RawSuperTypeWithRecursiveBoundMultipleParameters.Super<R!, T!>!> {
public abstract fun dummy(): kotlin.Unit
public abstract fun foo(/*0*/ p0: R!, /*1*/ p1: T!): kotlin.Unit
}
}
@@ -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");
@@ -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()) {
@@ -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() {
@@ -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());
@@ -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<Nothing>(), context.getSuspendContext().getSuspendPolicy())
}
catch(e: EvaluateException) {
e.getExceptionFromTargetVM()