Remake Raw type representation.

(cherry picked from commit b21cede)
This commit is contained in:
Stanislav Erokhin
2016-05-31 16:22:33 +03:00
parent 04e97f5058
commit 203c4cd94d
42 changed files with 277 additions and 354 deletions
@@ -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
@@ -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<RawTypeCapability>() != null) return
if (expectedType.unwrap() is RawTypeImpl) return
val correspondingSubType = TypeCheckingProcedure.findCorrespondingSupertype(expressionTypeWithSmartCast, lowerBound) ?: return
@@ -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
}
@@ -9,11 +9,11 @@ public interface A</*0*/ T : kotlin.Any!> {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface B : A<kotlin.Any!> {
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?>): 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 {
@@ -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<kotlin.CharSequence!, kotlin.Any!> {
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
@@ -8,10 +8,10 @@ public open class A</*0*/ T : kotlin.Any!> {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public open class B : A<kotlin.Any!> {
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
}
@@ -29,7 +29,6 @@ val strList: List<String> = 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(<!TYPE_MISMATCH(\(Mutable\)List<Double!>!; List<String>)!>strList<!>)
}
@@ -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<kotlin.Any!> {
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
@@ -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 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
@@ -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<kotlin.Any!> {
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
}
}
@@ -12,46 +12,46 @@ public open class A</*0*/ T : kotlin.CharSequence!> {
public final class B1 : RawADerived {
public constructor B1()
protected open override /*1*/ fun bar(/*0*/ d: kotlin.Array<kotlin.Array<kotlin.collections.List<*>>>): 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<kotlin.Any?, kotlin.Any?>, /*2*/ z: java.util.HashMap<kotlin.Any, kotlin.Any>): 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.Array<kotlin.collections.MutableList<*>>>): 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<kotlin.Any?, kotlin.Any?>, /*2*/ z: java.util.HashMap<kotlin.Any?, kotlin.Any?>): A<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 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<kotlin.Any?, kotlin.Any>, /*2*/ z: java.util.HashMap<kotlin.Any, kotlin.Any>): 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.Array<kotlin.collections.MutableList<kotlin.Array<kotlin.Double>>>>): 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<kotlin.CharSequence!> {
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
}
@@ -12,6 +12,7 @@ public class A<T> {
// FILE: B.java
// TODO: E shoult has supertype A<*> which is raw type
public class B<E extends A> {
public E foo() { return null;}
E field;
@@ -26,7 +27,7 @@ public class Test {
// FILE: main.kt
fun foo(x: B<*>) {
val q: MutableList<String> = <!TYPE_MISMATCH!>x.foo().getChildrenStubs()<!>
val q: MutableList<String> = x.foo().getChildrenStubs()
// Raw(B).field erased to A<Any!>..A<out Any!>?
Test.rawB.field = A<String>()
@@ -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<kotlin.Any!> {
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
+1 -1
View File
@@ -7,7 +7,7 @@ public open class RawOverrides {
public abstract fun </*0*/ E : kotlin.CharSequence!> foo(/*0*/ p0: T!, /*1*/ p1: (kotlin.collections.MutableList<out T!>..kotlin.collections.List<T!>?)): E!
}
public open inner class B : test.RawOverrides.A<kotlin.Any!> {
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!
}
@@ -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<kotlin.reflect.KClass<*>>)
public final val arg: kotlin.Array<kotlin.reflect.KClass<*>>
public final val value: kotlin.reflect.KClass<*>
public constructor Anno(/*0*/ value: kotlin.reflect.KClass<(raw) kotlin.Any>, /*1*/ arg: kotlin.Array<kotlin.reflect.KClass<(raw) kotlin.Any>>)
public final val arg: kotlin.Array<kotlin.reflect.KClass<(raw) kotlin.Any>>
public final val value: kotlin.reflect.KClass<(raw) kotlin.Any>
}
@test.ClassObjectInParamRaw.Anno(arg = {}, value = test.ClassObjectInParamRaw::class) public open class Nested {
@@ -3,7 +3,7 @@ package test
public open class RawSuperType {
public constructor RawSuperType()
public open inner class Derived : test.RawSuperType.Super<kotlin.Any!> {
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
@@ -6,7 +6,7 @@ public open class RawSuperTypeWithBound {
public interface Bound {
}
public open inner class Derived : test.RawSuperTypeWithBound.Super<test.RawSuperTypeWithBound.Bound!> {
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
@@ -3,7 +3,7 @@ package test
public open class RawSuperTypeWithRecursiveBound {
public constructor RawSuperTypeWithRecursiveBound()
public open inner class Derived : test.RawSuperTypeWithRecursiveBound.Super<out 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
@@ -3,7 +3,7 @@ package test
public open class RawSuperTypeWithRecursiveBoundMultipleParameters {
public constructor RawSuperTypeWithRecursiveBoundMultipleParameters()
public open inner class Derived : test.RawSuperTypeWithRecursiveBoundMultipleParameters.Super<kotlin.Any!, out 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
@@ -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<RawTypeCapability>() == 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
@@ -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)
@@ -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<TypeProjection> {
val typeParameters = constructor.parameters
if (isRaw()) {
if (eraseTypeParameters()) {
return typeParameters.map {
parameter ->
// Some activity for preventing recursion in cases like `class A<T extends A, F extends T>`
@@ -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<t>) = G<*> // UpperBound(T) is a type G<t> with arguments
@@ -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<String, String>? {
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 <T : TypeCapability> getCapability(capabilityClass: Class<T>): 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<SimpleType, Boolean> {
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<T>) => (List<Any?>..List<*>)
// Raw(Enum<T>) => (Enum<Enum<*>>..Enum<out 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<T> -> Enum<*>
Variance.INVARIANT, erasedUpperBound
)
JavaTypeFlexibility.FLEXIBLE_UPPER_BOUND, JavaTypeFlexibility.INFLEXIBLE -> {
RawBound.UPPER, RawBound.NOT_RAW -> {
if (!parameter.variance.allowsOutPosition)
// in T -> Comparable<Nothing>
TypeProjectionImpl(Variance.INVARIANT, parameter.builtIns.nothingType)
@@ -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)
@@ -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
)
@@ -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)
}
}
@@ -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
}
@@ -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<TypeProjection>): 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("<", "&lt;").replace(">", "&gt;")
};
abstract fun escape(string: String): String
}
enum class OverrideRenderingPolicy {
@@ -61,12 +61,7 @@ internal class DescriptorRendererImpl(
}
}
private fun escape(string: String): String {
when (textFormat) {
RenderingFormat.PLAIN -> return string
RenderingFormat.HTML -> return string.replace("<", "&lt;").replace(">", "&gt;")
}
}
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<RawTypeCapability>()?.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<RawTypeCapability>()?.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<Foo> -> (Mutable)List<Foo!>!
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<out "), kotlinPrefix + escape("Array<(out) "))
if (array != null) return array
return renderFlexibleTypeWithBothBounds(lowerRendered, upperRendered)
return "($lowerRendered..$upperRendered)"
}
override fun renderTypeArguments(typeArguments: List<TypeProjection>): String {
@@ -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<RawTypeCapability>()?.substitution
?: TypeConstructorSubstitution.create(constructor, arguments)
descriptor.getMemberScope(substitution)
}
is ClassDescriptor -> descriptor.getMemberScope(TypeConstructorSubstitution.create(constructor, arguments))
else -> throw IllegalStateException("Unsupported classifier: $descriptor")
}
}
@@ -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<String, String>?
}
interface RawType
@@ -113,19 +113,6 @@ class IndexedParametersSubstitution(
}
}
fun KotlinType.computeNewSubstitution(
typeConstructor: TypeConstructor,
newArguments: List<TypeProjection>
): TypeSubstitution {
val newSubstitution = TypeConstructorSubstitution.create(typeConstructor, newArguments)
// If previous substitution was trivial just replace it with indexed one
val substitutionToComposeWith = getCapability<RawTypeCapability>()?.substitutionToComposeWith ?: return newSubstitution
val composedSubstitution = CompositeTypeSubstitution(newSubstitution, substitutionToComposeWith)
return composedSubstitution
}
@JvmOverloads
fun KotlinType.replace(
newArguments: List<TypeProjection> = 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)
@@ -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
}
@@ -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()
}
@@ -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"
}
@@ -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))
}
}
@@ -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)
}
}
@@ -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()
}
}
@@ -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
}
@@ -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)
@@ -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
) {
@@ -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)) {