FIR: support private-in-file effective visibility
This commit is contained in:
+1
-1
@@ -63,7 +63,7 @@ fun deserializeClassToSymbol(
|
||||
val status = FirResolvedDeclarationStatusImpl(
|
||||
visibility,
|
||||
modality,
|
||||
visibility.toEffectiveVisibility(parentContext?.outerClassSymbol)
|
||||
visibility.toEffectiveVisibility(parentContext?.outerClassSymbol, forClass = true)
|
||||
).apply {
|
||||
isExpect = Flags.IS_EXPECT_CLASS.get(flags)
|
||||
isActual = false
|
||||
|
||||
@@ -248,7 +248,7 @@ class JavaSymbolProvider(
|
||||
existingNestedClassifierNames += javaClass.innerClassNames
|
||||
scopeProvider = this@JavaSymbolProvider.scopeProvider
|
||||
|
||||
val selfEffectiveVisibility = visibility.toEffectiveVisibility(parentClassSymbol?.toLookupTag())
|
||||
val selfEffectiveVisibility = visibility.toEffectiveVisibility(parentClassSymbol?.toLookupTag(), forClass = true)
|
||||
val parentEffectiveVisibility = parentClassSymbol?.let {
|
||||
parentClassEffectiveVisibilityCache[it] ?: it.fir.effectiveVisibility
|
||||
} ?: EffectiveVisibility.Public
|
||||
|
||||
@@ -13,18 +13,21 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
|
||||
fun Visibility.toEffectiveVisibility(
|
||||
ownerSymbol: FirClassLikeSymbol<*>?,
|
||||
forClass: Boolean = false,
|
||||
checkPublishedApi: Boolean = false
|
||||
): EffectiveVisibility {
|
||||
return toEffectiveVisibility(ownerSymbol?.toLookupTag(), checkPublishedApi)
|
||||
return toEffectiveVisibility(ownerSymbol?.toLookupTag(), forClass, checkPublishedApi)
|
||||
}
|
||||
|
||||
fun Visibility.toEffectiveVisibility(
|
||||
owner: ConeClassLikeLookupTag?,
|
||||
forClass: Boolean = false,
|
||||
checkPublishedApi: Boolean = false
|
||||
): EffectiveVisibility {
|
||||
customEffectiveVisibility()?.let { return it }
|
||||
return when (this.normalize()) {
|
||||
Visibilities.Private, Visibilities.PrivateToThis, Visibilities.InvisibleFake -> EffectiveVisibility.PrivateInClass
|
||||
Visibilities.PrivateToThis, Visibilities.InvisibleFake -> EffectiveVisibility.PrivateInClass
|
||||
Visibilities.Private -> if (owner == null && forClass) EffectiveVisibility.PrivateInFile else EffectiveVisibility.PrivateInClass
|
||||
Visibilities.Protected -> EffectiveVisibility.Protected(owner)
|
||||
Visibilities.Internal -> when (!checkPublishedApi /*|| !owner.isPublishedApi()*/) { // TODO
|
||||
true -> EffectiveVisibility.Internal
|
||||
|
||||
+3
-1
@@ -168,7 +168,9 @@ class FirStatusResolver(
|
||||
containingClass is FirAnonymousObject -> EffectiveVisibility.Local
|
||||
else -> EffectiveVisibility.Public
|
||||
}
|
||||
val selfEffectiveVisibility = visibility.toEffectiveVisibility(containingClass?.symbol?.toLookupTag())
|
||||
val selfEffectiveVisibility = visibility.toEffectiveVisibility(
|
||||
containingClass?.symbol?.toLookupTag(), forClass = declaration is FirClass<*>
|
||||
)
|
||||
val effectiveVisibility = parentEffectiveVisibility.lowerBound(selfEffectiveVisibility, session.typeContext)
|
||||
return status.resolved(visibility, modality, effectiveVisibility)
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,13 +1,13 @@
|
||||
compiler/testData/cli/jvm/firError.kt:5:13: error: x must be initialized before access
|
||||
println(x)
|
||||
^
|
||||
compiler/testData/cli/jvm/firError.kt:10:16: error: public subclass exposes its private supertype 'Private'
|
||||
compiler/testData/cli/jvm/firError.kt:10:16: error: public subclass exposes its private-in-file supertype 'Private'
|
||||
class Public : Private() {
|
||||
^
|
||||
compiler/testData/cli/jvm/firError.kt:11:5: error: property must be initialized or be abstract
|
||||
val x: Private
|
||||
^
|
||||
compiler/testData/cli/jvm/firError.kt:11:9: error: public property exposes its private type 'Private'
|
||||
compiler/testData/cli/jvm/firError.kt:11:9: error: public property exposes its private-in-file type 'Private'
|
||||
val x: Private
|
||||
^
|
||||
COMPILATION_ERROR
|
||||
|
||||
@@ -13,17 +13,17 @@ class Public {
|
||||
private class PrivateInFileClass {
|
||||
private open class NestedPrivate
|
||||
|
||||
fun test1() = NestedPrivate()
|
||||
fun test2(p: NestedPrivate) {}
|
||||
fun NestedPrivate.test3() {}
|
||||
val test4 = NestedPrivate()
|
||||
class Test5 : NestedPrivate()
|
||||
fun <!EXPOSED_FUNCTION_RETURN_TYPE!>test1<!>() = NestedPrivate()
|
||||
fun test2(<!EXPOSED_PARAMETER_TYPE!>p: NestedPrivate<!>) {}
|
||||
fun <!EXPOSED_RECEIVER_TYPE!>NestedPrivate<!>.test3() {}
|
||||
val <!EXPOSED_PROPERTY_TYPE!>test4<!> = NestedPrivate()
|
||||
class Test5 : <!EXPOSED_SUPER_CLASS!>NestedPrivate<!>()
|
||||
}
|
||||
|
||||
private interface PrivateInFile {
|
||||
private class Private
|
||||
|
||||
fun expose() = Private()
|
||||
fun <!EXPOSED_FUNCTION_RETURN_TYPE!>expose<!>() = Private()
|
||||
}
|
||||
|
||||
// Exposes 'PrivateInFile$Private' via 'expose'
|
||||
|
||||
@@ -13,17 +13,17 @@ class Public {
|
||||
private class PrivateInFileClass {
|
||||
private open class NestedPrivate
|
||||
|
||||
fun test1() = NestedPrivate()
|
||||
fun test2(p: NestedPrivate) {}
|
||||
fun NestedPrivate.test3() {}
|
||||
val test4 = NestedPrivate()
|
||||
class Test5 : NestedPrivate()
|
||||
fun <!EXPOSED_FUNCTION_RETURN_TYPE!>test1<!>() = NestedPrivate()
|
||||
fun test2(<!EXPOSED_PARAMETER_TYPE!>p: NestedPrivate<!>) {}
|
||||
fun <!EXPOSED_RECEIVER_TYPE!>NestedPrivate<!>.test3() {}
|
||||
val <!EXPOSED_PROPERTY_TYPE!>test4<!> = NestedPrivate()
|
||||
class Test5 : <!EXPOSED_SUPER_CLASS!>NestedPrivate<!>()
|
||||
}
|
||||
|
||||
private interface PrivateInFile {
|
||||
private class Private
|
||||
|
||||
fun expose() = Private()
|
||||
fun <!EXPOSED_FUNCTION_RETURN_TYPE!>expose<!>() = Private()
|
||||
}
|
||||
|
||||
// Exposes 'PrivateInFile$Private' via 'expose'
|
||||
|
||||
+1
-1
@@ -11,4 +11,4 @@ package a
|
||||
|
||||
import pack1.SomeClass.*
|
||||
|
||||
private class X : <!HIDDEN!>N<!>()
|
||||
private class X : <!EXPOSED_SUPER_CLASS, HIDDEN!>N<!>()
|
||||
|
||||
+6
-6
@@ -2,18 +2,18 @@ private class A
|
||||
|
||||
open class B<T>(val x: T)
|
||||
|
||||
class C(<error descr="[EXPOSED_PARAMETER_TYPE] public function exposes its private parameter type 'A'">x: A</error>): <error descr="[EXPOSED_SUPER_CLASS] public subclass exposes its private supertype 'A'">B<A></error>(x)
|
||||
class C(<error descr="[EXPOSED_PARAMETER_TYPE] public function exposes its private-in-file parameter type 'A'">x: A</error>): <error descr="[EXPOSED_SUPER_CLASS] public subclass exposes its private-in-file supertype 'A'">B<A></error>(x)
|
||||
|
||||
private class D {
|
||||
class E
|
||||
}
|
||||
|
||||
fun <error descr="[EXPOSED_FUNCTION_RETURN_TYPE] public function exposes its private return type 'A'">create</error>() = A()
|
||||
fun <error descr="[EXPOSED_FUNCTION_RETURN_TYPE] public function exposes its private-in-file return type 'A'">create</error>() = A()
|
||||
|
||||
fun <error descr="[EXPOSED_FUNCTION_RETURN_TYPE] public function exposes its private return type 'A'">create</error>(<error descr="[EXPOSED_PARAMETER_TYPE] public function exposes its private parameter type 'A'">a: A</error>) = B(a)
|
||||
fun <error descr="[EXPOSED_FUNCTION_RETURN_TYPE] public function exposes its private-in-file return type 'A'">create</error>(<error descr="[EXPOSED_PARAMETER_TYPE] public function exposes its private-in-file parameter type 'A'">a: A</error>) = B(a)
|
||||
|
||||
val <error descr="[EXPOSED_PROPERTY_TYPE] public property exposes its private type 'A'">x</error> = create()
|
||||
val <error descr="[EXPOSED_PROPERTY_TYPE] public property exposes its private-in-file type 'A'">x</error> = create()
|
||||
|
||||
val <error descr="[EXPOSED_PROPERTY_TYPE] public property exposes its private type 'A'">y</error> = create(x)
|
||||
val <error descr="[EXPOSED_PROPERTY_TYPE] public property exposes its private-in-file type 'A'">y</error> = create(x)
|
||||
|
||||
val <error descr="[EXPOSED_PROPERTY_TYPE] public property exposes its private type 'E'">z</error>: B<D.E>? = null
|
||||
val <error descr="[EXPOSED_PROPERTY_TYPE] public property exposes its private-in-file type 'E'">z</error>: B<D.E>? = null
|
||||
|
||||
Reference in New Issue
Block a user