[FE, Java resolve] Support inheritors of sealed Java type without permits clause
This fixes a false negative NO_ELSE_IN_WHEN in K2 and incidentally also fixes a false positive NO_ELSE_IN_WHEN in K1 since the fix is in the common code. #KT-62491 Fixed
This commit is contained in:
committed by
Space Team
parent
15d3bf5e25
commit
ac203591e5
+6
@@ -45,6 +45,12 @@ public class DiagnosticCompilerTestFirTestdataTestGenerated extends AbstractDiag
|
|||||||
runTest("compiler/fir/analysis-tests/testData/resolve/accessJavaFromKotlinViaStaticImportAndPermits.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/accessJavaFromKotlinViaStaticImportAndPermits.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("accessJavaFromKotlinViaStaticImportWithoutPermits.kt")
|
||||||
|
public void testAccessJavaFromKotlinViaStaticImportWithoutPermits() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/accessJavaFromKotlinViaStaticImportWithoutPermits.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAllFilesPresentInResolve() throws Exception {
|
public void testAllFilesPresentInResolve() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
|
|||||||
+6
@@ -45,6 +45,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFirTestDataTestGenerated
|
|||||||
runTest("compiler/fir/analysis-tests/testData/resolve/accessJavaFromKotlinViaStaticImportAndPermits.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/accessJavaFromKotlinViaStaticImportAndPermits.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("accessJavaFromKotlinViaStaticImportWithoutPermits.kt")
|
||||||
|
public void testAccessJavaFromKotlinViaStaticImportWithoutPermits() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/accessJavaFromKotlinViaStaticImportWithoutPermits.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAllFilesPresentInResolve() throws Exception {
|
public void testAllFilesPresentInResolve() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
|
|||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
FILE: useSite.kt
|
||||||
|
public final fun foo(): R|kotlin/Int| {
|
||||||
|
^foo Int(4)
|
||||||
|
}
|
||||||
|
FILE: KotlinInterface.kt
|
||||||
|
public abstract interface KotlinInterface : R|kotlin/Any| {
|
||||||
|
public abstract var selectedOptions: R|kotlin/Int|
|
||||||
|
public get(): R|kotlin/Int|
|
||||||
|
public set(value: R|kotlin/Int|): R|kotlin/Unit|
|
||||||
|
|
||||||
|
}
|
||||||
Vendored
+25
@@ -0,0 +1,25 @@
|
|||||||
|
// FILE: useSite.kt
|
||||||
|
|
||||||
|
import C.StaticConfigurationClass.INIT_INSPECTIONS
|
||||||
|
|
||||||
|
fun foo(): Int = 4
|
||||||
|
|
||||||
|
// FILE: InspectionProfileImpl.java
|
||||||
|
import static Configuration.StaticConfigurationClass
|
||||||
|
|
||||||
|
public static final class C extends StaticConfigurationClass {
|
||||||
|
public abstract sealed class StaticConfigurationClass {
|
||||||
|
public static boolean INIT_INSPECTIONS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: Configuration.java
|
||||||
|
public class Configuration implements KotlinInterface {
|
||||||
|
public static class StaticConfigurationClass {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: KotlinInterface.kt
|
||||||
|
interface KotlinInterface {
|
||||||
|
var selectedOptions: Int
|
||||||
|
}
|
||||||
+6
@@ -45,6 +45,12 @@ public class FirLightTreeDiagnosticsTestGenerated extends AbstractFirLightTreeDi
|
|||||||
runTest("compiler/fir/analysis-tests/testData/resolve/accessJavaFromKotlinViaStaticImportAndPermits.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/accessJavaFromKotlinViaStaticImportAndPermits.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("accessJavaFromKotlinViaStaticImportWithoutPermits.kt")
|
||||||
|
public void testAccessJavaFromKotlinViaStaticImportWithoutPermits() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/accessJavaFromKotlinViaStaticImportWithoutPermits.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAllFilesPresentInResolve() throws Exception {
|
public void testAllFilesPresentInResolve() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
|
|||||||
+6
@@ -45,6 +45,12 @@ public class FirPsiDiagnosticTestGenerated extends AbstractFirPsiDiagnosticTest
|
|||||||
runTest("compiler/fir/analysis-tests/testData/resolve/accessJavaFromKotlinViaStaticImportAndPermits.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/accessJavaFromKotlinViaStaticImportAndPermits.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("accessJavaFromKotlinViaStaticImportWithoutPermits.kt")
|
||||||
|
public void testAccessJavaFromKotlinViaStaticImportWithoutPermits() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/accessJavaFromKotlinViaStaticImportWithoutPermits.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAllFilesPresentInResolve() throws Exception {
|
public void testAllFilesPresentInResolve() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||||
|
|||||||
@@ -387,7 +387,7 @@ abstract class FirJavaFacade(
|
|||||||
if (modality == Modality.SEALED) {
|
if (modality == Modality.SEALED) {
|
||||||
val permittedTypes = javaClass.permittedTypes
|
val permittedTypes = javaClass.permittedTypes
|
||||||
setSealedClassInheritors {
|
setSealedClassInheritors {
|
||||||
permittedTypes.mapNotNull { classifierType ->
|
permittedTypes.mapNotNullTo(mutableListOf()) { classifierType ->
|
||||||
val classifier = classifierType.classifier as? JavaClass
|
val classifier = classifierType.classifier as? JavaClass
|
||||||
classifier?.let { JavaToKotlinClassMap.mapJavaToKotlin(it.fqName!!) ?: it.classId }
|
classifier?.let { JavaToKotlinClassMap.mapJavaToKotlin(it.fqName!!) ?: it.classId }
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -162,7 +162,7 @@ class MockKotlinClassifier(override val classId: ClassId,
|
|||||||
override val isEnum get() = shouldNotBeCalled()
|
override val isEnum get() = shouldNotBeCalled()
|
||||||
override val isRecord get() = shouldNotBeCalled()
|
override val isRecord get() = shouldNotBeCalled()
|
||||||
override val isSealed: Boolean get() = shouldNotBeCalled()
|
override val isSealed: Boolean get() = shouldNotBeCalled()
|
||||||
override val permittedTypes: Collection<JavaClassifierType> get() = shouldNotBeCalled()
|
override val permittedTypes: Sequence<JavaClassifierType> get() = shouldNotBeCalled()
|
||||||
override val methods get() = shouldNotBeCalled()
|
override val methods get() = shouldNotBeCalled()
|
||||||
override val fields get() = shouldNotBeCalled()
|
override val fields get() = shouldNotBeCalled()
|
||||||
override val constructors get() = shouldNotBeCalled()
|
override val constructors get() = shouldNotBeCalled()
|
||||||
|
|||||||
+1
-1
@@ -71,7 +71,7 @@ class FakeSymbolBasedClass(
|
|||||||
|
|
||||||
override val isSealed: Boolean get() = false
|
override val isSealed: Boolean get() = false
|
||||||
|
|
||||||
override val permittedTypes: Collection<JavaClassifierType> get() = emptyList()
|
override val permittedTypes: Sequence<JavaClassifierType> get() = emptySequence()
|
||||||
|
|
||||||
override val lightClassOriginKind: LightClassOriginKind? get() = null
|
override val lightClassOriginKind: LightClassOriginKind? get() = null
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -111,8 +111,8 @@ class SymbolBasedClass(
|
|||||||
override val isSealed: Boolean
|
override val isSealed: Boolean
|
||||||
get() = false
|
get() = false
|
||||||
|
|
||||||
override val permittedTypes: Collection<JavaClassifierType>
|
override val permittedTypes: Sequence<JavaClassifierType>
|
||||||
get() = emptyList()
|
get() = emptySequence()
|
||||||
|
|
||||||
override val lightClassOriginKind: LightClassOriginKind?
|
override val lightClassOriginKind: LightClassOriginKind?
|
||||||
get() = null
|
get() = null
|
||||||
|
|||||||
+2
-2
@@ -125,8 +125,8 @@ class TreeBasedClass(
|
|||||||
override val isSealed: Boolean
|
override val isSealed: Boolean
|
||||||
get() = false
|
get() = false
|
||||||
|
|
||||||
override val permittedTypes: Collection<JavaClassifierType>
|
override val permittedTypes: Sequence<JavaClassifierType>
|
||||||
get() = emptyList()
|
get() = emptySequence()
|
||||||
|
|
||||||
override val lightClassOriginKind: LightClassOriginKind?
|
override val lightClassOriginKind: LightClassOriginKind?
|
||||||
get() = null
|
get() = null
|
||||||
|
|||||||
+30
-3
@@ -19,7 +19,9 @@ package org.jetbrains.kotlin.load.java.structure.impl
|
|||||||
import com.intellij.openapi.diagnostic.Logger
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.psi.PsiClass
|
import com.intellij.psi.PsiClass
|
||||||
|
import com.intellij.psi.PsiElementFactory
|
||||||
import com.intellij.psi.PsiTypeParameter
|
import com.intellij.psi.PsiTypeParameter
|
||||||
|
import com.intellij.psi.SyntaxTraverser
|
||||||
import com.intellij.psi.search.SearchScope
|
import com.intellij.psi.search.SearchScope
|
||||||
import org.jetbrains.kotlin.asJava.KtLightClassMarker
|
import org.jetbrains.kotlin.asJava.KtLightClassMarker
|
||||||
import org.jetbrains.kotlin.asJava.isSyntheticValuesOrValueOfMethod
|
import org.jetbrains.kotlin.asJava.isSyntheticValuesOrValueOfMethod
|
||||||
@@ -68,9 +70,18 @@ class JavaClassImpl(psiClassSource: JavaElementPsiSource<PsiClass>) : JavaClassi
|
|||||||
override val isSealed: Boolean
|
override val isSealed: Boolean
|
||||||
get() = JavaElementUtil.isSealed(this)
|
get() = JavaElementUtil.isSealed(this)
|
||||||
|
|
||||||
override val permittedTypes: Collection<JavaClassifierType>
|
override val permittedTypes: Sequence<JavaClassifierType>
|
||||||
get() = psi.permitsListTypes.convertIndexed { index, _ ->
|
get() {
|
||||||
JavaClassifierTypeImpl(sourceFactory.createPermittedTypeSource(psiElementSource, index))
|
if (!isSealed) return emptySequence()
|
||||||
|
|
||||||
|
val permitsListTypes = psi.permitsListTypes
|
||||||
|
return if (permitsListTypes.isNotEmpty()) {
|
||||||
|
permitsListTypes.convertIndexed { index, _ ->
|
||||||
|
JavaClassifierTypeImpl(sourceFactory.createPermittedTypeSource(psiElementSource, index))
|
||||||
|
}.asSequence()
|
||||||
|
} else {
|
||||||
|
lazilyComputePermittedTypesInSameFile(psiElementSource)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val isRecord: Boolean
|
override val isRecord: Boolean
|
||||||
@@ -163,3 +174,19 @@ class JavaClassImpl(psiClassSource: JavaElementPsiSource<PsiClass>) : JavaClassi
|
|||||||
private val LOGGER = Logger.getInstance(JavaClassImpl::class.java)
|
private val LOGGER = Logger.getInstance(JavaClassImpl::class.java)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun lazilyComputePermittedTypesInSameFile(psiElementSource: JavaElementPsiSource<PsiClass>): Sequence<JavaClassifierType> {
|
||||||
|
return Sequence {
|
||||||
|
// Don't capture PSI directly but only via psiElementSource
|
||||||
|
val psi = psiElementSource.psi
|
||||||
|
val elementFactory = PsiElementFactory.getInstance(psi.project)
|
||||||
|
|
||||||
|
SyntaxTraverser.psiTraverser(psi.containingFile)
|
||||||
|
.filter(PsiClass::class.java)
|
||||||
|
// isInheritor can lead to resolution which can cause contract violations,
|
||||||
|
// that's why we compute it lazily only when the sequence is iterated.
|
||||||
|
.filter { it.isInheritor(psi, /* checkDeep: */ false) }
|
||||||
|
.map { JavaClassifierTypeImpl(psiElementSource.factory.createTypeSource(elementFactory.createType(it))) }
|
||||||
|
.iterator()
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
-3
@@ -79,8 +79,10 @@ class BinaryJavaClass(
|
|||||||
|
|
||||||
override val lightClassOriginKind: LightClassOriginKind? get() = null
|
override val lightClassOriginKind: LightClassOriginKind? get() = null
|
||||||
|
|
||||||
override val isSealed: Boolean get() = permittedTypes.isNotEmpty()
|
private val permittedTypesList: ArrayList<JavaClassifierType> = arrayListOf()
|
||||||
override val permittedTypes = arrayListOf<JavaClassifierType>()
|
override val isSealed: Boolean get() = permittedTypesList.isNotEmpty()
|
||||||
|
override val permittedTypes: Sequence<JavaClassifierType>
|
||||||
|
get() = permittedTypesList.asSequence()
|
||||||
|
|
||||||
override fun isFromSourceCodeInScope(scope: SearchScope): Boolean = false
|
override fun isFromSourceCodeInScope(scope: SearchScope): Boolean = false
|
||||||
|
|
||||||
@@ -258,6 +260,6 @@ class BinaryJavaClass(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitPermittedSubclass(permittedSubclass: String?) {
|
override fun visitPermittedSubclass(permittedSubclass: String?) {
|
||||||
permittedTypes.addIfNotNull(permittedSubclass?.convertInternalNameToClassifierType())
|
permittedTypesList.addIfNotNull(permittedSubclass?.convertInternalNameToClassifierType())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+62
-1
@@ -10,11 +10,29 @@ public final class A extends Base {}
|
|||||||
|
|
||||||
// FILE: B.java
|
// FILE: B.java
|
||||||
public sealed class B extends Base permits B.C, B.D {
|
public sealed class B extends Base permits B.C, B.D {
|
||||||
public static final class C implements B {}
|
public static final class C extends B {}
|
||||||
|
|
||||||
public static non-sealed class D extends B {}
|
public static non-sealed class D extends B {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FILE: SameFile.java
|
||||||
|
public sealed class SameFile {
|
||||||
|
public static final class A extends SameFile {}
|
||||||
|
public static sealed class B extends SameFile {
|
||||||
|
public static final class C extends B {}
|
||||||
|
public static non-sealed class D extends B {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: SameFileNonSealed.java
|
||||||
|
public class SameFileNonSealed {
|
||||||
|
public static final class A extends SameFileNonSealed {}
|
||||||
|
public static class B extends SameFileNonSealed {
|
||||||
|
public static final class C extends B {}
|
||||||
|
public static class D extends B {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
fun test_ok_1(base: Base) {
|
fun test_ok_1(base: Base) {
|
||||||
val x = when (base) {
|
val x = when (base) {
|
||||||
@@ -31,6 +49,21 @@ fun test_ok_2(base: Base) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun test_ok_3(sameFile: SameFile) {
|
||||||
|
val x = when (sameFile) {
|
||||||
|
is SameFile.A -> 1
|
||||||
|
is SameFile.B -> 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test_ok_4(sameFile: SameFile) {
|
||||||
|
val x = when (sameFile) {
|
||||||
|
is SameFile.A -> 1
|
||||||
|
is SameFile.B.C -> 2
|
||||||
|
is SameFile.B.D -> 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun test_error_1(base: Base) {
|
fun test_error_1(base: Base) {
|
||||||
val x = <!NO_ELSE_IN_WHEN!>when<!> (base) {
|
val x = <!NO_ELSE_IN_WHEN!>when<!> (base) {
|
||||||
is A -> 1
|
is A -> 1
|
||||||
@@ -43,3 +76,31 @@ fun test_error_2(base: Base) {
|
|||||||
is B.C -> 2
|
is B.C -> 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun test_error_3(sameFile: SameFile) {
|
||||||
|
val x = <!NO_ELSE_IN_WHEN!>when<!> (sameFile) {
|
||||||
|
is SameFile.A -> 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test_error_4(sameFile: SameFile) {
|
||||||
|
val x = <!NO_ELSE_IN_WHEN!>when<!> (sameFile) {
|
||||||
|
is SameFile.A -> 1
|
||||||
|
is SameFile.B.C -> 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test_error_5(sameFile: SameFileNonSealed) {
|
||||||
|
val x = <!NO_ELSE_IN_WHEN!>when<!> (sameFile) {
|
||||||
|
is SameFileNonSealed.A -> 1
|
||||||
|
is SameFileNonSealed.B -> 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test_error_6(sameFile: SameFileNonSealed) {
|
||||||
|
val x = <!NO_ELSE_IN_WHEN!>when<!> (sameFile) {
|
||||||
|
is SameFileNonSealed.A -> 1
|
||||||
|
is SameFileNonSealed.B.C -> 2
|
||||||
|
is SameFileNonSealed.B.D -> 2
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+77
@@ -2,8 +2,14 @@ package
|
|||||||
|
|
||||||
public fun test_error_1(/*0*/ base: Base): kotlin.Unit
|
public fun test_error_1(/*0*/ base: Base): kotlin.Unit
|
||||||
public fun test_error_2(/*0*/ base: Base): kotlin.Unit
|
public fun test_error_2(/*0*/ base: Base): kotlin.Unit
|
||||||
|
public fun test_error_3(/*0*/ sameFile: SameFile): kotlin.Unit
|
||||||
|
public fun test_error_4(/*0*/ sameFile: SameFile): kotlin.Unit
|
||||||
|
public fun test_error_5(/*0*/ sameFile: SameFileNonSealed): kotlin.Unit
|
||||||
|
public fun test_error_6(/*0*/ sameFile: SameFileNonSealed): kotlin.Unit
|
||||||
public fun test_ok_1(/*0*/ base: Base): kotlin.Unit
|
public fun test_ok_1(/*0*/ base: Base): kotlin.Unit
|
||||||
public fun test_ok_2(/*0*/ base: Base): kotlin.Unit
|
public fun test_ok_2(/*0*/ base: Base): kotlin.Unit
|
||||||
|
public fun test_ok_3(/*0*/ sameFile: SameFile): kotlin.Unit
|
||||||
|
public fun test_ok_4(/*0*/ sameFile: SameFile): kotlin.Unit
|
||||||
|
|
||||||
public final class A : Base {
|
public final class A : Base {
|
||||||
public constructor A()
|
public constructor A()
|
||||||
@@ -39,3 +45,74 @@ public sealed class Base {
|
|||||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sealed class SameFile {
|
||||||
|
public constructor SameFile()
|
||||||
|
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public final class A : SameFile {
|
||||||
|
public constructor A()
|
||||||
|
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class B : SameFile {
|
||||||
|
public constructor B()
|
||||||
|
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public final class C : SameFile.B {
|
||||||
|
public constructor C()
|
||||||
|
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public open class D : SameFile.B {
|
||||||
|
public constructor D()
|
||||||
|
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public open class SameFileNonSealed {
|
||||||
|
public constructor SameFileNonSealed()
|
||||||
|
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public final class A : SameFileNonSealed {
|
||||||
|
public constructor A()
|
||||||
|
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public open class B : SameFileNonSealed {
|
||||||
|
public constructor B()
|
||||||
|
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public final class C : SameFileNonSealed.B {
|
||||||
|
public constructor C()
|
||||||
|
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public open class D : SameFileNonSealed.B {
|
||||||
|
public constructor D()
|
||||||
|
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
+19
@@ -20,6 +20,12 @@ public enum E implements Base {
|
|||||||
First, Second
|
First, Second
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FILE: SameFile.java
|
||||||
|
public sealed interface SameFile {
|
||||||
|
public static final class A implements SameFile {}
|
||||||
|
public static non-sealed class B implements SameFile {}
|
||||||
|
}
|
||||||
|
|
||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
fun test_ok_1(base: Base) {
|
fun test_ok_1(base: Base) {
|
||||||
val x = when (base) {
|
val x = when (base) {
|
||||||
@@ -39,6 +45,13 @@ fun test_ok_2(base: Base) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun test_ok_3(sameFile: SameFile) {
|
||||||
|
val x = when (sameFile) {
|
||||||
|
is SameFile.A -> 1
|
||||||
|
is SameFile.B -> 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun test_error_1(base: Base) {
|
fun test_error_1(base: Base) {
|
||||||
val x = <!NO_ELSE_IN_WHEN!>when<!> (base) {
|
val x = <!NO_ELSE_IN_WHEN!>when<!> (base) {
|
||||||
is A -> 1
|
is A -> 1
|
||||||
@@ -63,3 +76,9 @@ fun test_error_3(base: Base) {
|
|||||||
E.Second -> 5
|
E.Second -> 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun test_error_4(sameFile: SameFile) {
|
||||||
|
val x = <!NO_ELSE_IN_WHEN!>when<!> (sameFile) {
|
||||||
|
is SameFile.A -> 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+23
@@ -3,8 +3,10 @@ package
|
|||||||
public fun test_error_1(/*0*/ base: Base): kotlin.Unit
|
public fun test_error_1(/*0*/ base: Base): kotlin.Unit
|
||||||
public fun test_error_2(/*0*/ base: Base): kotlin.Unit
|
public fun test_error_2(/*0*/ base: Base): kotlin.Unit
|
||||||
public fun test_error_3(/*0*/ base: Base): kotlin.Unit
|
public fun test_error_3(/*0*/ base: Base): kotlin.Unit
|
||||||
|
public fun test_error_4(/*0*/ sameFile: SameFile): kotlin.Unit
|
||||||
public fun test_ok_1(/*0*/ base: Base): kotlin.Unit
|
public fun test_ok_1(/*0*/ base: Base): kotlin.Unit
|
||||||
public fun test_ok_2(/*0*/ base: Base): kotlin.Unit
|
public fun test_ok_2(/*0*/ base: Base): kotlin.Unit
|
||||||
|
public fun test_ok_3(/*0*/ sameFile: SameFile): kotlin.Unit
|
||||||
|
|
||||||
public interface A : Base {
|
public interface A : Base {
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
@@ -59,3 +61,24 @@ public final enum class E : kotlin.Enum<E!>, Base {
|
|||||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): E
|
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): E
|
||||||
public final /*synthesized*/ fun values(): kotlin.Array<E>
|
public final /*synthesized*/ fun values(): kotlin.Array<E>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sealed interface SameFile {
|
||||||
|
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public final class A : SameFile {
|
||||||
|
public constructor A()
|
||||||
|
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public open class B : SameFile {
|
||||||
|
public constructor B()
|
||||||
|
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 open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -102,7 +102,7 @@ interface JavaClass : JavaClassifier, JavaTypeParameterListOwner, JavaModifierLi
|
|||||||
val isEnum: Boolean
|
val isEnum: Boolean
|
||||||
val isRecord: Boolean
|
val isRecord: Boolean
|
||||||
val isSealed: Boolean
|
val isSealed: Boolean
|
||||||
val permittedTypes: Collection<JavaClassifierType>
|
val permittedTypes: Sequence<JavaClassifierType>
|
||||||
val lightClassOriginKind: LightClassOriginKind?
|
val lightClassOriginKind: LightClassOriginKind?
|
||||||
|
|
||||||
val methods: Collection<JavaMethod>
|
val methods: Collection<JavaMethod>
|
||||||
|
|||||||
+1
-1
@@ -197,7 +197,7 @@ class LazyJavaClassDescriptor(
|
|||||||
|
|
||||||
override fun getSealedSubclasses(): Collection<ClassDescriptor> = if (modality == Modality.SEALED) {
|
override fun getSealedSubclasses(): Collection<ClassDescriptor> = if (modality == Modality.SEALED) {
|
||||||
val attributes = TypeUsage.COMMON.toAttributes()
|
val attributes = TypeUsage.COMMON.toAttributes()
|
||||||
jClass.permittedTypes.mapNotNull {
|
jClass.permittedTypes.mapNotNullTo(mutableListOf()) {
|
||||||
c.typeResolver.transformJavaType(it, attributes).constructor.declarationDescriptor as? ClassDescriptor
|
c.typeResolver.transformJavaType(it, attributes).constructor.declarationDescriptor as? ClassDescriptor
|
||||||
}.sortedBy { it.fqNameSafe.asString() }
|
}.sortedBy { it.fqNameSafe.asString() }
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+2
-2
@@ -193,8 +193,8 @@ class SyntheticJavaClassDescriptor(
|
|||||||
get() = this@SyntheticJavaClassDescriptor.isRecord
|
get() = this@SyntheticJavaClassDescriptor.isRecord
|
||||||
override val isSealed: Boolean
|
override val isSealed: Boolean
|
||||||
get() = modality == Modality.SEALED
|
get() = modality == Modality.SEALED
|
||||||
override val permittedTypes: Collection<JavaClassifierType>
|
override val permittedTypes: Sequence<JavaClassifierType>
|
||||||
get() = emptyList()
|
get() = emptySequence()
|
||||||
override val lightClassOriginKind: LightClassOriginKind?
|
override val lightClassOriginKind: LightClassOriginKind?
|
||||||
get() = null
|
get() = null
|
||||||
override val methods: Collection<JavaMethod>
|
override val methods: Collection<JavaMethod>
|
||||||
|
|||||||
+3
-2
@@ -133,10 +133,11 @@ class ReflectJavaClass(
|
|||||||
override val isSealed: Boolean
|
override val isSealed: Boolean
|
||||||
get() = Java16SealedRecordLoader.loadIsSealed(klass) ?: false
|
get() = Java16SealedRecordLoader.loadIsSealed(klass) ?: false
|
||||||
|
|
||||||
override val permittedTypes: Collection<JavaClassifierType>
|
override val permittedTypes: Sequence<JavaClassifierType>
|
||||||
get() = Java16SealedRecordLoader.loadGetPermittedSubclasses(klass)
|
get() = Java16SealedRecordLoader.loadGetPermittedSubclasses(klass)
|
||||||
?.map(::ReflectJavaClassifierType)
|
?.map(::ReflectJavaClassifierType)
|
||||||
?: emptyList()
|
?.asSequence()
|
||||||
|
?: emptySequence()
|
||||||
|
|
||||||
override fun equals(other: Any?) = other is ReflectJavaClass && klass == other.klass
|
override fun equals(other: Any?) = other is ReflectJavaClass && klass == other.klass
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -75,7 +75,7 @@ class DummyJavaClass(name: String, override val fqName: FqName, numberOfTypePara
|
|||||||
get() = shouldNotBeCalled()
|
get() = shouldNotBeCalled()
|
||||||
override val isSealed: Boolean
|
override val isSealed: Boolean
|
||||||
get() = shouldNotBeCalled()
|
get() = shouldNotBeCalled()
|
||||||
override val permittedTypes: Collection<JavaClassifierType>
|
override val permittedTypes: Sequence<JavaClassifierType>
|
||||||
get() = shouldNotBeCalled()
|
get() = shouldNotBeCalled()
|
||||||
override val lightClassOriginKind: LightClassOriginKind?
|
override val lightClassOriginKind: LightClassOriginKind?
|
||||||
get() = shouldNotBeCalled()
|
get() = shouldNotBeCalled()
|
||||||
|
|||||||
Reference in New Issue
Block a user