From 54cfd1f6250ab276ba42a29e93bc3db7561dd3e1 Mon Sep 17 00:00:00 2001 From: rapturemain Date: Mon, 27 Apr 2020 18:17:47 +0300 Subject: [PATCH] [FIR] Handle protected effective visibility relation properly #KT-38401 Fixed --- .../kotlin/fir/FirEffectiveVisibilityImpl.kt | 38 ++++++++++++------- .../tests/exposed/internalAndProtected.fir.kt | 10 ----- .../tests/exposed/internalAndProtected.kt | 1 + .../tests/exposed/protectedJava.fir.kt | 2 +- .../tests/exposed/protectedSameWay.fir.kt | 2 +- .../tests/imports/ImportProtectedClass.fir.kt | 2 +- 6 files changed, 29 insertions(+), 26 deletions(-) delete mode 100644 compiler/testData/diagnostics/tests/exposed/internalAndProtected.fir.kt diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirEffectiveVisibilityImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirEffectiveVisibilityImpl.kt index ed5688563da..15c6152fea4 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirEffectiveVisibilityImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirEffectiveVisibilityImpl.kt @@ -7,7 +7,10 @@ package org.jetbrains.kotlin.fir import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.FirEffectiveVisibility.Permissiveness +import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirRegularClass +import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes +import org.jetbrains.kotlin.fir.types.classId sealed class FirEffectiveVisibilityImpl( override val name: String, @@ -185,18 +188,27 @@ sealed class FirEffectiveVisibilityImpl( Permissiveness.MORE -> other Permissiveness.UNKNOWN -> Private } + + companion object { + private fun containerRelation(first: FirRegularClass?, second: FirRegularClass?): Permissiveness = + if (first == null || second == null) { + Permissiveness.UNKNOWN + } else if (first == second) { + Permissiveness.SAME + } else { + when { + first.collectSupertypes().any { it.classId == second.symbol.classId } -> Permissiveness.LESS + second.collectSupertypes().any { it.classId == first.symbol.classId } -> Permissiveness.MORE + else -> Permissiveness.UNKNOWN + } + } + + private fun FirRegularClass.collectSupertypes() = lookupSuperTypes( + this as FirClass<*>, + lookupInterfaces = true, + deep = true, + useSiteSession = this.session + ) + } } -internal fun containerRelation(first: FirRegularClass?, second: FirRegularClass?): Permissiveness = - if (first == null || second == null) { - Permissiveness.UNKNOWN - } else if (first == second) { - Permissiveness.SAME - // TODO -// } else if (DescriptorUtils.isSubclass(first, second)) { -// Permissiveness.LESS -// } else if (DescriptorUtils.isSubclass(second, first)) { -// Permissiveness.MORE - } else { - Permissiveness.UNKNOWN - } diff --git a/compiler/testData/diagnostics/tests/exposed/internalAndProtected.fir.kt b/compiler/testData/diagnostics/tests/exposed/internalAndProtected.fir.kt deleted file mode 100644 index 394273d9dad..00000000000 --- a/compiler/testData/diagnostics/tests/exposed/internalAndProtected.fir.kt +++ /dev/null @@ -1,10 +0,0 @@ -public open class A { - protected open class B -} - -public open class C : A() { - protected open class D { - // internal & protected(in C) <= protected(in A): Ok - internal open class E : A.B() - } -} diff --git a/compiler/testData/diagnostics/tests/exposed/internalAndProtected.kt b/compiler/testData/diagnostics/tests/exposed/internalAndProtected.kt index 25d2b2f6780..266857bf8fe 100644 --- a/compiler/testData/diagnostics/tests/exposed/internalAndProtected.kt +++ b/compiler/testData/diagnostics/tests/exposed/internalAndProtected.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL public open class A { protected open class B } diff --git a/compiler/testData/diagnostics/tests/exposed/protectedJava.fir.kt b/compiler/testData/diagnostics/tests/exposed/protectedJava.fir.kt index 2276a93325a..7dc16417a2e 100644 --- a/compiler/testData/diagnostics/tests/exposed/protectedJava.fir.kt +++ b/compiler/testData/diagnostics/tests/exposed/protectedJava.fir.kt @@ -10,7 +10,7 @@ public abstract class Outer { class OuterDerived: Outer() { // valid, My has better visibility - protected class His: Outer.My() + protected class His: Outer.My() // valid, My and Your have better visibility override fun foo(my: Outer.My) = Outer.Your() } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/exposed/protectedSameWay.fir.kt b/compiler/testData/diagnostics/tests/exposed/protectedSameWay.fir.kt index 2acdd1386c7..6a0cc23ebf3 100644 --- a/compiler/testData/diagnostics/tests/exposed/protectedSameWay.fir.kt +++ b/compiler/testData/diagnostics/tests/exposed/protectedSameWay.fir.kt @@ -7,7 +7,7 @@ abstract class Outer { class OuterDerived: Outer() { // valid, My has better visibility - protected class His: Outer.My() + protected class His: Outer.My() // valid, My and Your have better visibility override fun foo(my: Outer.My) = Outer.Your() } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/imports/ImportProtectedClass.fir.kt b/compiler/testData/diagnostics/tests/imports/ImportProtectedClass.fir.kt index 4c48bbf90f5..bad5d7c283b 100644 --- a/compiler/testData/diagnostics/tests/imports/ImportProtectedClass.fir.kt +++ b/compiler/testData/diagnostics/tests/imports/ImportProtectedClass.fir.kt @@ -7,7 +7,7 @@ open class Foo { } class Bar: Foo() { - protected fun foo(): Nested? = null + protected fun foo(): Nested? = null } private fun foo(): Nested? = null