diff --git a/compiler/testData/diagnostics/tests/generics/PseudoRawTypes.txt b/compiler/testData/diagnostics/tests/generics/PseudoRawTypes.txt index 8fe1643c420..7d4a2f3af53 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.(Mutable)Collection<*>!): kotlin.Unit + public/*package*/ open fun foo(/*0*/ c: (kotlin.MutableCollection..kotlin.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/j+k/overrideRawType.txt b/compiler/testData/diagnostics/tests/j+k/overrideRawType.txt index 317e11460ef..61ceeb7aa21 100644 --- a/compiler/testData/diagnostics/tests/j+k/overrideRawType.txt +++ b/compiler/testData/diagnostics/tests/j+k/overrideRawType.txt @@ -1,10 +1,10 @@ package -public /*synthesized*/ fun Bar(/*0*/ function: (Foo<*>!) -> kotlin.Unit): Bar +public /*synthesized*/ fun Bar(/*0*/ function: ((Foo..Foo<*>?)) -> kotlin.Unit): Bar public interface Bar { public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean - public abstract fun f(/*0*/ f: Foo<*>!): kotlin.Unit + public abstract fun f(/*0*/ f: (Foo..Foo<*>?)): kotlin.Unit public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } diff --git a/compiler/testData/diagnostics/tests/j+k/recursiveRawUpperBound.txt b/compiler/testData/diagnostics/tests/j+k/recursiveRawUpperBound.txt index 585148de949..29312aec310 100644 --- a/compiler/testData/diagnostics/tests/j+k/recursiveRawUpperBound.txt +++ b/compiler/testData/diagnostics/tests/j+k/recursiveRawUpperBound.txt @@ -1,9 +1,9 @@ package -internal fun foo(/*0*/ p: X): Bad<*>! +internal fun foo(/*0*/ p: X): (Bad<(Bad!>..Bad!>?)>..Bad!>..Bad!>?)>?) -public/*package*/ open class Bad!> { - public/*package*/ constructor Bad!>() +public/*package*/ open class Bad>..Bad>?)> { + public/*package*/ constructor Bad>..Bad>?)>() 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 @@ -12,7 +12,7 @@ public/*package*/ open class Bad!> { public/*package*/ open class X { public/*package*/ constructor X() public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean - public/*package*/ open fun foo(): Bad<*>! + public/*package*/ open fun foo(): (Bad<(Bad!>..Bad!>?)>..Bad!>..Bad!>?)>?) 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/arrays.kt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/arrays.kt new file mode 100644 index 00000000000..6367d8dad3f --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/arrays.kt @@ -0,0 +1,43 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE +// FILE: A.java + +import java.util.*; + +public class A { + T[] charSequences; + Map[] maps; + List[][] arraysOfLists; + E[][] arraysOfAny; + + List[] erasedLists; +} + +// FILE: Test.java + +class Test { + static class RawADerived extends A {} + static A rawAField = null; +} + +// FILE: main.kt + +fun arrayOf(): Array = null!! + +fun main() { + val raw = Test.rawAField + + raw.charSequences = arrayOf() + raw.charSequences = arrayOf() + + raw.maps = arrayOf>() + raw.maps = arrayOf>() + raw.maps = arrayOf>() + + raw.arraysOfLists = arrayOf>>() + raw.arraysOfLists = arrayOf>() + raw.arraysOfLists = arrayOf>>() + + raw.arraysOfAny = arrayOf>>() + + raw.erasedLists = arrayOf>() +} diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/arrays.txt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/arrays.txt new file mode 100644 index 00000000000..9716b5f35a4 --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/arrays.txt @@ -0,0 +1,38 @@ +package + +internal fun arrayOf(): kotlin.Array +internal fun main(): kotlin.Unit + +public open class A { + public constructor A() + public/*package*/ final var arraysOfAny: kotlin.Array<(out) kotlin.Array<(out) E!>!>! + public/*package*/ final var arraysOfLists: kotlin.Array<(out) kotlin.Array<(out) kotlin.(Mutable)List!>!>! + public/*package*/ final var charSequences: kotlin.Array<(out) T!>! + public/*package*/ final var erasedLists: kotlin.Array<(out) kotlin.(Mutable)List!>!>! + public/*package*/ final var maps: kotlin.Array<(out) kotlin.(Mutable)Map!>! + 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 +} + +public/*package*/ open class Test { + public/*package*/ constructor Test() + 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 + + public/*package*/ open class RawADerived : A { + public/*package*/ constructor RawADerived() + 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.MutableList..kotlin.List<*>?)>!>! + 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.MutableList..kotlin.List<*>?)>! + public/*package*/ final override /*1*/ /*fake_override*/ var maps: kotlin.Array<(out) (kotlin.MutableMap..kotlin.Map<*, *>?)>! + 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 + public/*package*/ final var rawAField: (A..A<*, *>?) +} diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/genericInnerClass.kt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/genericInnerClass.kt new file mode 100644 index 00000000000..566dbd6be6d --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/genericInnerClass.kt @@ -0,0 +1,34 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE +// FILE: A.java + +import java.util.*; + +class A { + + void foo(T x) + + public class Inner { + Inner(E x0, T x, List y) {} + + void foo(E x0, T x, List y) {} + A> bar() {} + } +} + +// FILE: Test.java + +class Test { + static A rawAField = null; +} + +// FILE: main.kt + +val strList: List = null!! + +fun main() { + val rawA = Test.rawAField + var rawInner = rawA.Inner("", "", strList) + rawInner.foo("", "", strList) + rawInner.bar().foo("") +} + diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/genericInnerClass.txt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/genericInnerClass.txt new file mode 100644 index 00000000000..d7821979dcb --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/genericInnerClass.txt @@ -0,0 +1,31 @@ +package + +internal val strList: kotlin.List +internal fun main(): kotlin.Unit + +public/*package*/ open class A { + public/*package*/ constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public/*package*/ open fun foo(/*0*/ x: T!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public open inner class Inner { + public/*package*/ constructor Inner(/*0*/ x0: E!, /*1*/ x: T!, /*2*/ y: kotlin.(Mutable)List!) + public/*package*/ open fun bar(): A!>! + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public/*package*/ open fun foo(/*0*/ x0: E!, /*1*/ x: T!, /*2*/ y: kotlin.(Mutable)List!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +public/*package*/ open class Test { + public/*package*/ constructor Test() + 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 + public/*package*/ final var rawAField: (A..A<*>?) +} diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonGenericRawMember.kt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonGenericRawMember.kt new file mode 100644 index 00000000000..d4ab71e0501 --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonGenericRawMember.kt @@ -0,0 +1,34 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE +// FILE: A.java + +import java.util.*; + +class A { + B b; +} + +// FILE: B.java + +import java.util.*; + +class B { + void bar(List x); +} + +// FILE: Test.java + +class Test { + static A rawAField = null; +} + + +// FILE: main.kt + +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) +} diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonGenericRawMember.txt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonGenericRawMember.txt new file mode 100644 index 00000000000..0bc70cf0f40 --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonGenericRawMember.txt @@ -0,0 +1,30 @@ +package + +internal val strList: kotlin.List +internal fun main(): kotlin.Unit + +public/*package*/ open class A { + public/*package*/ constructor A() + public/*package*/ final 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 +} + +public/*package*/ open class B { + public/*package*/ constructor B() + public/*package*/ open fun bar(/*0*/ x: kotlin.(Mutable)List!): kotlin.Unit + 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 +} + +public/*package*/ open class Test { + public/*package*/ constructor Test() + 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 + public/*package*/ final var rawAField: (A..A<*>?) +} diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonTrivialErasure.kt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonTrivialErasure.kt new file mode 100644 index 00000000000..a9959a962a5 --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonTrivialErasure.kt @@ -0,0 +1,29 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE +// FILE: A.java + +import java.util.*; + +class A, E extends T, F extends List> { + T first; + E second; + F listOfDoubles; +} + +// FILE: Test.java + +class Test { + static class DerivedRawA extends A {} + static A rawAField = null; +} + +// FILE: main.kt +val strList: List = null!! + +fun main() { + val rawA = Test.rawAField + rawA.first = Test.rawAField.second + Test.rawAField.second = rawA.first.second + + rawA.listOfDoubles = strList + rawA.listOfDoubles = "" // first should be List +} diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonTrivialErasure.txt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonTrivialErasure.txt new file mode 100644 index 00000000000..c29fa568548 --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonTrivialErasure.txt @@ -0,0 +1,34 @@ +package + +internal val strList: kotlin.List +internal fun main(): kotlin.Unit + +public/*package*/ open class A, A<*, *, *>, kotlin.(Mutable)List<*>!>..A, out A<*, *, *>, out kotlin.(Mutable)List<*>!>?), /*1*/ E : T!, /*2*/ F : (kotlin.MutableList..kotlin.List?)> { + public/*package*/ constructor A, A<*, *, *>, kotlin.(Mutable)List<*>!>..A, out A<*, *, *>, out kotlin.(Mutable)List<*>!>?), /*1*/ E : T!, /*2*/ F : (kotlin.MutableList..kotlin.List?)>() + public/*package*/ final var first: T! + public/*package*/ final var listOfDoubles: F! + public/*package*/ final var second: E! + 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 +} + +public/*package*/ open class Test { + public/*package*/ constructor Test() + 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 + + public/*package*/ open class DerivedRawA : A!, out A<*, *, *>!, out kotlin.(Mutable)List<*>!> { + public/*package*/ constructor DerivedRawA() + public/*package*/ final override /*1*/ /*fake_override*/ var first: (A!, A<*, *, *>!, kotlin.(Mutable)List<*>!>..A!, out A<*, *, *>!, out kotlin.(Mutable)List<*>!>?) + public/*package*/ final override /*1*/ /*fake_override*/ var listOfDoubles: (kotlin.MutableList..kotlin.List<*>?) + public/*package*/ final override /*1*/ /*fake_override*/ var second: (A!, A<*, *, *>!, kotlin.(Mutable)List<*>!>..A!, out A<*, *, *>!, out kotlin.(Mutable)List<*>!>?) + 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 + public/*package*/ final var rawAField: (A<(A!, A<*, *, *>!, kotlin.(Mutable)List<*>!>..A!, out A<*, *, *>!, out kotlin.(Mutable)List<*>!>?), (A!, A<*, *, *>!, kotlin.(Mutable)List<*>!>..A!, out A<*, *, *>!, out kotlin.(Mutable)List<*>!>?), (kotlin.MutableList..kotlin.List<*>?)>..A!, A<*, *, *>!, kotlin.(Mutable)List<*>!>..A!, out A<*, *, *>!, out kotlin.(Mutable)List<*>!>?), out (A!, A<*, *, *>!, kotlin.(Mutable)List<*>!>..A!, out A<*, *, *>!, out kotlin.(Mutable)List<*>!>?), out (kotlin.MutableList..kotlin.List<*>?)>?) +} diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawSupertype.kt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawSupertype.kt new file mode 100644 index 00000000000..5df133ccfb8 --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawSupertype.kt @@ -0,0 +1,36 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE +// FILE: A.java + +import java.util.*; + +class A { + List x; + + void foo(T x, List y) {} + + A> bar() {} +} + +// FILE: Test.java + +class Test { + static class RawADerived extends A { + + } +} + +// FILE: main.kt + +val strList: List = null!! +val strMap: Map = null!! + +fun main() { + val rawADerived = Test.RawADerived() + rawADerived.x = strList + rawADerived.foo("", strList) + + + val rawA = rawADerived.bar() + rawA.x = strList + rawA.foo("", strList) +} diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawSupertype.txt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawSupertype.txt new file mode 100644 index 00000000000..84558052bc8 --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawSupertype.txt @@ -0,0 +1,32 @@ +package + +internal val strList: kotlin.List +internal val strMap: kotlin.Map +internal fun main(): kotlin.Unit + +public/*package*/ open class A { + public/*package*/ constructor A() + public/*package*/ final var x: kotlin.(Mutable)List! + public/*package*/ open fun bar(): A!>! + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public/*package*/ open fun foo(/*0*/ x: T!, /*1*/ y: kotlin.(Mutable)List!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public/*package*/ open class Test { + public/*package*/ constructor Test() + 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 + + public/*package*/ open class RawADerived : A { + public/*package*/ constructor RawADerived() + public/*package*/ final override /*1*/ /*fake_override*/ var x: (kotlin.MutableList..kotlin.List<*>?) + public/*package*/ open override /*1*/ /*fake_override*/ fun bar(): (A..A<*>?) + 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.MutableList..kotlin.List<*>?)): 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.kt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawSupertypeOverride.kt new file mode 100644 index 00000000000..54353a9648e --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawSupertypeOverride.kt @@ -0,0 +1,41 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE +// FILE: A.java + +import java.util.*; + +class A { + A> foo(T x, Map> y, HashMap z) {} + + void bar(List[][] d) {} +} + +// FILE: RawADerived.java + +class RawADerived extends A { +} + +// FILE: main.kt +import java.util.*; + +class B1 : RawADerived() { + override fun foo(x: CharSequence, y: Map, z: HashMap): A<*> = null!! + + override fun bar(d: Array>>) {} +} + +class B2 : RawADerived() { + override fun foo(x: CharSequence?, y: MutableMap, z: HashMap): A = null!! + + override fun bar(d: Array>>) {} +} + +class B3 : RawADerived() { + // Type of second parameter (y) is not equal to overridden + // RawADerived.foo.y --- (MutableMap..Map) is not a subtype of Map + override fun foo(x: CharSequence, y: Map, z: HashMap): A<*> = null!! +} + +class B4 : RawADerived() { + // Type of first parameter is not equal to overridden + override fun bar(d: Array>>>) {} +} diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawSupertypeOverride.txt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawSupertypeOverride.txt new file mode 100644 index 00000000000..958f39c540e --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawSupertypeOverride.txt @@ -0,0 +1,57 @@ +package + +public/*package*/ open class A { + public/*package*/ constructor A() + public/*package*/ open fun bar(/*0*/ d: kotlin.Array<(out) kotlin.Array<(out) kotlin.(Mutable)List!>!>!>!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public/*package*/ open fun foo(/*0*/ x: T!, /*1*/ y: kotlin.(Mutable)Map!>!, /*2*/ z: java.util.HashMap!): A!>! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +internal final class B1 : RawADerived { + public constructor B1() + internal open override /*1*/ fun bar(/*0*/ d: kotlin.Array>>): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + internal open override /*1*/ fun foo(/*0*/ x: kotlin.CharSequence, /*1*/ y: kotlin.Map, /*2*/ z: java.util.HashMap): A<*> + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +internal final class B2 : RawADerived { + public constructor B2() + internal open override /*1*/ fun bar(/*0*/ d: kotlin.Array>>): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + internal open override /*1*/ fun foo(/*0*/ x: kotlin.CharSequence?, /*1*/ y: kotlin.MutableMap, /*2*/ z: java.util.HashMap): A + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +internal 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.MutableList..kotlin.List<*>?)>!>!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + internal open fun foo(/*0*/ x: kotlin.CharSequence, /*1*/ y: kotlin.Map, /*2*/ z: java.util.HashMap): A<*> + public/*package*/ open override /*1*/ /*fake_override*/ fun foo(/*0*/ x: kotlin.CharSequence!, /*1*/ y: (kotlin.MutableMap..kotlin.Map<*, *>?), /*2*/ z: (java.util.HashMap..java.util.HashMap<*, *>?)): (A..A<*>?) + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +internal 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.MutableList..kotlin.List<*>?)>!>!): kotlin.Unit + internal open fun bar(/*0*/ d: kotlin.Array>>>): 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.MutableMap..kotlin.Map<*, *>?), /*2*/ z: (java.util.HashMap..java.util.HashMap<*, *>?)): (A..A<*>?) + 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*/ constructor RawADerived() + public/*package*/ open override /*1*/ /*fake_override*/ fun bar(/*0*/ d: kotlin.Array<(out) kotlin.Array<(out) (kotlin.MutableList..kotlin.List<*>?)>!>!): 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.MutableMap..kotlin.Map<*, *>?), /*2*/ z: (java.util.HashMap..java.util.HashMap<*, *>?)): (A..A<*>?) + 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 new file mode 100644 index 00000000000..2d85a4f0fb2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawTypeInUpperBound.kt @@ -0,0 +1,37 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE +// FILE: A.java + +import java.util.List; + +public class A { + List getChildrenStubs() { return null; } + void consume(T x) {} + + T produce() { return null; } +} + +// FILE: B.java + +public class B { + public E foo() { return null;} + E field; +} + +// FILE: Test.java + +public class Test { + static B rawB = null; +} + +// FILE: main.kt + +fun foo(x: B<*>) { + val q: MutableList = x.foo().getChildrenStubs() + + // Raw(B).field erased to A..A? + Test.rawB.field = A() + val anyA: A = Test.rawB.field + + Test.rawB.field.consume("") + val y: Any = Test.rawB.field.produce() +} diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawTypeInUpperBound.txt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawTypeInUpperBound.txt new file mode 100644 index 00000000000..ede9115b0eb --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawTypeInUpperBound.txt @@ -0,0 +1,32 @@ +package + +internal fun foo(/*0*/ x: B<*>): kotlin.Unit + +public open class A { + public constructor A() + public/*package*/ open fun consume(/*0*/ x: T!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public/*package*/ open fun getChildrenStubs(): kotlin.(Mutable)List! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public/*package*/ open fun produce(): T! + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class B..A<*>?)> { + public constructor B..A<*>?)>() + public/*package*/ final var field: E! + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open fun foo(): E! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class Test { + public constructor Test() + 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 + public/*package*/ final var rawB: (B<(A..A<*>?)>..B..A<*>?)>?) +} diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawWithInProjection.kt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawWithInProjection.kt new file mode 100644 index 00000000000..db44de8b200 --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawWithInProjection.kt @@ -0,0 +1,11 @@ +// FILE: Test.java + +class Test { + static void foo(Comparable x) {} +} + +// FILE: main.kt + +fun main() { + Test.foo(1) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawWithInProjection.txt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawWithInProjection.txt new file mode 100644 index 00000000000..717ef620710 --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawWithInProjection.txt @@ -0,0 +1,13 @@ +package + +internal fun main(): kotlin.Unit + +public/*package*/ open class Test { + public/*package*/ constructor Test() + 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 + public/*package*/ open fun foo(/*0*/ x: (kotlin.Comparable..kotlin.Comparable?)): kotlin.Unit +} diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/recursiveBound.kt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/recursiveBound.kt new file mode 100644 index 00000000000..2c6e7839c86 --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/recursiveBound.kt @@ -0,0 +1,15 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE +// FILE: A.java + +import java.util.List; + +public interface A {} +// FILE: main.kt + +class D : A + +fun main(x: A<*>) { + if (x is D) { + + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/recursiveBound.txt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/recursiveBound.txt new file mode 100644 index 00000000000..9a799bd6f04 --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/recursiveBound.txt @@ -0,0 +1,16 @@ +package + +internal fun main(/*0*/ x: A<*>): kotlin.Unit + +public interface A>..A>?)> { + 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 +} + +internal final class D : A { + public constructor D() + 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 +} diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/samRaw.kt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/samRaw.kt new file mode 100644 index 00000000000..4e66f885a44 --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/samRaw.kt @@ -0,0 +1,27 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE +// FILE: A.java + +import java.util.List; + +public interface A { + boolean value(T t); +} + +// FILE: B.java + +class B { + void foo(Runnable runnable, A x); + + static A bar() {} +} + +// FILE: main.kt + +fun main() { + fun println() {} + // All parameters in SAM adapter of `foo` have functional types + B().foo({ println() }, B.bar()) + // So you should use SAM constructors when you want to use mix lambdas and Java objects + B().foo(Runnable { println() }, B.bar()) + B().foo({ println() }, { it: Any? -> true } ) +} diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/samRaw.txt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/samRaw.txt new file mode 100644 index 00000000000..2dd7268e8ea --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/samRaw.txt @@ -0,0 +1,23 @@ +package + +public /*synthesized*/ fun A(/*0*/ function: (T!) -> kotlin.Boolean): A +internal fun main(): kotlin.Unit + +public interface A { + 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 + public abstract fun value(/*0*/ t: T!): kotlin.Boolean +} + +public/*package*/ open class B { + public/*package*/ constructor B() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public/*package*/ final /*synthesized*/ fun foo(/*0*/ runnable: (() -> kotlin.Unit)!, /*1*/ x: ((kotlin.Any!) -> kotlin.Boolean)!): kotlin.Unit + public/*package*/ open fun foo(/*0*/ runnable: java.lang.Runnable!, /*1*/ x: (A..A<*>?)): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public/*package*/ open fun bar(): (A..A<*>?) +} diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/simple.kt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/simple.kt new file mode 100644 index 00000000000..1dfe6e102fb --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/simple.kt @@ -0,0 +1,39 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE +// FILE: A.java + +import java.util.*; + +class A { + List x; + Map y; + + A> z; + + void foo(T x, List y, List> z) {} + + A> bar() {} +} + +// FILE: Test.java + +class Test { + static A rawAField = null; +} + +// FILE: main.kt + +val strList: List = null!! +val strMap: Map = null!! + +fun main() { + val rawA = Test.rawAField + rawA.x = strList + rawA.y = strMap + rawA.foo("", strList, strList) + + val barResult = rawA.bar() + + barResult.x = strList + barResult.y = strMap + barResult.foo("", strList, null) +} diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/simple.txt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/simple.txt new file mode 100644 index 00000000000..771688563c3 --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/simple.txt @@ -0,0 +1,27 @@ +package + +internal val strList: kotlin.List +internal val strMap: kotlin.Map +internal fun main(): kotlin.Unit + +public/*package*/ open class A { + public/*package*/ constructor A() + public/*package*/ final var x: kotlin.(Mutable)List! + public/*package*/ final var y: kotlin.(Mutable)Map! + public/*package*/ final var z: A!>! + public/*package*/ open fun bar(): A!>! + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public/*package*/ open fun foo(/*0*/ x: T!, /*1*/ y: kotlin.(Mutable)List!, /*2*/ z: kotlin.(Mutable)List!>!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public/*package*/ open class Test { + public/*package*/ constructor Test() + 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 + public/*package*/ final var rawAField: (A..A<*>?) +} diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/starProjectionToRaw.kt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/starProjectionToRaw.kt new file mode 100644 index 00000000000..1d679597497 --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/starProjectionToRaw.kt @@ -0,0 +1,25 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE +// FILE: A.java + +import java.util.*; + +class A {} + +// FILE: B.java + +import java.util.*; + +class B {} + +// FILE: Test.java + +class Test { + static void foo(B x) {} +} + +// FILE: main.kt + + +fun main(x: B<*>) { + Test.foo(x) +} diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/starProjectionToRaw.txt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/starProjectionToRaw.txt new file mode 100644 index 00000000000..9bad5424952 --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/starProjectionToRaw.txt @@ -0,0 +1,27 @@ +package + +internal fun main(/*0*/ x: B<*>): kotlin.Unit + +public/*package*/ open class A { + public/*package*/ constructor A() + 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 +} + +public/*package*/ open class B..A<*>?)> { + public/*package*/ constructor B..A<*>?)>() + 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 +} + +public/*package*/ open class Test { + public/*package*/ constructor Test() + 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 + public/*package*/ open fun foo(/*0*/ x: (B<(A..A<*>?)>..B..A<*>?)>?)): kotlin.Unit +} diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/typeEnhancement.kt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/typeEnhancement.kt new file mode 100644 index 00000000000..61b0b4a793e --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/typeEnhancement.kt @@ -0,0 +1,27 @@ +// FILE: A.java + +import org.jetbrains.annotations.*; +import java.util.*; + +class A { + @NotNull + List<@Nullable String> foo(@NotNull T x, @Nullable List<@NotNull String> y) {} +} + +// FILE: Test.java + +class Test { + static class DerivedRawA extends A {} + + static A rawField = null; +} + +// FILE: main.kt + +val doubleList: List = null!! + +fun main() { + Test.rawField.foo("", doubleList) + Test.rawField.foo(null, doubleList) + Test.DerivedRawA().foo(null, doubleList) +} diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/typeEnhancement.txt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/typeEnhancement.txt new file mode 100644 index 00000000000..9c0fc5e2893 --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/typeEnhancement.txt @@ -0,0 +1,30 @@ +package + +internal val doubleList: kotlin.List +internal fun main(): kotlin.Unit + +public/*package*/ open class A { + public/*package*/ constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + org.jetbrains.annotations.NotNull() public/*package*/ open fun foo(/*0*/ org.jetbrains.annotations.NotNull() x: T, /*1*/ org.jetbrains.annotations.Nullable() y: kotlin.(Mutable)List?): kotlin.(Mutable)List + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public/*package*/ open class Test { + public/*package*/ constructor Test() + 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 + + public/*package*/ open class DerivedRawA : A { + public/*package*/ constructor DerivedRawA() + 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.MutableList?..kotlin.List<*>?)): (kotlin.MutableList..kotlin.List<*>) + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + // Static members + public/*package*/ final var rawField: (A..A<*>?) +} diff --git a/compiler/testData/diagnostics/tests/platformTypes/supertypeTypeArguments.txt b/compiler/testData/diagnostics/tests/platformTypes/supertypeTypeArguments.txt index fe79b88083d..d9c2082df6f 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/supertypeTypeArguments.txt +++ b/compiler/testData/diagnostics/tests/platformTypes/supertypeTypeArguments.txt @@ -61,7 +61,7 @@ internal final class HashMapEx : java.util.HashMap, ExtM invisible_fake open override /*1*/ /*fake_override*/ fun resize(/*0*/ p0: kotlin.Int): kotlin.Unit public open override /*2*/ /*fake_override*/ fun size(): kotlin.Int public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String - invisible_fake open override /*1*/ /*fake_override*/ fun transfer(/*0*/ p0: kotlin.Array<(out) java.util.HashMap.Entry<*, *>!>!, /*1*/ p1: kotlin.Boolean): kotlin.Unit + invisible_fake open override /*1*/ /*fake_override*/ fun transfer(/*0*/ p0: kotlin.Array<(out) (java.util.HashMap.Entry..java.util.HashMap.Entry<*, *>?)>!, /*1*/ p1: kotlin.Boolean): kotlin.Unit public open override /*2*/ /*fake_override*/ fun values(): kotlin.MutableCollection invisible_fake open override /*1*/ /*fake_override*/ fun writeObject(/*0*/ p0: java.io.ObjectOutputStream!): kotlin.Unit } diff --git a/compiler/testData/diagnostics/tests/regressions/kt1639-JFrame.txt b/compiler/testData/diagnostics/tests/regressions/kt1639-JFrame.txt index 6463448f65c..2b693b154e2 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt1639-JFrame.txt +++ b/compiler/testData/diagnostics/tests/regressions/kt1639-JFrame.txt @@ -37,7 +37,7 @@ package test { invisible_fake final override /*1*/ /*fake_override*/ var focusCycleRoot: kotlin.Boolean invisible_fake final override /*1*/ /*fake_override*/ var focusListener: [ERROR : Unresolved java classifier: FocusListener]! invisible_fake final override /*1*/ /*fake_override*/ var focusMgr: [ERROR : Unresolved java classifier: FocusManager]! - invisible_fake final override /*1*/ /*fake_override*/ var focusTraversalKeys: kotlin.Array<(out) kotlin.(Mutable)Set<*>!>! + invisible_fake final override /*1*/ /*fake_override*/ var focusTraversalKeys: kotlin.Array<(out) (kotlin.MutableSet..kotlin.Set<*>?)>! invisible_fake final override /*1*/ /*fake_override*/ var focusTraversalKeysEnabled: kotlin.Boolean invisible_fake final override /*1*/ /*fake_override*/ var focusTraversalPolicy: [ERROR : Unresolved java classifier: FocusTraversalPolicy]! invisible_fake final override /*1*/ /*fake_override*/ var focusTraversalPolicyProvider: kotlin.Boolean @@ -98,7 +98,7 @@ package test { invisible_fake final override /*1*/ /*fake_override*/ var prefSizeSet: kotlin.Boolean invisible_fake final override /*1*/ /*fake_override*/ var preserveBackgroundColor: [ERROR : Unresolved java classifier: Color]! invisible_fake final override /*1*/ /*fake_override*/ var printing: kotlin.Boolean - invisible_fake final override /*1*/ /*fake_override*/ var printingThreads: kotlin.(Mutable)Set<*>! + invisible_fake final override /*1*/ /*fake_override*/ var printingThreads: (kotlin.MutableSet..kotlin.Set<*>?) invisible_fake final override /*1*/ /*fake_override*/ var resizable: kotlin.Boolean protected/*protected and package*/ final override /*1*/ /*fake_override*/ var rootPane: [ERROR : Unresolved java classifier: JRootPane]! protected/*protected and package*/ final override /*1*/ /*fake_override*/ var rootPaneCheckingEnabled: kotlin.Boolean @@ -290,7 +290,7 @@ package test { public open override /*1*/ /*fake_override*/ fun getFocusOwner(): java.awt.Component! public open override /*1*/ /*fake_override*/ fun getFocusTraversalKeys(/*0*/ p0: kotlin.Int): kotlin.(Mutable)Set! public open override /*1*/ /*fake_override*/ fun getFocusTraversalKeysEnabled(): kotlin.Boolean - invisible_fake final override /*1*/ /*fake_override*/ fun getFocusTraversalKeys_NoIDCheck(/*0*/ p0: kotlin.Int): kotlin.(Mutable)Set<*>! + invisible_fake final override /*1*/ /*fake_override*/ fun getFocusTraversalKeys_NoIDCheck(/*0*/ p0: kotlin.Int): (kotlin.MutableSet..kotlin.Set<*>?) public open override /*1*/ /*fake_override*/ fun getFocusTraversalPolicy(): [ERROR : Unresolved java classifier: FocusTraversalPolicy]! public open override /*1*/ /*fake_override*/ fun getFocusableWindowState(): kotlin.Boolean [ERROR : java.beans.Transient]() public open override /*1*/ /*fake_override*/ fun getFont(): [ERROR : Unresolved java classifier: Font]! diff --git a/compiler/testData/loadJava/compiledJava/RawTypeWithUpperBound.txt b/compiler/testData/loadJava/compiledJava/RawTypeWithUpperBound.txt index 8708cc1e291..e5c622d6968 100644 --- a/compiler/testData/loadJava/compiledJava/RawTypeWithUpperBound.txt +++ b/compiler/testData/loadJava/compiledJava/RawTypeWithUpperBound.txt @@ -3,8 +3,8 @@ package test public interface RawTypeWithUpperBound { public interface Bar { - public abstract fun f(/*0*/ p0: test.RawTypeWithUpperBound.Foo<*>!): kotlin.Unit - public abstract fun g(/*0*/ p0: kotlin.(Mutable)List!>!): kotlin.Unit + public abstract fun f(/*0*/ p0: (test.RawTypeWithUpperBound.Foo..test.RawTypeWithUpperBound.Foo<*>?)): kotlin.Unit + public abstract fun g(/*0*/ p0: kotlin.(Mutable)List<(test.RawTypeWithUpperBound.Foo..test.RawTypeWithUpperBound.Foo<*>?)>!): kotlin.Unit } public interface Foo { diff --git a/compiler/testData/loadJava/compiledJava/RawUpperBound.txt b/compiler/testData/loadJava/compiledJava/RawUpperBound.txt index d42d54146bd..8f78dcda07d 100644 --- a/compiler/testData/loadJava/compiledJava/RawUpperBound.txt +++ b/compiler/testData/loadJava/compiledJava/RawUpperBound.txt @@ -1,4 +1,4 @@ package test -public interface RawUpperBound!> { +public interface RawUpperBound>..test.RawUpperBound>?)> { } diff --git a/compiler/testData/loadJava/compiledJava/RecursiveRawUpperBound.txt b/compiler/testData/loadJava/compiledJava/RecursiveRawUpperBound.txt index 93327f13d33..18ebd33c64f 100644 --- a/compiler/testData/loadJava/compiledJava/RecursiveRawUpperBound.txt +++ b/compiler/testData/loadJava/compiledJava/RecursiveRawUpperBound.txt @@ -1,4 +1,4 @@ package test -public interface RecursiveRawUpperBound!> { +public interface RecursiveRawUpperBound>..test.RecursiveRawUpperBound>?)> { } diff --git a/compiler/testData/loadJava/compiledJava/RecursiveWildcardUpperBound.txt b/compiler/testData/loadJava/compiledJava/RecursiveWildcardUpperBound.txt index 122200567f3..5f298bdd53e 100644 --- a/compiler/testData/loadJava/compiledJava/RecursiveWildcardUpperBound.txt +++ b/compiler/testData/loadJava/compiledJava/RecursiveWildcardUpperBound.txt @@ -1,4 +1,4 @@ package test -public interface RecursiveWildcardUpperBound!> { +public interface RecursiveWildcardUpperBound>..test.RecursiveWildcardUpperBound>?)> { } diff --git a/compiler/testData/loadJava/compiledJava/rendering/Rendering.txt b/compiler/testData/loadJava/compiledJava/rendering/Rendering.txt index c9906dedb0d..95e545a5bd7 100644 --- a/compiler/testData/loadJava/compiledJava/rendering/Rendering.txt +++ b/compiler/testData/loadJava/compiledJava/rendering/Rendering.txt @@ -42,8 +42,8 @@ public open class Rendering { } public/*package*/ interface H_Raw { - public abstract fun foo1(/*0*/ p0: kotlin.(Mutable)List<*>!): kotlin.Unit - public abstract fun foo2(/*0*/ p0: test.Rendering.D_SuperG<*>!): kotlin.Unit + public abstract fun foo1(/*0*/ p0: (kotlin.MutableList..kotlin.List<*>?)): kotlin.Unit + public abstract fun foo2(/*0*/ p0: (test.Rendering.D_SuperG..test.Rendering.D_SuperG<*>?)): kotlin.Unit } public/*package*/ interface I_Wildcard { diff --git a/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBound.txt b/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBound.txt index c12c0756237..7422aabbe1c 100644 --- a/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBound.txt +++ b/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBound.txt @@ -3,11 +3,11 @@ 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!> { public constructor Derived() public open override /*1*/ fun dummy(): kotlin.Unit + public open override /*1*/ fun foo(/*0*/ p0: (test.RawSuperTypeWithRecursiveBound.Super<(test.RawSuperTypeWithRecursiveBound.Super!>..test.RawSuperTypeWithRecursiveBound.Super!>?)>..test.RawSuperTypeWithRecursiveBound.Super!>..test.RawSuperTypeWithRecursiveBound.Super!>?)>?)): kotlin.Unit public open fun foo(/*0*/ p0: kotlin.Any!): kotlin.Unit - public open override /*1*/ fun foo(/*0*/ p0: test.RawSuperTypeWithRecursiveBound.Super<*>!): kotlin.Unit } public interface Super!> { diff --git a/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBoundMultipleParameters.txt b/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBoundMultipleParameters.txt index e1ed1f006b3..9f20e6321ea 100644 --- a/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBoundMultipleParameters.txt +++ b/compiler/testData/loadJava/compiledJava/signaturePropagation/RawSuperTypeWithRecursiveBoundMultipleParameters.txt @@ -3,11 +3,11 @@ 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!> { public constructor Derived() public open override /*1*/ fun dummy(): kotlin.Unit + public open override /*1*/ fun foo(/*0*/ p0: kotlin.Any!, /*1*/ p1: (test.RawSuperTypeWithRecursiveBoundMultipleParameters.Super!>..test.RawSuperTypeWithRecursiveBoundMultipleParameters.Super<*, out test.RawSuperTypeWithRecursiveBoundMultipleParameters.Super<*, *>!>?)>..test.RawSuperTypeWithRecursiveBoundMultipleParameters.Super<*, out (test.RawSuperTypeWithRecursiveBoundMultipleParameters.Super!>..test.RawSuperTypeWithRecursiveBoundMultipleParameters.Super<*, out test.RawSuperTypeWithRecursiveBoundMultipleParameters.Super<*, *>!>?)>?)): kotlin.Unit public open fun foo(/*0*/ p0: kotlin.Any!, /*1*/ p1: kotlin.Any!): kotlin.Unit - public open override /*1*/ fun foo(/*0*/ p0: kotlin.Any!, /*1*/ p1: test.RawSuperTypeWithRecursiveBoundMultipleParameters.Super<*, *>!): kotlin.Unit } public interface Super!> { diff --git a/compiler/testData/loadJava/compiledJava/signaturePropagation/SubclassWithRawType.txt b/compiler/testData/loadJava/compiledJava/signaturePropagation/SubclassWithRawType.txt index 9851a9fb8b5..ffa40ef64c4 100644 --- a/compiler/testData/loadJava/compiledJava/signaturePropagation/SubclassWithRawType.txt +++ b/compiler/testData/loadJava/compiledJava/signaturePropagation/SubclassWithRawType.txt @@ -4,22 +4,22 @@ public interface SubclassWithRawType { public interface Sub : test.SubclassWithRawType.Super { public abstract override /*1*/ fun array1(): kotlin.Array<(out) kotlin.(Mutable)List!>! - public abstract override /*1*/ fun array2(): kotlin.Array<(out) kotlin.(Mutable)List<*>!>! + public abstract override /*1*/ fun array2(): kotlin.Array<(out) (kotlin.MutableList..kotlin.List<*>?)>! public abstract override /*1*/ fun boundWildcard1(): (kotlin.MutableList!>..kotlin.List!>?) - public abstract override /*1*/ fun boundWildcard2(): kotlin.(Mutable)List..kotlin.List?)>! + public abstract override /*1*/ fun boundWildcard2(): kotlin.(Mutable)List..kotlin.List<*>?)>! public abstract override /*1*/ fun simple1(): kotlin.(Mutable)List! public abstract override /*1*/ fun simple2(): kotlin.(Mutable)List!>! - public abstract override /*1*/ fun simple3(): kotlin.(Mutable)List<*>! - public abstract override /*1*/ fun wildcard(): kotlin.(Mutable)List<*>! + public abstract override /*1*/ fun simple3(): (kotlin.MutableList..kotlin.List<*>?) + public abstract override /*1*/ fun wildcard(): (kotlin.MutableList..kotlin.List<*>?) } public interface Super { - public abstract fun array1(): kotlin.Array<(out) kotlin.(Mutable)List<*>!>! + public abstract fun array1(): kotlin.Array<(out) (kotlin.MutableList..kotlin.List<*>?)>! public abstract fun array2(): kotlin.Array<(out) kotlin.(Mutable)List!>! - public abstract fun boundWildcard1(): (kotlin.MutableList..kotlin.List?)>..kotlin.List<(kotlin.MutableList..kotlin.List?)>?) + public abstract fun boundWildcard1(): (kotlin.MutableList..kotlin.List<*>?)>..kotlin.List<(kotlin.MutableList..kotlin.List<*>?)>?) public abstract fun boundWildcard2(): kotlin.(Mutable)List!>! - public abstract fun simple1(): kotlin.(Mutable)List<*>! - public abstract fun simple2(): kotlin.(Mutable)List<*>! + public abstract fun simple1(): (kotlin.MutableList..kotlin.List<*>?) + public abstract fun simple2(): (kotlin.MutableList..kotlin.List<*>?) public abstract fun simple3(): kotlin.(Mutable)List! public abstract fun wildcard(): kotlin.(Mutable)List<*>! } diff --git a/compiler/testData/loadJava/sourceJava/WrongNumberOfGenericParameters.txt b/compiler/testData/loadJava/sourceJava/WrongNumberOfGenericParameters.txt index eeda4a9bcbf..da2a5d30a53 100644 --- a/compiler/testData/loadJava/sourceJava/WrongNumberOfGenericParameters.txt +++ b/compiler/testData/loadJava/sourceJava/WrongNumberOfGenericParameters.txt @@ -1,9 +1,9 @@ package test public interface WrongNumberOfGenericParameters { - public abstract fun o0(): test.WrongNumberOfGenericParameters.One<*>! + public abstract fun o0(): (test.WrongNumberOfGenericParameters.One..test.WrongNumberOfGenericParameters.One<*>?) public abstract fun o2(): test.WrongNumberOfGenericParameters.One<[ERROR : T]>! - public abstract fun t1(): test.WrongNumberOfGenericParameters.Two<*, *>! + public abstract fun t1(): (test.WrongNumberOfGenericParameters.Two..test.WrongNumberOfGenericParameters.Two<*, *>?) public abstract fun z(): test.WrongNumberOfGenericParameters.Zero! public interface One { diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index 4696a2ca321..b84de03e4f0 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -10566,6 +10566,93 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { } } + @TestMetadata("compiler/testData/diagnostics/tests/platformTypes/rawTypes") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class RawTypes extends AbstractJetDiagnosticsTest { + public void testAllFilesPresentInRawTypes() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/platformTypes/rawTypes"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("arrays.kt") + public void testArrays() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/rawTypes/arrays.kt"); + doTest(fileName); + } + + @TestMetadata("genericInnerClass.kt") + public void testGenericInnerClass() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/rawTypes/genericInnerClass.kt"); + doTest(fileName); + } + + @TestMetadata("nonGenericRawMember.kt") + public void testNonGenericRawMember() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonGenericRawMember.kt"); + doTest(fileName); + } + + @TestMetadata("nonTrivialErasure.kt") + public void testNonTrivialErasure() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonTrivialErasure.kt"); + doTest(fileName); + } + + @TestMetadata("rawSupertype.kt") + public void testRawSupertype() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawSupertype.kt"); + doTest(fileName); + } + + @TestMetadata("rawSupertypeOverride.kt") + public void testRawSupertypeOverride() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawSupertypeOverride.kt"); + doTest(fileName); + } + + @TestMetadata("rawTypeInUpperBound.kt") + public void testRawTypeInUpperBound() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawTypeInUpperBound.kt"); + doTest(fileName); + } + + @TestMetadata("rawWithInProjection.kt") + public void testRawWithInProjection() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawWithInProjection.kt"); + doTest(fileName); + } + + @TestMetadata("recursiveBound.kt") + public void testRecursiveBound() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/rawTypes/recursiveBound.kt"); + doTest(fileName); + } + + @TestMetadata("samRaw.kt") + public void testSamRaw() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/rawTypes/samRaw.kt"); + doTest(fileName); + } + + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/rawTypes/simple.kt"); + doTest(fileName); + } + + @TestMetadata("starProjectionToRaw.kt") + public void testStarProjectionToRaw() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/rawTypes/starProjectionToRaw.kt"); + doTest(fileName); + } + + @TestMetadata("typeEnhancement.kt") + public void testTypeEnhancement() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/rawTypes/typeEnhancement.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/diagnostics/tests/platformTypes/typeEnhancement") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaTypeParameterDescriptor.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaTypeParameterDescriptor.kt index 62add3013c7..816a7b3a78b 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaTypeParameterDescriptor.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaTypeParameterDescriptor.kt @@ -55,7 +55,7 @@ class LazyJavaTypeParameterDescriptor( } else { return bounds.map { - javaType -> c.typeResolver.transformJavaType(javaType, TypeUsage.UPPER_BOUND.toAttributes()) + javaType -> c.typeResolver.transformJavaType(javaType, TypeUsage.UPPER_BOUND.toAttributes(upperBoundForTypeParameter = this)) }.toSet() } } 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 7941dd790c2..3e1ac5ef070 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 @@ -98,16 +98,6 @@ class LazyJavaTypeResolver( }.replaceAnnotations(attr.typeAnnotations) } - fun makeStarProjection( - typeParameter: TypeParameterDescriptor, - attr: JavaTypeAttributes - ): TypeProjection { - return if (attr.howThisTypeIsUsed == SUPERTYPE) - TypeProjectionImpl(typeParameter.starProjectionType()) - else - StarProjectionImpl(typeParameter) - } - private inner class LazyJavaClassifierType( private val javaType: JavaClassifierType, private val attr: JavaTypeAttributes @@ -207,19 +197,24 @@ class LazyJavaTypeResolver( if (isRaw()) { return typeParameters.map { parameter -> + // Some activity for preventing recursion in cases like `class A` + // + // When calculating upper bound of some parameter (attr.upperBoundOfTypeParameter), + // do not try to start upper bound calculation of it again. + // If we met such recursive dependency it means that upper bound of `attr.upperBoundOfTypeParameter` based effectively + // on the current class, so we can manually erase default type of current constructor. + // + // In example above corner cases are: + // - Calculating first argument for raw upper bound of T. It depends on T, so we just get A<*, *> + // - Calculating second argument for raw upper bound of T. It depends on F, that again depends on upper bound of T, + // so we get A<*, *>. + // Summary result for upper bound of T is `A, A<*, *>>..A, out A<*, *>>` + val erasedUpperBound = + parameter.getErasedUpperBound(attr.upperBoundOfTypeParameter) { + constructor.declarationDescriptor!!.defaultType.replaceArgumentsWithStarProjections() + } - if (attr.howThisTypeIsUsed == UPPER_BOUND) { - // not making a star projection because of this case: - // Java: - // class C {} - // The upper bound is raw here, and we can't compute the projection: it would be infinite: - // C<*> = C>> - // this way we lose some type information, even when the case is not so bad, but it doesn't seem to matter - val projectionKind = if (parameter.getVariance() == OUT_VARIANCE) INVARIANT else OUT_VARIANCE - TypeProjectionImpl(projectionKind, c.module.builtIns.getNullableAnyType()) - } - else - makeStarProjection(parameter, attr) + RawSubstitution.computeProjection(parameter, attr, erasedUpperBound) } } if (isConstructorTypeParameter()) { @@ -268,10 +263,86 @@ class LazyJavaTypeResolver( if (descriptor is TypeParameterDescriptor) return descriptor.getDefaultType().getMemberScope() - return (descriptor as ClassDescriptor).getMemberScope(getArguments()) + return (descriptor as ClassDescriptor).getMemberScope(substitution) } - override fun computeCustomSubstitution(): TypeSubstitution? = null + override fun computeCustomSubstitution() = if (isRaw()) RawSubstitution else null + + private object RawSubstitution : TypeSubstitution() { + override fun get(key: JetType) = TypeProjectionImpl(eraseType(key)) + + private val lowerTypeAttr = MEMBER_SIGNATURE_INVARIANT.toAttributes().toFlexible(FLEXIBLE_LOWER_BOUND) + private val upperTypeAttr = MEMBER_SIGNATURE_INVARIANT.toAttributes().toFlexible(FLEXIBLE_UPPER_BOUND) + + private fun eraseType(type: JetType): JetType { + val declaration = type.constructor.declarationDescriptor + return when (declaration) { + is TypeParameterDescriptor -> eraseType(declaration.getErasedUpperBound()) + is ClassDescriptor -> { + val lower = type.lowerIfFlexible() + val upper = type.upperIfFlexible() + FlexibleJavaClassifierTypeCapabilities.create( + eraseInflexibleBasedOnClassDescriptor(lower, declaration, lowerTypeAttr), + eraseInflexibleBasedOnClassDescriptor(upper, declaration, upperTypeAttr) + ) + } + else -> error("Unexpected declaration kind: $declaration") + } + } + + private fun eraseInflexibleBasedOnClassDescriptor(type: JetType, declaration: ClassDescriptor, attr: JavaTypeAttributes): JetType { + if (KotlinBuiltIns.isArray(type)) { + val componentTypeProjection = type.arguments[0] + val arguments = listOf( + TypeProjectionImpl(componentTypeProjection.projectionKind, eraseType(componentTypeProjection.type)) + ) + return JetTypeImpl( + type.annotations, type.constructor, type.isMarkedNullable, arguments, + (type.constructor.declarationDescriptor as ClassDescriptor).getMemberScope(arguments) + ) + } + + val constructor = type.constructor + return JetTypeImpl( + type.annotations, constructor, type.isMarkedNullable, + type.constructor.parameters.map { + parameter -> computeProjection(parameter, attr) + }, + RawSubstitution, + declaration.getMemberScope(RawSubstitution) + ) + } + + fun computeProjection( + parameter: TypeParameterDescriptor, + attr: JavaTypeAttributes, + erasedUpperBound: JetType = parameter.getErasedUpperBound() + ) = when (attr.flexibility) { + // 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) + FLEXIBLE_LOWER_BOUND -> TypeProjectionImpl( + // T : String -> String + // in T : String -> String + // T : Enum -> Enum<*> + Variance.INVARIANT, erasedUpperBound + ) + FLEXIBLE_UPPER_BOUND, INFLEXIBLE -> { + if (!parameter.variance.allowsOutPosition) + // in T -> Comparable + TypeProjectionImpl(Variance.INVARIANT, parameter.lowerBounds.first()) + else if (erasedUpperBound.constructor.parameters.isNotEmpty()) + // T : Enum -> out Enum<*> + TypeProjectionImpl(Variance.OUT_VARIANCE, erasedUpperBound) + else + // T : String -> * + makeStarProjection(parameter, attr) + } + } + + override fun isEmpty() = false + } private val nullable = c.storageManager.createLazyValue l@ { when (attr.flexibility) { @@ -349,6 +420,16 @@ class LazyJavaTypeResolver( } +private fun makeStarProjection( + typeParameter: TypeParameterDescriptor, + attr: JavaTypeAttributes +): TypeProjection { + return if (attr.howThisTypeIsUsed == SUPERTYPE) + TypeProjectionImpl(typeParameter.starProjectionType()) + else + StarProjectionImpl(typeParameter) +} + interface JavaTypeAttributes { val howThisTypeIsUsed: TypeUsage val howThisTypeIsUsedAccordingToAnnotations: TypeUsage @@ -360,6 +441,9 @@ interface JavaTypeAttributes { val typeAnnotations: Annotations val isForAnnotationParameter: Boolean get() = false + // Current type is upper bound of this type parameter + val upperBoundOfTypeParameter: TypeParameterDescriptor? + get() = null } enum class JavaTypeFlexibility { @@ -390,7 +474,11 @@ class LazyJavaTypeAttributes( internal fun Annotations.isMarkedNotNull() = findAnnotation(JETBRAINS_NOT_NULL_ANNOTATION) != null internal fun Annotations.isMarkedNullable() = findAnnotation(JETBRAINS_NULLABLE_ANNOTATION) != null -fun TypeUsage.toAttributes(allowFlexible: Boolean = true, isForAnnotationParameter: Boolean = false) = object : JavaTypeAttributes { +fun TypeUsage.toAttributes( + allowFlexible: Boolean = true, + isForAnnotationParameter: Boolean = false, + upperBoundForTypeParameter: TypeParameterDescriptor? = null +) = object : JavaTypeAttributes { override val howThisTypeIsUsed: TypeUsage = this@toAttributes override val howThisTypeIsUsedAccordingToAnnotations: TypeUsage get() = howThisTypeIsUsed @@ -400,9 +488,70 @@ fun TypeUsage.toAttributes(allowFlexible: Boolean = true, isForAnnotationParamet override val typeAnnotations: Annotations = Annotations.EMPTY override val isForAnnotationParameter: Boolean = isForAnnotationParameter + override val upperBoundOfTypeParameter: TypeParameterDescriptor? = upperBoundForTypeParameter } fun JavaTypeAttributes.toFlexible(flexibility: JavaTypeFlexibility) = object : JavaTypeAttributes by this { override val flexibility = flexibility } + + +// Definition: +// ErasedUpperBound(T : G) = G<*> // UpperBound(T) is a type G with arguments +// ErasedUpperBound(T : A) = A // UpperBound(T) is a type A without arguments +// ErasedUpperBound(T : F) = UpperBound(F) // UB(T) is another type parameter F +private fun TypeParameterDescriptor.getErasedUpperBound( + // Calculation of `potentiallyRecursiveTypeParameter.upperBounds` may recursively depend on `this.getErasedUpperBound` + // E.g. `class A` + // To prevent recursive calls return defaultValue() instead + potentiallyRecursiveTypeParameter: TypeParameterDescriptor? = null, + defaultValue: (() -> JetType) = { ErrorUtils.createErrorType("Can't compute erased upper bound of type parameter `$this`") } +): JetType { + if (this === potentiallyRecursiveTypeParameter) return defaultValue() + + val firstUpperBound = upperBounds.first() + + if (firstUpperBound.constructor.declarationDescriptor is ClassDescriptor) { + return firstUpperBound.replaceArgumentsWithStarProjections() + } + + val stopAt = potentiallyRecursiveTypeParameter ?: this + var current = firstUpperBound.constructor.declarationDescriptor as TypeParameterDescriptor + + while (current != stopAt) { + val nextUpperBound = current.upperBounds.first() + if (nextUpperBound.constructor.declarationDescriptor is ClassDescriptor) { + return nextUpperBound.replaceArgumentsWithStarProjections() + } + + current = nextUpperBound.constructor.declarationDescriptor as TypeParameterDescriptor + } + + return defaultValue() +} + +private fun JetType.replaceArgumentsWithStarProjections(): JetType { + 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: JetType): TypeProjection? { + // Let substitutor deal with flexibility + if (key.isFlexible()) return null + + val newProjections = key.constructor.parameters.map(::StarProjectionImpl) + + val substitution = IndexedParametersSubstitution(key.constructor, newProjections) + + return TypeProjectionImpl( + TypeSubstitutor.create(substitution).substitute(key.constructor.declarationDescriptor!!.defaultType, Variance.INVARIANT)!! + ) + } + + override fun isEmpty() = false +} diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhacement/typeEnhancement.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhacement/typeEnhancement.kt index 1ef38fcc189..4bf5e469691 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhacement/typeEnhancement.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/typeEnhacement/typeEnhancement.kt @@ -98,13 +98,18 @@ private fun JetType.enhanceInflexible(qualifiers: (Int) -> JavaTypeQualifiers, i enhancedNullabilityAnnotations ).filterNotNull().compositeAnnotationsOrSingle() + val (newSubstitution, substitutedEnhancedArgs) = computeNewSubstitutionAndArguments( + enhancedClassifier.typeConstructor.parameters, enhancedArguments + ) + val enhancedType = JetTypeImpl( newAnnotations, enhancedClassifier.getTypeConstructor(), enhancedNullability, - enhancedArguments, + substitutedEnhancedArgs, + newSubstitution, if (enhancedClassifier is ClassDescriptor) - enhancedClassifier.getMemberScope(enhancedArguments) + enhancedClassifier.getMemberScope(newSubstitution) else enhancedClassifier.getDefaultType().getMemberScope() ) return Result(enhancedType, globalArgIndex - index) diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitution.kt b/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitution.kt index 67b725244a3..cb030ffb999 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitution.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitution.kt @@ -90,3 +90,39 @@ public class IndexedParametersSubstitution( return null } } + +public fun JetType.computeNewSubstitutionAndArguments( + newParameters: List, + newArguments: List +): Pair> { + val previousSubstitution = getSubstitution() + if (newArguments.isEmpty()) return Pair(previousSubstitution, emptyList()) + + val newIndexedSubstitution = IndexedParametersSubstitution(newParameters, newArguments) + + // If previous substitution was trivial just replace it with indexed one + if (previousSubstitution is IndexedParametersSubstitution || previousSubstitution.isEmpty()) { + return Pair(newIndexedSubstitution, newArguments) + } + + val composedSubstitution = CompositeTypeSubstitution(newIndexedSubstitution, previousSubstitution) + val newSubstitutor = composedSubstitution.buildSubstitutor() + val resultArguments = newParameters.map { newSubstitutor.substitute(TypeProjectionImpl(it.variance, it.defaultType))!! } + + return Pair(composedSubstitution, resultArguments) +} + +private class CompositeTypeSubstitution( + private val first: TypeSubstitution, + private val second: TypeSubstitution +) : TypeSubstitution() { + + override fun get(key: JetType): TypeProjection? { + val firstResult = first[key] ?: return second[key] + return second.buildSubstitutor().substitute(firstResult) + } + + override fun isEmpty() = first.isEmpty() && second.isEmpty() + // + override fun approximateCapturedTypes() = first.approximateCapturedTypes() || second.approximateCapturedTypes() +} diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt index a8ada261c7d..5cee83e56a4 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeUtils.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.scopes.SubstitutingScope import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.checker.JetTypeChecker import org.jetbrains.kotlin.utils.toReadOnlyList @@ -134,3 +135,4 @@ fun JetType.containsError() = ErrorUtils.containsErrorType(this) public fun List.defaultProjections(): List = map { TypeProjectionImpl(it) } public fun JetType.isDefaultBound(): Boolean = KotlinBuiltIns.isDefaultBound(getSupertypeRepresentative()) + diff --git a/idea/testData/editor/quickDoc/JavaClassUsedInKotlin.kt b/idea/testData/editor/quickDoc/JavaClassUsedInKotlin.kt index ab68212b151..44e6aa4fdd6 100644 --- a/idea/testData/editor/quickDoc/JavaClassUsedInKotlin.kt +++ b/idea/testData/editor/quickDoc/JavaClassUsedInKotlin.kt @@ -2,4 +2,4 @@ fun testing() { SomeClass>() } -// INFO: public constructor SomeClass<T : (MutableList<out Any?>..List<Any?>?)>()
Java declaration:
[light_idea_test_case] public class SomeClass<T extends java.util.List> extends Object \ No newline at end of file +// INFO: public constructor SomeClass<T : (MutableList<Any?>..List<*>?)>()
Java declaration:
[light_idea_test_case] public class SomeClass<T extends java.util.List> extends Object \ No newline at end of file diff --git a/spec-docs/flexible-java-types.md b/spec-docs/flexible-java-types.md index 12b23399515..d8a4cc1bdf0 100644 --- a/spec-docs/flexible-java-types.md +++ b/spec-docs/flexible-java-types.md @@ -65,6 +65,49 @@ k(Foo) = Foo! k(int[]) = IntArray ``` +## Raw types +Raw Java types (see https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.8 for clarification) are loaded as usual flexible types with special arguments projections. + +``` +Raw(G..F) = (G..F) // T1 and T2 have invariant or `out` variance +Raw(G..F) = (G..F) // T1 and T2 have `in` variance +``` + +where `G..F` is initially loaded flexible type with yet unsubstituted type parameters. + +`ErasedUpperBound` defined as follows: + +``` +ErasedUpperBound(T : G) = G<*> // UB(T) is a type G with arguments +ErasedUpperBound(T : A) = A // UB(T) is a type A without arguments +ErasedUpperBound(T : F) = ErasedUpperBound(F) // UB(T) is another type parameter F +``` +and `UB(T)` means first upper bound with notation `T : UB(T)`. + +NOTE: On Java code with errors later definition may recursively depend on the same type parameter, +that should be handled properly, e.g. by loading such ErasedUpperBound as Error type + +Examples: + +``` +Raw(java.util.concurrent.Future) = (Future..Future?) +Raw(java.util.Collection) = (MutableCollection..Collection?) + +class A {} +Raw(A) = (A..A) + +Raw(java.lang.Enum) = (Enum>..Enum>?) +``` + +Also raw types have special types of contained members, each of them is replaced with it's JVM erasure representation: + +``` +Erase(T) = Erase(UpperBound(T)) // T is a type variable +Erase(Array) = Array +Erase(G) = Raw(G) // G is a type constructed with argument t mapped onto parameter T +Erase(A) = A // A is a type constructor without parameters +``` + ## Overriding When overriding a method from a Java class, one can not use flexible type, only replace them with denotable Kotlin types: