diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/syntheticExtensionsUtils.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/syntheticExtensionsUtils.kt index df49a513e5a..028421c481f 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/syntheticExtensionsUtils.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/syntheticExtensionsUtils.kt @@ -32,29 +32,34 @@ fun FunctionDescriptor.hasJavaOriginInHierarchy(): Boolean { original.overriddenDescriptors.any { it.hasJavaOriginInHierarchy() } } -fun DescriptorVisibility.isVisibleOutside() = this != DescriptorVisibilities.PRIVATE && this != DescriptorVisibilities.PRIVATE_TO_THIS && this != DescriptorVisibilities.INVISIBLE_FAKE +fun DescriptorVisibility.isVisibleOutside() = + this != DescriptorVisibilities.PRIVATE && this != DescriptorVisibilities.PRIVATE_TO_THIS && this != DescriptorVisibilities.INVISIBLE_FAKE fun syntheticVisibility(originalDescriptor: DeclarationDescriptorWithVisibility, isUsedForExtension: Boolean): DescriptorVisibility { - val originalVisibility = originalDescriptor.visibility - return when (originalVisibility) { + return when (val originalVisibility = originalDescriptor.visibility) { DescriptorVisibilities.PUBLIC -> DescriptorVisibilities.PUBLIC - else -> object : DescriptorVisibility(originalVisibility.name, originalVisibility.isPublicAPI) { + else -> object : DescriptorVisibility() { + override val delegate: Visibility + get() = originalVisibility.delegate + override fun isVisible( - receiver: ReceiverValue?, - what: DeclarationDescriptorWithVisibility, - from: DeclarationDescriptor + receiver: ReceiverValue?, + what: DeclarationDescriptorWithVisibility, + from: DeclarationDescriptor ) = originalVisibility.isVisible( - if (isUsedForExtension) DescriptorVisibilities.ALWAYS_SUITABLE_RECEIVER else receiver, originalDescriptor, from) + if (isUsedForExtension) DescriptorVisibilities.ALWAYS_SUITABLE_RECEIVER else receiver, originalDescriptor, from + ) - override fun mustCheckInImports() - = throw UnsupportedOperationException("Should never be called for this visibility") + override fun mustCheckInImports() = throw UnsupportedOperationException("Should never be called for this visibility") - override fun normalize() - = originalVisibility.normalize() + override fun normalize() = originalVisibility.normalize() override val internalDisplayName: String get() = originalVisibility.internalDisplayName + " for synthetic extension" + + override val externalDisplayName: String + get() = internalDisplayName } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineChecker.kt index f07b7091f74..3d7d92f250a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/InlineChecker.kt @@ -267,8 +267,8 @@ internal class InlineChecker(private val descriptor: FunctionDescriptor) : CallC if (calledDescriptor !is ConstructorDescriptor && isInlineFunPublicOrPublishedApi && - inlineFunEffectiveVisibility.toVisibility() !== DescriptorVisibilities.PROTECTED && - calledFunEffectiveVisibility.toVisibility() === DescriptorVisibilities.PROTECTED) { + inlineFunEffectiveVisibility.toVisibility() !== Visibilities.Protected && + calledFunEffectiveVisibility.toVisibility() === Visibilities.Protected) { if (prohibitProtectedCallFromInline) { context.trace.report(PROTECTED_CALL_FROM_PUBLIC_INLINE_ERROR.on(expression, calledDescriptor)) } else { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExplicitApiDeclarationChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExplicitApiDeclarationChecker.kt index eace2e2ea89..f3a256faac1 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExplicitApiDeclarationChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExplicitApiDeclarationChecker.kt @@ -105,8 +105,8 @@ class ExplicitApiDeclarationChecker : DeclarationChecker { val callableMemberDescriptor = descriptor as? CallableMemberDescriptor val visibility = callableMemberDescriptor?.effectiveVisibility()?.toVisibility() - return (checkForPublicApi && visibility?.isPublicAPI == true) || (checkForInternal && visibility == DescriptorVisibilities.INTERNAL) || - (checkForPrivate && visibility == DescriptorVisibilities.PRIVATE) + return (checkForPublicApi && visibility?.isPublicAPI == true) || (checkForInternal && visibility == Visibilities.Internal) || + (checkForPrivate && visibility == Visibilities.Internal) } fun returnTypeCheckIsApplicable(element: KtCallableDeclaration): Boolean { diff --git a/core/compiler.common.jvm/src/org/jetbrains/kotlin/descriptors/java/JavaVisibilities.kt b/core/compiler.common.jvm/src/org/jetbrains/kotlin/descriptors/java/JavaVisibilities.kt index 3230ec38b33..ba61a7e7f51 100644 --- a/core/compiler.common.jvm/src/org/jetbrains/kotlin/descriptors/java/JavaVisibilities.kt +++ b/core/compiler.common.jvm/src/org/jetbrains/kotlin/descriptors/java/JavaVisibilities.kt @@ -5,11 +5,14 @@ package org.jetbrains.kotlin.descriptors.java +import org.jetbrains.kotlin.descriptors.EffectiveVisibility import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibility object JavaVisibilities { object PackageVisibility : Visibility("package", isPublicAPI = false) { + override fun mustCheckInImports(): Boolean = true + override fun compareTo(visibility: Visibility): Int? { if (this === visibility) return 0 if (Visibilities.isPrivate(visibility)) return 1 @@ -22,15 +25,27 @@ object JavaVisibilities { override val internalDisplayName: String get() = "public/*package*/" + + override val externalDisplayName: String + get() = "package-private" + + override fun customEffectiveVisibility(): EffectiveVisibility? { + return EffectiveVisibility.PackagePrivate + } } object ProtectedStaticVisibility : Visibility("protected_static", isPublicAPI = true) { + override fun mustCheckInImports(): Boolean = false + override fun normalize(): Visibility { return Visibilities.Protected } override val internalDisplayName: String get() = "protected/*protected static*/" + + override val externalDisplayName: String + get() = "protected" } object ProtectedAndPackage : Visibility("protected_and_package", isPublicAPI = true) { @@ -44,7 +59,12 @@ object JavaVisibilities { return Visibilities.Protected } + override fun mustCheckInImports(): Boolean = false + override val internalDisplayName: String get() = "protected/*protected and package*/" + + override val externalDisplayName: String + get() = "protected" } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibility.kt b/core/compiler.common/src/org/jetbrains/kotlin/descriptors/EffectiveVisibility.kt similarity index 85% rename from core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibility.kt rename to core/compiler.common/src/org/jetbrains/kotlin/descriptors/EffectiveVisibility.kt index 91358efa3ef..c7dc8a40497 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibility.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/descriptors/EffectiveVisibility.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * 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.descriptors @@ -41,7 +30,7 @@ sealed class EffectiveVisibility(val name: String, val publicApi: Boolean = fals override fun relation(other: EffectiveVisibility): Permissiveness = if (this == other || Local == other) Permissiveness.SAME else Permissiveness.LESS - override fun toVisibility(): DescriptorVisibility = DescriptorVisibilities.PRIVATE + override fun toVisibility(): Visibility = Visibilities.Private } // Effectively same as Private @@ -49,14 +38,14 @@ sealed class EffectiveVisibility(val name: String, val publicApi: Boolean = fals override fun relation(other: EffectiveVisibility): Permissiveness = if (this == other || Private == other) Permissiveness.SAME else Permissiveness.LESS - override fun toVisibility(): DescriptorVisibility = DescriptorVisibilities.LOCAL + override fun toVisibility(): Visibility = Visibilities.Local } object Public : EffectiveVisibility("public", publicApi = true) { override fun relation(other: EffectiveVisibility): Permissiveness = if (this == other) Permissiveness.SAME else Permissiveness.MORE - override fun toVisibility(): DescriptorVisibility = DescriptorVisibilities.PUBLIC + override fun toVisibility(): Visibility = Visibilities.Public } abstract class InternalOrPackage protected constructor(internal: Boolean) : EffectiveVisibility( @@ -78,11 +67,11 @@ sealed class EffectiveVisibility(val name: String, val publicApi: Boolean = fals } object Internal : InternalOrPackage(true) { - override fun toVisibility(): DescriptorVisibility = DescriptorVisibilities.INTERNAL + override fun toVisibility(): Visibility = Visibilities.Internal } object PackagePrivate : InternalOrPackage(false) { - override fun toVisibility(): DescriptorVisibility = DescriptorVisibilities.PRIVATE + override fun toVisibility(): Visibility = Visibilities.Private } class Protected( @@ -123,7 +112,7 @@ sealed class EffectiveVisibility(val name: String, val publicApi: Boolean = fals is InternalOrPackage -> InternalProtected(containerTypeConstructor, typeContext) } - override fun toVisibility(): DescriptorVisibility = DescriptorVisibilities.PROTECTED + override fun toVisibility(): Visibility = Visibilities.Protected } // Lower bound for all protected visibilities @@ -141,7 +130,7 @@ sealed class EffectiveVisibility(val name: String, val publicApi: Boolean = fals is InternalOrPackage, is InternalProtected -> InternalProtectedBound } - override fun toVisibility(): DescriptorVisibility = DescriptorVisibilities.PROTECTED + override fun toVisibility(): Visibility = Visibilities.Protected } // Lower bound for internal and protected(C) @@ -179,7 +168,7 @@ sealed class EffectiveVisibility(val name: String, val publicApi: Boolean = fals ProtectedBound -> InternalProtectedBound } - override fun toVisibility(): DescriptorVisibility = DescriptorVisibilities.PRIVATE + override fun toVisibility(): Visibility = Visibilities.Private } // Lower bound for internal and protected lower bound @@ -190,7 +179,7 @@ sealed class EffectiveVisibility(val name: String, val publicApi: Boolean = fals InternalProtectedBound -> Permissiveness.SAME } - override fun toVisibility(): DescriptorVisibility = DescriptorVisibilities.PRIVATE + override fun toVisibility(): Visibility = Visibilities.Private } enum class Permissiveness { @@ -202,9 +191,9 @@ sealed class EffectiveVisibility(val name: String, val publicApi: Boolean = fals abstract fun relation(other: EffectiveVisibility): Permissiveness - abstract fun toVisibility(): DescriptorVisibility + abstract fun toVisibility(): Visibility - internal open fun lowerBound(other: EffectiveVisibility) = when (relation(other)) { + open fun lowerBound(other: EffectiveVisibility) = when (relation(other)) { Permissiveness.SAME, Permissiveness.LESS -> this Permissiveness.MORE -> other Permissiveness.UNKNOWN -> Private diff --git a/core/compiler.common/src/org/jetbrains/kotlin/descriptors/Visibilities.kt b/core/compiler.common/src/org/jetbrains/kotlin/descriptors/Visibilities.kt index e04b93bfeec..1f7d06960ef 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/descriptors/Visibilities.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/descriptors/Visibilities.kt @@ -6,19 +6,51 @@ package org.jetbrains.kotlin.descriptors object Visibilities { - object Private : Visibility("private", isPublicAPI = false) + object Private : Visibility("private", isPublicAPI = false) { + override fun mustCheckInImports(): Boolean = true + } object PrivateToThis : Visibility("private_to_this", isPublicAPI = false) { override val internalDisplayName: String get() = "private/*private to this*/" + + override fun mustCheckInImports(): Boolean = true } - object Protected : Visibility("protected", isPublicAPI = true) - object Internal : Visibility("internal", isPublicAPI = false) - object Public : Visibility("public", isPublicAPI = true) - object Local : Visibility("local", isPublicAPI = false) - object InvisibleFake : Visibility("invisible_fake", isPublicAPI = false) - object Unknown : Visibility("unknown", isPublicAPI = false) + object Protected : Visibility("protected", isPublicAPI = true) { + override fun mustCheckInImports(): Boolean = false + } + + object Internal : Visibility("internal", isPublicAPI = false) { + override fun mustCheckInImports(): Boolean = true + } + + object Public : Visibility("public", isPublicAPI = true) { + override fun mustCheckInImports(): Boolean = false + } + + object Local : Visibility("local", isPublicAPI = false) { + override fun mustCheckInImports(): Boolean = true + } + + object Inherited : Visibility("inherited", isPublicAPI = false) { + override fun mustCheckInImports(): Boolean { + throw IllegalStateException("This method shouldn't be invoked for INHERITED visibility") + } + } + + object InvisibleFake : Visibility("invisible_fake", isPublicAPI = false) { + override fun mustCheckInImports(): Boolean = true + + override val externalDisplayName: String + get() = "invisible (private in a supertype)" + } + + object Unknown : Visibility("unknown", isPublicAPI = false) { + override fun mustCheckInImports(): Boolean { + throw IllegalStateException("This method shouldn't be invoked for UNKNOWN visibility") + } + } @OptIn(ExperimentalStdlibApi::class) private val ORDERED_VISIBILITIES: Map = buildMap { diff --git a/core/compiler.common/src/org/jetbrains/kotlin/descriptors/Visibility.kt b/core/compiler.common/src/org/jetbrains/kotlin/descriptors/Visibility.kt index 6b02fac19a4..ab3dcd81ada 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/descriptors/Visibility.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/descriptors/Visibility.kt @@ -12,11 +12,19 @@ abstract class Visibility protected constructor( open val internalDisplayName: String get() = name - final override fun toString() = internalDisplayName + open val externalDisplayName: String + get() = internalDisplayName + + abstract fun mustCheckInImports(): Boolean open fun compareTo(visibility: Visibility): Int? { return Visibilities.compareLocal(this, visibility) } + final override fun toString() = internalDisplayName + open fun normalize(): Visibility = this + + // Should be overloaded in Java visibilities + open fun customEffectiveVisibility(): EffectiveVisibility? = null } diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/JavaDescriptorVisibilities.java b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/JavaDescriptorVisibilities.java index 9eb3575e706..5dd2fa52a44 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/JavaDescriptorVisibilities.java +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/JavaDescriptorVisibilities.java @@ -19,125 +19,39 @@ package org.jetbrains.kotlin.load.java; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.descriptors.*; +import org.jetbrains.kotlin.descriptors.java.JavaVisibilities; import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue; +import java.util.HashMap; +import java.util.Map; + public class JavaDescriptorVisibilities { private JavaDescriptorVisibilities() { } @NotNull - public static final DescriptorVisibility PACKAGE_VISIBILITY = new DescriptorVisibility("package", false) { + public static final DescriptorVisibility PACKAGE_VISIBILITY = new DelegatedDescriptorVisibility(JavaVisibilities.PackageVisibility.INSTANCE) { @Override public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { return areInSamePackage(what, from); } - - @Override - public boolean mustCheckInImports() { - return true; - } - - @Override - protected Integer compareTo(@NotNull DescriptorVisibility visibility) { - if (this == visibility) return 0; - if (DescriptorVisibilities.isPrivate(visibility)) return 1; - return -1; - } - - @NotNull - @Override - public String getInternalDisplayName() { - return "public/*package*/"; - } - - @NotNull - @Override - public String getExternalDisplayName() { - return "package-private"; - } - - @NotNull - @Override - public DescriptorVisibility normalize() { - return DescriptorVisibilities.PROTECTED; - } - - @Nullable - @Override - public EffectiveVisibility customEffectiveVisibility() { - return EffectiveVisibility.PackagePrivate.INSTANCE; - } }; @NotNull - public static final DescriptorVisibility PROTECTED_STATIC_VISIBILITY = new DescriptorVisibility("protected_static", true) { + public static final DescriptorVisibility PROTECTED_STATIC_VISIBILITY = new DelegatedDescriptorVisibility(JavaVisibilities.ProtectedStaticVisibility.INSTANCE) { @Override public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { return isVisibleForProtectedAndPackage(receiver, what, from); } - - @Override - public boolean mustCheckInImports() { - return false; - } - - @NotNull - @Override - public String getInternalDisplayName() { - return "protected/*protected static*/"; - } - - @NotNull - @Override - public String getExternalDisplayName() { - return "protected"; - } - - @NotNull - @Override - public DescriptorVisibility normalize() { - return DescriptorVisibilities.PROTECTED; - } }; @NotNull - public static final DescriptorVisibility PROTECTED_AND_PACKAGE = new DescriptorVisibility("protected_and_package", true) { + public static final DescriptorVisibility PROTECTED_AND_PACKAGE = new DelegatedDescriptorVisibility(JavaVisibilities.ProtectedAndPackage.INSTANCE) { @Override public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { return isVisibleForProtectedAndPackage(receiver, what, from); } - - @Override - public boolean mustCheckInImports() { - return false; - } - - @Override - protected Integer compareTo(@NotNull DescriptorVisibility visibility) { - if (this == visibility) return 0; - if (visibility == DescriptorVisibilities.INTERNAL) return null; - if (DescriptorVisibilities.isPrivate(visibility)) return 1; - return -1; - } - - @NotNull - @Override - public String getInternalDisplayName() { - return "protected/*protected and package*/"; - } - - @NotNull - @Override - public String getExternalDisplayName() { - return "protected"; - } - - @NotNull - @Override - public DescriptorVisibility normalize() { - return DescriptorVisibilities.PROTECTED; - } }; private static boolean isVisibleForProtectedAndPackage( @@ -157,4 +71,26 @@ public class JavaDescriptorVisibilities { PackageFragmentDescriptor fromPackage = DescriptorUtils.getParentOfType(second, PackageFragmentDescriptor.class, false); return fromPackage != null && whatPackage != null && whatPackage.getFqName().equals(fromPackage.getFqName()); } + + @NotNull + private static final Map visibilitiesMapping = new HashMap(); + + private static void recordVisibilityMapping(DescriptorVisibility visibility) { + visibilitiesMapping.put(visibility.getDelegate(), visibility); + } + + static { + recordVisibilityMapping(PACKAGE_VISIBILITY); + recordVisibilityMapping(PROTECTED_STATIC_VISIBILITY); + recordVisibilityMapping(PROTECTED_AND_PACKAGE); + } + + @NotNull + public static DescriptorVisibility toDescriptorVisibility(@NotNull Visibility visibility) { + DescriptorVisibility correspondingVisibility = visibilitiesMapping.get(visibility); + if (correspondingVisibility == null) { + return DescriptorVisibilities.toDescriptorVisibility(visibility); + } + return correspondingVisibility; + } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/DescriptorVisibilities.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/DescriptorVisibilities.java index f3f1fb30160..f782fd9f064 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/DescriptorVisibilities.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/DescriptorVisibilities.java @@ -33,12 +33,7 @@ import java.util.*; public class DescriptorVisibilities { @NotNull - public static final DescriptorVisibility PRIVATE = new DescriptorVisibility("private", false) { - @Override - public boolean mustCheckInImports() { - return true; - } - + public static final DescriptorVisibility PRIVATE = new DelegatedDescriptorVisibility(Visibilities.Private.INSTANCE) { private boolean hasContainingSourceFile(@NotNull DeclarationDescriptor descriptor) { return DescriptorUtils.getContainingSourceFile(descriptor) != SourceFile.NO_SOURCE_FILE; } @@ -102,7 +97,7 @@ public class DescriptorVisibilities { * } */ @NotNull - public static final DescriptorVisibility PRIVATE_TO_THIS = new DescriptorVisibility("private_to_this", false) { + public static final DescriptorVisibility PRIVATE_TO_THIS = new DelegatedDescriptorVisibility(Visibilities.PrivateToThis.INSTANCE) { @Override public boolean isVisible(@Nullable ReceiverValue thisObject, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { if (PRIVATE.isVisible(thisObject, what, from)) { @@ -118,26 +113,10 @@ public class DescriptorVisibilities { } return false; } - - @Override - public boolean mustCheckInImports() { - return true; - } - - @NotNull - @Override - public String getInternalDisplayName() { - return "private/*private to this*/"; - } }; @NotNull - public static final DescriptorVisibility PROTECTED = new DescriptorVisibility("protected", true) { - @Override - public boolean mustCheckInImports() { - return false; - } - + public static final DescriptorVisibility PROTECTED = new DelegatedDescriptorVisibility(Visibilities.Protected.INSTANCE) { @Override public boolean isVisible( @Nullable ReceiverValue receiver, @@ -198,12 +177,7 @@ public class DescriptorVisibilities { }; @NotNull - public static final DescriptorVisibility INTERNAL = new DescriptorVisibility("internal", false) { - @Override - public boolean mustCheckInImports() { - return true; - } - + public static final DescriptorVisibility INTERNAL = new DelegatedDescriptorVisibility(Visibilities.Internal.INSTANCE) { @Override public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { ModuleDescriptor whatModule = DescriptorUtils.getContainingModule(what); @@ -220,12 +194,7 @@ public class DescriptorVisibilities { }; @NotNull - public static final DescriptorVisibility PUBLIC = new DescriptorVisibility("public", true) { - @Override - public boolean mustCheckInImports() { - return false; - } - + public static final DescriptorVisibility PUBLIC = new DelegatedDescriptorVisibility(Visibilities.Public.INSTANCE) { @Override public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { return true; @@ -233,12 +202,7 @@ public class DescriptorVisibilities { }; @NotNull - public static final DescriptorVisibility LOCAL = new DescriptorVisibility("local", false) { - @Override - public boolean mustCheckInImports() { - return true; - } - + public static final DescriptorVisibility LOCAL = new DelegatedDescriptorVisibility(Visibilities.Local.INSTANCE) { @Override public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { throw new IllegalStateException("This method shouldn't be invoked for LOCAL visibility"); @@ -246,12 +210,7 @@ public class DescriptorVisibilities { }; @NotNull - public static final DescriptorVisibility INHERITED = new DescriptorVisibility("inherited", false) { - @Override - public boolean mustCheckInImports() { - throw new IllegalStateException("This method shouldn't be invoked for INHERITED visibility"); - } - + public static final DescriptorVisibility INHERITED = new DelegatedDescriptorVisibility(Visibilities.Inherited.INSTANCE) { @Override public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { throw new IllegalStateException("Visibility is unknown yet"); //This method shouldn't be invoked for INHERITED visibility @@ -260,33 +219,17 @@ public class DescriptorVisibilities { /* Visibility for fake override invisible members (they are created for better error reporting) */ @NotNull - public static final DescriptorVisibility INVISIBLE_FAKE = new DescriptorVisibility("invisible_fake", false) { - @Override - public boolean mustCheckInImports() { - return true; - } - + public static final DescriptorVisibility INVISIBLE_FAKE = new DelegatedDescriptorVisibility(Visibilities.InvisibleFake.INSTANCE) { @Override public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { return false; } - - @Override - @NotNull - public String getExternalDisplayName() { - return "invisible (private in a supertype)"; - } }; // Currently used as default visibility of FunctionDescriptor // It's needed to prevent NPE when requesting non-nullable visibility of descriptor before `initialize` has been called @NotNull - public static final DescriptorVisibility UNKNOWN = new DescriptorVisibility("unknown", false) { - @Override - public boolean mustCheckInImports() { - throw new IllegalStateException("This method shouldn't be invoked for UNKNOWN visibility"); - } - + public static final DescriptorVisibility UNKNOWN = new DelegatedDescriptorVisibility(Visibilities.Unknown.INSTANCE) { @Override public boolean isVisible( @Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from @@ -473,4 +416,32 @@ public class DescriptorVisibilities { Iterator iterator = ServiceLoader.load(ModuleVisibilityHelper.class, ModuleVisibilityHelper.class.getClassLoader()).iterator(); MODULE_VISIBILITY_HELPER = iterator.hasNext() ? iterator.next() : ModuleVisibilityHelper.EMPTY.INSTANCE; } + + @NotNull + private static final Map visibilitiesMapping = new HashMap(); + + private static void recordVisibilityMapping(DescriptorVisibility visibility) { + visibilitiesMapping.put(visibility.getDelegate(), visibility); + } + + static { + recordVisibilityMapping(PRIVATE); + recordVisibilityMapping(PRIVATE_TO_THIS); + recordVisibilityMapping(PROTECTED); + recordVisibilityMapping(INTERNAL); + recordVisibilityMapping(PUBLIC); + recordVisibilityMapping(LOCAL); + recordVisibilityMapping(INHERITED); + recordVisibilityMapping(INVISIBLE_FAKE); + recordVisibilityMapping(UNKNOWN); + } + + @NotNull + public static DescriptorVisibility toDescriptorVisibility(@NotNull Visibility visibility) { + DescriptorVisibility correspondingVisibility = visibilitiesMapping.get(visibility); + if (correspondingVisibility == null) { + throw new IllegalArgumentException("Inapplicable visibility: " + visibility); + } + return correspondingVisibility; + } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/DescriptorVisibility.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/DescriptorVisibility.kt index 9b7eed5fd5e..74cb7743b57 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/DescriptorVisibility.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/DescriptorVisibility.kt @@ -18,10 +18,15 @@ package org.jetbrains.kotlin.descriptors import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue -abstract class DescriptorVisibility protected constructor( - val name: String, +abstract class DescriptorVisibility protected constructor() { + abstract val delegate: Visibility + + val name: String + get() = delegate.name + val isPublicAPI: Boolean -) { + get() = delegate.isPublicAPI + /** * @param receiver can be used to determine callee accessibility for some special receiver value * @@ -52,22 +57,36 @@ abstract class DescriptorVisibility protected constructor( /** * @return null if the answer is unknown */ - protected open fun compareTo(visibility: DescriptorVisibility): Int? { - return DescriptorVisibilities.compareLocal(this, visibility) + fun compareTo(visibility: DescriptorVisibility): Int? { + return delegate.compareTo(visibility.delegate) } // internal representation for descriptors - open val internalDisplayName: String - get() = name + abstract val internalDisplayName: String // external representation for diagnostics - open val externalDisplayName: String - get() = internalDisplayName + abstract val externalDisplayName: String - final override fun toString() = internalDisplayName + final override fun toString(): String = delegate.toString() - open fun normalize(): DescriptorVisibility = this + abstract fun normalize(): DescriptorVisibility // Should be overloaded in Java visibilities - open fun customEffectiveVisibility(): EffectiveVisibility? = null + fun customEffectiveVisibility(): EffectiveVisibility? = delegate.customEffectiveVisibility() +} + +abstract class DelegatedDescriptorVisibility(override val delegate: Visibility) : DescriptorVisibility() { + override fun mustCheckInImports(): Boolean { + return delegate.mustCheckInImports() + } + + // internal representation for descriptors + override val internalDisplayName: String + get() = delegate.internalDisplayName + + // external representation for diagnostics + override val externalDisplayName: String + get() = delegate.externalDisplayName + + override fun normalize(): DescriptorVisibility = DescriptorVisibilities.toDescriptorVisibility(delegate.normalize()) } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibilityUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibilityUtils.kt index 2954850740b..509a78f6547 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibilityUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibilityUtils.kt @@ -9,6 +9,8 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.isPublishedApi import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.checker.ClassicTypeCheckerContext +fun EffectiveVisibility.toDescriptorVisibility(): DescriptorVisibility = DescriptorVisibilities.toDescriptorVisibility(toVisibility()) + fun DescriptorVisibility.effectiveVisibility( descriptor: DeclarationDescriptor, checkPublishedApi: Boolean = false diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVisibilityOnExposureFactory.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVisibilityOnExposureFactory.kt index 74706211a87..1b581080dd0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVisibilityOnExposureFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVisibilityOnExposureFactory.kt @@ -17,12 +17,9 @@ package org.jetbrains.kotlin.idea.quickfix import com.intellij.codeInsight.intention.IntentionAction -import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility -import org.jetbrains.kotlin.descriptors.DescriptorWithRelation -import org.jetbrains.kotlin.descriptors.EffectiveVisibility +import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.EffectiveVisibility.Permissiveness.LESS import org.jetbrains.kotlin.descriptors.DescriptorVisibilities.* -import org.jetbrains.kotlin.descriptors.DescriptorVisibility import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.DiagnosticFactory3 import org.jetbrains.kotlin.idea.core.toDescriptor @@ -62,7 +59,7 @@ object ChangeVisibilityOnExposureFactory : KotlinIntentionActionsFactory() { val exposedVisibility = exposedDiagnostic.c val userVisibility = exposedDiagnostic.a val (targetUserVisibility, targetExposedVisibility) = when (exposedVisibility.relation(userVisibility)) { - LESS -> Pair(exposedVisibility.toVisibility(), userVisibility.toVisibility()) + LESS -> Pair(exposedVisibility.toDescriptorVisibility(), userVisibility.toDescriptorVisibility()) else -> Pair(PRIVATE, PUBLIC) } val result = ArrayList() diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/descriptorUtils/descriptorUtils.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/descriptorUtils/descriptorUtils.kt index 82d62385b41..9c5f39ca15d 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/descriptorUtils/descriptorUtils.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/descriptorUtils/descriptorUtils.kt @@ -53,5 +53,5 @@ fun DeclarationDescriptor.shouldBeExported(config: JsConfig): Boolean = private fun EffectiveVisibility.shouldBeExported(config: JsConfig): Boolean { if (publicApi) return true if (config.configuration.getBoolean(JSConfigurationKeys.FRIEND_PATHS_DISABLED)) return false - return toVisibility() == DescriptorVisibilities.INTERNAL + return toVisibility() == Visibilities.Internal } diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/naming/NameSuggestion.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/naming/NameSuggestion.kt index a7f434f91ac..2fdcd368660 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/naming/NameSuggestion.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/naming/NameSuggestion.kt @@ -348,8 +348,8 @@ class NameSuggestion { return if (absHashCode != 0) absHashCode.toString(Character.MAX_RADIX) else "" } - private val DeclarationDescriptorWithVisibility.ownEffectiveVisibility - get() = visibility.effectiveVisibility(this, checkPublishedApi = true).toVisibility() + private val DeclarationDescriptorWithVisibility.ownEffectiveVisibility: DescriptorVisibility + get() = visibility.effectiveVisibility(this, checkPublishedApi = true).toDescriptorVisibility() @JvmStatic fun sanitizeName(name: String): String { if (name.isEmpty()) return "_"