diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.java index f9691b3bf8d..a8cda2a47c2 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.java @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.kotlin.load.java.JvmAbi; +import org.jetbrains.kotlin.load.java.lazy.types.RawTypeImpl; import org.jetbrains.kotlin.load.kotlin.JavaFlexibleTypeDeserializer; import org.jetbrains.kotlin.name.ClassId; import org.jetbrains.kotlin.serialization.AnnotationSerializer; @@ -34,7 +35,6 @@ import org.jetbrains.kotlin.serialization.jvm.ClassMapperLite; import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf; import org.jetbrains.kotlin.types.DelegatingFlexibleType; import org.jetbrains.kotlin.types.KotlinType; -import org.jetbrains.kotlin.types.RawTypeCapability; import org.jetbrains.org.objectweb.asm.Type; import org.jetbrains.org.objectweb.asm.commons.Method; @@ -89,6 +89,11 @@ public class JvmSerializerExtension extends SerializerExtension { @NotNull ProtoBuf.Type.Builder upperProto ) { lowerProto.setFlexibleTypeCapabilitiesId(getStringTable().getStringIndex(JavaFlexibleTypeDeserializer.INSTANCE.getId())); + + if (flexibleType instanceof RawTypeImpl) { + lowerProto.setExtension(JvmProtoBuf.isRaw, true); + upperProto.setExtension(JvmProtoBuf.isRaw, true); + } } @Override @@ -97,10 +102,6 @@ public class JvmSerializerExtension extends SerializerExtension { for (AnnotationDescriptor annotation : type.getAnnotations()) { proto.addExtension(JvmProtoBuf.typeAnnotation, annotationSerializer.serializeAnnotation(annotation)); } - - if (type.getCapability(RawTypeCapability.class) != null) { - proto.setExtension(JvmProtoBuf.isRaw, true); - } } @Override diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JavaGenericVarianceViolationTypeChecker.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JavaGenericVarianceViolationTypeChecker.kt index 4c8841f4e5f..66cbee35cde 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JavaGenericVarianceViolationTypeChecker.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/platform/JavaGenericVarianceViolationTypeChecker.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.resolve.jvm.platform +import org.jetbrains.kotlin.load.java.lazy.types.RawTypeImpl import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.resolve.calls.checkers.AdditionalTypeChecker import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext @@ -51,7 +52,7 @@ object JavaGenericVarianceViolationTypeChecker : AdditionalTypeChecker { // Use site variance projection is always the same for flexible types if (lowerBound.constructor == upperBound.constructor) return // Anything is acceptable for raw types - if (expectedType.getCapability() != null) return + if (expectedType.unwrap() is RawTypeImpl) return val correspondingSubType = TypeCheckingProcedure.findCorrespondingSupertype(expressionTypeWithSmartCast, lowerBound) ?: return diff --git a/compiler/testData/diagnostics/tests/generics/PseudoRawTypes.txt b/compiler/testData/diagnostics/tests/generics/PseudoRawTypes.txt index d16d6479d39..2ff8ddb0861 100644 --- a/compiler/testData/diagnostics/tests/generics/PseudoRawTypes.txt +++ b/compiler/testData/diagnostics/tests/generics/PseudoRawTypes.txt @@ -6,7 +6,7 @@ package test { public open class Usage { public constructor Usage() public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean - public/*package*/ open fun foo(/*0*/ c: kotlin.collections.(Mutable)Collection<(raw) kotlin.Any?>!): kotlin.Unit + public/*package*/ open fun foo(/*0*/ c: kotlin.collections.(Mutable)Collection<*>!): 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/diagnostics/tests/platformTypes/rawOverrides.txt b/compiler/testData/diagnostics/tests/platformTypes/rawOverrides.txt index fbe24904556..c4470096b0d 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/rawOverrides.txt +++ b/compiler/testData/diagnostics/tests/platformTypes/rawOverrides.txt @@ -9,11 +9,11 @@ public interface A { public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } -public interface B : A { - public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any(raw)?): kotlin.Boolean(raw) +public interface B : A<(raw) kotlin.Any!> { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean @java.lang.Override() public abstract override /*1*/ fun foo(/*0*/ x: kotlin.Any!, /*1*/ y: kotlin.collections.(Mutable)List<(raw) kotlin.Any?>!): kotlin.String! - public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int(raw) - public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String(raw) + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } public abstract class C { @@ -43,11 +43,11 @@ public final class E : D, B { public final class E2 : B { public constructor E2() - public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any(raw)?): kotlin.Boolean(raw) + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open fun foo(/*0*/ x: kotlin.Any, /*1*/ y: kotlin.collections.List): kotlin.String @java.lang.Override() public abstract override /*1*/ /*fake_override*/ fun foo(/*0*/ x: kotlin.Any!, /*1*/ y: kotlin.collections.(Mutable)List<(raw) kotlin.Any?>!): kotlin.String! - public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int(raw) - public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String(raw) + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } public final class F : D { diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/arrays.txt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/arrays.txt index 695f5c580eb..b1b7afb622c 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/arrays.txt +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/arrays.txt @@ -21,16 +21,16 @@ public/*package*/ open class Test { public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String - public/*package*/ open class RawADerived : A { + public/*package*/ open class RawADerived : A<(raw) kotlin.CharSequence!, (raw) kotlin.Any!> { public/*package*/ constructor RawADerived() - public/*package*/ final override /*1*/ /*fake_override*/ var arraysOfAny: kotlin.Array<(out) kotlin.Array<(out) kotlin.Any(raw)!>!>! + public/*package*/ final override /*1*/ /*fake_override*/ var arraysOfAny: kotlin.Array<(out) kotlin.Array<(out) kotlin.Any!>!>! public/*package*/ final override /*1*/ /*fake_override*/ var arraysOfLists: kotlin.Array<(out) kotlin.Array<(out) kotlin.collections.(Mutable)List<(raw) kotlin.Any?>!>!>! - public/*package*/ final override /*1*/ /*fake_override*/ var charSequences: kotlin.Array<(out) kotlin.CharSequence(raw)!>! + public/*package*/ final override /*1*/ /*fake_override*/ var charSequences: kotlin.Array<(out) kotlin.CharSequence!>! public/*package*/ final override /*1*/ /*fake_override*/ var erasedLists: kotlin.Array<(out) kotlin.collections.(Mutable)List<(raw) kotlin.Any?>!>! public/*package*/ final override /*1*/ /*fake_override*/ var maps: kotlin.Array<(out) kotlin.collections.(Mutable)Map<(raw) kotlin.Any?, (raw) kotlin.Any?>!>! - public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any(raw)?): kotlin.Boolean(raw) - public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int(raw) - public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String(raw) + 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 diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/errorType.txt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/errorType.txt index 80f8790d9df..7d1c62918d2 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/errorType.txt +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/errorType.txt @@ -8,10 +8,10 @@ public open class A { public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } -public open class B : A { +public open class B : A<(raw) kotlin.Any!> { public constructor B() - public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any(raw)?): kotlin.Boolean(raw) - public open override /*1*/ /*fake_override*/ fun foo(/*0*/ x: Err(raw)!, /*1*/ y: kotlin.collections.(Mutable)List<(raw) kotlin.Any?>!): kotlin.Unit(raw) - public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int(raw) - public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String(raw) + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun foo(/*0*/ x: Err!, /*1*/ y: kotlin.collections.(Mutable)List<(raw) kotlin.Any?>!): 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/diagnostics/tests/platformTypes/rawTypes/nonGenericRawMember.kt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonGenericRawMember.kt index 1291ca7195c..57114da4e32 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonGenericRawMember.kt +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonGenericRawMember.kt @@ -29,7 +29,6 @@ val strList: List = null!! fun main() { val rawB = Test.rawAField.b; - // Raw(A).b is erased too although it have no type parameters - // so it's `bar` allows lists of any types - var rawInner = rawB.bar(strList) + // Raw(A).b is not erased because it have no type parameters + var rawInner = rawB.bar(!; List)!>strList) } diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonGenericRawMember.txt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonGenericRawMember.txt index 960273a3f27..50e7720425e 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonGenericRawMember.txt +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonGenericRawMember.txt @@ -25,12 +25,12 @@ public/*package*/ open class Test { public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String - public/*package*/ open class RawADerived : A { + public/*package*/ open class RawADerived : A<(raw) kotlin.Any!> { public/*package*/ constructor RawADerived() - public/*package*/ final override /*1*/ /*fake_override*/ var b: B(raw)! - public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any(raw)?): kotlin.Boolean(raw) - public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int(raw) - public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String(raw) + public/*package*/ final override /*1*/ /*fake_override*/ var b: B! + 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 diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonTrivialErasure.txt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonTrivialErasure.txt index ea3708c424c..cfebced0ff9 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonTrivialErasure.txt +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonTrivialErasure.txt @@ -19,14 +19,14 @@ public/*package*/ open class Test { public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String - public/*package*/ open class DerivedRawA : A!, out A<*, *, *>!, out kotlin.collections.(Mutable)List<*>!> { + public/*package*/ open class DerivedRawA : A<(raw) A<*, *, *>!, (raw) A<*, *, *>!, (raw) kotlin.collections.(Mutable)List<*>!> { public/*package*/ constructor DerivedRawA() public/*package*/ final override /*1*/ /*fake_override*/ var first: A<(raw) A<*, *, *>!, (raw) A<*, *, *>!, (raw) kotlin.collections.(Mutable)List<*>!>! public/*package*/ final override /*1*/ /*fake_override*/ var listOfDoubles: kotlin.collections.(Mutable)List<(raw) kotlin.Any?>! public/*package*/ final override /*1*/ /*fake_override*/ var second: A<(raw) A<*, *, *>!, (raw) A<*, *, *>!, (raw) kotlin.collections.(Mutable)List<*>!>! - public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any(raw)?): kotlin.Boolean(raw) - public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int(raw) - public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String(raw) + 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 diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawSupertype.txt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawSupertype.txt index 5fbed01b074..629440e3286 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawSupertype.txt +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawSupertype.txt @@ -20,13 +20,13 @@ public/*package*/ open class Test { public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String - public/*package*/ open class RawADerived : A { + public/*package*/ open class RawADerived : A<(raw) kotlin.Any!> { public/*package*/ constructor RawADerived() public/*package*/ final override /*1*/ /*fake_override*/ var x: kotlin.collections.(Mutable)List<(raw) kotlin.Any?>! public/*package*/ open override /*1*/ /*fake_override*/ fun bar(): A<(raw) kotlin.Any!>! - public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any(raw)?): kotlin.Boolean(raw) - public/*package*/ open override /*1*/ /*fake_override*/ fun foo(/*0*/ x: kotlin.Any(raw)!, /*1*/ y: kotlin.collections.(Mutable)List<(raw) kotlin.Any?>!): kotlin.Unit(raw) - public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int(raw) - public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String(raw) + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public/*package*/ open override /*1*/ /*fake_override*/ fun foo(/*0*/ x: kotlin.Any!, /*1*/ y: kotlin.collections.(Mutable)List<(raw) kotlin.Any?>!): 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/diagnostics/tests/platformTypes/rawTypes/rawSupertypeOverride.txt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawSupertypeOverride.txt index 04d55a98098..d437ddb906e 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawSupertypeOverride.txt +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawSupertypeOverride.txt @@ -12,46 +12,46 @@ public open class A { public final class B1 : RawADerived { public constructor B1() protected open override /*1*/ fun bar(/*0*/ d: kotlin.Array>>): kotlin.Unit - public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any(raw)?): kotlin.Boolean(raw) + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean protected open override /*1*/ fun foo(/*0*/ x: kotlin.CharSequence, /*1*/ y: kotlin.collections.Map, /*2*/ z: java.util.HashMap): A<*> - public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int(raw) - public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String(raw) + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } public final class B2 : RawADerived { public constructor B2() protected open override /*1*/ fun bar(/*0*/ d: kotlin.Array>>): kotlin.Unit - public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any(raw)?): kotlin.Boolean(raw) + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean protected open override /*1*/ fun foo(/*0*/ x: kotlin.CharSequence?, /*1*/ y: kotlin.collections.MutableMap, /*2*/ z: java.util.HashMap): A - public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int(raw) - public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String(raw) + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } public final class B3 : RawADerived { public constructor B3() - public/*package*/ open override /*1*/ /*fake_override*/ fun bar(/*0*/ d: kotlin.Array<(out) kotlin.Array<(out) kotlin.collections.(Mutable)List<(raw) kotlin.Any?>!>!>!): kotlin.Unit(raw) - public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any(raw)?): kotlin.Boolean(raw) + public/*package*/ open override /*1*/ /*fake_override*/ fun bar(/*0*/ d: kotlin.Array<(out) kotlin.Array<(out) kotlin.collections.(Mutable)List<(raw) kotlin.Any?>!>!>!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open fun foo(/*0*/ x: kotlin.CharSequence, /*1*/ y: kotlin.collections.Map, /*2*/ z: java.util.HashMap): A<*> - public/*package*/ open override /*1*/ /*fake_override*/ fun foo(/*0*/ x: kotlin.CharSequence(raw)!, /*1*/ y: kotlin.collections.(Mutable)Map<(raw) kotlin.Any?, (raw) kotlin.Any?>!, /*2*/ z: java.util.HashMap<(raw) kotlin.Any!, (raw) kotlin.Any!>!): A<(raw) kotlin.CharSequence!>! - public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int(raw) - public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String(raw) + public/*package*/ open override /*1*/ /*fake_override*/ fun foo(/*0*/ x: kotlin.CharSequence!, /*1*/ y: kotlin.collections.(Mutable)Map<(raw) kotlin.Any?, (raw) kotlin.Any?>!, /*2*/ z: java.util.HashMap<(raw) kotlin.Any!, (raw) kotlin.Any!>!): A<(raw) kotlin.CharSequence!>! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } public final class B4 : RawADerived { public constructor B4() - public/*package*/ open override /*1*/ /*fake_override*/ fun bar(/*0*/ d: kotlin.Array<(out) kotlin.Array<(out) kotlin.collections.(Mutable)List<(raw) kotlin.Any?>!>!>!): kotlin.Unit(raw) + public/*package*/ open override /*1*/ /*fake_override*/ fun bar(/*0*/ d: kotlin.Array<(out) kotlin.Array<(out) kotlin.collections.(Mutable)List<(raw) kotlin.Any?>!>!>!): kotlin.Unit public open fun bar(/*0*/ d: kotlin.Array>>>): kotlin.Unit - public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any(raw)?): kotlin.Boolean(raw) - public/*package*/ open override /*1*/ /*fake_override*/ fun foo(/*0*/ x: kotlin.CharSequence(raw)!, /*1*/ y: kotlin.collections.(Mutable)Map<(raw) kotlin.Any?, (raw) kotlin.Any?>!, /*2*/ z: java.util.HashMap<(raw) kotlin.Any!, (raw) kotlin.Any!>!): A<(raw) kotlin.CharSequence!>! - public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int(raw) - public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String(raw) + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public/*package*/ open override /*1*/ /*fake_override*/ fun foo(/*0*/ x: kotlin.CharSequence!, /*1*/ y: kotlin.collections.(Mutable)Map<(raw) kotlin.Any?, (raw) kotlin.Any?>!, /*2*/ z: java.util.HashMap<(raw) kotlin.Any!, (raw) kotlin.Any!>!): A<(raw) kotlin.CharSequence!>! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } -public open class RawADerived : A { +public open class RawADerived : A<(raw) kotlin.CharSequence!> { public constructor RawADerived() - public/*package*/ open override /*1*/ /*fake_override*/ fun bar(/*0*/ d: kotlin.Array<(out) kotlin.Array<(out) kotlin.collections.(Mutable)List<(raw) kotlin.Any?>!>!>!): kotlin.Unit(raw) - public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any(raw)?): kotlin.Boolean(raw) - public/*package*/ open override /*1*/ /*fake_override*/ fun foo(/*0*/ x: kotlin.CharSequence(raw)!, /*1*/ y: kotlin.collections.(Mutable)Map<(raw) kotlin.Any?, (raw) kotlin.Any?>!, /*2*/ z: java.util.HashMap<(raw) kotlin.Any!, (raw) kotlin.Any!>!): A<(raw) kotlin.CharSequence!>! - public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int(raw) - public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String(raw) + public/*package*/ open override /*1*/ /*fake_override*/ fun bar(/*0*/ d: kotlin.Array<(out) kotlin.Array<(out) kotlin.collections.(Mutable)List<(raw) kotlin.Any?>!>!>!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public/*package*/ open override /*1*/ /*fake_override*/ fun foo(/*0*/ x: kotlin.CharSequence!, /*1*/ y: kotlin.collections.(Mutable)Map<(raw) kotlin.Any?, (raw) kotlin.Any?>!, /*2*/ z: java.util.HashMap<(raw) kotlin.Any!, (raw) kotlin.Any!>!): A<(raw) kotlin.CharSequence!>! + 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/diagnostics/tests/platformTypes/rawTypes/rawTypeInUpperBound.kt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawTypeInUpperBound.kt index 2d85a4f0fb2..60dbaee2729 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawTypeInUpperBound.kt +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawTypeInUpperBound.kt @@ -12,6 +12,7 @@ public class A { // FILE: B.java +// TODO: E shoult has supertype A<*> which is raw type public class B { public E foo() { return null;} E field; @@ -26,7 +27,7 @@ public class Test { // FILE: main.kt fun foo(x: B<*>) { - val q: MutableList = x.foo().getChildrenStubs() + val q: MutableList = x.foo().getChildrenStubs() // Raw(B).field erased to A..A? Test.rawB.field = A() diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/typeEnhancement.txt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/typeEnhancement.txt index 7ca576d8847..11f7508fe05 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/typeEnhancement.txt +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/typeEnhancement.txt @@ -17,12 +17,12 @@ public/*package*/ open class Test { public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String - public/*package*/ open class DerivedRawA : A { + public/*package*/ open class DerivedRawA : A<(raw) kotlin.Any!> { public/*package*/ constructor DerivedRawA() - public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any(raw)?): kotlin.Boolean(raw) - @org.jetbrains.annotations.NotNull() public/*package*/ open override /*1*/ /*fake_override*/ fun foo(/*0*/ @org.jetbrains.annotations.NotNull() x: kotlin.Any(raw), /*1*/ @org.jetbrains.annotations.Nullable() y: kotlin.collections.(Mutable)List<(raw) kotlin.Any?>?): kotlin.collections.(Mutable)List<(raw) kotlin.Any?> - public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int(raw) - public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String(raw) + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @org.jetbrains.annotations.NotNull() public/*package*/ open override /*1*/ /*fake_override*/ fun foo(/*0*/ @org.jetbrains.annotations.NotNull() x: kotlin.Any, /*1*/ @org.jetbrains.annotations.Nullable() y: kotlin.collections.(Mutable)List<(raw) kotlin.Any?>?): kotlin.collections.(Mutable)List<(raw) kotlin.Any?> + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } // Static members diff --git a/compiler/testData/loadJava/compiledJava/RawOverrides.txt b/compiler/testData/loadJava/compiledJava/RawOverrides.txt index 225e96e07f7..0f2083fcee3 100644 --- a/compiler/testData/loadJava/compiledJava/RawOverrides.txt +++ b/compiler/testData/loadJava/compiledJava/RawOverrides.txt @@ -7,7 +7,7 @@ public open class RawOverrides { public abstract fun foo(/*0*/ p0: T!, /*1*/ p1: (kotlin.collections.MutableList..kotlin.collections.List?)): E! } - public open inner class B : test.RawOverrides.A { + public open inner class B : test.RawOverrides.A<(raw) kotlin.Any!> { public constructor B() public open override /*1*/ fun foo(/*0*/ p0: kotlin.Any!, /*1*/ p1: kotlin.collections.(Mutable)List<(raw) kotlin.Any?>!): kotlin.String! } diff --git a/compiler/testData/loadJava/compiledJava/annotations/ClassObjectInParamRaw.txt b/compiler/testData/loadJava/compiledJava/annotations/ClassObjectInParamRaw.txt index 9e8d6f2016b..0b7675c3e77 100644 --- a/compiler/testData/loadJava/compiledJava/annotations/ClassObjectInParamRaw.txt +++ b/compiler/testData/loadJava/compiledJava/annotations/ClassObjectInParamRaw.txt @@ -4,9 +4,9 @@ public open class ClassObjectInParamRaw { public constructor ClassObjectInParamRaw() public final annotation class Anno : kotlin.Annotation { - public constructor Anno(/*0*/ value: kotlin.reflect.KClass<*>, /*1*/ arg: kotlin.Array>) - public final val arg: kotlin.Array> - public final val value: kotlin.reflect.KClass<*> + public constructor Anno(/*0*/ value: kotlin.reflect.KClass<(raw) kotlin.Any>, /*1*/ arg: kotlin.Array>) + public final val arg: kotlin.Array> + public final val value: kotlin.reflect.KClass<(raw) kotlin.Any> } @test.ClassObjectInParamRaw.Anno(arg = {}, value = test.ClassObjectInParamRaw::class) public open class Nested { diff --git a/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperType.txt b/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperType.txt index 03ea4b67048..b756eef64f7 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<(raw) 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 diff --git a/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithBound.txt b/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithBound.txt index 4f805869743..c412402517c 100644 --- a/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithBound.txt +++ b/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithBound.txt @@ -6,7 +6,7 @@ public open class RawSuperTypeWithBound { public interface Bound { } - public open inner class Derived : test.RawSuperTypeWithBound.Super { + public open inner class Derived : test.RawSuperTypeWithBound.Super<(raw) test.RawSuperTypeWithBound.Bound!> { public constructor Derived() public open override /*1*/ fun dummy(): kotlin.Unit public open fun foo(/*0*/ p0: kotlin.Any!): kotlin.Unit diff --git a/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBound.txt b/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBound.txt index eacb121b698..71b8e985eaa 100644 --- a/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBound.txt +++ b/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBound.txt @@ -3,7 +3,7 @@ package test public open class RawSuperTypeWithRecursiveBound { public constructor RawSuperTypeWithRecursiveBound() - public open inner class Derived : test.RawSuperTypeWithRecursiveBound.Super!> { + public open inner class Derived : test.RawSuperTypeWithRecursiveBound.Super<(raw) test.RawSuperTypeWithRecursiveBound.Super<*>!> { public constructor Derived() public open override /*1*/ fun dummy(): kotlin.Unit public open fun foo(/*0*/ p0: kotlin.Any!): kotlin.Unit diff --git a/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBoundMultipleParameters.txt b/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBoundMultipleParameters.txt index eb531f53423..01f328fa4fa 100644 --- a/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBoundMultipleParameters.txt +++ b/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBoundMultipleParameters.txt @@ -3,7 +3,7 @@ package test public open class RawSuperTypeWithRecursiveBoundMultipleParameters { public constructor RawSuperTypeWithRecursiveBoundMultipleParameters() - public open inner class Derived : test.RawSuperTypeWithRecursiveBoundMultipleParameters.Super!> { + public open inner class Derived : test.RawSuperTypeWithRecursiveBoundMultipleParameters.Super<(raw) kotlin.Any!, (raw) 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 diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/ErasedOverridabilityCondition.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/ErasedOverridabilityCondition.kt index c1c3174a4ad..43144a4278e 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/ErasedOverridabilityCondition.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/ErasedOverridabilityCondition.kt @@ -18,15 +18,14 @@ package org.jetbrains.kotlin.load.java import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor import org.jetbrains.kotlin.load.java.lazy.types.RawSubstitution +import org.jetbrains.kotlin.load.java.lazy.types.RawTypeImpl import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition.Result import org.jetbrains.kotlin.resolve.OverridingUtil -import org.jetbrains.kotlin.types.RawTypeCapability -import org.jetbrains.kotlin.types.getCapability +import org.jetbrains.kotlin.types.unwrap import org.jetbrains.kotlin.utils.singletonOrEmptyList class ErasedOverridabilityCondition : ExternalOverridabilityCondition { @@ -40,7 +39,7 @@ class ErasedOverridabilityCondition : ExternalOverridabilityCondition { subDescriptor.returnType!! + subDescriptor.extensionReceiverParameter?.type.singletonOrEmptyList() - if (signatureTypes.any { it.arguments.isNotEmpty() && it.getCapability() == null }) return Result.UNKNOWN + if (signatureTypes.any { it.arguments.isNotEmpty() && it.unwrap() !is RawTypeImpl }) return Result.UNKNOWN var erasedSuper = superDescriptor.substitute(RawSubstitution.buildSubstitutor()) ?: return Result.UNKNOWN diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt index d4136221993..aba7ce5472f 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt @@ -138,9 +138,8 @@ class LazyJavaAnnotationDescriptor( val arguments = listOf(TypeProjectionImpl(type)) val javaClassObjectType = object : AbstractLazyType(c.storageManager) { - override fun computeTypeConstructor() = jlClass.getTypeConstructor() + override fun computeTypeConstructor() = jlClass.typeConstructor override fun computeArguments() = arguments - override fun computeMemberScope() = jlClass.getMemberScope(arguments) } return factory.createKClassValue(javaClassObjectType) 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 da53aa8edf9..8f8ef550a2d 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 @@ -54,13 +54,7 @@ class LazyJavaTypeResolver( if (primitiveType != null) c.module.builtIns.getPrimitiveKotlinType(primitiveType) else c.module.builtIns.getUnitType() } - is JavaClassifierType -> - if (attr.allowFlexible && attr.howThisTypeIsUsed != SUPERTYPE) - KotlinTypeFactory.flexibleType( - LazyJavaClassifierType(javaType, attr.toFlexible(FLEXIBLE_LOWER_BOUND)), - LazyJavaClassifierType(javaType, attr.toFlexible(FLEXIBLE_UPPER_BOUND)) - ) - else LazyJavaClassifierType(javaType, attr) + is JavaClassifierType -> transformJavaClassifierType(javaType, attr) is JavaArrayType -> transformArrayType(javaType, attr) // Top level type can be a wildcard only in case of broken Java code, but we should not fail with exceptions in such cases is JavaWildcardType -> javaType.bound?.let { transformJavaType(it, attr) } ?: c.module.builtIns.defaultBound @@ -68,6 +62,27 @@ class LazyJavaTypeResolver( } } + private fun transformJavaClassifierType(javaType: JavaClassifierType, attr: JavaTypeAttributes): KotlinType { + val allowFlexible = attr.allowFlexible && attr.howThisTypeIsUsed != SUPERTYPE + + val lowerAttr = if (allowFlexible) attr.toFlexible(FLEXIBLE_LOWER_BOUND) else attr + val upperAttr = if (allowFlexible) attr.toFlexible(FLEXIBLE_UPPER_BOUND) else attr + + return if (javaType.isRaw) { + RawTypeImpl(LazyJavaClassifierType(javaType, lowerAttr.toRawBound(RawBound.LOWER)), + LazyJavaClassifierType(javaType, upperAttr.toRawBound(RawBound.UPPER))) + } + else if (allowFlexible) { + KotlinTypeFactory.flexibleType( + LazyJavaClassifierType(javaType, lowerAttr), + LazyJavaClassifierType(javaType, upperAttr) + ) + } + else { + LazyJavaClassifierType(javaType, attr) + } + } + fun transformArrayType(arrayType: JavaArrayType, attr: JavaTypeAttributes, isVararg: Boolean = false): KotlinType { return run { val javaComponentType = arrayType.componentType @@ -176,19 +191,18 @@ class LazyJavaTypeResolver( private fun JavaType?.isSuperWildcard(): Boolean = (this as? JavaWildcardType)?.let { it.bound != null && !it.isExtends } ?: false - private fun isRaw(): Boolean { - if (javaType.isRaw) return true + private fun eraseTypeParameters(): Boolean { + if (attr.rawBound != RawBound.NOT_RAW) return true // This option is needed because sometimes we get weird versions of JDK classes in the class path, // such as collections with no generics, so the Java types are not raw, formally, but they don't match with // their Kotlin analogs, so we treat them as raw to avoid exceptions - // No type arguments, but some are expected => raw return javaType.typeArguments.isEmpty() && !constructor.parameters.isEmpty() } override fun computeArguments(): List { val typeParameters = constructor.parameters - if (isRaw()) { + if (eraseTypeParameters()) { return typeParameters.map { parameter -> // Some activity for preventing recursion in cases like `class A` @@ -258,8 +272,6 @@ class LazyJavaTypeResolver( return this != typeParameter.variance } - override val capabilities: TypeCapabilities get() = if (isRaw()) RawTypeCapabilities else TypeCapabilities.NONE - private val nullable = c.storageManager.createLazyValue l@ { if (attr.flexibility == FLEXIBLE_LOWER_BOUND) return@l false if (attr.flexibility == FLEXIBLE_UPPER_BOUND) return@l true @@ -306,6 +318,14 @@ interface JavaTypeAttributes { // Current type is upper bound of this type parameter val upperBoundOfTypeParameter: TypeParameterDescriptor? get() = null + val rawBound: RawBound + get() = RawBound.NOT_RAW +} + +enum class RawBound { + LOWER, + UPPER, + NOT_RAW } enum class JavaTypeFlexibility { @@ -358,6 +378,11 @@ fun JavaTypeAttributes.toFlexible(flexibility: JavaTypeFlexibility) = override val flexibility = flexibility } +fun JavaTypeAttributes.toRawBound(rawBound: RawBound) = + object : JavaTypeAttributes by this { + override val rawBound = rawBound + } + // Definition: // ErasedUpperBound(T : G) = G<*> // UpperBound(T) is a type G with arguments diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/RawType.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/RawType.kt index 95e441e1436..733508b2a0d 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/RawType.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/RawType.kt @@ -19,128 +19,139 @@ package org.jetbrains.kotlin.load.java.lazy.types import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor +import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.load.java.components.TypeUsage import org.jetbrains.kotlin.renderer.DescriptorRenderer +import org.jetbrains.kotlin.renderer.DescriptorRendererOptions import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns +import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.types.* +import org.jetbrains.kotlin.types.checker.KotlinTypeChecker +import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations -object RawTypeCapabilities : TypeCapabilities { +class RawTypeImpl(lowerBound: SimpleType, upperBound: SimpleType) : DelegatingFlexibleType(lowerBound, upperBound), RawType { + init { + assert (KotlinTypeChecker.DEFAULT.isSubtypeOf(lowerBound, upperBound)) { + "Lower bound $lowerBound of a flexible type must be a subtype of the upper bound $upperBound" + } + } + override fun getDelegate(): KotlinType = delegateType - private object Impl : RawTypeCapability { - override val substitution: TypeSubstitution? - get() = RawSubstitution - override val substitutionToComposeWith: TypeSubstitution? - get() = RawSubstitution + override val delegateType: KotlinType get() = lowerBound - private fun DescriptorRenderer.renderArguments(jetType: KotlinType) = jetType.arguments.map { renderTypeProjection(it) } + override val memberScope: MemberScope + get() { + val classDescriptor = constructor.declarationDescriptor as? ClassDescriptor + ?: error("Incorrect classifier: ${constructor.declarationDescriptor}") + return classDescriptor.getMemberScope(RawSubstitution) + } - private fun String.replaceArgs(newArgs: String): String { + override fun replaceAnnotations(newAnnotations: Annotations): KotlinType + = RawTypeImpl(lowerBound.replaceAnnotations(newAnnotations).asSimpleType(), upperBound) + + override fun makeNullableAsSpecified(nullable: Boolean): KotlinType + = RawTypeImpl(TypeUtils.makeNullableAsSpecified(lowerBound, nullable), TypeUtils.makeNullableAsSpecified(upperBound, nullable)) + + override fun render(renderer: DescriptorRenderer, options: DescriptorRendererOptions): String { + fun onlyOutDiffers(first: String, second: String) = first == second.removePrefix("out ") || second == "*" + + fun renderArguments(type: KotlinType) = type.arguments.map { renderer.renderTypeProjection(it) } + + fun String.replaceArgs(newArgs: String): String { if (!contains('<')) return this return "${substringBefore('<')}<$newArgs>${substringAfterLast('>')}" } - override fun renderInflexible(type: KotlinType, renderer: DescriptorRenderer): String? { - if (type.arguments.isNotEmpty()) return null + val lowerRendered = renderer.renderType(lowerBound) + val upperRendered = renderer.renderType(upperBound) - return buildString { - append(renderer.renderTypeConstructor(type.constructor)) - append("(raw)") - if (type.isMarkedNullable) append('?') - } + if (options.debugMode) { + return "raw ($lowerRendered..$upperRendered)" } + if (upperBound.arguments.isEmpty()) return renderer.renderFlexibleType(lowerRendered, upperRendered) - override fun renderBounds(flexibleType: FlexibleType, renderer: DescriptorRenderer): Pair? { - val lowerArgs = renderer.renderArguments(flexibleType.lowerBound) - val upperArgs = renderer.renderArguments(flexibleType.upperBound) - - val lowerRendered = renderer.renderType(flexibleType.lowerBound) - val upperRendered = renderer.renderType(flexibleType.upperBound) - - if (!upperArgs.isNotEmpty()) return null - - val newArgs = lowerArgs.map { "(raw) $it" }.joinToString(", ") - val newUpper = - if (lowerArgs.zip(upperArgs).all { onlyOutDiffers(it.first, it.second) }) - upperRendered.replaceArgs(newArgs) - else upperRendered - return Pair(lowerRendered.replaceArgs(newArgs), newUpper) - } - - private fun onlyOutDiffers(first: String, second: String) = first == second.removePrefix("out ") || second == "*" - } - - override fun getCapability(capabilityClass: Class): T? { - @Suppress("UNCHECKED_CAST") - return when(capabilityClass) { - RawTypeCapability::class.java -> Impl as T - else -> null - } + val lowerArgs = renderArguments(lowerBound) + val upperArgs = renderArguments(upperBound) + val newArgs = lowerArgs.map { "(raw) $it" }.joinToString(", ") + val newUpper = + if (lowerArgs.zip(upperArgs).all { onlyOutDiffers(it.first, it.second) }) + upperRendered.replaceArgs(newArgs) + else upperRendered + val newLower = lowerRendered.replaceArgs(newArgs) + if (newLower == newUpper) return newLower + return renderer.renderFlexibleType(newLower, newUpper) } } internal object RawSubstitution : TypeSubstitution() { override fun get(key: KotlinType) = TypeProjectionImpl(eraseType(key)) - private val lowerTypeAttr = TypeUsage.MEMBER_SIGNATURE_INVARIANT.toAttributes().toFlexible(JavaTypeFlexibility.FLEXIBLE_LOWER_BOUND) - private val upperTypeAttr = TypeUsage.MEMBER_SIGNATURE_INVARIANT.toAttributes().toFlexible(JavaTypeFlexibility.FLEXIBLE_UPPER_BOUND) + private val lowerTypeAttr = TypeUsage.MEMBER_SIGNATURE_INVARIANT.toAttributes().toRawBound(RawBound.LOWER) + private val upperTypeAttr = TypeUsage.MEMBER_SIGNATURE_INVARIANT.toAttributes().toRawBound(RawBound.UPPER) fun eraseType(type: KotlinType): KotlinType { val declaration = type.constructor.declarationDescriptor return when (declaration) { is TypeParameterDescriptor -> eraseType(declaration.getErasedUpperBound()) is ClassDescriptor -> { - val lower = type.lowerIfFlexible() - val upper = type.upperIfFlexible() - KotlinTypeFactory.flexibleType( - eraseInflexibleBasedOnClassDescriptor(lower, declaration, lowerTypeAttr), - eraseInflexibleBasedOnClassDescriptor(upper, declaration, upperTypeAttr) - ) + val (lower, isRawL) = eraseInflexibleBasedOnClassDescriptor(type.lowerIfFlexible(), declaration, lowerTypeAttr) + val (upper, isRawU) = eraseInflexibleBasedOnClassDescriptor(type.upperIfFlexible(), declaration, upperTypeAttr) + + if (isRawL || isRawU) { + RawTypeImpl(lower, upper) + } + else { + KotlinTypeFactory.flexibleType(lower, upper) + } } else -> error("Unexpected declaration kind: $declaration") } } - private fun eraseInflexibleBasedOnClassDescriptor(type: KotlinType, declaration: ClassDescriptor, attr: JavaTypeAttributes): SimpleType { + private fun eraseInflexibleBasedOnClassDescriptor( + type: SimpleType, declaration: ClassDescriptor, attr: JavaTypeAttributes + ): Pair { + if (type.constructor.parameters.isEmpty()) return type to false + if (KotlinBuiltIns.isArray(type)) { val componentTypeProjection = type.arguments[0] val arguments = listOf( TypeProjectionImpl(componentTypeProjection.projectionKind, eraseType(componentTypeProjection.type)) ) - return KotlinTypeFactory.simpleType(type.annotations, type.constructor, arguments, - type.isMarkedNullable, (type.constructor.declarationDescriptor as ClassDescriptor).getMemberScope(arguments) - ) + return KotlinTypeFactory.simpleType( + type.annotations, type.constructor, arguments, type.isMarkedNullable, + declaration.getMemberScope(arguments) + ) to false } - if (type.isError) return ErrorUtils.createErrorType("Raw error type: ${type.constructor}") + if (type.isError) return ErrorUtils.createErrorType("Raw error type: ${type.constructor}") to false - val constructor = type.constructor - return KotlinTypeImpl.create( - type.annotations, constructor, type.isMarkedNullable, + return KotlinTypeFactory.simpleType( + type.annotations, type.constructor, type.constructor.parameters.map { parameter -> computeProjection(parameter, attr) }, - declaration.getMemberScope(RawSubstitution), - RawTypeCapabilities - ) + type.isMarkedNullable, declaration.getMemberScope(RawSubstitution) + ) to true } fun computeProjection( parameter: TypeParameterDescriptor, attr: JavaTypeAttributes, erasedUpperBound: KotlinType = parameter.getErasedUpperBound() - ) = when (attr.flexibility) { + ) = when (attr.rawBound) { // Raw(List) => (List..List<*>) // Raw(Enum) => (Enum>..Enum>) // In the last case upper bound is equal to star projection `Enum<*>`, // but we want to keep matching tree structure of flexible bounds (at least they should have the same size) - JavaTypeFlexibility.FLEXIBLE_LOWER_BOUND -> TypeProjectionImpl( + RawBound.LOWER -> TypeProjectionImpl( // T : String -> String // in T : String -> String // T : Enum -> Enum<*> Variance.INVARIANT, erasedUpperBound ) - JavaTypeFlexibility.FLEXIBLE_UPPER_BOUND, JavaTypeFlexibility.INFLEXIBLE -> { + RawBound.UPPER, RawBound.NOT_RAW -> { if (!parameter.variance.allowsOutPosition) // in T -> Comparable TypeProjectionImpl(Variance.INVARIANT, parameter.builtIns.nothingType) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt index 684ac966c63..218dead893f 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeEnhancement.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations import org.jetbrains.kotlin.load.java.JvmAnnotationNames +import org.jetbrains.kotlin.load.java.lazy.types.RawTypeImpl import org.jetbrains.kotlin.load.java.typeEnhancement.MutabilityQualifier.MUTABLE import org.jetbrains.kotlin.load.java.typeEnhancement.MutabilityQualifier.READ_ONLY import org.jetbrains.kotlin.load.java.typeEnhancement.NullabilityQualifier.NOT_NULL @@ -56,7 +57,7 @@ private data class Result(val type: KotlinType, val subtreeSize: Int, val wereCh } private fun KotlinType.enhancePossiblyFlexible(qualifiers: (Int) -> JavaTypeQualifiers, index: Int): Result { - if (this.isError) return Result(this, 1, false) + if (this.isError || unwrap() is RawTypeImpl) return Result(this, 1, false) // todo: Raw return if (this.isFlexible()) { with(this.asFlexibleType()) { val lowerResult = lowerBound.enhanceInflexible(qualifiers, index, TypeComponentPosition.FLEXIBLE_LOWER) @@ -121,9 +122,7 @@ private fun KotlinType.enhanceInflexible(qualifiers: (Int) -> JavaTypeQualifiers enhancedNullabilityAnnotations ).filterNotNull().compositeAnnotationsOrSingle() - val newSubstitution = computeNewSubstitution( - typeConstructor, enhancedArguments - ) + val newSubstitution = TypeConstructorSubstitution.create(typeConstructor, enhancedArguments) val newCapabilities = if (effectiveQualifiers.isNotNullTypeParameter) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/DeserializationComponentsForJava.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/DeserializationComponentsForJava.kt index dedbe369bca..2d68d28221d 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/DeserializationComponentsForJava.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/DeserializationComponentsForJava.kt @@ -42,7 +42,7 @@ class DeserializationComponentsForJava( components = DeserializationComponents( storageManager, moduleDescriptor, classDataFinder, annotationAndConstantLoader, packageFragmentProvider, localClassResolver, errorReporter, lookupTracker, JavaFlexibleTypeDeserializer, ClassDescriptorFactory.EMPTY, - notFoundClasses, JavaTypeCapabilitiesLoader, + notFoundClasses, additionalClassPartsProvider = settings, platformDependentDeclarationFilter = settings ) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/JavaFlexibleTypeDeserializer.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/JavaFlexibleTypeDeserializer.kt index 4e8ce70e898..1e1a16c279d 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/JavaFlexibleTypeDeserializer.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/JavaFlexibleTypeDeserializer.kt @@ -16,7 +16,10 @@ package org.jetbrains.kotlin.load.kotlin +import org.jetbrains.kotlin.load.java.lazy.types.RawTypeImpl +import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.deserialization.FlexibleTypeDeserializer +import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinTypeFactory @@ -25,8 +28,11 @@ import org.jetbrains.kotlin.types.SimpleType object JavaFlexibleTypeDeserializer : FlexibleTypeDeserializer { val id = "kotlin.jvm.PlatformType" - override fun create(flexibleId: String, lowerBound: SimpleType, upperBound: SimpleType): KotlinType { + override fun create(proto: ProtoBuf.Type, flexibleId: String, lowerBound: SimpleType, upperBound: SimpleType): KotlinType { if (flexibleId != id) return ErrorUtils.createErrorType("Error java flexible type with id: $flexibleId. ($lowerBound..$upperBound)") + if (proto.hasExtension(JvmProtoBuf.isRaw)) { + return RawTypeImpl(lowerBound, upperBound) + } return KotlinTypeFactory.flexibleType(lowerBound, upperBound) } } \ No newline at end of file diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/JavaTypeCapabilitiesLoader.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/JavaTypeCapabilitiesLoader.kt deleted file mode 100644 index 1673a99f5e9..00000000000 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/JavaTypeCapabilitiesLoader.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.kotlin.load.kotlin - -import org.jetbrains.kotlin.load.java.lazy.types.RawTypeCapabilities -import org.jetbrains.kotlin.serialization.ProtoBuf -import org.jetbrains.kotlin.serialization.deserialization.TypeCapabilitiesLoader -import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf -import org.jetbrains.kotlin.types.TypeCapabilities - -object JavaTypeCapabilitiesLoader : TypeCapabilitiesLoader() { - override fun loadCapabilities(type: ProtoBuf.Type): TypeCapabilities = - if (type.hasExtension(JvmProtoBuf.isRaw)) RawTypeCapabilities else TypeCapabilities.NONE -} diff --git a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRenderer.kt b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRenderer.kt index 0bfd02c0f86..57e613ed1a1 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRenderer.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRenderer.kt @@ -38,6 +38,8 @@ abstract class DescriptorRenderer { abstract fun renderType(type: KotlinType): String + abstract fun renderFlexibleType(lowerRendered: String, upperRendered: String): String + abstract fun renderTypeArguments(typeArguments: List): String abstract fun renderTypeProjection(typeProjection: TypeProjection): String @@ -219,8 +221,14 @@ object ExcludedTypeAnnotations { } enum class RenderingFormat { - PLAIN, - HTML + PLAIN { + override fun escape(string: String) = string; + }, + HTML { + override fun escape(string: String) = string.replace("<", "<").replace(">", ">") + }; + + abstract fun escape(string: String): String } enum class OverrideRenderingPolicy { diff --git a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt index c7c9e039083..4b6116308e2 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt @@ -61,12 +61,7 @@ internal class DescriptorRendererImpl( } } - private fun escape(string: String): String { - when (textFormat) { - RenderingFormat.PLAIN -> return string - RenderingFormat.HTML -> return string.replace("<", "<").replace(">", ">") - } - } + private fun escape(string: String) = textFormat.escape(string) private fun lt() = escape("<") private fun gt() = escape(">") @@ -145,32 +140,14 @@ internal class DescriptorRendererImpl( if (type is LazyType && debugMode) { return type.toString() } - if (type.isDynamic()) { - return "dynamic" + val unwrappedType = type.unwrap() + if (unwrappedType is FlexibleType) { + return unwrappedType.render(this, this) } - if (type.isFlexible()) { - if (debugMode) { - return renderFlexibleTypeWithBothBounds(type.asFlexibleType().lowerBound, type.asFlexibleType().upperBound) - } - else { - return renderFlexibleType(type) - } - } - return renderInflexibleType(type) + return renderSimpleType(unwrappedType.asSimpleType()) } - private fun renderFlexibleTypeWithBothBounds(lower: KotlinType, upper: KotlinType): String { - return renderFlexibleTypeWithBothBounds(renderNormalizedType(lower), renderNormalizedType(upper)) - } - - private fun renderFlexibleTypeWithBothBounds(lower: String, upper: String) = "($lower..$upper)" - - private fun renderInflexibleType(type: KotlinType): String { - assert(!type.isFlexible()) { "Flexible types not allowed here: " + renderNormalizedType(type) } - - val customResult = type.getCapability()?.renderInflexible(type, this) - if (customResult != null) return customResult - + private fun renderSimpleType(type: SimpleType): String { if (type == CANT_INFER_FUNCTION_PARAM_TYPE || TypeUtils.isDontCarePlaceholder(type)) { return "???" } @@ -193,23 +170,16 @@ internal class DescriptorRendererImpl( return type.isFunctionType && type.arguments.none { it.isStarProjection } } - private fun renderFlexibleType(type: KotlinType): String { - val lower = type.asFlexibleType().lowerBound - val upper = type.asFlexibleType().upperBound - - val (lowerRendered, upperRendered) = type.getCapability()?.renderBounds(type.asFlexibleType(), this) - ?: Pair(renderInflexibleType(lower), renderInflexibleType(upper)) - + override fun renderFlexibleType(lowerRendered: String, upperRendered: String): String { if (differsOnlyInNullability(lowerRendered, upperRendered)) { if (upperRendered.startsWith("(")) { // the case of complex type, e.g. (() -> Unit)? - return "(" + lowerRendered + ")!" + return "($lowerRendered)!" } return lowerRendered + "!" } - - val kotlinCollectionsPrefix = classifierNamePolicy.renderClassifier(type.builtIns.collection, this).substringBefore("Collection") + val kotlinCollectionsPrefix = classifierNamePolicy.renderClassifier(DefaultBuiltIns.Instance.collection, this).substringBefore("Collection") val mutablePrefix = "Mutable" // java.util.List -> (Mutable)List! val simpleCollection = replacePrefixes(lowerRendered, kotlinCollectionsPrefix + mutablePrefix, upperRendered, kotlinCollectionsPrefix, kotlinCollectionsPrefix + "(" + mutablePrefix + ")") @@ -218,11 +188,12 @@ internal class DescriptorRendererImpl( val mutableEntry = replacePrefixes(lowerRendered, kotlinCollectionsPrefix + "MutableMap.MutableEntry", upperRendered, kotlinCollectionsPrefix + "Map.Entry", kotlinCollectionsPrefix + "(Mutable)Map.(Mutable)Entry") if (mutableEntry != null) return mutableEntry - val kotlinPrefix = classifierNamePolicy.renderClassifier(type.builtIns.array, this).substringBefore("Array") + val kotlinPrefix = classifierNamePolicy.renderClassifier(DefaultBuiltIns.Instance.array, this).substringBefore("Array") // Foo[] -> Array<(out) Foo!>! val array = replacePrefixes(lowerRendered, kotlinPrefix + escape("Array<"), upperRendered, kotlinPrefix + escape("Array): String { diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/AbstractLazyType.kt b/core/descriptors/src/org/jetbrains/kotlin/types/AbstractLazyType.kt index 845a39923ca..8e57b6fb41b 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/AbstractLazyType.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/AbstractLazyType.kt @@ -37,15 +37,11 @@ abstract class AbstractLazyType(storageManager: StorageManager) : AbstractKotlin override val memberScope by storageManager.createLazyValue { computeMemberScope() } - protected open fun computeMemberScope(): MemberScope { + fun computeMemberScope(): MemberScope { val descriptor = constructor.declarationDescriptor return when (descriptor) { is TypeParameterDescriptor -> descriptor.getDefaultType().memberScope - is ClassDescriptor -> { - val substitution = getCapability()?.substitution - ?: TypeConstructorSubstitution.create(constructor, arguments) - descriptor.getMemberScope(substitution) - } + is ClassDescriptor -> descriptor.getMemberScope(TypeConstructorSubstitution.create(constructor, arguments)) else -> throw IllegalStateException("Unsupported classifier: $descriptor") } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/RawTypeCapability.kt b/core/descriptors/src/org/jetbrains/kotlin/types/RawType.kt similarity index 62% rename from core/descriptors/src/org/jetbrains/kotlin/types/RawTypeCapability.kt rename to core/descriptors/src/org/jetbrains/kotlin/types/RawType.kt index ca1605b8301..3dda769ef24 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/RawTypeCapability.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/RawType.kt @@ -16,14 +16,4 @@ package org.jetbrains.kotlin.types -import org.jetbrains.kotlin.renderer.DescriptorRenderer - -interface RawTypeCapability : TypeCapability { - - val substitution: TypeSubstitution? - val substitutionToComposeWith: TypeSubstitution? - - fun renderInflexible(type: KotlinType, renderer: DescriptorRenderer): String? - fun renderBounds(flexibleType: FlexibleType, renderer: DescriptorRenderer): Pair? - -} \ No newline at end of file +interface RawType \ No newline at end of file diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitution.kt b/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitution.kt index 133fdd28acd..716db20f361 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitution.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitution.kt @@ -113,19 +113,6 @@ class IndexedParametersSubstitution( } } -fun KotlinType.computeNewSubstitution( - typeConstructor: TypeConstructor, - newArguments: List -): TypeSubstitution { - val newSubstitution = TypeConstructorSubstitution.create(typeConstructor, newArguments) - - // If previous substitution was trivial just replace it with indexed one - val substitutionToComposeWith = getCapability()?.substitutionToComposeWith ?: return newSubstitution - val composedSubstitution = CompositeTypeSubstitution(newSubstitution, substitutionToComposeWith) - - return composedSubstitution -} - @JvmOverloads fun KotlinType.replace( newArguments: List = arguments, @@ -145,7 +132,7 @@ fun KotlinType.replace( ) } - val newSubstitution = computeNewSubstitution(constructor, newArguments) + val newSubstitution = TypeConstructorSubstitution.create(constructor, newArguments) val declarationDescriptor = constructor.declarationDescriptor val newScope = @@ -163,27 +150,6 @@ fun KotlinType.replace( ) } -private class CompositeTypeSubstitution( - private val first: TypeSubstitution, - private val second: TypeSubstitution -) : TypeSubstitution() { - - override fun get(key: KotlinType): TypeProjection? { - val firstResult = first[key] ?: return second[key] - return second.buildSubstitutor().substitute(firstResult) - } - - override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) = - second.prepareTopLevelType(first.prepareTopLevelType(topLevelType, position), position) - - override fun isEmpty() = first.isEmpty() && second.isEmpty() - - override fun approximateCapturedTypes() = first.approximateCapturedTypes() || second.approximateCapturedTypes() - override fun approximateContravariantCapturedTypes() = first.approximateContravariantCapturedTypes() || second.approximateContravariantCapturedTypes() - - override fun filterAnnotations(annotations: Annotations): Annotations = second.filterAnnotations(first.filterAnnotations(annotations)) -} - open class DelegatedTypeSubstitution(val substitution: TypeSubstitution): TypeSubstitution() { override fun get(key: KotlinType) = substitution[key] override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) = substitution.prepareTopLevelType(topLevelType, position) diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java b/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java index 00fe26b2e2f..5e48c3d7154 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java @@ -133,7 +133,7 @@ public class TypeSubstitutor { // The type is within the substitution range, i.e. T or T? KotlinType type = originalProjection.getType(); - if (DynamicTypesKt.isDynamic(type)) { + if (DynamicTypesKt.isDynamic(type) || KotlinTypeKt.unwrap(type) instanceof RawType) { return originalProjection; // todo investigate } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt index ef7cb64ee06..b6a7a62252a 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt @@ -157,26 +157,22 @@ fun KotlinType.asTypeProjection(): TypeProjection = TypeProjectionImpl(this) fun KotlinType.contains(predicate: (KotlinType) -> Boolean) = TypeUtils.contains(this, predicate) fun KotlinType.replaceArgumentsWithStarProjections(): KotlinType { - if (constructor.parameters.isEmpty() || constructor.declarationDescriptor == null) return this - - // We could just create JetTypeImpl with current type constructor and star projections, - // but we want to preserve flexibility of type, and that it what TypeSubstitutor does - return TypeSubstitutor.create(ConstantStarSubstitution).substitute(this, Variance.INVARIANT)!! -} - -private object ConstantStarSubstitution : TypeSubstitution() { - override fun get(key: KotlinType): TypeProjection? { - // Let substitutor deal with flexibility - if (key.isFlexible()) return null - - val newProjections = key.constructor.parameters.map(::StarProjectionImpl) - - val substitution = TypeConstructorSubstitution.create(key.constructor, newProjections) - - return TypeProjectionImpl( - TypeSubstitutor.create(substitution).substitute(key.constructor.declarationDescriptor!!.defaultType, Variance.INVARIANT)!! + val unwrapped = unwrap() + if (unwrapped is FlexibleType) { + return KotlinTypeFactory.flexibleType( + unwrapped.lowerBound.replaceArgumentsWithStarProjections(), + unwrapped.upperBound.replaceArgumentsWithStarProjections() ) } - - override fun isEmpty() = false + else { + return asSimpleType().replaceArgumentsWithStarProjections() + } +} + +private fun SimpleType.replaceArgumentsWithStarProjections(): SimpleType { + if (constructor.parameters.isEmpty() || constructor.declarationDescriptor == null) return this + + val newArguments = constructor.parameters.map(::StarProjectionImpl) + + return replace(newArguments).asSimpleType() } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/dynamicTypes.kt b/core/descriptors/src/org/jetbrains/kotlin/types/dynamicTypes.kt index b0e3983b089..d5f3d1b8a14 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/dynamicTypes.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/dynamicTypes.kt @@ -18,7 +18,8 @@ package org.jetbrains.kotlin.types import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.annotations.Annotations -import org.jetbrains.kotlin.types.checker.KotlinTypeChecker +import org.jetbrains.kotlin.renderer.DescriptorRenderer +import org.jetbrains.kotlin.renderer.DescriptorRendererOptions import org.jetbrains.kotlin.types.typeUtil.builtIns open class DynamicTypesSettings { @@ -46,4 +47,6 @@ class DynamicType(builtIns: KotlinBuiltIns, override val annotations: Annotation override val isMarkedNullable: Boolean get() = false override fun replaceAnnotations(newAnnotations: Annotations): KotlinType = DynamicType(delegateType.builtIns, annotations) + + override fun render(renderer: DescriptorRenderer, options: DescriptorRendererOptions): String = "dynamic" } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/flexibleTypes.kt b/core/descriptors/src/org/jetbrains/kotlin/types/flexibleTypes.kt index a2d822014e6..973f6be84ed 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/flexibleTypes.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/flexibleTypes.kt @@ -18,6 +18,8 @@ package org.jetbrains.kotlin.types import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.renderer.DescriptorRenderer +import org.jetbrains.kotlin.renderer.DescriptorRendererOptions import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations @@ -33,6 +35,8 @@ interface FlexibleType : SubtypingRepresentatives, TypeWithCustomReplacement { get() = upperBound override fun sameTypeConstructor(type: KotlinType) = false + + fun render(renderer: DescriptorRenderer, options: DescriptorRendererOptions): String } fun KotlinType.isFlexible(): Boolean = unwrap() is FlexibleType @@ -115,7 +119,7 @@ abstract class DelegatingFlexibleType protected constructor( return KotlinTypeFactory.flexibleType(TypeUtils.makeNullableAsSpecified(lowerBound, nullable), TypeUtils.makeNullableAsSpecified(upperBound, nullable)) } - final override fun getDelegate(): KotlinType { + override fun getDelegate(): KotlinType { runAssertions() return delegateType } @@ -149,4 +153,11 @@ class FlexibleTypeImpl(lowerBound: SimpleType, upperBound: SimpleType) : Delegat override fun replaceAnnotations(newAnnotations: Annotations): KotlinType = KotlinTypeFactory.flexibleType(lowerBound.replaceAnnotations(newAnnotations).asSimpleType(), upperBound) + + override fun render(renderer: DescriptorRenderer, options: DescriptorRendererOptions): String { + if (options.debugMode) { + return "(${renderer.renderType(lowerBound)}..${renderer.renderType(upperBound)})" + } + return renderer.renderFlexibleType(renderer.renderType(lowerBound), renderer.renderType(upperBound)) + } } diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedType.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedType.kt index fe2fc06b376..7073609f4d2 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedType.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedType.kt @@ -56,15 +56,9 @@ class DeserializedType( override val capabilities: TypeCapabilities get() = typeCapabilities() private val typeCapabilities = c.storageManager.createLazyValue { - val deserializedCapabilities = c.components.typeCapabilitiesLoader.loadCapabilities(typeProto) + val abbreviatedTypeProto = typeProto.abbreviatedType(c.typeTable) ?: return@createLazyValue TypeCapabilities.NONE - val abbreviatedTypeProto = typeProto.abbreviatedType(c.typeTable) - if (abbreviatedTypeProto == null) { - deserializedCapabilities - } - else { - val abbreviatedType = c.typeDeserializer.type(abbreviatedTypeProto, additionalAnnotations) - deserializedCapabilities.withAbbreviatedType(abbreviatedType) - } + val abbreviatedType = c.typeDeserializer.type(abbreviatedTypeProto, additionalAnnotations) + TypeCapabilities.NONE.withAbbreviatedType(abbreviatedType) } } diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/FlexibleTypeDeserializer.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/FlexibleTypeDeserializer.kt index 99248aadfaa..068e4855b17 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/FlexibleTypeDeserializer.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/FlexibleTypeDeserializer.kt @@ -16,15 +16,16 @@ package org.jetbrains.kotlin.serialization.deserialization +import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.SimpleType interface FlexibleTypeDeserializer { - fun create(flexibleId: String, lowerBound: SimpleType, upperBound: SimpleType): KotlinType + fun create(proto: ProtoBuf.Type, flexibleId: String, lowerBound: SimpleType, upperBound: SimpleType): KotlinType object ThrowException : FlexibleTypeDeserializer { private fun error(): Nothing = throw IllegalArgumentException("This factory should not be used.") - override fun create(flexibleId: String, lowerBound: SimpleType, upperBound: SimpleType): KotlinType = error() + override fun create(proto: ProtoBuf.Type, flexibleId: String, lowerBound: SimpleType, upperBound: SimpleType): KotlinType = error() } } diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeCapabilitiesLoader.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeCapabilitiesLoader.kt deleted file mode 100644 index fbb98d76123..00000000000 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeCapabilitiesLoader.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.kotlin.serialization.deserialization - -import org.jetbrains.kotlin.serialization.ProtoBuf -import org.jetbrains.kotlin.types.TypeCapabilities - -abstract class TypeCapabilitiesLoader { - object NONE : TypeCapabilitiesLoader() { - override fun loadCapabilities(type: ProtoBuf.Type): TypeCapabilities = TypeCapabilities.NONE - } - - abstract fun loadCapabilities(type: ProtoBuf.Type): TypeCapabilities -} diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt index 215a272b6b2..262b1163ade 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt @@ -58,7 +58,9 @@ class TypeDeserializer( fun type(proto: ProtoBuf.Type, additionalAnnotations: Annotations = Annotations.EMPTY): KotlinType { if (proto.hasFlexibleTypeCapabilitiesId()) { val id = c.nameResolver.getString(proto.flexibleTypeCapabilitiesId) - return c.components.flexibleTypeDeserializer.create(id, DeserializedType(c, proto), DeserializedType(c, proto.flexibleUpperBound(c.typeTable)!!)) + val lowerBound = DeserializedType(c, proto, additionalAnnotations) + val upperBound = DeserializedType(c, proto.flexibleUpperBound(c.typeTable)!!, additionalAnnotations) + return c.components.flexibleTypeDeserializer.create(proto, id, lowerBound, upperBound) } return DeserializedType(c, proto, additionalAnnotations) diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/context.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/context.kt index fa144b4cf07..6d3f0bed03e 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/context.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/context.kt @@ -37,7 +37,6 @@ class DeserializationComponents( val flexibleTypeDeserializer: FlexibleTypeDeserializer, val fictitiousClassDescriptorFactory: ClassDescriptorFactory, val notFoundClasses: NotFoundClasses, - val typeCapabilitiesLoader: TypeCapabilitiesLoader = TypeCapabilitiesLoader.NONE, val additionalClassPartsProvider: AdditionalClassPartsProvider = AdditionalClassPartsProvider.None, val platformDependentDeclarationFilter: PlatformDependentDeclarationFilter = PlatformDependentDeclarationFilter.All ) { diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/DynamicTypeDeserializer.kt b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/DynamicTypeDeserializer.kt index 052961f68cb..c3a24b123ee 100644 --- a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/DynamicTypeDeserializer.kt +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/DynamicTypeDeserializer.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.serialization.js +import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.deserialization.FlexibleTypeDeserializer import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.KotlinType @@ -27,7 +28,7 @@ import org.jetbrains.kotlin.types.typeUtil.builtIns object DynamicTypeDeserializer : FlexibleTypeDeserializer { val id = "kotlin.DynamicType" - override fun create(flexibleId: String, lowerBound: SimpleType, upperBound: SimpleType): KotlinType { + override fun create(proto: ProtoBuf.Type, flexibleId: String, lowerBound: SimpleType, upperBound: SimpleType): KotlinType { if (flexibleId != id) return ErrorUtils.createErrorType("Unexpected id: $flexibleId. ($lowerBound..$upperBound)") if (KotlinTypeChecker.FLEXIBLE_UNEQUAL_TO_INFLEXIBLE.equalTypes(lowerBound, lowerBound.builtIns.nothingType) && KotlinTypeChecker.FLEXIBLE_UNEQUAL_TO_INFLEXIBLE.equalTypes(upperBound, upperBound.builtIns.nullableAnyType)) {