From 62a55b7b00e776fd666697251fcbe43f41fc3df3 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Mon, 24 Apr 2017 11:43:52 +0300 Subject: [PATCH] Fix false-positive resolution ambiguity when using akka com.typesafe.akka:akka-cluster-sharding_2.12:2.5 akka.cluster.sharding.ClusterSharding has the following methods: public static ClusterSharding get(ActorSystem var0) { return ClusterSharding$.MODULE$.get(var0); } public static Extension get(ActorSystem var0) { return ClusterSharding$.MODULE$.get(var0); } NB: ClusterSharding <: Extension None of these methods is synthetic or something, but javac allows calls like ClusterSharding.get(null) and they get resolved to the first method returning ClusterSharding It seems that both javac and IntelliJ resolution algorithms filter out such clashing declarations choosing the one that has the most specific return type, the same idea is applied in the change #KT-17560 Fixed --- .../diagnostics/tests/j+k/selectMoreSpecific.kt | 16 ++++++++++++++++ .../diagnostics/tests/j+k/selectMoreSpecific.txt | 14 ++++++++++++++ .../checkers/DiagnosticsTestGenerated.java | 6 ++++++ .../load/java/lazy/descriptors/LazyJavaScope.kt | 3 +++ .../jetbrains/kotlin/resolve/overridingUtils.kt | 6 ++++++ 5 files changed, 45 insertions(+) create mode 100644 compiler/testData/diagnostics/tests/j+k/selectMoreSpecific.kt create mode 100644 compiler/testData/diagnostics/tests/j+k/selectMoreSpecific.txt diff --git a/compiler/testData/diagnostics/tests/j+k/selectMoreSpecific.kt b/compiler/testData/diagnostics/tests/j+k/selectMoreSpecific.kt new file mode 100644 index 00000000000..d4548d99214 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/selectMoreSpecific.kt @@ -0,0 +1,16 @@ +// !CHECK_TYPE +// FILE: A.java +public class A { + public String foo() {} + public CharSequence foo() {} + + public static String bar() {} + public static CharSequence bar() {} +} + +// FILE: main.kt + +fun foo(a: A) { + a.foo() checkType { _() } + A.bar() checkType { _() } +} diff --git a/compiler/testData/diagnostics/tests/j+k/selectMoreSpecific.txt b/compiler/testData/diagnostics/tests/j+k/selectMoreSpecific.txt new file mode 100644 index 00000000000..f29c9271dbb --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/selectMoreSpecific.txt @@ -0,0 +1,14 @@ +package + +public fun foo(/*0*/ a: A): kotlin.Unit + +public open class A { + public constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open fun foo(): kotlin.String! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public open fun bar(): kotlin.String! +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index eb59d9251d4..fedd06ed3de 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -12100,6 +12100,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("selectMoreSpecific.kt") + public void testSelectMoreSpecific() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/selectMoreSpecific.kt"); + doTest(fileName); + } + @TestMetadata("serializable.kt") public void testSerializable() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/serializable.kt"); 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 595ee5085eb..fb38129ec27 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 @@ -36,6 +36,7 @@ import org.jetbrains.kotlin.load.java.structure.JavaValueParameter import org.jetbrains.kotlin.load.java.typeEnhancement.enhanceSignatures import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.retainMostSpecificInEachOverridableGroup import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude.NonExtensions import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.MemberScope @@ -86,6 +87,8 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS } } + result.retainMostSpecificInEachOverridableGroup() + computeNonDeclaredFunctions(result, name) enhanceSignatures(result).toList() diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/overridingUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/overridingUtils.kt index 2ad26db6818..e208a83653a 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/overridingUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/overridingUtils.kt @@ -81,3 +81,9 @@ fun Collection.selectMostSpecificInEachOverridableGroup( } return result } + +fun MutableCollection.retainMostSpecificInEachOverridableGroup() { + val newResult = selectMostSpecificInEachOverridableGroup { this } + if (size == newResult.size) return + retainAll(newResult) +}