diff --git a/compiler/testData/codegen/boxWithJava/collections/irrelevantImplCharSequence/J.java b/compiler/testData/codegen/boxWithJava/collections/irrelevantImplCharSequence/J.java new file mode 100644 index 00000000000..c154786144b --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/collections/irrelevantImplCharSequence/J.java @@ -0,0 +1,15 @@ +public class J { + abstract static public class AImpl { + public char charAt(int index) { + return 'A'; + } + + public final int length() { return 56; } + } + + public static class A extends AImpl implements CharSequence { + public CharSequence subSequence(int start, int end) { + return null; + } + } +} diff --git a/compiler/testData/codegen/boxWithJava/collections/irrelevantImplCharSequence/irrelevantImplCharSequence.kt b/compiler/testData/codegen/boxWithJava/collections/irrelevantImplCharSequence/irrelevantImplCharSequence.kt new file mode 100644 index 00000000000..5bae53d8786 --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/collections/irrelevantImplCharSequence/irrelevantImplCharSequence.kt @@ -0,0 +1,9 @@ + +class X : J.A() + +fun box(): String { + val x = X() + if (x.length != 56) return "fail 1" + if (x[0] != 'A') return "fail 2" + return "OK" +} diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplCharSequence.kt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplCharSequence.kt new file mode 100644 index 00000000000..e544b2be1c8 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplCharSequence.kt @@ -0,0 +1,25 @@ +// FILE: AImpl.java + +abstract public class AImpl { + public char charAt(int index) { + return '1'; + } + + public final int length() { return 1; } +} + +// FILE: A.java +public class A extends AImpl implements CharSequence { + public CharSequence subSequence(int start, int end) { + return null; + } +} + +// FILE: X.kt +class X : A() + +fun main() { + val x = X() + x[0] + x.length +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplCharSequence.txt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplCharSequence.txt new file mode 100644 index 00000000000..cd494fa5f8a --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplCharSequence.txt @@ -0,0 +1,32 @@ +package + +public fun main(): kotlin.Unit + +public open class A : AImpl, kotlin.CharSequence { + public constructor A() + public final override /*2*/ /*fake_override*/ val length: kotlin.Int + public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*2*/ /*fake_override*/ fun get(/*0*/ index: kotlin.Int): kotlin.Char + public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ fun subSequence(/*0*/ start: kotlin.Int, /*1*/ end: kotlin.Int): kotlin.CharSequence + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String +} + +public abstract class AImpl { + public constructor AImpl() + public open fun charAt(/*0*/ index: kotlin.Int): kotlin.Char + 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 final fun length(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class X : A { + public constructor X() + public final override /*1*/ /*fake_override*/ val length: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun get(/*0*/ index: kotlin.Int): kotlin.Char + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun subSequence(/*0*/ start: kotlin.Int, /*1*/ end: kotlin.Int): kotlin.CharSequence + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplCharSequenceKotlin.kt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplCharSequenceKotlin.kt new file mode 100644 index 00000000000..65a03831ee2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplCharSequenceKotlin.kt @@ -0,0 +1,28 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER +// FILE: AImpl.kt + +abstract class AImpl { + fun charAt(index: Int): Char { + return '1' + } + + fun length(): Int { + return 1 + } +} + +// FILE: A.java +public class A extends AImpl implements CharSequence { + public CharSequence subSequence(int start, int end) { + return null; + } +} + +// FILE: X.kt +class X : A() + +fun main() { + val x = X() + x[0] + x.length +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplCharSequenceKotlin.txt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplCharSequenceKotlin.txt new file mode 100644 index 00000000000..fbdaaa36f03 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplCharSequenceKotlin.txt @@ -0,0 +1,32 @@ +package + +public fun main(): kotlin.Unit + +public open class A : AImpl, kotlin.CharSequence { + public constructor A() + public final override /*2*/ /*fake_override*/ val length: kotlin.Int + public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final override /*2*/ /*fake_override*/ fun get(/*0*/ index: kotlin.Int): kotlin.Char + public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ fun subSequence(/*0*/ start: kotlin.Int, /*1*/ end: kotlin.Int): kotlin.CharSequence + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String +} + +public abstract class AImpl { + public constructor AImpl() + public final fun charAt(/*0*/ index: kotlin.Int): kotlin.Char + 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 final fun length(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class X : A { + public constructor X() + public final override /*1*/ /*fake_override*/ val length: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final override /*1*/ /*fake_override*/ fun get(/*0*/ index: kotlin.Int): kotlin.Char + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun subSequence(/*0*/ start: kotlin.Int, /*1*/ end: kotlin.Int): kotlin.CharSequence + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplMutableList.kt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplMutableList.kt new file mode 100644 index 00000000000..d421efa2b10 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplMutableList.kt @@ -0,0 +1,119 @@ +// FILE: AImpl.java + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; + +public abstract class AImpl { + public int size() { + return 0; + } + + public boolean isEmpty() { + return false; + } + + public boolean contains(Object o) { + return false; + } + + public Iterator iterator() { + return null; + } + + public Object[] toArray() { + return new Object[0]; + } + + public T[] toArray(T[] a) { + return null; + } + + public boolean add(String s) { + return false; + } + + public boolean remove(Object o) { + return false; + } + + public boolean containsAll(Collection c) { + return false; + } + + public boolean addAll(Collection c) { + return false; + } + + public boolean addAll(int index, Collection c) { + return false; + } + + public boolean removeAll(Collection c) { + return false; + } + + public boolean retainAll(Collection c) { + return false; + } + + public void clear() { + + } + + public String get(int index) { + return null; + } + + public String set(int index, String element) { + return null; + } + + public void add(int index, String element) { + + } + + public String remove(int index) { + return null; + } + + public int indexOf(Object o) { + return 0; + } + + public int lastIndexOf(Object o) { + return 0; + } + + public ListIterator listIterator() { + return null; + } + + public ListIterator listIterator(int index) { + return null; + } + + public List subList(int fromIndex, int toIndex) { + return null; + } +} + + +// FILE: A.java +import java.util.List; + +public class A extends AImpl implements List { + +} + +// FILE: X.kt +class X : A() + +fun main() { + val x = X() + x[0] + x.size + x.remove("") + x.remove(1) +} diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplMutableList.txt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplMutableList.txt new file mode 100644 index 00000000000..82a7679aa40 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplMutableList.txt @@ -0,0 +1,93 @@ +package + +public fun main(): kotlin.Unit + +public open class A : AImpl, kotlin.MutableList { + public constructor A() + public open override /*2*/ /*fake_override*/ val size: kotlin.Int + public open override /*2*/ /*fake_override*/ fun add(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.String!): kotlin.Unit + public open override /*2*/ /*fake_override*/ fun add(/*0*/ element: kotlin.String!): kotlin.Boolean + public open override /*2*/ /*fake_override*/ fun addAll(/*0*/ elements: kotlin.Collection): kotlin.Boolean + public open override /*2*/ /*fake_override*/ fun addAll(/*0*/ index: kotlin.Int, /*1*/ elements: kotlin.Collection): kotlin.Boolean + public open override /*2*/ /*fake_override*/ fun clear(): kotlin.Unit + public open override /*2*/ /*fake_override*/ fun contains(/*0*/ o: kotlin.String!): kotlin.Boolean + public open override /*2*/ /*fake_override*/ fun containsAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*2*/ /*fake_override*/ fun get(/*0*/ index: kotlin.Int): kotlin.String! + public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*2*/ /*fake_override*/ fun indexOf(/*0*/ o: kotlin.String!): kotlin.Int + public open override /*2*/ /*fake_override*/ fun isEmpty(): kotlin.Boolean + public open override /*2*/ /*fake_override*/ fun iterator(): kotlin.MutableIterator + public open override /*2*/ /*fake_override*/ fun lastIndexOf(/*0*/ o: kotlin.String!): kotlin.Int + public open override /*2*/ /*fake_override*/ fun listIterator(): kotlin.MutableListIterator + public open override /*2*/ /*fake_override*/ fun listIterator(/*0*/ index: kotlin.Int): kotlin.MutableListIterator + public open override /*2*/ /*fake_override*/ fun remove(/*0*/ o: kotlin.String!): kotlin.Boolean + public open override /*2*/ /*fake_override*/ fun removeAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public open override /*2*/ /*fake_override*/ fun removeAt(/*0*/ index: kotlin.Int): kotlin.String! + public open override /*2*/ /*fake_override*/ fun retainAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public open override /*2*/ /*fake_override*/ fun set(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.String!): kotlin.String! + public open override /*2*/ /*fake_override*/ fun subList(/*0*/ fromIndex: kotlin.Int, /*1*/ toIndex: kotlin.Int): kotlin.MutableList + public open override /*1*/ /*fake_override*/ fun toArray(): kotlin.Array<(out) kotlin.Any!>! + public open override /*1*/ /*fake_override*/ fun toArray(/*0*/ a: kotlin.Array<(out) T!>!): kotlin.Array<(out) T!>! + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String +} + +public abstract class AImpl { + public constructor AImpl() + public open fun add(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.String!): kotlin.Unit + public open fun add(/*0*/ s: kotlin.String!): kotlin.Boolean + public open fun addAll(/*0*/ c: (kotlin.MutableCollection..kotlin.Collection?)): kotlin.Boolean + public open fun addAll(/*0*/ index: kotlin.Int, /*1*/ c: (kotlin.MutableCollection..kotlin.Collection?)): kotlin.Boolean + public open fun clear(): kotlin.Unit + public open operator fun contains(/*0*/ o: kotlin.Any!): kotlin.Boolean + public open fun containsAll(/*0*/ c: kotlin.(Mutable)Collection<*>!): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open operator fun get(/*0*/ index: kotlin.Int): kotlin.String! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open fun indexOf(/*0*/ o: kotlin.Any!): kotlin.Int + public open fun isEmpty(): kotlin.Boolean + public open operator fun iterator(): kotlin.(Mutable)Iterator! + public open fun lastIndexOf(/*0*/ o: kotlin.Any!): kotlin.Int + public open fun listIterator(): kotlin.(Mutable)ListIterator! + public open fun listIterator(/*0*/ index: kotlin.Int): kotlin.(Mutable)ListIterator! + public open fun remove(/*0*/ o: kotlin.Any!): kotlin.Boolean + public open fun remove(/*0*/ index: kotlin.Int): kotlin.String! + public open fun removeAll(/*0*/ c: kotlin.(Mutable)Collection<*>!): kotlin.Boolean + public open fun retainAll(/*0*/ c: kotlin.(Mutable)Collection<*>!): kotlin.Boolean + public open operator fun set(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.String!): kotlin.String! + public open fun size(): kotlin.Int + public open fun subList(/*0*/ fromIndex: kotlin.Int, /*1*/ toIndex: kotlin.Int): kotlin.(Mutable)List! + public open fun toArray(): kotlin.Array<(out) kotlin.Any!>! + public open fun toArray(/*0*/ a: kotlin.Array<(out) T!>!): kotlin.Array<(out) T!>! + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class X : A { + public constructor X() + public open override /*1*/ /*fake_override*/ val size: kotlin.Int + public open override /*1*/ /*fake_override*/ fun add(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.String!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun add(/*0*/ element: kotlin.String!): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun addAll(/*0*/ elements: kotlin.Collection): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun addAll(/*0*/ index: kotlin.Int, /*1*/ elements: kotlin.Collection): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun clear(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun contains(/*0*/ o: kotlin.String!): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun containsAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun get(/*0*/ index: kotlin.Int): kotlin.String! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun indexOf(/*0*/ o: kotlin.String!): kotlin.Int + public open override /*1*/ /*fake_override*/ fun isEmpty(): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun iterator(): kotlin.MutableIterator + public open override /*1*/ /*fake_override*/ fun lastIndexOf(/*0*/ o: kotlin.String!): kotlin.Int + public open override /*1*/ /*fake_override*/ fun listIterator(): kotlin.MutableListIterator + public open override /*1*/ /*fake_override*/ fun listIterator(/*0*/ index: kotlin.Int): kotlin.MutableListIterator + public open override /*1*/ /*fake_override*/ fun remove(/*0*/ o: kotlin.String!): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun removeAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun removeAt(/*0*/ index: kotlin.Int): kotlin.String! + public open override /*1*/ /*fake_override*/ fun retainAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun set(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.String!): kotlin.String! + public open override /*1*/ /*fake_override*/ fun subList(/*0*/ fromIndex: kotlin.Int, /*1*/ toIndex: kotlin.Int): kotlin.MutableList + public open override /*1*/ /*fake_override*/ fun toArray(): kotlin.Array<(out) kotlin.Any!>! + public open override /*1*/ /*fake_override*/ fun toArray(/*0*/ a: kotlin.Array<(out) T!>!): kotlin.Array<(out) T!>! + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplMutableListKotlin.kt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplMutableListKotlin.kt new file mode 100644 index 00000000000..438ff6625a2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplMutableListKotlin.kt @@ -0,0 +1,106 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER +// FILE: AImpl.kt + +public abstract class AImpl { + fun add(element: String): Boolean { + throw UnsupportedOperationException() + } + + fun remove(element: String): Boolean { + throw UnsupportedOperationException() + } + + fun addAll(elements: Collection): Boolean { + throw UnsupportedOperationException() + } + + fun addAll(index: Int, elements: Collection): Boolean { + throw UnsupportedOperationException() + } + + fun removeAll(elements: Collection): Boolean { + throw UnsupportedOperationException() + } + + fun retainAll(elements: Collection): Boolean { + throw UnsupportedOperationException() + } + + fun clear() { + throw UnsupportedOperationException() + } + + fun set(index: Int, element: String): String { + throw UnsupportedOperationException() + } + + fun add(index: Int, element: String) { + throw UnsupportedOperationException() + } + + fun remove(index: Int): String { + throw UnsupportedOperationException() + } + + fun listIterator(): MutableListIterator { + throw UnsupportedOperationException() + } + + fun listIterator(index: Int): MutableListIterator { + throw UnsupportedOperationException() + } + + fun subList(fromIndex: Int, toIndex: Int): MutableList { + throw UnsupportedOperationException() + } + + val size: Int + get() = throw UnsupportedOperationException() + + fun isEmpty(): Boolean { + throw UnsupportedOperationException() + } + + fun contains(element: Any?): Boolean { + throw UnsupportedOperationException() + } + + fun containsAll(elements: Collection<*>): Boolean { + throw UnsupportedOperationException() + } + + fun get(index: Int): String { + throw UnsupportedOperationException() + } + + fun indexOf(element: String): Int { + throw UnsupportedOperationException() + } + + fun lastIndexOf(element: String): Int { + throw UnsupportedOperationException() + } + + fun iterator(): MutableIterator { + throw UnsupportedOperationException() + } +} + + +// FILE: A.java +import java.util.List; + +public class A extends AImpl implements List { + +} + +// FILE: X.kt +class X : A() + +fun main() { + val x = X() + x[0] + x.size + x.remove("") + x.remove(1) +} diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplMutableListKotlin.txt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplMutableListKotlin.txt new file mode 100644 index 00000000000..450e5a6a32d --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplMutableListKotlin.txt @@ -0,0 +1,87 @@ +package + +public fun main(): kotlin.Unit + +public open class A : AImpl, kotlin.MutableList { + public constructor A() + public final override /*2*/ /*fake_override*/ val size: kotlin.Int + public final override /*2*/ /*fake_override*/ fun add(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.String!): kotlin.Unit + public final override /*2*/ /*fake_override*/ fun add(/*0*/ element: kotlin.String!): kotlin.Boolean + public final override /*2*/ /*fake_override*/ fun addAll(/*0*/ elements: kotlin.Collection): kotlin.Boolean + public final override /*2*/ /*fake_override*/ fun addAll(/*0*/ index: kotlin.Int, /*1*/ elements: kotlin.Collection): kotlin.Boolean + public final override /*2*/ /*fake_override*/ fun clear(): kotlin.Unit + public final override /*2*/ /*fake_override*/ fun contains(/*0*/ element: kotlin.String!): kotlin.Boolean + public final override /*2*/ /*fake_override*/ fun containsAll(/*0*/ elements: kotlin.Collection): kotlin.Boolean + public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final override /*2*/ /*fake_override*/ fun get(/*0*/ index: kotlin.Int): kotlin.String! + public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final override /*2*/ /*fake_override*/ fun indexOf(/*0*/ element: kotlin.String!): kotlin.Int + public final override /*2*/ /*fake_override*/ fun isEmpty(): kotlin.Boolean + public final override /*2*/ /*fake_override*/ fun iterator(): kotlin.MutableIterator + public final override /*2*/ /*fake_override*/ fun lastIndexOf(/*0*/ element: kotlin.String!): kotlin.Int + public final override /*2*/ /*fake_override*/ fun listIterator(): kotlin.MutableListIterator + public final override /*2*/ /*fake_override*/ fun listIterator(/*0*/ index: kotlin.Int): kotlin.MutableListIterator + public final override /*2*/ /*fake_override*/ fun remove(/*0*/ element: kotlin.String!): kotlin.Boolean + public final override /*2*/ /*fake_override*/ fun removeAll(/*0*/ elements: kotlin.Collection): kotlin.Boolean + public final override /*2*/ /*fake_override*/ fun removeAt(/*0*/ index: kotlin.Int): kotlin.String + public final override /*2*/ /*fake_override*/ fun retainAll(/*0*/ elements: kotlin.Collection): kotlin.Boolean + public final override /*2*/ /*fake_override*/ fun set(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.String!): kotlin.String! + public final override /*2*/ /*fake_override*/ fun subList(/*0*/ fromIndex: kotlin.Int, /*1*/ toIndex: kotlin.Int): kotlin.MutableList + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String +} + +public abstract class AImpl { + public constructor AImpl() + public final val size: kotlin.Int + public final fun add(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.String): kotlin.Unit + public final fun add(/*0*/ element: kotlin.String): kotlin.Boolean + public final fun addAll(/*0*/ elements: kotlin.Collection): kotlin.Boolean + public final fun addAll(/*0*/ index: kotlin.Int, /*1*/ elements: kotlin.Collection): kotlin.Boolean + public final fun clear(): kotlin.Unit + public final fun contains(/*0*/ element: kotlin.Any?): kotlin.Boolean + public final fun containsAll(/*0*/ elements: kotlin.Collection<*>): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun get(/*0*/ index: kotlin.Int): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final fun indexOf(/*0*/ element: kotlin.String): kotlin.Int + public final fun isEmpty(): kotlin.Boolean + public final fun iterator(): kotlin.MutableIterator + public final fun lastIndexOf(/*0*/ element: kotlin.String): kotlin.Int + public final fun listIterator(): kotlin.MutableListIterator + public final fun listIterator(/*0*/ index: kotlin.Int): kotlin.MutableListIterator + public final fun remove(/*0*/ index: kotlin.Int): kotlin.String + public final fun remove(/*0*/ element: kotlin.String): kotlin.Boolean + public final fun removeAll(/*0*/ elements: kotlin.Collection): kotlin.Boolean + public final fun retainAll(/*0*/ elements: kotlin.Collection): kotlin.Boolean + public final fun set(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.String): kotlin.String + public final fun subList(/*0*/ fromIndex: kotlin.Int, /*1*/ toIndex: kotlin.Int): kotlin.MutableList + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class X : A { + public constructor X() + public final override /*1*/ /*fake_override*/ val size: kotlin.Int + public final override /*1*/ /*fake_override*/ fun add(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.String!): kotlin.Unit + public final override /*1*/ /*fake_override*/ fun add(/*0*/ element: kotlin.String!): kotlin.Boolean + public final override /*1*/ /*fake_override*/ fun addAll(/*0*/ elements: kotlin.Collection): kotlin.Boolean + public final override /*1*/ /*fake_override*/ fun addAll(/*0*/ index: kotlin.Int, /*1*/ elements: kotlin.Collection): kotlin.Boolean + public final override /*1*/ /*fake_override*/ fun clear(): kotlin.Unit + public final override /*1*/ /*fake_override*/ fun contains(/*0*/ element: kotlin.String!): kotlin.Boolean + public final override /*1*/ /*fake_override*/ fun containsAll(/*0*/ elements: kotlin.Collection): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final override /*1*/ /*fake_override*/ fun get(/*0*/ index: kotlin.Int): kotlin.String! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final override /*1*/ /*fake_override*/ fun indexOf(/*0*/ element: kotlin.String!): kotlin.Int + public final override /*1*/ /*fake_override*/ fun isEmpty(): kotlin.Boolean + public final override /*1*/ /*fake_override*/ fun iterator(): kotlin.MutableIterator + public final override /*1*/ /*fake_override*/ fun lastIndexOf(/*0*/ element: kotlin.String!): kotlin.Int + public final override /*1*/ /*fake_override*/ fun listIterator(): kotlin.MutableListIterator + public final override /*1*/ /*fake_override*/ fun listIterator(/*0*/ index: kotlin.Int): kotlin.MutableListIterator + public final override /*1*/ /*fake_override*/ fun remove(/*0*/ element: kotlin.String!): kotlin.Boolean + public final override /*1*/ /*fake_override*/ fun removeAll(/*0*/ elements: kotlin.Collection): kotlin.Boolean + public final override /*1*/ /*fake_override*/ fun removeAt(/*0*/ index: kotlin.Int): kotlin.String + public final override /*1*/ /*fake_override*/ fun retainAll(/*0*/ elements: kotlin.Collection): kotlin.Boolean + public final override /*1*/ /*fake_override*/ fun set(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.String!): kotlin.String! + public final override /*1*/ /*fake_override*/ fun subList(/*0*/ fromIndex: kotlin.Int, /*1*/ toIndex: kotlin.Int): kotlin.MutableList + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index 8af0bc22834..5348ec126bb 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -9344,6 +9344,30 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("irrelevantImplCharSequence.kt") + public void testIrrelevantImplCharSequence() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplCharSequence.kt"); + doTest(fileName); + } + + @TestMetadata("irrelevantImplCharSequenceKotlin.kt") + public void testIrrelevantImplCharSequenceKotlin() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplCharSequenceKotlin.kt"); + doTest(fileName); + } + + @TestMetadata("irrelevantImplMutableList.kt") + public void testIrrelevantImplMutableList() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplMutableList.kt"); + doTest(fileName); + } + + @TestMetadata("irrelevantImplMutableListKotlin.kt") + public void testIrrelevantImplMutableListKotlin() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/collectionOverrides/irrelevantImplMutableListKotlin.kt"); + doTest(fileName); + } + @TestMetadata("mapGetOverride.kt") public void testMapGetOverride() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/collectionOverrides/mapGetOverride.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java index eea869b5faf..3b2df98ae08 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java @@ -209,6 +209,12 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege doTestWithJava(fileName); } + @TestMetadata("irrelevantImplCharSequence") + public void testIrrelevantImplCharSequence() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/collections/irrelevantImplCharSequence/"); + doTestWithJava(fileName); + } + @TestMetadata("irrelevantRemoveAtOverrideInJava") public void testIrrelevantRemoveAtOverrideInJava() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/collections/irrelevantRemoveAtOverrideInJava/"); diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt index fed227c3b87..6caf99b3046 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassMemberScope.kt @@ -19,9 +19,7 @@ package org.jetbrains.kotlin.load.java.lazy.descriptors import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations -import org.jetbrains.kotlin.descriptors.impl.ConstructorDescriptorImpl -import org.jetbrains.kotlin.descriptors.impl.EnumEntrySyntheticClassDescriptor -import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl +import org.jetbrains.kotlin.descriptors.impl.* import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.load.java.* @@ -88,17 +86,26 @@ public class LazyJavaClassMemberScope( ).toReadOnlyList() } - override fun JavaMethodDescriptor.isVisibleAsFunction() = isVisibleAsFunction(this) - - private fun isVisibleAsFunction(function: SimpleFunctionDescriptor): Boolean { - // Do not load Java annotation methods as Kotlin functions (load them as properties instead) + override fun JavaMethodDescriptor.isVisibleAsFunction(): Boolean { if (jClass.isAnnotationType) return false + return isVisibleAsFunctionInCurrentClass(this) + } + private fun isVisibleAsFunctionInCurrentClass(function: SimpleFunctionDescriptor): Boolean { if (getPropertyNamesCandidatesByAccessorName(function.name).any { propertyName -> getPropertiesFromSupertypes(propertyName).any { property -> - doesClassOverridesProperty(property) && (property.isVar || !JvmAbi.isSetterName(function.name.asString())) + doesClassOverridesProperty(property) { + accessorName -> + // This lambda should return property accessors available in this class by their name + // If 'accessorName' is current function we return only it just because we check exactly + // that current method is override of accessor + if (function.name == accessorName) + listOf(function) + else + searchMethodsByNameWithoutBuiltinMagic(accessorName) + searchMethodsInSupertypesWithoutBuiltinMagic(accessorName) + } && (property.isVar || !JvmAbi.isSetterName(function.name.asString())) } }) return false @@ -116,7 +123,11 @@ public class LazyJavaClassMemberScope( private fun searchMethodsByNameWithoutBuiltinMagic(name: Name): Collection = memberIndex().findMethodsByName(name).map { resolveMethodToFunctionDescriptor(it) } - private fun searchMethodsByNameWithoutBuiltinMagic(name: String) = searchMethodsByNameWithoutBuiltinMagic(Name.identifier(name)) + private fun searchMethodsInSupertypesWithoutBuiltinMagic(name: Name): Collection = + getFunctionsFromSupertypes(name).filterNot { + it.doesOverrideBuiltinWithDifferentJvmName() + || BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(it) != null + } private fun SimpleFunctionDescriptor.doesOverrideRenamedBuiltins(): Boolean { return BuiltinMethodsWithDifferentJvmName.getBuiltinFunctionNamesByJvmName(name).any { @@ -144,21 +155,26 @@ public class LazyJavaClassMemberScope( ).result == OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE } - private fun PropertyDescriptor.findGetterOverride(): SimpleFunctionDescriptor? { + private fun PropertyDescriptor.findGetterOverride( + functions: (Name) -> Collection + ): SimpleFunctionDescriptor? { val overriddenBuiltinProperty = getter?.getOverriddenBuiltinWithDifferentJvmName() val specialGetterName = overriddenBuiltinProperty?.getBuiltinSpecialPropertyGetterName() if (specialGetterName != null && !this@LazyJavaClassMemberScope.getContainingDeclaration().hasRealKotlinSuperClassWithOverrideOf( overriddenBuiltinProperty!!) ) { - return findGetterByName(specialGetterName) + return findGetterByName(specialGetterName, functions) } - return findGetterByName(JvmAbi.getterName(name.asString())) + return findGetterByName(JvmAbi.getterName(name.asString()), functions) } - private fun PropertyDescriptor.findGetterByName(getterName: String): SimpleFunctionDescriptor? { - return searchMethodsByNameWithoutBuiltinMagic(getterName).firstNotNullResult factory@{ + private fun PropertyDescriptor.findGetterByName( + getterName: String, + functions: (Name) -> Collection + ): SimpleFunctionDescriptor? { + return functions(Name.identifier(getterName)).firstNotNullResult factory@{ descriptor -> if (descriptor.valueParameters.size != 0) return@factory null @@ -166,8 +182,10 @@ public class LazyJavaClassMemberScope( } } - private fun PropertyDescriptor.findSetterOverride(): SimpleFunctionDescriptor? { - return searchMethodsByNameWithoutBuiltinMagic(JvmAbi.setterName(name.asString())).firstNotNullResult factory@{ + private fun PropertyDescriptor.findSetterOverride( + functions: (Name) -> Collection + ): SimpleFunctionDescriptor? { + return functions(Name.identifier(JvmAbi.setterName(name.asString()))).firstNotNullResult factory@{ descriptor -> if (descriptor.valueParameters.size != 1) return@factory null @@ -176,10 +194,13 @@ public class LazyJavaClassMemberScope( } } - private fun doesClassOverridesProperty(property: PropertyDescriptor): Boolean { + private fun doesClassOverridesProperty( + property: PropertyDescriptor, + functions: (Name) -> Collection + ): Boolean { if (property.isJavaField) return false - val getter = property.findGetterOverride() - val setter = property.findSetterOverride() + val getter = property.findGetterOverride(functions) + val setter = property.findSetterOverride(functions) if (getter == null) return false if (!property.isVar) return true @@ -190,29 +211,56 @@ public class LazyJavaClassMemberScope( override fun computeNonDeclaredFunctions(result: MutableCollection, name: Name) { val functionsFromSupertypes = getFunctionsFromSupertypes(name) - if (name.sameAsRenamedInJvmBuiltin || name.sameAsBuiltinMethodWithErasedValueParameters) { - addOverriddenBuiltinMethods(result, name, functionsFromSupertypes) + if (!name.sameAsRenamedInJvmBuiltin && !name.sameAsBuiltinMethodWithErasedValueParameters) { + addFunctionFromSupertypes(result, name, functionsFromSupertypes.filter { isVisibleAsFunctionInCurrentClass(it) }) + return } - result.addAll(DescriptorResolverUtils.resolveOverrides(name, functionsFromSupertypes, result, getContainingDeclaration(), c.components.errorReporter)) - } + var specialBuiltinsFromSuperTypes = SmartSet.create() - private fun addOverriddenBuiltinMethods( - result: MutableCollection, - name: Name, - functionsFromSupertypes: Set - ) { // Merge functions with same signatures val mergedFunctionFromSuperTypes = DescriptorResolverUtils.resolveOverrides( name, functionsFromSupertypes, emptyList(), getContainingDeclaration(), ErrorReporter.DO_NOTHING) - for (descriptor in mergedFunctionFromSuperTypes) { + // add declarations + addOverriddenBuiltinMethods(name, result, mergedFunctionFromSuperTypes, result) { + searchMethodsByNameWithoutBuiltinMagic(it) + } + + // add from super types + addOverriddenBuiltinMethods(name, result, mergedFunctionFromSuperTypes, specialBuiltinsFromSuperTypes) { + searchMethodsInSupertypesWithoutBuiltinMagic(it) + } + + val visibleFunctionsFromSupertypes = + functionsFromSupertypes.filter { isVisibleAsFunctionInCurrentClass(it) } + specialBuiltinsFromSuperTypes + + addFunctionFromSupertypes(result, name, visibleFunctionsFromSupertypes) + } + + private fun addFunctionFromSupertypes( + result: MutableCollection, + name: Name, + functionsFromSupertypes: Collection + ) { + result.addAll(DescriptorResolverUtils.resolveOverrides( + name, functionsFromSupertypes, result, getContainingDeclaration(), c.components.errorReporter)) + } + + private fun addOverriddenBuiltinMethods( + name: Name, + alreadyDeclaredFunctions: Collection, + candidatesForOverride: Collection, + result: MutableCollection, + functions: (Name) -> Collection + ) { + for (descriptor in candidatesForOverride) { val overriddenBuiltin = descriptor.getOverriddenBuiltinWithDifferentJvmName() ?: continue - if (result.any { it.doesOverride(overriddenBuiltin) }) continue + if (alreadyDeclaredFunctions.any { it.doesOverride(overriddenBuiltin) }) continue val nameInJava = getJvmMethodNameIfSpecial(overriddenBuiltin)!! - for (method in searchMethodsByNameWithoutBuiltinMagic(nameInJava)) { + for (method in functions(Name.identifier(nameInJava))) { val renamedCopy = method.createRenamedCopy(name) if (isOverridableRenamedDescriptor(overriddenBuiltin, renamedCopy)) { @@ -221,21 +269,27 @@ public class LazyJavaClassMemberScope( } } - for (descriptor in mergedFunctionFromSuperTypes) { - val overridden = + for (descriptor in candidatesForOverride) { + val overriddenBuiltin = BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(descriptor) ?: continue - if (result.any { it.doesOverride(overridden) }) continue + if (alreadyDeclaredFunctions.any { it.doesOverride(overriddenBuiltin) }) continue - result.addIfNotNull( - createOverrideForBuiltinFunctionWithErasedParameterIfNeeded(overridden) - ?.check { override -> isVisibleAsFunction(override) }) + createOverrideForBuiltinFunctionWithErasedParameterIfNeeded(overriddenBuiltin, functions)?.let { + override -> + if (isVisibleAsFunctionInCurrentClass(override)) { + result.add(override) + } + } } } - private fun createOverrideForBuiltinFunctionWithErasedParameterIfNeeded(overridden: FunctionDescriptor): SimpleFunctionDescriptor? { - return searchMethodsByNameWithoutBuiltinMagic(overridden.name).firstOrNull { + private fun createOverrideForBuiltinFunctionWithErasedParameterIfNeeded( + overridden: FunctionDescriptor, + functions: (Name) -> Collection + ): SimpleFunctionDescriptor? { + return functions(overridden.name).firstOrNull { it.doesOverrideBuiltinFunctionWithErasedValueParameters(overridden) }?.let { override -> @@ -257,18 +311,27 @@ public class LazyJavaClassMemberScope( } val propertiesFromSupertypes = getPropertiesFromSupertypes(name) - addPropertyOverrideByMethod(propertiesFromSupertypes, result) + if (propertiesFromSupertypes.isEmpty()) return - result.addAll(DescriptorResolverUtils.resolveOverrides(name, propertiesFromSupertypes, result, getContainingDeclaration(), - c.components.errorReporter)) + val propertiesOverridesFromSuperTypes = SmartSet.create() + + addPropertyOverrideByMethod(propertiesFromSupertypes, result) { searchMethodsByNameWithoutBuiltinMagic(it) } + + addPropertyOverrideByMethod(propertiesFromSupertypes, propertiesOverridesFromSuperTypes) { + searchMethodsInSupertypesWithoutBuiltinMagic(it) + } + + result.addAll(DescriptorResolverUtils.resolveOverrides( + name, propertiesFromSupertypes + propertiesOverridesFromSuperTypes, result, getContainingDeclaration(), c.components.errorReporter)) } private fun addPropertyOverrideByMethod( propertiesFromSupertypes: Set, - result: MutableCollection + result: MutableCollection, + functions: (Name) -> Collection ) { for (property in propertiesFromSupertypes) { - val newProperty = createPropertyDescriptorByMethods(property) + val newProperty = createPropertyDescriptorByMethods(property, functions) if (newProperty != null) { result.add(newProperty) break @@ -303,14 +366,15 @@ public class LazyJavaClassMemberScope( } private fun createPropertyDescriptorByMethods( - overriddenProperty: PropertyDescriptor + overriddenProperty: PropertyDescriptor, + functions: (Name) -> Collection ): JavaPropertyDescriptor? { - if (!doesClassOverridesProperty(overriddenProperty)) return null + if (!doesClassOverridesProperty(overriddenProperty, functions)) return null - val getterMethod = overriddenProperty.findGetterOverride()!! + val getterMethod = overriddenProperty.findGetterOverride(functions)!! val setterMethod = if (overriddenProperty.isVar) - overriddenProperty.findSetterOverride()!! + overriddenProperty.findSetterOverride(functions)!! else null