From 1f52dfccdbfcbfe1189eae567187a7b5f86462aa Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Wed, 7 Oct 2015 21:31:24 +0300 Subject: [PATCH] Setup specific loading contains/containsAll from java If they override Kotlin collection members contains(Object) -> contains(E) containsAll(Collection) -> containsAll(Collection) --- .../kotlin/resolve/BindingContextUtils.java | 5 - .../tests/j+k/collectionOverrides/contains.kt | 65 +++++++++ .../j+k/collectionOverrides/contains.txt | 124 ++++++++++++++++++ .../j+k/collectionOverrides/containsAll.kt | 55 ++++++++ .../j+k/collectionOverrides/containsAll.txt | 124 ++++++++++++++++++ .../containsAndOverload.kt | 24 ++++ .../containsAndOverload.txt | 40 ++++++ .../checkers/JetDiagnosticsTestGenerated.java | 27 ++++ .../load/java/builtinsPropertiesUtil.kt | 50 ++++++- .../descriptors/LazyJavaClassMemberScope.kt | 78 ++++++++++- .../java/lazy/descriptors/LazyJavaScope.kt | 2 +- .../kotlin/load/java/lazy/types/RawType.kt | 2 +- 12 files changed, 581 insertions(+), 15 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/j+k/collectionOverrides/contains.kt create mode 100644 compiler/testData/diagnostics/tests/j+k/collectionOverrides/contains.txt create mode 100644 compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAll.kt create mode 100644 compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAll.txt create mode 100644 compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAndOverload.kt create mode 100644 compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAndOverload.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContextUtils.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContextUtils.java index 9d961a3c7a7..f8006e230f7 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContextUtils.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContextUtils.java @@ -69,11 +69,6 @@ public class BindingContextUtils { public static void recordFunctionDeclarationToDescriptor(@NotNull BindingTrace trace, @NotNull PsiElement psiElement, @NotNull SimpleFunctionDescriptor function) { - - if (function.getKind() != DECLARATION) { - throw new IllegalArgumentException("function of kind " + function.getKind() + " cannot have declaration"); - } - trace.record(BindingContext.FUNCTION, psiElement, function); } diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/contains.kt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/contains.kt new file mode 100644 index 00000000000..d0bc1bf423a --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/contains.kt @@ -0,0 +1,65 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -PARAMETER_NAME_CHANGED_ON_OVERRIDE +// FILE: A.java + +abstract public class A implements java.util.Collection { + public boolean contains(Object x) {return false;} +} + +// FILE: B.java + +abstract public class B implements java.util.Collection { + public boolean contains(Object x) {return false;} +} + +// FILE: IC.java +public interface IC implements java.util.Collection { + public boolean contains(Object x); +} + +// FILE: main.kt +abstract class KA : java.util.AbstractList() { + override fun contains(x: T) = false +} + +abstract class KB : java.util.AbstractList(), IC { + override fun contains(x: String) = false +} + + +// Raw? + +fun foo( + a: A, b: B, ic: IC, + ka: KA, kb: KB, + al: java.util.ArrayList +) { + a.contains("") + a.contains(1) + "" in a + 1 in a + + b.contains("") + b.contains(1) + "" in b + 1 in b + + ic.contains("") + ic.contains(1) + "" in ic + 1 in ic + + ka.contains("") + ka.contains(1) + "" in ka + 1 in ka + + kb.contains("") + kb.contains(1) + "" in kb + 1 in kb + + al.contains("") + al.contains(1) + "" in al + 1 in al +} diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/contains.txt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/contains.txt new file mode 100644 index 00000000000..972ae7a84c0 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/contains.txt @@ -0,0 +1,124 @@ +package + +public fun foo(/*0*/ a: A, /*1*/ b: B, /*2*/ ic: IC, /*3*/ ka: KA, /*4*/ kb: KB, /*5*/ al: java.util.ArrayList): kotlin.Unit + +public abstract class A : kotlin.MutableCollection { + public constructor A() + public abstract override /*1*/ /*fake_override*/ val size: kotlin.Int + 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 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 + public abstract override /*1*/ /*fake_override*/ fun isEmpty(): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun iterator(): kotlin.MutableIterator + public abstract override /*1*/ /*fake_override*/ fun remove(/*0*/ o: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun removeAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun retainAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public abstract class B : kotlin.MutableCollection { + public constructor B() + public abstract override /*1*/ /*fake_override*/ val size: kotlin.Int + 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 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 + public abstract override /*1*/ /*fake_override*/ fun isEmpty(): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun iterator(): kotlin.MutableIterator + public abstract override /*1*/ /*fake_override*/ fun remove(/*0*/ o: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun removeAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun retainAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface IC : kotlin.MutableCollection { + public abstract override /*1*/ /*fake_override*/ val size: kotlin.Int + 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*/ /*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 + public abstract override /*1*/ /*fake_override*/ fun isEmpty(): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun iterator(): kotlin.MutableIterator + public abstract override /*1*/ /*fake_override*/ fun remove(/*0*/ o: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun removeAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun retainAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public abstract class KA : java.util.AbstractList { + public constructor KA() + protected/*protected and package*/ final override /*1*/ /*fake_override*/ var modCount: kotlin.Int + public abstract override /*1*/ /*fake_override*/ val size: kotlin.Int + public open override /*1*/ /*fake_override*/ fun add(/*0*/ e: T!): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun add(/*0*/ index: kotlin.Int, /*1*/ element: T!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun addAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun addAll(/*0*/ index: kotlin.Int, /*1*/ c: kotlin.Collection): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun clear(): kotlin.Unit + public open override /*1*/ fun contains(/*0*/ x: T): 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 abstract override /*1*/ /*fake_override*/ fun get(/*0*/ index: kotlin.Int): T! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun indexOf(/*0*/ o: kotlin.Any?): 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.Any?): 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 + 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*/ /*fake_override*/ fun remove(/*0*/ o: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun remove(/*0*/ index: kotlin.Int): T! + public open override /*1*/ /*fake_override*/ fun removeAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + protected/*protected and package*/ open override /*1*/ /*fake_override*/ fun removeRange(/*0*/ p0: kotlin.Int, /*1*/ p1: kotlin.Int): kotlin.Unit + 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: T!): T! + 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*/ p0: kotlin.Array<(out) T!>!): kotlin.Array<(out) T!>! + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public abstract class KB : java.util.AbstractList, IC { + public constructor KB() + protected/*protected and package*/ final override /*1*/ /*fake_override*/ var modCount: kotlin.Int + public abstract override /*2*/ /*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 /*2*/ /*fake_override*/ fun add(/*0*/ e: kotlin.String!): kotlin.Boolean + public open override /*2*/ /*fake_override*/ fun addAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun addAll(/*0*/ index: kotlin.Int, /*1*/ c: kotlin.Collection): kotlin.Boolean + public open override /*2*/ /*fake_override*/ fun clear(): kotlin.Unit + public open override /*2*/ fun contains(/*0*/ x: 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 abstract override /*1*/ /*fake_override*/ fun get(/*0*/ index: kotlin.Int): kotlin.String! + public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun indexOf(/*0*/ o: kotlin.Any?): 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 /*1*/ /*fake_override*/ fun lastIndexOf(/*0*/ o: kotlin.Any?): 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 + 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 /*2*/ /*fake_override*/ fun remove(/*0*/ o: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun remove(/*0*/ index: kotlin.Int): kotlin.String! + public open override /*2*/ /*fake_override*/ fun removeAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + protected/*protected and package*/ open override /*1*/ /*fake_override*/ fun removeRange(/*0*/ p0: kotlin.Int, /*1*/ p1: kotlin.Int): kotlin.Unit + public open override /*2*/ /*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*/ p0: kotlin.Array<(out) T!>!): kotlin.Array<(out) T!>! + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAll.kt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAll.kt new file mode 100644 index 00000000000..61ce9d94991 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAll.kt @@ -0,0 +1,55 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -PARAMETER_NAME_CHANGED_ON_OVERRIDE +// FILE: A.java +import java.util.*; + +abstract public class A implements java.util.Collection { + public boolean containsAll(Collection x) {return false;} +} + +// FILE: B.java +import java.util.*; + +abstract public class B implements java.util.Collection { + public boolean containsAll(Collection x) {return false;} +} + +// FILE: IC.java +import java.util.*; + +public interface IC implements java.util.Collection { + public boolean containsAll(Collection x); +} + +// FILE: main.kt +abstract class KA : java.util.AbstractList() { + override fun containsAll(x: Collection) = false +} + +abstract class KB : java.util.AbstractList(), IC { + override fun containsAll(x: Collection) = false +} + +fun foo( + a: A, b: B, ic: IC, + ka: KA, kb: KB, + al: java.util.ArrayList, + cs: Collection, ca: Collection +) { + a.containsAll(cs) + a.containsAll(ca) + + b.containsAll(cs) + b.containsAll(ca) + + ic.containsAll(cs) + ic.containsAll(ca) + + ka.containsAll(cs) + ka.containsAll(ca) + + kb.containsAll(cs) + kb.containsAll(ca) + + al.containsAll(cs) + al.containsAll(ca) +} diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAll.txt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAll.txt new file mode 100644 index 00000000000..8ac3164122a --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAll.txt @@ -0,0 +1,124 @@ +package + +public fun foo(/*0*/ a: A, /*1*/ b: B, /*2*/ ic: IC, /*3*/ ka: KA, /*4*/ kb: KB, /*5*/ al: java.util.ArrayList, /*6*/ cs: kotlin.Collection, /*7*/ ca: kotlin.Collection): kotlin.Unit + +public abstract class A : kotlin.MutableCollection { + public constructor A() + public abstract override /*1*/ /*fake_override*/ val size: kotlin.Int + 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 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*/ /*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 isEmpty(): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun iterator(): kotlin.MutableIterator + public abstract override /*1*/ /*fake_override*/ fun remove(/*0*/ o: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun removeAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun retainAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public abstract class B : kotlin.MutableCollection { + public constructor B() + public abstract override /*1*/ /*fake_override*/ val size: kotlin.Int + 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*/ /*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*/ /*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 isEmpty(): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun iterator(): kotlin.MutableIterator + public abstract override /*1*/ /*fake_override*/ fun remove(/*0*/ o: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun removeAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun retainAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface IC : kotlin.MutableCollection { + public abstract override /*1*/ /*fake_override*/ val size: kotlin.Int + 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*/ /*fake_override*/ fun contains(/*0*/ o: kotlin.String!): kotlin.Boolean + public abstract override /*1*/ /*synthesized*/ 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 isEmpty(): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun iterator(): kotlin.MutableIterator + public abstract override /*1*/ /*fake_override*/ fun remove(/*0*/ o: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun removeAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun retainAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public abstract class KA : java.util.AbstractList { + public constructor KA() + protected/*protected and package*/ final override /*1*/ /*fake_override*/ var modCount: kotlin.Int + public abstract override /*1*/ /*fake_override*/ val size: kotlin.Int + public open override /*1*/ /*fake_override*/ fun add(/*0*/ e: T!): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun add(/*0*/ index: kotlin.Int, /*1*/ element: T!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun addAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun addAll(/*0*/ index: kotlin.Int, /*1*/ c: kotlin.Collection): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun clear(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun contains(/*0*/ o: T!): kotlin.Boolean + public open override /*1*/ fun containsAll(/*0*/ x: kotlin.Collection): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun get(/*0*/ index: kotlin.Int): T! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun indexOf(/*0*/ o: kotlin.Any?): 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.Any?): 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 + 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*/ /*fake_override*/ fun remove(/*0*/ o: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun remove(/*0*/ index: kotlin.Int): T! + public open override /*1*/ /*fake_override*/ fun removeAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + protected/*protected and package*/ open override /*1*/ /*fake_override*/ fun removeRange(/*0*/ p0: kotlin.Int, /*1*/ p1: kotlin.Int): kotlin.Unit + 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: T!): T! + 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*/ p0: kotlin.Array<(out) T!>!): kotlin.Array<(out) T!>! + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public abstract class KB : java.util.AbstractList, IC { + public constructor KB() + protected/*protected and package*/ final override /*1*/ /*fake_override*/ var modCount: kotlin.Int + public abstract override /*2*/ /*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 /*2*/ /*fake_override*/ fun add(/*0*/ e: kotlin.String!): kotlin.Boolean + public open override /*2*/ /*fake_override*/ fun addAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun addAll(/*0*/ index: kotlin.Int, /*1*/ c: 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*/ fun containsAll(/*0*/ x: kotlin.Collection): kotlin.Boolean + public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun get(/*0*/ index: kotlin.Int): kotlin.String! + public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun indexOf(/*0*/ o: kotlin.Any?): 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 /*1*/ /*fake_override*/ fun lastIndexOf(/*0*/ o: kotlin.Any?): 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 + 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 /*2*/ /*fake_override*/ fun remove(/*0*/ o: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun remove(/*0*/ index: kotlin.Int): kotlin.String! + public open override /*2*/ /*fake_override*/ fun removeAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + protected/*protected and package*/ open override /*1*/ /*fake_override*/ fun removeRange(/*0*/ p0: kotlin.Int, /*1*/ p1: kotlin.Int): kotlin.Unit + public open override /*2*/ /*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*/ p0: kotlin.Array<(out) T!>!): kotlin.Array<(out) T!>! + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAndOverload.kt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAndOverload.kt new file mode 100644 index 00000000000..564636d378b --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAndOverload.kt @@ -0,0 +1,24 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -PARAMETER_NAME_CHANGED_ON_OVERRIDE + +// FILE: A.java +abstract public class A implements java.util.Collection { + public boolean contains(Object x) {return false;} + public boolean contains(String x) {return false;} +} + +// FILE: main.kt +abstract class KA: A() { + override fun contains(x: String) = false +} + +fun foo(a: A, ka: KA) { + a.contains("") + a.contains(1) + "" in a + 1 in a + + ka.contains("") + ka.contains(1) + "" in ka + 1 in ka +} diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAndOverload.txt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAndOverload.txt new file mode 100644 index 00000000000..9d398fdd2e0 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAndOverload.txt @@ -0,0 +1,40 @@ +package + +public fun foo(/*0*/ a: A, /*1*/ ka: KA): kotlin.Unit + +public abstract class A : kotlin.MutableCollection { + public constructor A() + public abstract override /*1*/ /*fake_override*/ val size: kotlin.Int + 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*/ 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 + public abstract override /*1*/ /*fake_override*/ fun isEmpty(): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun iterator(): kotlin.MutableIterator + public abstract override /*1*/ /*fake_override*/ fun remove(/*0*/ o: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun removeAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun retainAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public abstract class KA : A { + public constructor KA() + public abstract override /*1*/ /*fake_override*/ val size: kotlin.Int + 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 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 + public abstract override /*1*/ /*fake_override*/ fun isEmpty(): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun iterator(): kotlin.MutableIterator + public abstract override /*1*/ /*fake_override*/ fun remove(/*0*/ o: kotlin.Any?): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun removeAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + public abstract override /*1*/ /*fake_override*/ fun retainAll(/*0*/ c: kotlin.Collection): kotlin.Boolean + 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 7ca8803a9f7..863de548140 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -9078,6 +9078,33 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("compiler/testData/diagnostics/tests/j+k/collectionOverrides") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class CollectionOverrides extends AbstractJetDiagnosticsTest { + public void testAllFilesPresentInCollectionOverrides() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/j+k/collectionOverrides"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("contains.kt") + public void testContains() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/collectionOverrides/contains.kt"); + doTest(fileName); + } + + @TestMetadata("containsAll.kt") + public void testContainsAll() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAll.kt"); + doTest(fileName); + } + + @TestMetadata("containsAndOverload.kt") + public void testContainsAndOverload() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/collectionOverrides/containsAndOverload.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/diagnostics/tests/j+k/types") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/builtinsPropertiesUtil.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/builtinsPropertiesUtil.kt index 6c77db845db..48d8636dcfb 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/builtinsPropertiesUtil.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/builtinsPropertiesUtil.kt @@ -24,12 +24,23 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe import org.jetbrains.kotlin.resolve.descriptorUtil.module +import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.addToStdlib.check import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult private val BUILTIN_SPECIAL_PROPERTIES_FQ_NAMES = setOf(FqName("kotlin.Collection.size"), FqName("kotlin.Map.size")) private val BUILTIN_SPECIAL_PROPERTIES_SHORT_NAMES = BUILTIN_SPECIAL_PROPERTIES_FQ_NAMES.map { it.shortName() }.toSet() + +private val BUILTIN_METHODS_ERASED_COLLECTION_PARAMETER_FQ_NAMES = setOf(FqName("kotlin.Collection.containsAll")) +private val BUILTIN_METHODS_GENERIC_PARAMETERS_FQ_NAMES = setOf(FqName("kotlin.Collection.contains")) + +private val BUILTIN_METHODS_ERASED_VALUE_PARAMETERS_FQ_NAMES = + BUILTIN_METHODS_GENERIC_PARAMETERS_FQ_NAMES + BUILTIN_METHODS_ERASED_COLLECTION_PARAMETER_FQ_NAMES + +private val BUILTIN_METHODS_ERASED_VALUE_PARAMETERS_SHORT_NAMES = + BUILTIN_METHODS_ERASED_VALUE_PARAMETERS_FQ_NAMES.map { it.shortName() }.toSet() + public fun CallableDescriptor.hasBuiltinSpecialPropertyFqName(): Boolean { if (this is PropertyAccessorDescriptor) return correspondingProperty.hasBuiltinSpecialPropertyFqName() if (name !in BUILTIN_SPECIAL_PROPERTIES_SHORT_NAMES) return false @@ -38,7 +49,7 @@ public fun CallableDescriptor.hasBuiltinSpecialPropertyFqName(): Boolean { } private fun CallableDescriptor.hasBuiltinSpecialPropertyFqNameImpl(): Boolean { - if (fqNameUnsafe.check { it.isSafe }?.toSafe() in BUILTIN_SPECIAL_PROPERTIES_FQ_NAMES) return true + if (fqNameOrNull() in BUILTIN_SPECIAL_PROPERTIES_FQ_NAMES) return true if (!fqNameUnsafe.firstSegmentIs(KotlinBuiltIns.BUILT_INS_PACKAGE_NAME)) return false if (builtIns.builtInsModule != module) return false @@ -46,6 +57,8 @@ private fun CallableDescriptor.hasBuiltinSpecialPropertyFqNameImpl(): Boolean { return overriddenDescriptors.any(CallableDescriptor::hasBuiltinSpecialPropertyFqName) } +private fun CallableDescriptor.fqNameOrNull(): FqName? = fqNameUnsafe.check { it.isSafe }?.toSafe() + val Name.isBuiltinSpecialPropertyName: Boolean get() = this in BUILTIN_SPECIAL_PROPERTIES_SHORT_NAMES private val CallableDescriptor.builtinSpecialPropertyAccessorName: String? @@ -78,3 +91,38 @@ private val CallableDescriptor.isFromJava: Boolean private val CallableDescriptor.propertyIfAccessor: CallableDescriptor get() = if (this is PropertyAccessorDescriptor) correspondingProperty else this + +val CallableMemberDescriptor.hasErasedValueParametersInJava: Boolean + get() = fqNameOrNull() in BUILTIN_METHODS_ERASED_VALUE_PARAMETERS_FQ_NAMES + + +val FunctionDescriptor.overriddenBuiltinFunctionWithErasedValueParametersInJava: FunctionDescriptor? + get() { + if (!name.sameAsBuiltinMethodWithErasedValueParameters) return null + return firstOverridden { it.hasErasedValueParametersInJava } as FunctionDescriptor? + } + +private fun CallableMemberDescriptor.firstOverridden( + predicate: (CallableMemberDescriptor) -> Boolean +): CallableMemberDescriptor? { + var result: CallableMemberDescriptor? = null + return DFS.dfs(listOf(this), + object : DFS.Neighbors { + override fun getNeighbors(current: CallableMemberDescriptor?): Iterable { + return current?.overriddenDescriptors ?: emptyList() + } + }, + object : DFS.AbstractNodeHandler() { + override fun beforeChildren(current: CallableMemberDescriptor) = result == null + override fun afterChildren(current: CallableMemberDescriptor) { + if (result == null && predicate(current)) { + result = current + } + } + override fun result(): CallableMemberDescriptor? = result + } + ) +} + +val Name.sameAsBuiltinMethodWithErasedValueParameters: Boolean + get () = this in BUILTIN_METHODS_ERASED_VALUE_PARAMETERS_SHORT_NAMES 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 611c740c78e..71965982ac2 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 @@ -23,18 +23,16 @@ import org.jetbrains.kotlin.descriptors.impl.EnumEntrySyntheticClassDescriptor import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation -import org.jetbrains.kotlin.load.java.JavaVisibilities -import org.jetbrains.kotlin.load.java.JvmAnnotationNames -import org.jetbrains.kotlin.load.java.builtinSpecialOverridden +import org.jetbrains.kotlin.load.java.* import org.jetbrains.kotlin.load.java.components.DescriptorResolverUtils 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.isBuiltinSpecialPropertyName import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext import org.jetbrains.kotlin.load.java.lazy.child import org.jetbrains.kotlin.load.java.lazy.resolveAnnotations +import org.jetbrains.kotlin.load.java.lazy.types.RawSubstitution import org.jetbrains.kotlin.load.java.lazy.types.toAttributes import org.jetbrains.kotlin.load.java.structure.JavaArrayType import org.jetbrains.kotlin.load.java.structure.JavaClass @@ -49,6 +47,8 @@ import org.jetbrains.kotlin.types.JetType import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.checker.JetTypeChecker import org.jetbrains.kotlin.utils.* +import org.jetbrains.kotlin.utils.addToStdlib.check +import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult import java.util.* public class LazyJavaClassMemberScope( @@ -105,12 +105,13 @@ public class LazyJavaClassMemberScope( } override fun computeNonDeclaredFunctions(result: MutableCollection, name: Name) { - val functionsFromSupertypes = getFunctionsFromSupertypes(name, getContainingDeclaration()) + val functionsFromSupertypes = getFunctionsFromSupertypes(name) + result.addAll(DescriptorResolverUtils.resolveOverrides(name, functionsFromSupertypes, result, getContainingDeclaration(), c.components.errorReporter)) } - private fun getFunctionsFromSupertypes(name: Name, descriptor: ClassDescriptor): Set { - return descriptor.typeConstructor.supertypes.flatMap { + private fun getFunctionsFromSupertypes(name: Name): Set { + return getContainingDeclaration().typeConstructor.supertypes.flatMap { it.memberScope.getFunctions(name, NoLookupLocation.WHEN_GET_SUPER_MEMBERS).map { f -> f as SimpleFunctionDescriptor } }.toSet() } @@ -193,6 +194,69 @@ public class LazyJavaClassMemberScope( return LazyJavaScope.MethodSignatureData(effectiveSignature, propagated.getErrors() + effectiveSignature.getErrors()) } + override fun resolveMethodToFunctionDescriptor(method: JavaMethod): JavaMethodDescriptor { + val commonResult = super.resolveMethodToFunctionDescriptor(method) + + if (commonResult.name.sameAsBuiltinMethodWithErasedValueParameters) { + val erasedCopy = createOverrideForErasedIfNeeded(commonResult) + if (erasedCopy != null) return erasedCopy + } + + return commonResult + } + + private fun createOverrideForErasedIfNeeded( + methodDescriptor: JavaMethodDescriptor + ): JavaMethodDescriptor? { + + val overriddenCandidates = + getFunctionsFromSupertypes(methodDescriptor.name).map { it.overriddenBuiltinFunctionWithErasedValueParametersInJava }.filterNotNull() + + if (overriddenCandidates.isEmpty()) return null + + 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 + } + + private fun firstOverriddenBuiltinFunctionWithErasedValueParameters( + javaMethodDescriptor: JavaMethodDescriptor, + candidatesToOverride: Collection + ): FunctionDescriptor? { + return candidatesToOverride.firstNotNullResult overrides@{ + candidate -> + candidate.check { javaMethodDescriptor.doesOverrideBuiltinFunctionWithErasedValueParameters(candidate) } + } + } + + private fun JavaMethodDescriptor.doesOverrideBuiltinFunctionWithErasedValueParameters( + builtinWithErasedParameters: FunctionDescriptor + ): Boolean { + if (this.valueParameters.size() != builtinWithErasedParameters.valueParameters.size()) return false + if (!this.typeParameters.isEmpty() || !builtinWithErasedParameters.typeParameters.isEmpty()) return false + if (this.extensionReceiverParameter != null || builtinWithErasedParameters.extensionReceiverParameter != null) return false + + return this.valueParameters.indices.all { + index -> + val currentType = valueParameters[index].type + val overriddenCandidate = RawSubstitution.eraseType( + builtinWithErasedParameters.original.valueParameters[index].type) + JetTypeChecker.DEFAULT.equalTypes(currentType, overriddenCandidate) + } && returnType.isSubtypeOf(builtinWithErasedParameters.returnType) + } + + private fun JetType?.isSubtypeOf(other: JetType?): Boolean { + return JetTypeChecker.DEFAULT.isSubtypeOf(this ?: return false, other ?: return false) + } + private fun resolveConstructor(constructor: JavaConstructor): JavaConstructorDescriptor { val classDescriptor = getContainingDeclaration() diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt index 8643ac6661d..bf0f4bb346e 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaScope.kt @@ -109,7 +109,7 @@ public abstract class LazyJavaScope( returnType: JetType, valueParameters: ResolvedValueParameters): MethodSignatureData - fun resolveMethodToFunctionDescriptor(method: JavaMethod): JavaMethodDescriptor { + open fun resolveMethodToFunctionDescriptor(method: JavaMethod): JavaMethodDescriptor { val annotations = c.resolveAnnotations(method) val functionDescriptorImpl = JavaMethodDescriptor.createJavaMethod( containingDeclaration, annotations, method.getName(), c.components.sourceElementFactory.source(method) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/RawType.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/RawType.kt index 63784804c6d..f305bad0841 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/RawType.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/RawType.kt @@ -86,7 +86,7 @@ internal object RawSubstitution : TypeSubstitution() { private val lowerTypeAttr = TypeUsage.MEMBER_SIGNATURE_INVARIANT.toAttributes().toFlexible(JavaTypeFlexibility.FLEXIBLE_LOWER_BOUND) private val upperTypeAttr = TypeUsage.MEMBER_SIGNATURE_INVARIANT.toAttributes().toFlexible(JavaTypeFlexibility.FLEXIBLE_UPPER_BOUND) - private fun eraseType(type: JetType): JetType { + public fun eraseType(type: JetType): JetType { val declaration = type.constructor.declarationDescriptor return when (declaration) { is TypeParameterDescriptor -> eraseType(declaration.getErasedUpperBound())