K1: Fix false-positive ABSTRACT_MEMBER_NOT_IMPLEMENTED with JDK 21

Previously, it was reported for List.toArray because, when traversing
supertypes, we've been stopped at j.u.SequencedCollection
as it has no JavaAnalogue.

^KT-60770 Fixed
This commit is contained in:
Denis.Zharkov
2023-08-02 11:31:13 +02:00
committed by Space Team
parent e3efff7a33
commit 180a3bb320
5 changed files with 74 additions and 3 deletions
@@ -29,4 +29,10 @@ public class FirLightTreeJdk21DiagnosticTestGenerated extends AbstractFirLightTr
public void testNewListMethods() throws Exception {
runTest("compiler/testData/diagnostics/testsWithJdk21/newListMethods.kt");
}
@Test
@TestMetadata("noFalsePositiveAbstractToArray.kt")
public void testNoFalsePositiveAbstractToArray() throws Exception {
runTest("compiler/testData/diagnostics/testsWithJdk21/noFalsePositiveAbstractToArray.kt");
}
}
@@ -29,4 +29,10 @@ public class FirPsiJdk21DiagnosticTestGenerated extends AbstractFirPsiJdk21Diagn
public void testNewListMethods() throws Exception {
runTest("compiler/testData/diagnostics/testsWithJdk21/newListMethods.kt");
}
@Test
@TestMetadata("noFalsePositiveAbstractToArray.kt")
public void testNoFalsePositiveAbstractToArray() throws Exception {
runTest("compiler/testData/diagnostics/testsWithJdk21/noFalsePositiveAbstractToArray.kt");
}
}
@@ -0,0 +1,48 @@
// FIR_IDENTICAL
// ISSUE: KT-60770
// Should be no ABSTRACT_MEMBER_NOT_IMPLEMENTED
class B<F> : List<F> {
override val size: Int
get() = throw UnsupportedOperationException()
override fun contains(element: F): Boolean {
throw UnsupportedOperationException()
}
override fun containsAll(elements: Collection<F>): Boolean {
throw UnsupportedOperationException()
}
override fun get(index: Int): F {
throw UnsupportedOperationException()
}
override fun indexOf(element: F): Int {
throw UnsupportedOperationException()
}
override fun isEmpty(): Boolean {
throw UnsupportedOperationException()
}
override fun iterator(): Iterator<F> {
throw UnsupportedOperationException()
}
override fun lastIndexOf(element: F): Int {
throw UnsupportedOperationException()
}
override fun listIterator(): ListIterator<F> {
throw UnsupportedOperationException()
}
override fun listIterator(index: Int): ListIterator<F> {
throw UnsupportedOperationException()
}
override fun subList(fromIndex: Int, toIndex: Int): List<F> {
throw UnsupportedOperationException()
}
}
@@ -29,4 +29,10 @@ public class Jdk21DiagnosticTestGenerated extends AbstractJdk21DiagnosticTest {
public void testNewListMethods() throws Exception {
runTest("compiler/testData/diagnostics/testsWithJdk21/newListMethods.kt");
}
@Test
@TestMetadata("noFalsePositiveAbstractToArray.kt")
public void testNoFalsePositiveAbstractToArray() throws Exception {
runTest("compiler/testData/diagnostics/testsWithJdk21/noFalsePositiveAbstractToArray.kt");
}
}
@@ -43,7 +43,6 @@ import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.LazyWrappedType
import org.jetbrains.kotlin.utils.DFS
import org.jetbrains.kotlin.utils.SmartSet
import java.util.*
// This class is worth splitting into two implementations of AdditionalClassPartsProvider and PlatformDependentDeclarationFilter
// But currently, they shares a piece of code and probably it's better to postpone it
@@ -232,8 +231,14 @@ class JvmBuiltInsCustomizer(
// Search through mapped supertypes to determine that Set.toArray should be invisible, while we have only
// Collection.toArray there explicitly
// Note, that we can't find j.u.Collection.toArray within overriddenDescriptors of j.u.Set.toArray
it.typeConstructor.supertypes.mapNotNull {
(it.constructor.declarationDescriptor?.original as? ClassDescriptor)?.getJavaAnalogue()
it.typeConstructor.supertypes.mapNotNull { supertype ->
val superClassDescriptor =
supertype.constructor.declarationDescriptor?.original as? ClassDescriptor ?: return@mapNotNull null
// j.u.List in JDK 8 from Kotlin POV has a supertype kotlin.collections.MutableCollection
// that actually has JavaAnalogue, but since JDK 21 it has j.u.SequencedCollection as a supertype
// so `getJavaAnalogue()` might return null, but we still should continue traversing the supertypes
superClassDescriptor.getJavaAnalogue() ?: superClassDescriptor
}
},
object : DFS.AbstractNodeHandler<ClassDescriptor, JDKMemberStatus>() {