From e062e32f9558f708823b7433dd8ea1386e0664b8 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Tue, 13 Oct 2015 17:48:41 +0300 Subject: [PATCH] Do not load special builtin overrides from Java as synthesized It has been done just to avoid clashes with real declarations that look like our builtins: e.g. 'String removeAt(int index) {}' and 'String remove(int index) {}'in Java. But synthesized members are even weaker than extensions. Solution is just to ignore the latter declaration and treat first as effective override of out builltin. --- .../collectionOverrides/commonCollections.kt | 28 ++++ .../collectionOverrides/commonCollections.txt | 3 + .../j+k/collectionOverrides/contains.txt | 6 +- .../j+k/collectionOverrides/containsAll.txt | 6 +- .../containsAndOverload.txt | 3 +- .../collectionOverrides/mapGetOverride.txt | 2 +- .../overridesBuiltinNoMagic.kt | 157 ++++++++++++++++++ .../overridesBuiltinNoMagic.txt | 63 +++++++ .../j+k/collectionOverrides/removeAt.txt | 2 +- .../j+k/collectionOverrides/removeAtInt.txt | 2 +- .../testsWithStdLib/commonCollections.kt | 28 ++++ .../testsWithStdLib/commonCollections.txt | 3 + .../checkers/JetDiagnosticsTestGenerated.java | 12 ++ ...JetDiagnosticsTestWithStdLibGenerated.java | 6 + .../JavaConstructorDescriptor.java | 2 +- .../descriptors/JavaMethodDescriptor.java | 2 +- .../kotlin/load/java/descriptors/util.kt | 10 +- .../descriptors/LazyJavaClassMemberScope.kt | 77 ++++++--- 18 files changed, 375 insertions(+), 37 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/j+k/collectionOverrides/commonCollections.kt create mode 100644 compiler/testData/diagnostics/tests/j+k/collectionOverrides/commonCollections.txt create mode 100644 compiler/testData/diagnostics/tests/j+k/collectionOverrides/overridesBuiltinNoMagic.kt create mode 100644 compiler/testData/diagnostics/tests/j+k/collectionOverrides/overridesBuiltinNoMagic.txt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/commonCollections.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/commonCollections.txt diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/commonCollections.kt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/commonCollections.kt new file mode 100644 index 00000000000..79ff8cf3b38 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/commonCollections.kt @@ -0,0 +1,28 @@ +import java.util.* +fun foo() { + val al = ArrayList() + al.size + al.contains(1) + al.contains("") + + al.remove("") + al.removeAt(1) + + val hs = HashSet() + hs.size + hs.contains(1) + hs.contains("") + + hs.remove("") + + + val hm = HashMap() + hm.size + hm.containsKey(1) + hm.containsKey("") + + hm[1] + hm[""] + + hm.remove("") +} diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/commonCollections.txt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/commonCollections.txt new file mode 100644 index 00000000000..65a6ac47e1f --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/commonCollections.txt @@ -0,0 +1,3 @@ +package + +public fun foo(): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/contains.txt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/contains.txt index bb0b3563a43..adb122d2c34 100644 --- a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/contains.txt +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/contains.txt @@ -9,7 +9,7 @@ public abstract class A : kotlin.MutableCollection { public abstract override /*1*/ /*fake_override*/ fun add(/*0*/ e: T!): kotlin.Boolean public abstract override /*1*/ /*fake_override*/ fun addAll(/*0*/ c: kotlin.Collection): kotlin.Boolean public abstract override /*1*/ /*fake_override*/ fun clear(): kotlin.Unit - public open override /*1*/ /*synthesized*/ fun contains(/*0*/ o: T!): kotlin.Boolean + public open override /*1*/ fun contains(/*0*/ o: T!): kotlin.Boolean public abstract 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 hashCode(): kotlin.Int @@ -27,7 +27,7 @@ public abstract class B : kotlin.MutableCollection { public abstract override /*1*/ /*fake_override*/ fun add(/*0*/ e: kotlin.String!): kotlin.Boolean public abstract override /*1*/ /*fake_override*/ fun addAll(/*0*/ c: kotlin.Collection): kotlin.Boolean public abstract override /*1*/ /*fake_override*/ fun clear(): kotlin.Unit - public open override /*1*/ /*synthesized*/ fun contains(/*0*/ x: kotlin.String!): kotlin.Boolean + public open override /*1*/ fun contains(/*0*/ x: kotlin.String!): kotlin.Boolean public abstract 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 hashCode(): kotlin.Int @@ -44,7 +44,7 @@ public interface IC : kotlin.MutableCollection { public abstract override /*1*/ /*fake_override*/ fun add(/*0*/ e: kotlin.String!): kotlin.Boolean public abstract override /*1*/ /*fake_override*/ fun addAll(/*0*/ c: kotlin.Collection): kotlin.Boolean public abstract override /*1*/ /*fake_override*/ fun clear(): kotlin.Unit - public abstract override /*1*/ /*synthesized*/ fun contains(/*0*/ x: kotlin.String!): kotlin.Boolean + public abstract override /*1*/ fun contains(/*0*/ x: kotlin.String!): kotlin.Boolean public abstract 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 hashCode(): kotlin.Int diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAll.txt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAll.txt index fca71bdb162..4fb8ab879ce 100644 --- a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAll.txt +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAll.txt @@ -10,7 +10,7 @@ public abstract class A : kotlin.MutableCollection { public abstract override /*1*/ /*fake_override*/ fun addAll(/*0*/ c: kotlin.Collection): kotlin.Boolean public abstract override /*1*/ /*fake_override*/ fun clear(): kotlin.Unit public abstract override /*1*/ /*fake_override*/ fun contains(/*0*/ o: T!): kotlin.Boolean - public open override /*1*/ /*synthesized*/ fun containsAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public open override /*1*/ 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 hashCode(): kotlin.Int public abstract override /*1*/ /*fake_override*/ fun iterator(): kotlin.MutableIterator @@ -28,7 +28,7 @@ public abstract class B : kotlin.MutableCollection { public abstract override /*1*/ /*fake_override*/ fun addAll(/*0*/ c: kotlin.Collection): kotlin.Boolean public abstract override /*1*/ /*fake_override*/ fun clear(): kotlin.Unit public abstract override /*1*/ /*fake_override*/ fun contains(/*0*/ o: kotlin.String!): kotlin.Boolean - public open override /*1*/ /*synthesized*/ fun containsAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public open override /*1*/ 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 hashCode(): kotlin.Int public abstract override /*1*/ /*fake_override*/ fun iterator(): kotlin.MutableIterator @@ -45,7 +45,7 @@ public interface IC : kotlin.MutableCollection { public abstract override /*1*/ /*fake_override*/ fun addAll(/*0*/ c: kotlin.Collection): kotlin.Boolean public abstract override /*1*/ /*fake_override*/ fun clear(): kotlin.Unit public abstract override /*1*/ /*fake_override*/ fun contains(/*0*/ o: kotlin.String!): kotlin.Boolean - public abstract override /*1*/ /*synthesized*/ fun containsAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public abstract override /*1*/ 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 hashCode(): kotlin.Int public abstract override /*1*/ /*fake_override*/ fun iterator(): kotlin.MutableIterator diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAndOverload.txt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAndOverload.txt index 6b3b4bc225f..026c1b0996d 100644 --- a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAndOverload.txt +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAndOverload.txt @@ -10,7 +10,6 @@ public abstract class A : kotlin.MutableCollection { public abstract override /*1*/ /*fake_override*/ fun addAll(/*0*/ c: kotlin.Collection): kotlin.Boolean public abstract override /*1*/ /*fake_override*/ fun clear(): kotlin.Unit public open override /*1*/ fun contains(/*0*/ o: kotlin.String!): kotlin.Boolean - public open override /*1*/ /*synthesized*/ fun contains(/*0*/ x: kotlin.String!): kotlin.Boolean public abstract 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 hashCode(): kotlin.Int @@ -28,7 +27,7 @@ public abstract class KA : A { public abstract override /*1*/ /*fake_override*/ fun add(/*0*/ e: kotlin.String!): kotlin.Boolean public abstract override /*1*/ /*fake_override*/ fun addAll(/*0*/ c: kotlin.Collection): kotlin.Boolean public abstract override /*1*/ /*fake_override*/ fun clear(): kotlin.Unit - public open override /*2*/ fun contains(/*0*/ x: kotlin.String): kotlin.Boolean + public open override /*1*/ fun contains(/*0*/ x: kotlin.String): kotlin.Boolean public abstract 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 hashCode(): kotlin.Int diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/mapGetOverride.txt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/mapGetOverride.txt index dc122895256..071d63cc16f 100644 --- a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/mapGetOverride.txt +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/mapGetOverride.txt @@ -16,7 +16,7 @@ public abstract class MyMap : java.util.AbstractMap): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/overridesBuiltinNoMagic.kt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/overridesBuiltinNoMagic.kt new file mode 100644 index 00000000000..5f93550d448 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/overridesBuiltinNoMagic.kt @@ -0,0 +1,157 @@ +// FILE: X.java +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; + +public class X implements java.util.List { + @Override + public int size() { + return 0; + } + + public int getSize() { + return 0; + } + + @Override + public boolean isEmpty() { + return false; + } + + public boolean contains(String o) { + return false; + } + + @Override + public boolean contains(Object o) { + return false; + } + + @NotNull + @Override + public Iterator iterator() { + return null; + } + + @NotNull + @Override + public Object[] toArray() { + return new Object[0]; + } + + @NotNull + @Override + public T[] toArray(T[] a) { + return null; + } + + @Override + public boolean add(String s) { + return false; + } + + @Override + public boolean remove(Object o) { + return false; + } + + @Override + public boolean containsAll(Collection c) { + return false; + } + + @Override + public boolean addAll(Collection c) { + return false; + } + + @Override + public boolean addAll(int index, Collection c) { + return false; + } + + @Override + public boolean removeAll(Collection c) { + return false; + } + + @Override + public boolean retainAll(Collection c) { + return false; + } + + @Override + public void clear() { + + } + + @Override + public String get(int index) { + return null; + } + + @Override + public String set(int index, String element) { + return null; + } + + @Override + public void add(int index, String element) { + + } + + @Override + public String remove(int index) { + return null; + } + + public String removeAt(int index) { + return null; + } + + @Override + public int indexOf(Object o) { + return 0; + } + + @Override + public int lastIndexOf(Object o) { + return 0; + } + + @NotNull + @Override + public ListIterator listIterator() { + return null; + } + + @NotNull + @Override + public ListIterator listIterator(int index) { + return null; + } + + @NotNull + @Override + public List subList(int fromIndex, int toIndex) { + return null; + } +} + +// FILE: main.kt + +class Y : X() + +fun main() { + X().remove("") + X().removeAt(1) + + val y: MutableList = Y() + y.removeAt(1) + + Y().remove("") + Y().removeAt(1) +} diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/overridesBuiltinNoMagic.txt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/overridesBuiltinNoMagic.txt new file mode 100644 index 00000000000..925a64a1158 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/overridesBuiltinNoMagic.txt @@ -0,0 +1,63 @@ +package + +public fun main(): kotlin.Unit + +public open class X : kotlin.MutableList { + public constructor X() + public open override /*1*/ val isEmpty: kotlin.Boolean + public open override /*1*/ val size: kotlin.Int + @java.lang.Override() public open override /*1*/ fun add(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.String!): kotlin.Unit + @java.lang.Override() public open override /*1*/ fun add(/*0*/ e: kotlin.String!): kotlin.Boolean + @java.lang.Override() public open override /*1*/ fun addAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + @java.lang.Override() public open override /*1*/ fun addAll(/*0*/ index: kotlin.Int, /*1*/ c: kotlin.Collection): kotlin.Boolean + @java.lang.Override() public open override /*1*/ fun clear(): kotlin.Unit + public open override /*1*/ fun contains(/*0*/ o: kotlin.String!): kotlin.Boolean + @java.lang.Override() public open override /*1*/ fun containsAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + @java.lang.Override() public open override /*1*/ fun get(/*0*/ index: kotlin.Int): kotlin.String! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + @java.lang.Override() public open override /*1*/ fun indexOf(/*0*/ o: kotlin.Any?): kotlin.Int + @org.jetbrains.annotations.NotNull() @java.lang.Override() public open override /*1*/ fun iterator(): kotlin.MutableIterator + @java.lang.Override() public open override /*1*/ fun lastIndexOf(/*0*/ o: kotlin.Any?): kotlin.Int + @org.jetbrains.annotations.NotNull() @java.lang.Override() public open override /*1*/ fun listIterator(): kotlin.MutableListIterator + @org.jetbrains.annotations.NotNull() @java.lang.Override() public open override /*1*/ fun listIterator(/*0*/ index: kotlin.Int): kotlin.MutableListIterator + @java.lang.Override() public open override /*1*/ fun remove(/*0*/ o: kotlin.String!): kotlin.Boolean + @java.lang.Override() public open override /*1*/ fun removeAll(/*0*/ c: kotlin.Collection<*>): kotlin.Boolean + public open override /*1*/ fun removeAt(/*0*/ index: kotlin.Int): kotlin.String! + @java.lang.Override() public open override /*1*/ fun retainAll(/*0*/ c: kotlin.Collection<*>): kotlin.Boolean + @java.lang.Override() public open override /*1*/ fun set(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.String!): kotlin.String! + @org.jetbrains.annotations.NotNull() @java.lang.Override() public open override /*1*/ fun subList(/*0*/ fromIndex: kotlin.Int, /*1*/ toIndex: kotlin.Int): kotlin.MutableList + @org.jetbrains.annotations.NotNull() @java.lang.Override() public open fun toArray(): kotlin.Array<(out) kotlin.Any!> + @org.jetbrains.annotations.NotNull() @java.lang.Override() 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 Y : X { + public constructor Y() + public open override /*1*/ /*fake_override*/ val isEmpty: kotlin.Boolean + public open override /*1*/ /*fake_override*/ val size: kotlin.Int + @java.lang.Override() public open override /*1*/ /*fake_override*/ fun add(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.String!): kotlin.Unit + @java.lang.Override() public open override /*1*/ /*fake_override*/ fun add(/*0*/ e: kotlin.String!): kotlin.Boolean + @java.lang.Override() public open override /*1*/ /*fake_override*/ fun addAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + @java.lang.Override() public open override /*1*/ /*fake_override*/ fun addAll(/*0*/ index: kotlin.Int, /*1*/ c: kotlin.Collection): kotlin.Boolean + @java.lang.Override() public open override /*1*/ /*fake_override*/ fun clear(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun contains(/*0*/ o: kotlin.String!): kotlin.Boolean + @java.lang.Override() 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 + @java.lang.Override() public open override /*1*/ /*fake_override*/ fun get(/*0*/ index: kotlin.Int): kotlin.String! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + @java.lang.Override() public open override /*1*/ /*fake_override*/ fun indexOf(/*0*/ o: kotlin.Any?): kotlin.Int + @org.jetbrains.annotations.NotNull() @java.lang.Override() public open override /*1*/ /*fake_override*/ fun iterator(): kotlin.MutableIterator + @java.lang.Override() public open override /*1*/ /*fake_override*/ fun lastIndexOf(/*0*/ o: kotlin.Any?): kotlin.Int + @org.jetbrains.annotations.NotNull() @java.lang.Override() public open override /*1*/ /*fake_override*/ fun listIterator(): kotlin.MutableListIterator + @org.jetbrains.annotations.NotNull() @java.lang.Override() public open override /*1*/ /*fake_override*/ fun listIterator(/*0*/ index: kotlin.Int): kotlin.MutableListIterator + @java.lang.Override() public open override /*1*/ /*fake_override*/ fun remove(/*0*/ o: kotlin.String!): kotlin.Boolean + @java.lang.Override() 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! + @java.lang.Override() public open override /*1*/ /*fake_override*/ fun retainAll(/*0*/ c: kotlin.Collection<*>): kotlin.Boolean + @java.lang.Override() public open override /*1*/ /*fake_override*/ fun set(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.String!): kotlin.String! + @org.jetbrains.annotations.NotNull() @java.lang.Override() public open override /*1*/ /*fake_override*/ fun subList(/*0*/ fromIndex: kotlin.Int, /*1*/ toIndex: kotlin.Int): kotlin.MutableList + @org.jetbrains.annotations.NotNull() @java.lang.Override() public open override /*1*/ /*fake_override*/ fun toArray(): kotlin.Array<(out) kotlin.Any!> + @org.jetbrains.annotations.NotNull() @java.lang.Override() 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/removeAt.txt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/removeAt.txt index 737a2f391ef..ade32a4dc3c 100644 --- a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/removeAt.txt +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/removeAt.txt @@ -24,7 +24,7 @@ public abstract class A : B { public open override /*1*/ /*fake_override*/ fun listIterator(/*0*/ index: kotlin.Int): kotlin.MutableListIterator invisible_fake open override /*1*/ /*fake_override*/ fun outOfBoundsMsg(/*0*/ p0: kotlin.Int): kotlin.String! invisible_fake open override /*1*/ /*fake_override*/ fun rangeCheckForAdd(/*0*/ p0: kotlin.Int): kotlin.Unit - public open override /*1*/ /*synthesized*/ fun remove(/*0*/ o: F!): kotlin.Boolean + public open override /*1*/ fun remove(/*0*/ o: F!): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun removeAll(/*0*/ c: kotlin.Collection): kotlin.Boolean public open override /*1*/ fun removeAt(/*0*/ x: kotlin.Int): F! protected/*protected and package*/ open override /*1*/ /*fake_override*/ fun removeRange(/*0*/ p0: kotlin.Int, /*1*/ p1: kotlin.Int): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/removeAtInt.txt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/removeAtInt.txt index 46d44a5a973..ca49f08410a 100644 --- a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/removeAtInt.txt +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/removeAtInt.txt @@ -24,7 +24,7 @@ public abstract class A : B { public open override /*1*/ /*fake_override*/ fun listIterator(/*0*/ index: kotlin.Int): kotlin.MutableListIterator invisible_fake open override /*1*/ /*fake_override*/ fun outOfBoundsMsg(/*0*/ p0: kotlin.Int): kotlin.String! invisible_fake open override /*1*/ /*fake_override*/ fun rangeCheckForAdd(/*0*/ p0: kotlin.Int): kotlin.Unit - public open override /*1*/ /*synthesized*/ fun remove(/*0*/ x: kotlin.Int): kotlin.Boolean + public open override /*1*/ fun remove(/*0*/ x: kotlin.Int): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun removeAll(/*0*/ c: kotlin.Collection): kotlin.Boolean public open override /*1*/ fun removeAt(/*0*/ x: kotlin.Int): kotlin.Int protected/*protected and package*/ open override /*1*/ /*fake_override*/ fun removeRange(/*0*/ p0: kotlin.Int, /*1*/ p1: kotlin.Int): kotlin.Unit diff --git a/compiler/testData/diagnostics/testsWithStdLib/commonCollections.kt b/compiler/testData/diagnostics/testsWithStdLib/commonCollections.kt new file mode 100644 index 00000000000..5185a5e29c9 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/commonCollections.kt @@ -0,0 +1,28 @@ +import java.util.* +fun foo() { + val al = ArrayList() + al.size + al.contains(1) + al.contains("") + + al.remove("") + al.removeAt(1) + + val hs = HashSet() + hs.size + hs.contains(1) + hs.contains("") + + hs.remove("") + + + val hm = HashMap() + hm.size + hm.containsKey(1) + hm.containsKey("") + + hm[1] + hm[""] + + hm.remove("") +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/commonCollections.txt b/compiler/testData/diagnostics/testsWithStdLib/commonCollections.txt new file mode 100644 index 00000000000..65a6ac47e1f --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/commonCollections.txt @@ -0,0 +1,3 @@ +package + +public fun foo(): kotlin.Unit diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index ec890a988a3..2a365e6ab3a 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -9161,6 +9161,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/j+k/collectionOverrides"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("commonCollections.kt") + public void testCommonCollections() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/collectionOverrides/commonCollections.kt"); + doTest(fileName); + } + @TestMetadata("contains.kt") public void testContains() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/collectionOverrides/contains.kt"); @@ -9191,6 +9197,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("overridesBuiltinNoMagic.kt") + public void testOverridesBuiltinNoMagic() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/collectionOverrides/overridesBuiltinNoMagic.kt"); + doTest(fileName); + } + @TestMetadata("removeAt.kt") public void testRemoveAt() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/collectionOverrides/removeAt.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java index a6f1f3a7dd0..600decbf468 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java @@ -35,6 +35,12 @@ public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnostic JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("commonCollections.kt") + public void testCommonCollections() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/commonCollections.kt"); + doTest(fileName); + } + @TestMetadata("elvisOnUnitInLet.kt") public void testElvisOnUnitInLet() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/elvisOnUnitInLet.kt"); diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaConstructorDescriptor.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaConstructorDescriptor.java index 4343f749847..a4665c061e2 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaConstructorDescriptor.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaConstructorDescriptor.java @@ -106,7 +106,7 @@ public class JavaConstructorDescriptor extends ConstructorDescriptorImpl impleme enhancedReceiverType, getDispatchReceiverParameter(), getTypeParameters(), - DescriptorsPackage.createEnhancedValueParameters(enhancedValueParametersTypes, getValueParameters(), enhanced), + DescriptorsPackage.copyValueParameters(enhancedValueParametersTypes, getValueParameters(), enhanced), enhancedReturnType, getModality(), getVisibility() diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaMethodDescriptor.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaMethodDescriptor.java index 0614d021d61..290bc933d09 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaMethodDescriptor.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaMethodDescriptor.java @@ -135,7 +135,7 @@ public class JavaMethodDescriptor extends SimpleFunctionDescriptorImpl implement @NotNull JetType enhancedReturnType ) { List enhancedValueParameters = - DescriptorsPackage.createEnhancedValueParameters(enhancedValueParametersTypes, getValueParameters(), this); + UtilKt.copyValueParameters(enhancedValueParametersTypes, getValueParameters(), this); // We use `doSubstitute` here because it does exactly what we need: // 1. creates full copy of descriptor diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/util.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/util.kt index 4b8df6993b7..4a4b95c78a5 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/util.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/util.kt @@ -22,16 +22,16 @@ import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.types.JetType -fun createEnhancedValueParameters( - enhancedTypes: Collection, +fun copyValueParameters( + newValueParametersTypes: Collection, oldValueParameters: Collection, newOwner: CallableDescriptor ): List { - assert(enhancedTypes.size() == oldValueParameters.size()) { - "Different value parameters sizes: Enhanced = ${enhancedTypes.size()}, Old = ${oldValueParameters.size()}" + assert(newValueParametersTypes.size() == oldValueParameters.size()) { + "Different value parameters sizes: Enhanced = ${newValueParametersTypes.size}, Old = ${oldValueParameters.size}" } - return enhancedTypes.zip(oldValueParameters).map { + return newValueParametersTypes.zip(oldValueParameters).map { pair -> val (newType, oldParameter) = pair ValueParameterDescriptorImpl( 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 cd3b938a24b..c0c79ca2e55 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 @@ -34,6 +34,7 @@ import org.jetbrains.kotlin.load.java.components.TypeUsage import org.jetbrains.kotlin.load.java.descriptors.JavaConstructorDescriptor import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor +import org.jetbrains.kotlin.load.java.descriptors.copyValueParameters import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext import org.jetbrains.kotlin.load.java.lazy.child import org.jetbrains.kotlin.load.java.lazy.resolveAnnotations @@ -98,9 +99,25 @@ public class LazyJavaClassMemberScope( return false } + if (name.sameAsBuiltinMethodWithErasedValueParameters && javaMethod != null) { + val originalMethodDescriptor = super.resolveMethodToFunctionDescriptor(javaMethod) + val overridden = firstOverriddenBuiltinFunctionWithErasedValueParameters(originalMethodDescriptor) + if (overridden != null) { + if (doesClassOverrideBuiltinWithoutMagic(overridden)) return false + } + } + return true } + // E.g. it have explicit removeAt declaration in Java + private fun doesClassOverrideBuiltinWithoutMagic(callableMemberDescriptor: CallableMemberDescriptor): Boolean { + return memberIndex().findMethodsByName(callableMemberDescriptor.name).any { + otherJavaMethod -> + super.resolveMethodToFunctionDescriptor(otherJavaMethod).doesOverride(callableMemberDescriptor) + } + } + private fun JavaMethod.doesOverrideRenamedBuiltins(): Boolean { return BuiltinSpecialMethods.getSpecialBuiltinFunctionsByJvmName(name).any { builtinName -> @@ -118,13 +135,24 @@ public class LazyJavaClassMemberScope( // if we check 'removeAt', get original sub-descriptor to distinct `remove(int)` and `remove(E)` in Java val subDescriptorToCheck = if (superDescriptor.isRemoveAtByIndex) subDescriptor.original else subDescriptor + return subDescriptorToCheck.doesOverride(superDescriptor) + } + + private fun CallableDescriptor.doesOverride(superDescriptor: CallableDescriptor): Boolean { return OverridingUtil.DEFAULT.isOverridableByIncludingReturnType( - superDescriptor, subDescriptorToCheck + superDescriptor, this ).result == OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE } private fun PropertyDescriptor.findGetterOverride(): JavaMethodDescriptor? { - val getterName = getter?.getBuiltinSpecialOverridden()?.getBuiltinSpecialPropertyGetterName() ?: JvmAbi.getterName(name.asString()) + val commonProperty = findGetterByName(JvmAbi.getterName(name.asString())) + if (commonProperty != null) return commonProperty + + val specialGetterName = getter?.getBuiltinSpecialOverridden()?.getBuiltinSpecialPropertyGetterName() ?: return null + return findGetterByName(specialGetterName) + } + + private fun PropertyDescriptor.findGetterByName(getterName: String): JavaMethodDescriptor? { return memberIndex().findMethodsByName(Name.identifier(getterName)).firstNotNullResult factory@{ javaMethod -> val descriptor = resolveMethodToFunctionDescriptor(javaMethod) @@ -177,6 +205,9 @@ public class LazyJavaClassMemberScope( for (descriptor in mergedFunctionFromSuperTypes) { val overriddenBuiltin = descriptor.getBuiltinSpecialOverridden() ?: continue + + if (result.any { it.doesOverride(overriddenBuiltin) }) continue + val nameInJava = getJvmMethodNameIfSpecial(overriddenBuiltin)!! for (method in memberIndex().findMethodsByName(Name.identifier(nameInJava))) { val renamedCopy = resolveMethodToFunctionDescriptorWithName(method, name) @@ -316,30 +347,38 @@ public class LazyJavaClassMemberScope( methodDescriptor: JavaMethodDescriptor ): JavaMethodDescriptor? { - val overriddenCandidates = - getFunctionsFromSupertypes(methodDescriptor.name).map { - BuiltinMethodsWithSpecialJvmSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(it) - }.filterNotNull() + val overridden = firstOverriddenBuiltinFunctionWithErasedValueParameters(methodDescriptor) ?: return null - if (overriddenCandidates.isEmpty()) return null + val newMethod = JavaMethodDescriptor.createJavaMethod( + methodDescriptor.containingDeclaration, methodDescriptor.annotations, methodDescriptor.name, methodDescriptor.source) - val overridden = firstOverriddenBuiltinFunctionWithErasedValueParameters(methodDescriptor, overriddenCandidates) ?: return null - return methodDescriptor - .enhance( - methodDescriptor.extensionReceiverParameter?.type, - overridden.valueParameters.map { it.type }, - methodDescriptor.returnType!!) - .copy( - methodDescriptor.containingDeclaration, - methodDescriptor.modality, methodDescriptor.visibility, - CallableMemberDescriptor.Kind.SYNTHESIZED, false) as? JavaMethodDescriptor + assert(methodDescriptor.typeParameters.isEmpty()) { "There should be methods with no type parameters, but $methodDescriptor found" } + + newMethod.initialize( + methodDescriptor.extensionReceiverParameter?.type, + methodDescriptor.dispatchReceiverParameter, + emptyList(), + copyValueParameters(overridden.valueParameters.map { it.type }, methodDescriptor.valueParameters, newMethod), + methodDescriptor.returnType, + methodDescriptor.modality, + methodDescriptor.visibility + ) + + newMethod.setParameterNamesStatus(methodDescriptor.hasStableParameterNames(), methodDescriptor.hasSynthesizedParameterNames()) + + return newMethod } private fun firstOverriddenBuiltinFunctionWithErasedValueParameters( - javaMethodDescriptor: JavaMethodDescriptor, - candidatesToOverride: Collection + javaMethodDescriptor: JavaMethodDescriptor ): FunctionDescriptor? { + val candidatesToOverride = + getFunctionsFromSupertypes(javaMethodDescriptor.name).map { + BuiltinMethodsWithSpecialJvmSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(it) + }.filterNotNull() + + if (candidatesToOverride.isEmpty()) return null return candidatesToOverride.firstNotNullResult overrides@{ candidate -> candidate.check { javaMethodDescriptor.doesOverrideBuiltinFunctionWithErasedValueParameters(candidate) }