From 07e9b9517ac2d7d5ddadbffc68d61d36de7a15a0 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Tue, 28 Apr 2020 18:51:34 +0300 Subject: [PATCH] [FIR] Extract interface FirEffectiveVisibility --- .../expresssions/protectedVisibility.txt | 4 +- .../visibility/exposedPropertyType.txt | 4 +- .../backend/jvm/FirJvmSerializerExtension.kt | 4 +- .../kotlin/fir/FirEffectiveVisibilityImpl.kt | 202 ++++++++++++++++ .../kotlin/fir/FirEffectiveVisibilityUtils.kt | 4 +- .../FirStatusResolveTransformer.kt | 14 +- .../scopes/impl/FirIntegerLiteralTypeScope.kt | 2 +- .../kotlin/fir/FirEffectiveVisibility.kt | 224 +++--------------- .../org/jetbrains/kotlin/fir/FirRenderer.kt | 2 +- .../impl/FirDeclarationStatusImpl.kt | 3 +- 10 files changed, 247 insertions(+), 216 deletions(-) create mode 100644 compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirEffectiveVisibilityImpl.kt diff --git a/compiler/fir/analysis-tests/testData/resolve/expresssions/protectedVisibility.txt b/compiler/fir/analysis-tests/testData/resolve/expresssions/protectedVisibility.txt index 503194dfe9e..fc03a4b2fd2 100644 --- a/compiler/fir/analysis-tests/testData/resolve/expresssions/protectedVisibility.txt +++ b/compiler/fir/analysis-tests/testData/resolve/expresssions/protectedVisibility.txt @@ -24,11 +24,11 @@ FILE: protectedVisibility.kt } protected open class Nested : R|kotlin/Any| { - public[protected (in different classes)] constructor(): R|Protected.Nested| { + public[protected] constructor(): R|Protected.Nested| { super() } - public[protected (in different classes)] final fun foo(): R|kotlin/Unit| { + public[protected] final fun foo(): R|kotlin/Unit| { this@R|/Protected.Nested|.R|/Protected.Nested.bar|() } diff --git a/compiler/fir/analysis-tests/testData/resolve/visibility/exposedPropertyType.txt b/compiler/fir/analysis-tests/testData/resolve/visibility/exposedPropertyType.txt index ae9d030deaf..efe8be2e9d5 100644 --- a/compiler/fir/analysis-tests/testData/resolve/visibility/exposedPropertyType.txt +++ b/compiler/fir/analysis-tests/testData/resolve/visibility/exposedPropertyType.txt @@ -21,10 +21,10 @@ FILE: exposedPropertyType.kt public final static enum entry A: R|A.AInnerProtectedEnum| public final static enum entry B: R|A.AInnerProtectedEnum| - public final static fun values(): R|kotlin/Array| { + public[protected] final static fun values(): R|kotlin/Array| { } - public final static fun valueOf(value: R|kotlin/String|): R|A.AInnerProtectedEnum| { + public[protected] final static fun valueOf(value: R|kotlin/String|): R|A.AInnerProtectedEnum| { } } diff --git a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmSerializerExtension.kt b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmSerializerExtension.kt index 7e7709e75ce..37b1e548680 100644 --- a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmSerializerExtension.kt +++ b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmSerializerExtension.kt @@ -14,7 +14,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.Visibilities -import org.jetbrains.kotlin.fir.FirEffectiveVisibility +import org.jetbrains.kotlin.fir.FirEffectiveVisibilityImpl import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.backend.FirMetadataSource import org.jetbrains.kotlin.fir.declarations.* @@ -72,7 +72,7 @@ class FirJvmSerializerExtension @JvmOverloads constructor( } override fun shouldSerializeNestedClass(nestedClass: FirRegularClass): Boolean { - return classBuilderMode != ClassBuilderMode.ABI || nestedClass.effectiveVisibility != FirEffectiveVisibility.Private + return classBuilderMode != ClassBuilderMode.ABI || nestedClass.effectiveVisibility != FirEffectiveVisibilityImpl.Private } override fun serializeClass( diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirEffectiveVisibilityImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirEffectiveVisibilityImpl.kt new file mode 100644 index 00000000000..ed5688563da --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirEffectiveVisibilityImpl.kt @@ -0,0 +1,202 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir + +import org.jetbrains.kotlin.descriptors.Visibilities +import org.jetbrains.kotlin.fir.FirEffectiveVisibility.Permissiveness +import org.jetbrains.kotlin.fir.declarations.FirRegularClass + +sealed class FirEffectiveVisibilityImpl( + override val name: String, + override val publicApi: Boolean = false, + override val privateApi: Boolean = false +) : FirEffectiveVisibility { + + override fun toString() = name + + // Public + // /--/ | \-------------\ + // Protected(Base) | \ + // | Protected(Other) Internal = PackagePrivate + // Protected(Derived) | / \ + // | | / InternalProtected(Base) + // ProtectedBound / \ + // \ / /InternalProtected(Derived) + // \InternalProtectedBound/ + // | + // Private = Local + + + object Private : FirEffectiveVisibilityImpl("private", privateApi = true) { + override fun relation(other: FirEffectiveVisibility) = + if (this == other || Local == other) Permissiveness.SAME else Permissiveness.LESS + + override fun toVisibility() = Visibilities.PRIVATE + } + + // Effectively same as Private + object Local : FirEffectiveVisibilityImpl("local") { + override fun relation(other: FirEffectiveVisibility) = + if (this == other || Private == other) Permissiveness.SAME else Permissiveness.LESS + + override fun toVisibility() = Visibilities.LOCAL + } + + object Public : FirEffectiveVisibilityImpl("public", publicApi = true) { + override fun relation(other: FirEffectiveVisibility) = + if (this == other) Permissiveness.SAME else Permissiveness.MORE + + override fun toVisibility() = Visibilities.PUBLIC + } + + abstract class InternalOrPackage protected constructor(internal: Boolean) : FirEffectiveVisibilityImpl( + if (internal) "internal" else "public/*package*/" + ) { + override fun relation(other: FirEffectiveVisibility) = when (other as FirEffectiveVisibilityImpl) { + Public -> Permissiveness.LESS + Private, Local, InternalProtectedBound, is InternalProtected -> Permissiveness.MORE + is InternalOrPackage -> Permissiveness.SAME + ProtectedBound, is Protected -> Permissiveness.UNKNOWN + } + + override fun lowerBound(other: FirEffectiveVisibility) = when (val o = other as FirEffectiveVisibilityImpl) { + Public -> this + Private, Local, InternalProtectedBound, is InternalOrPackage, is InternalProtected -> other + is Protected -> InternalProtected(o.container) + ProtectedBound -> InternalProtectedBound + } + } + + object Internal : InternalOrPackage(true) { + override fun toVisibility() = Visibilities.INTERNAL + } + + object PackagePrivate : InternalOrPackage(false) { + override fun toVisibility() = Visibilities.PRIVATE + } + + class Protected(val container: FirRegularClass?) : FirEffectiveVisibilityImpl("protected", publicApi = true) { + + override fun equals(other: Any?) = (other is Protected && container == other.container) + + override fun hashCode() = container?.hashCode() ?: 0 + + override fun toString() = "${super.toString()} (in ${container?.name ?: '?'})" + + override fun relation(other: FirEffectiveVisibility) = when (val o = other as FirEffectiveVisibilityImpl) { + Public -> Permissiveness.LESS + Private, Local, ProtectedBound, InternalProtectedBound -> Permissiveness.MORE + is Protected -> containerRelation(container, o.container) + is InternalProtected -> when (containerRelation(container, o.container)) { + // Protected never can be less permissive than internal & protected + Permissiveness.SAME, Permissiveness.MORE -> Permissiveness.MORE + Permissiveness.UNKNOWN, Permissiveness.LESS -> Permissiveness.UNKNOWN + } + is InternalOrPackage -> Permissiveness.UNKNOWN + } + + override fun lowerBound(other: FirEffectiveVisibility) = when (other as FirEffectiveVisibilityImpl) { + Public -> this + Private, Local, ProtectedBound, InternalProtectedBound -> other + is Protected -> when (relation(other)) { + Permissiveness.SAME, Permissiveness.MORE -> this + Permissiveness.LESS -> other + Permissiveness.UNKNOWN -> ProtectedBound + } + is InternalProtected -> when (relation(other)) { + Permissiveness.LESS -> other + else -> InternalProtectedBound + } + is InternalOrPackage -> InternalProtected(container) + } + + override fun toVisibility() = Visibilities.PROTECTED + } + + // Lower bound for all protected visibilities + object ProtectedBound : FirEffectiveVisibilityImpl("protected (in different classes)", publicApi = true) { + override fun relation(other: FirEffectiveVisibility) = when (other as FirEffectiveVisibilityImpl) { + Public, is Protected -> Permissiveness.LESS + Private, Local, InternalProtectedBound -> Permissiveness.MORE + ProtectedBound -> Permissiveness.SAME + is InternalOrPackage, is InternalProtected -> Permissiveness.UNKNOWN + } + + override fun lowerBound(other: FirEffectiveVisibility) = when (other as FirEffectiveVisibilityImpl) { + Public, is Protected -> this + Private, Local, ProtectedBound, InternalProtectedBound -> other + is InternalOrPackage, is InternalProtected -> InternalProtectedBound + } + + override fun toVisibility() = Visibilities.PROTECTED + } + + // Lower bound for internal and protected(C) + class InternalProtected(val container: FirRegularClass?) : FirEffectiveVisibilityImpl("internal & protected") { + + override fun equals(other: Any?) = (other is InternalProtected && container == other.container) + + override fun hashCode() = container?.hashCode() ?: 0 + + override fun toString() = "${super.toString()} (in ${container?.name ?: '?'})" + + override fun relation(other: FirEffectiveVisibility) = when (val o = other as FirEffectiveVisibilityImpl) { + Public, is InternalOrPackage -> Permissiveness.LESS + Private, Local, InternalProtectedBound -> Permissiveness.MORE + is InternalProtected -> containerRelation(container, o.container) + is Protected -> when (containerRelation(container, o.container)) { + // Internal & protected never can be more permissive than just protected + Permissiveness.SAME, Permissiveness.LESS -> Permissiveness.LESS + Permissiveness.UNKNOWN, Permissiveness.MORE -> Permissiveness.UNKNOWN + } + ProtectedBound -> Permissiveness.UNKNOWN + } + + override fun lowerBound(other: FirEffectiveVisibility) = when (other as FirEffectiveVisibilityImpl) { + Public, is InternalOrPackage -> this + Private, Local, InternalProtectedBound -> other + is Protected, is InternalProtected -> when (relation(other)) { + Permissiveness.SAME, Permissiveness.MORE -> this + Permissiveness.LESS -> other + Permissiveness.UNKNOWN -> InternalProtectedBound + } + ProtectedBound -> InternalProtectedBound + } + + override fun toVisibility() = Visibilities.PRIVATE + } + + // Lower bound for internal and protected lower bound + object InternalProtectedBound : FirEffectiveVisibilityImpl("internal & protected (in different classes)") { + override fun relation(other: FirEffectiveVisibility) = when (other as FirEffectiveVisibilityImpl) { + Public, is Protected, is InternalProtected, ProtectedBound, is InternalOrPackage -> Permissiveness.LESS + Private, Local -> Permissiveness.MORE + InternalProtectedBound -> Permissiveness.SAME + } + + override fun toVisibility() = Visibilities.PRIVATE + } + + override fun lowerBound(other: FirEffectiveVisibility) = when (relation(other)) { + Permissiveness.SAME, Permissiveness.LESS -> this + Permissiveness.MORE -> other + Permissiveness.UNKNOWN -> Private + } +} + +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/fir/resolve/src/org/jetbrains/kotlin/fir/FirEffectiveVisibilityUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirEffectiveVisibilityUtils.kt index b45c4b46f69..e8dcaa82e0a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirEffectiveVisibilityUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirEffectiveVisibilityUtils.kt @@ -8,10 +8,10 @@ package org.jetbrains.kotlin.fir import org.jetbrains.kotlin.descriptors.RelationToType import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibility -import org.jetbrains.kotlin.fir.FirEffectiveVisibility.* +import org.jetbrains.kotlin.fir.FirEffectiveVisibility.Permissiveness +import org.jetbrains.kotlin.fir.FirEffectiveVisibilityImpl.* import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.resolve.declaredMemberScopeProvider -import org.jetbrains.kotlin.fir.resolve.firProvider import org.jetbrains.kotlin.fir.resolve.firSymbolProvider import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.types.ConeClassLikeType diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt index 6ae53209496..740c6907d54 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt @@ -9,14 +9,11 @@ import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibility -import org.jetbrains.kotlin.fir.FirEffectiveVisibility -import org.jetbrains.kotlin.fir.FirElement -import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl import org.jetbrains.kotlin.fir.expressions.FirBlock import org.jetbrains.kotlin.fir.expressions.FirStatement -import org.jetbrains.kotlin.fir.firEffectiveVisibility import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult import org.jetbrains.kotlin.fir.visitors.FirTransformer import org.jetbrains.kotlin.fir.visitors.compose @@ -171,7 +168,7 @@ private class FirStatusResolveTransformer( private val > FirClass.effectiveVisibility: FirEffectiveVisibility get() = when (this) { is FirRegularClass -> status.effectiveVisibility - is FirAnonymousObject -> FirEffectiveVisibility.Local + is FirAnonymousObject -> FirEffectiveVisibilityImpl.Local else -> error("Unknown kind of class: ${this::class}") } @@ -187,7 +184,9 @@ fun FirDeclaration.resolveStatus( containingClass: FirClass<*>?, isLocal: Boolean ): FirDeclarationStatus { - if (status.visibility == Visibilities.UNKNOWN || status.modality == null) { + if (status.visibility == Visibilities.UNKNOWN || status.modality == null || + status.effectiveVisibility == FirEffectiveVisibility.Default + ) { val visibility = when (status.visibility) { Visibilities.UNKNOWN -> when { isLocal -> Visibilities.LOCAL @@ -197,7 +196,8 @@ fun FirDeclaration.resolveStatus( else -> status.visibility } val modality = status.modality ?: resolveModality(containingClass) - val containerEffectiveVisibility = containingClass?.effectiveVisibility ?: FirEffectiveVisibility.Public + val containerEffectiveVisibility = containingClass?.effectiveVisibility?.takeIf { it !is FirEffectiveVisibility.Default } + ?: FirEffectiveVisibilityImpl.Public val effectiveVisibility = visibility.firEffectiveVisibility(session, this as? FirMemberDeclaration).lowerBound(containerEffectiveVisibility) return (status as FirDeclarationStatusImpl).resolved(visibility, effectiveVisibility, modality) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirIntegerLiteralTypeScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirIntegerLiteralTypeScope.kt index 82c331b6dc4..8742c287d3d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirIntegerLiteralTypeScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirIntegerLiteralTypeScope.kt @@ -76,7 +76,7 @@ class FirIntegerLiteralTypeScope(private val session: FirSession, val isUnsigned FirILTTypeRefPlaceHolder(isUnsigned), receiverTypeRef = null, ALL_OPERATORS.getValue(name), - FirResolvedDeclarationStatusImpl(Visibilities.PUBLIC, FirEffectiveVisibility.Public, Modality.FINAL), + FirResolvedDeclarationStatusImpl(Visibilities.PUBLIC, FirEffectiveVisibilityImpl.Public, Modality.FINAL), symbol ).apply { resolvePhase = FirResolvePhase.BODY_RESOLVE diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirEffectiveVisibility.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirEffectiveVisibility.kt index 24fde86473a..3a786f14f69 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirEffectiveVisibility.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirEffectiveVisibility.kt @@ -5,177 +5,15 @@ package org.jetbrains.kotlin.fir -import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibility -import org.jetbrains.kotlin.fir.FirEffectiveVisibility.* -import org.jetbrains.kotlin.fir.declarations.FirRegularClass -sealed class FirEffectiveVisibility(val name: String, val publicApi: Boolean = false, val privateApi: Boolean = false) { +interface FirEffectiveVisibility { - override fun toString() = name + val name: String - // Public - // /--/ | \-------------\ - // Protected(Base) | \ - // | Protected(Other) Internal = PackagePrivate - // Protected(Derived) | / \ - // | | / InternalProtected(Base) - // ProtectedBound / \ - // \ / /InternalProtected(Derived) - // \InternalProtectedBound/ - // | - // Private = Local + val publicApi: Boolean - - object Private : FirEffectiveVisibility("private", privateApi = true) { - override fun relation(other: FirEffectiveVisibility) = - if (this == other || Local == other) Permissiveness.SAME else Permissiveness.LESS - - override fun toVisibility() = Visibilities.PRIVATE - } - - // Effectively same as Private - object Local : FirEffectiveVisibility("local") { - override fun relation(other: FirEffectiveVisibility) = - if (this == other || Private == other) Permissiveness.SAME else Permissiveness.LESS - - override fun toVisibility() = Visibilities.LOCAL - } - - object Public : FirEffectiveVisibility("public", publicApi = true) { - override fun relation(other: FirEffectiveVisibility) = - if (this == other) Permissiveness.SAME else Permissiveness.MORE - - override fun toVisibility() = Visibilities.PUBLIC - } - - abstract class InternalOrPackage protected constructor(internal: Boolean) : FirEffectiveVisibility( - if (internal) "internal" else "public/*package*/" - ) { - override fun relation(other: FirEffectiveVisibility) = when (other) { - Public -> Permissiveness.LESS - Private, Local, InternalProtectedBound, is InternalProtected -> Permissiveness.MORE - is InternalOrPackage -> Permissiveness.SAME - ProtectedBound, is Protected -> Permissiveness.UNKNOWN - } - - override fun lowerBound(other: FirEffectiveVisibility) = when (other) { - Public -> this - Private, Local, InternalProtectedBound, is InternalOrPackage, is InternalProtected -> other - is Protected -> InternalProtected(other.container) - ProtectedBound -> InternalProtectedBound - } - } - - object Internal : InternalOrPackage(true) { - override fun toVisibility() = Visibilities.INTERNAL - } - - object PackagePrivate : InternalOrPackage(false) { - override fun toVisibility() = Visibilities.PRIVATE - } - - class Protected(val container: FirRegularClass?) : FirEffectiveVisibility("protected", publicApi = true) { - - override fun equals(other: Any?) = (other is Protected && container == other.container) - - override fun hashCode() = container?.hashCode() ?: 0 - - override fun toString() = "${super.toString()} (in ${container?.name ?: '?'})" - - override fun relation(other: FirEffectiveVisibility) = when (other) { - Public -> Permissiveness.LESS - Private, Local, ProtectedBound, InternalProtectedBound -> Permissiveness.MORE - is Protected -> containerRelation(container, other.container) - is InternalProtected -> when (containerRelation(container, other.container)) { - // Protected never can be less permissive than internal & protected - Permissiveness.SAME, Permissiveness.MORE -> Permissiveness.MORE - Permissiveness.UNKNOWN, Permissiveness.LESS -> Permissiveness.UNKNOWN - } - is InternalOrPackage -> Permissiveness.UNKNOWN - } - - override fun lowerBound(other: FirEffectiveVisibility) = when (other) { - Public -> this - Private, Local, ProtectedBound, InternalProtectedBound -> other - is Protected -> when (relation(other)) { - Permissiveness.SAME, Permissiveness.MORE -> this - Permissiveness.LESS -> other - Permissiveness.UNKNOWN -> ProtectedBound - } - is InternalProtected -> when (relation(other)) { - Permissiveness.LESS -> other - else -> InternalProtectedBound - } - is InternalOrPackage -> InternalProtected(container) - } - - override fun toVisibility() = Visibilities.PROTECTED - } - - // Lower bound for all protected visibilities - object ProtectedBound : FirEffectiveVisibility("protected (in different classes)", publicApi = true) { - override fun relation(other: FirEffectiveVisibility) = when (other) { - Public, is Protected -> Permissiveness.LESS - Private, Local, InternalProtectedBound -> Permissiveness.MORE - ProtectedBound -> Permissiveness.SAME - is InternalOrPackage, is InternalProtected -> Permissiveness.UNKNOWN - } - - override fun lowerBound(other: FirEffectiveVisibility) = when (other) { - Public, is Protected -> this - Private, Local, ProtectedBound, InternalProtectedBound -> other - is InternalOrPackage, is InternalProtected -> InternalProtectedBound - } - - override fun toVisibility() = Visibilities.PROTECTED - } - - // Lower bound for internal and protected(C) - class InternalProtected(val container: FirRegularClass?) : FirEffectiveVisibility("internal & protected") { - - override fun equals(other: Any?) = (other is InternalProtected && container == other.container) - - override fun hashCode() = container?.hashCode() ?: 0 - - override fun toString() = "${super.toString()} (in ${container?.name ?: '?'})" - - override fun relation(other: FirEffectiveVisibility) = when (other) { - Public, is InternalOrPackage -> Permissiveness.LESS - Private, Local, InternalProtectedBound -> Permissiveness.MORE - is InternalProtected -> containerRelation(container, other.container) - is Protected -> when (containerRelation(container, other.container)) { - // Internal & protected never can be more permissive than just protected - Permissiveness.SAME, Permissiveness.LESS -> Permissiveness.LESS - Permissiveness.UNKNOWN, Permissiveness.MORE -> Permissiveness.UNKNOWN - } - ProtectedBound -> Permissiveness.UNKNOWN - } - - override fun lowerBound(other: FirEffectiveVisibility) = when (other) { - Public, is InternalOrPackage -> this - Private, Local, InternalProtectedBound -> other - is Protected, is InternalProtected -> when (relation(other)) { - Permissiveness.SAME, Permissiveness.MORE -> this - Permissiveness.LESS -> other - Permissiveness.UNKNOWN -> InternalProtectedBound - } - ProtectedBound -> InternalProtectedBound - } - - override fun toVisibility() = Visibilities.PRIVATE - } - - // Lower bound for internal and protected lower bound - object InternalProtectedBound : FirEffectiveVisibility("internal & protected (in different classes)") { - override fun relation(other: FirEffectiveVisibility) = when (other) { - Public, is Protected, is InternalProtected, ProtectedBound, is InternalOrPackage -> Permissiveness.LESS - Private, Local -> Permissiveness.MORE - InternalProtectedBound -> Permissiveness.SAME - } - - override fun toVisibility() = Visibilities.PRIVATE - } + val privateApi: Boolean enum class Permissiveness { LESS, @@ -184,39 +22,31 @@ sealed class FirEffectiveVisibility(val name: String, val publicApi: Boolean = f UNKNOWN } - abstract fun relation(other: FirEffectiveVisibility): Permissiveness + fun relation(other: FirEffectiveVisibility): Permissiveness - abstract fun toVisibility(): Visibility + fun toVisibility(): Visibility - open fun lowerBound(other: FirEffectiveVisibility) = when (relation(other)) { - Permissiveness.SAME, Permissiveness.LESS -> this - Permissiveness.MORE -> other - Permissiveness.UNKNOWN -> Private + fun lowerBound(other: FirEffectiveVisibility): FirEffectiveVisibility + + object Default : FirEffectiveVisibility { + override val name: String + get() = "???" + override val publicApi: Boolean + get() = false + override val privateApi: Boolean + get() = false + + override fun relation(other: FirEffectiveVisibility): Permissiveness { + throw AssertionError("Should not be called") + } + + override fun toVisibility(): Visibility { + throw AssertionError("Should not be called") + } + + override fun lowerBound(other: FirEffectiveVisibility): FirEffectiveVisibility { + throw AssertionError("Should not be called") + } } } -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 - } - -internal fun Visibility.firEffectiveVisibilityApproximation(): FirEffectiveVisibility = - when (this) { - Visibilities.PUBLIC -> Public - Visibilities.PRIVATE -> Private - Visibilities.PRIVATE_TO_THIS -> Private - Visibilities.INTERNAL -> Internal - Visibilities.LOCAL -> Local - Visibilities.PROTECTED -> ProtectedBound - else -> Public - } - diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt index 92e6b377f16..3a72bc44037 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt @@ -174,7 +174,7 @@ class FirRenderer(builder: StringBuilder, private val mode: RenderMode = RenderM Visibilities.UNKNOWN -> return "public?" else -> toString() } - if (effectiveVisibility == null) return itself + if (effectiveVisibility == null || effectiveVisibility == FirEffectiveVisibility.Default) return itself val effectiveAsVisibility = effectiveVisibility.toVisibility() if (effectiveAsVisibility == this) return itself if (effectiveAsVisibility == Visibilities.PRIVATE && this == Visibilities.PRIVATE_TO_THIS) return itself diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirDeclarationStatusImpl.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirDeclarationStatusImpl.kt index b662f2c7f20..7a801152b46 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirDeclarationStatusImpl.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirDeclarationStatusImpl.kt @@ -12,7 +12,6 @@ import org.jetbrains.kotlin.fir.FirPureAbstractElement import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl.Modifier.* -import org.jetbrains.kotlin.fir.firEffectiveVisibilityApproximation import org.jetbrains.kotlin.fir.visitors.FirTransformer import org.jetbrains.kotlin.fir.visitors.FirVisitor @@ -22,7 +21,7 @@ open class FirDeclarationStatusImpl( ) : FirPureAbstractElement(), FirDeclarationStatus { override val source: FirSourceElement? get() = null override val effectiveVisibility: FirEffectiveVisibility - get() = visibility.firEffectiveVisibilityApproximation() + get() = FirEffectiveVisibility.Default protected var flags: Int = 0 private operator fun get(modifier: Modifier): Boolean = (flags and modifier.mask) != 0