Make DescriptorVisibility delegate to Visibility

This commit is contained in:
Dmitriy Novozhilov
2020-09-01 17:01:33 +03:00
parent a05d6da43b
commit 696f089b3e
14 changed files with 206 additions and 227 deletions
@@ -32,29 +32,34 @@ fun FunctionDescriptor.hasJavaOriginInHierarchy(): Boolean {
original.overriddenDescriptors.any { it.hasJavaOriginInHierarchy() } 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 { fun syntheticVisibility(originalDescriptor: DeclarationDescriptorWithVisibility, isUsedForExtension: Boolean): DescriptorVisibility {
val originalVisibility = originalDescriptor.visibility return when (val originalVisibility = originalDescriptor.visibility) {
return when (originalVisibility) {
DescriptorVisibilities.PUBLIC -> DescriptorVisibilities.PUBLIC DescriptorVisibilities.PUBLIC -> DescriptorVisibilities.PUBLIC
else -> object : DescriptorVisibility(originalVisibility.name, originalVisibility.isPublicAPI) { else -> object : DescriptorVisibility() {
override val delegate: Visibility
get() = originalVisibility.delegate
override fun isVisible( override fun isVisible(
receiver: ReceiverValue?, receiver: ReceiverValue?,
what: DeclarationDescriptorWithVisibility, what: DeclarationDescriptorWithVisibility,
from: DeclarationDescriptor from: DeclarationDescriptor
) = originalVisibility.isVisible( ) = 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() override fun mustCheckInImports() = throw UnsupportedOperationException("Should never be called for this visibility")
= throw UnsupportedOperationException("Should never be called for this visibility")
override fun normalize() override fun normalize() = originalVisibility.normalize()
= originalVisibility.normalize()
override val internalDisplayName: String override val internalDisplayName: String
get() = originalVisibility.internalDisplayName + " for synthetic extension" get() = originalVisibility.internalDisplayName + " for synthetic extension"
override val externalDisplayName: String
get() = internalDisplayName
} }
} }
@@ -267,8 +267,8 @@ internal class InlineChecker(private val descriptor: FunctionDescriptor) : CallC
if (calledDescriptor !is ConstructorDescriptor && if (calledDescriptor !is ConstructorDescriptor &&
isInlineFunPublicOrPublishedApi && isInlineFunPublicOrPublishedApi &&
inlineFunEffectiveVisibility.toVisibility() !== DescriptorVisibilities.PROTECTED && inlineFunEffectiveVisibility.toVisibility() !== Visibilities.Protected &&
calledFunEffectiveVisibility.toVisibility() === DescriptorVisibilities.PROTECTED) { calledFunEffectiveVisibility.toVisibility() === Visibilities.Protected) {
if (prohibitProtectedCallFromInline) { if (prohibitProtectedCallFromInline) {
context.trace.report(PROTECTED_CALL_FROM_PUBLIC_INLINE_ERROR.on(expression, calledDescriptor)) context.trace.report(PROTECTED_CALL_FROM_PUBLIC_INLINE_ERROR.on(expression, calledDescriptor))
} else { } else {
@@ -105,8 +105,8 @@ class ExplicitApiDeclarationChecker : DeclarationChecker {
val callableMemberDescriptor = descriptor as? CallableMemberDescriptor val callableMemberDescriptor = descriptor as? CallableMemberDescriptor
val visibility = callableMemberDescriptor?.effectiveVisibility()?.toVisibility() val visibility = callableMemberDescriptor?.effectiveVisibility()?.toVisibility()
return (checkForPublicApi && visibility?.isPublicAPI == true) || (checkForInternal && visibility == DescriptorVisibilities.INTERNAL) || return (checkForPublicApi && visibility?.isPublicAPI == true) || (checkForInternal && visibility == Visibilities.Internal) ||
(checkForPrivate && visibility == DescriptorVisibilities.PRIVATE) (checkForPrivate && visibility == Visibilities.Internal)
} }
fun returnTypeCheckIsApplicable(element: KtCallableDeclaration): Boolean { fun returnTypeCheckIsApplicable(element: KtCallableDeclaration): Boolean {
@@ -5,11 +5,14 @@
package org.jetbrains.kotlin.descriptors.java package org.jetbrains.kotlin.descriptors.java
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.descriptors.Visibility
object JavaVisibilities { object JavaVisibilities {
object PackageVisibility : Visibility("package", isPublicAPI = false) { object PackageVisibility : Visibility("package", isPublicAPI = false) {
override fun mustCheckInImports(): Boolean = true
override fun compareTo(visibility: Visibility): Int? { override fun compareTo(visibility: Visibility): Int? {
if (this === visibility) return 0 if (this === visibility) return 0
if (Visibilities.isPrivate(visibility)) return 1 if (Visibilities.isPrivate(visibility)) return 1
@@ -22,15 +25,27 @@ object JavaVisibilities {
override val internalDisplayName: String override val internalDisplayName: String
get() = "public/*package*/" get() = "public/*package*/"
override val externalDisplayName: String
get() = "package-private"
override fun customEffectiveVisibility(): EffectiveVisibility? {
return EffectiveVisibility.PackagePrivate
}
} }
object ProtectedStaticVisibility : Visibility("protected_static", isPublicAPI = true) { object ProtectedStaticVisibility : Visibility("protected_static", isPublicAPI = true) {
override fun mustCheckInImports(): Boolean = false
override fun normalize(): Visibility { override fun normalize(): Visibility {
return Visibilities.Protected return Visibilities.Protected
} }
override val internalDisplayName: String override val internalDisplayName: String
get() = "protected/*protected static*/" get() = "protected/*protected static*/"
override val externalDisplayName: String
get() = "protected"
} }
object ProtectedAndPackage : Visibility("protected_and_package", isPublicAPI = true) { object ProtectedAndPackage : Visibility("protected_and_package", isPublicAPI = true) {
@@ -44,7 +59,12 @@ object JavaVisibilities {
return Visibilities.Protected return Visibilities.Protected
} }
override fun mustCheckInImports(): Boolean = false
override val internalDisplayName: String override val internalDisplayName: String
get() = "protected/*protected and package*/" get() = "protected/*protected and package*/"
override val externalDisplayName: String
get() = "protected"
} }
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * 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.
* 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.
*/ */
package org.jetbrains.kotlin.descriptors 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 = override fun relation(other: EffectiveVisibility): Permissiveness =
if (this == other || Local == other) Permissiveness.SAME else Permissiveness.LESS 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 // Effectively same as Private
@@ -49,14 +38,14 @@ sealed class EffectiveVisibility(val name: String, val publicApi: Boolean = fals
override fun relation(other: EffectiveVisibility): Permissiveness = override fun relation(other: EffectiveVisibility): Permissiveness =
if (this == other || Private == other) Permissiveness.SAME else Permissiveness.LESS 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) { object Public : EffectiveVisibility("public", publicApi = true) {
override fun relation(other: EffectiveVisibility): Permissiveness = override fun relation(other: EffectiveVisibility): Permissiveness =
if (this == other) Permissiveness.SAME else Permissiveness.MORE 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( 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) { object Internal : InternalOrPackage(true) {
override fun toVisibility(): DescriptorVisibility = DescriptorVisibilities.INTERNAL override fun toVisibility(): Visibility = Visibilities.Internal
} }
object PackagePrivate : InternalOrPackage(false) { object PackagePrivate : InternalOrPackage(false) {
override fun toVisibility(): DescriptorVisibility = DescriptorVisibilities.PRIVATE override fun toVisibility(): Visibility = Visibilities.Private
} }
class Protected( class Protected(
@@ -123,7 +112,7 @@ sealed class EffectiveVisibility(val name: String, val publicApi: Boolean = fals
is InternalOrPackage -> InternalProtected(containerTypeConstructor, typeContext) is InternalOrPackage -> InternalProtected(containerTypeConstructor, typeContext)
} }
override fun toVisibility(): DescriptorVisibility = DescriptorVisibilities.PROTECTED override fun toVisibility(): Visibility = Visibilities.Protected
} }
// Lower bound for all protected visibilities // 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 is InternalOrPackage, is InternalProtected -> InternalProtectedBound
} }
override fun toVisibility(): DescriptorVisibility = DescriptorVisibilities.PROTECTED override fun toVisibility(): Visibility = Visibilities.Protected
} }
// Lower bound for internal and protected(C) // Lower bound for internal and protected(C)
@@ -179,7 +168,7 @@ sealed class EffectiveVisibility(val name: String, val publicApi: Boolean = fals
ProtectedBound -> InternalProtectedBound ProtectedBound -> InternalProtectedBound
} }
override fun toVisibility(): DescriptorVisibility = DescriptorVisibilities.PRIVATE override fun toVisibility(): Visibility = Visibilities.Private
} }
// Lower bound for internal and protected lower bound // 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 InternalProtectedBound -> Permissiveness.SAME
} }
override fun toVisibility(): DescriptorVisibility = DescriptorVisibilities.PRIVATE override fun toVisibility(): Visibility = Visibilities.Private
} }
enum class Permissiveness { 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 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.SAME, Permissiveness.LESS -> this
Permissiveness.MORE -> other Permissiveness.MORE -> other
Permissiveness.UNKNOWN -> Private Permissiveness.UNKNOWN -> Private
@@ -6,19 +6,51 @@
package org.jetbrains.kotlin.descriptors package org.jetbrains.kotlin.descriptors
object Visibilities { 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) { object PrivateToThis : Visibility("private_to_this", isPublicAPI = false) {
override val internalDisplayName: String override val internalDisplayName: String
get() = "private/*private to this*/" get() = "private/*private to this*/"
override fun mustCheckInImports(): Boolean = true
} }
object Protected : Visibility("protected", isPublicAPI = true) object Protected : Visibility("protected", isPublicAPI = true) {
object Internal : Visibility("internal", isPublicAPI = false) override fun mustCheckInImports(): Boolean = false
object Public : Visibility("public", isPublicAPI = true) }
object Local : Visibility("local", isPublicAPI = false)
object InvisibleFake : Visibility("invisible_fake", isPublicAPI = false) object Internal : Visibility("internal", isPublicAPI = false) {
object Unknown : Visibility("unknown", 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) @OptIn(ExperimentalStdlibApi::class)
private val ORDERED_VISIBILITIES: Map<Visibility, Int> = buildMap { private val ORDERED_VISIBILITIES: Map<Visibility, Int> = buildMap {
@@ -12,11 +12,19 @@ abstract class Visibility protected constructor(
open val internalDisplayName: String open val internalDisplayName: String
get() = name get() = name
final override fun toString() = internalDisplayName open val externalDisplayName: String
get() = internalDisplayName
abstract fun mustCheckInImports(): Boolean
open fun compareTo(visibility: Visibility): Int? { open fun compareTo(visibility: Visibility): Int? {
return Visibilities.compareLocal(this, visibility) return Visibilities.compareLocal(this, visibility)
} }
final override fun toString() = internalDisplayName
open fun normalize(): Visibility = this open fun normalize(): Visibility = this
// Should be overloaded in Java visibilities
open fun customEffectiveVisibility(): EffectiveVisibility? = null
} }
@@ -19,125 +19,39 @@ package org.jetbrains.kotlin.load.java;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.java.JavaVisibilities;
import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import java.util.HashMap;
import java.util.Map;
public class JavaDescriptorVisibilities { public class JavaDescriptorVisibilities {
private JavaDescriptorVisibilities() { private JavaDescriptorVisibilities() {
} }
@NotNull @NotNull
public static final DescriptorVisibility PACKAGE_VISIBILITY = new DescriptorVisibility("package", false) { public static final DescriptorVisibility PACKAGE_VISIBILITY = new DelegatedDescriptorVisibility(JavaVisibilities.PackageVisibility.INSTANCE) {
@Override @Override
public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
return areInSamePackage(what, 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 @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 @Override
public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
return isVisibleForProtectedAndPackage(receiver, what, 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 @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 @Override
public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
return isVisibleForProtectedAndPackage(receiver, what, 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( private static boolean isVisibleForProtectedAndPackage(
@@ -157,4 +71,26 @@ public class JavaDescriptorVisibilities {
PackageFragmentDescriptor fromPackage = DescriptorUtils.getParentOfType(second, PackageFragmentDescriptor.class, false); PackageFragmentDescriptor fromPackage = DescriptorUtils.getParentOfType(second, PackageFragmentDescriptor.class, false);
return fromPackage != null && whatPackage != null && whatPackage.getFqName().equals(fromPackage.getFqName()); return fromPackage != null && whatPackage != null && whatPackage.getFqName().equals(fromPackage.getFqName());
} }
@NotNull
private static final Map<Visibility, DescriptorVisibility> visibilitiesMapping = new HashMap<Visibility, DescriptorVisibility>();
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;
}
} }
@@ -33,12 +33,7 @@ import java.util.*;
public class DescriptorVisibilities { public class DescriptorVisibilities {
@NotNull @NotNull
public static final DescriptorVisibility PRIVATE = new DescriptorVisibility("private", false) { public static final DescriptorVisibility PRIVATE = new DelegatedDescriptorVisibility(Visibilities.Private.INSTANCE) {
@Override
public boolean mustCheckInImports() {
return true;
}
private boolean hasContainingSourceFile(@NotNull DeclarationDescriptor descriptor) { private boolean hasContainingSourceFile(@NotNull DeclarationDescriptor descriptor) {
return DescriptorUtils.getContainingSourceFile(descriptor) != SourceFile.NO_SOURCE_FILE; return DescriptorUtils.getContainingSourceFile(descriptor) != SourceFile.NO_SOURCE_FILE;
} }
@@ -102,7 +97,7 @@ public class DescriptorVisibilities {
* } * }
*/ */
@NotNull @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 @Override
public boolean isVisible(@Nullable ReceiverValue thisObject, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { public boolean isVisible(@Nullable ReceiverValue thisObject, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
if (PRIVATE.isVisible(thisObject, what, from)) { if (PRIVATE.isVisible(thisObject, what, from)) {
@@ -118,26 +113,10 @@ public class DescriptorVisibilities {
} }
return false; return false;
} }
@Override
public boolean mustCheckInImports() {
return true;
}
@NotNull
@Override
public String getInternalDisplayName() {
return "private/*private to this*/";
}
}; };
@NotNull @NotNull
public static final DescriptorVisibility PROTECTED = new DescriptorVisibility("protected", true) { public static final DescriptorVisibility PROTECTED = new DelegatedDescriptorVisibility(Visibilities.Protected.INSTANCE) {
@Override
public boolean mustCheckInImports() {
return false;
}
@Override @Override
public boolean isVisible( public boolean isVisible(
@Nullable ReceiverValue receiver, @Nullable ReceiverValue receiver,
@@ -198,12 +177,7 @@ public class DescriptorVisibilities {
}; };
@NotNull @NotNull
public static final DescriptorVisibility INTERNAL = new DescriptorVisibility("internal", false) { public static final DescriptorVisibility INTERNAL = new DelegatedDescriptorVisibility(Visibilities.Internal.INSTANCE) {
@Override
public boolean mustCheckInImports() {
return true;
}
@Override @Override
public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
ModuleDescriptor whatModule = DescriptorUtils.getContainingModule(what); ModuleDescriptor whatModule = DescriptorUtils.getContainingModule(what);
@@ -220,12 +194,7 @@ public class DescriptorVisibilities {
}; };
@NotNull @NotNull
public static final DescriptorVisibility PUBLIC = new DescriptorVisibility("public", true) { public static final DescriptorVisibility PUBLIC = new DelegatedDescriptorVisibility(Visibilities.Public.INSTANCE) {
@Override
public boolean mustCheckInImports() {
return false;
}
@Override @Override
public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
return true; return true;
@@ -233,12 +202,7 @@ public class DescriptorVisibilities {
}; };
@NotNull @NotNull
public static final DescriptorVisibility LOCAL = new DescriptorVisibility("local", false) { public static final DescriptorVisibility LOCAL = new DelegatedDescriptorVisibility(Visibilities.Local.INSTANCE) {
@Override
public boolean mustCheckInImports() {
return true;
}
@Override @Override
public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
throw new IllegalStateException("This method shouldn't be invoked for LOCAL visibility"); throw new IllegalStateException("This method shouldn't be invoked for LOCAL visibility");
@@ -246,12 +210,7 @@ public class DescriptorVisibilities {
}; };
@NotNull @NotNull
public static final DescriptorVisibility INHERITED = new DescriptorVisibility("inherited", false) { public static final DescriptorVisibility INHERITED = new DelegatedDescriptorVisibility(Visibilities.Inherited.INSTANCE) {
@Override
public boolean mustCheckInImports() {
throw new IllegalStateException("This method shouldn't be invoked for INHERITED visibility");
}
@Override @Override
public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { 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 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) */ /* Visibility for fake override invisible members (they are created for better error reporting) */
@NotNull @NotNull
public static final DescriptorVisibility INVISIBLE_FAKE = new DescriptorVisibility("invisible_fake", false) { public static final DescriptorVisibility INVISIBLE_FAKE = new DelegatedDescriptorVisibility(Visibilities.InvisibleFake.INSTANCE) {
@Override
public boolean mustCheckInImports() {
return true;
}
@Override @Override
public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
return false; return false;
} }
@Override
@NotNull
public String getExternalDisplayName() {
return "invisible (private in a supertype)";
}
}; };
// Currently used as default visibility of FunctionDescriptor // 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 // It's needed to prevent NPE when requesting non-nullable visibility of descriptor before `initialize` has been called
@NotNull @NotNull
public static final DescriptorVisibility UNKNOWN = new DescriptorVisibility("unknown", false) { public static final DescriptorVisibility UNKNOWN = new DelegatedDescriptorVisibility(Visibilities.Unknown.INSTANCE) {
@Override
public boolean mustCheckInImports() {
throw new IllegalStateException("This method shouldn't be invoked for UNKNOWN visibility");
}
@Override @Override
public boolean isVisible( public boolean isVisible(
@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from @Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from
@@ -473,4 +416,32 @@ public class DescriptorVisibilities {
Iterator<ModuleVisibilityHelper> iterator = ServiceLoader.load(ModuleVisibilityHelper.class, ModuleVisibilityHelper.class.getClassLoader()).iterator(); Iterator<ModuleVisibilityHelper> iterator = ServiceLoader.load(ModuleVisibilityHelper.class, ModuleVisibilityHelper.class.getClassLoader()).iterator();
MODULE_VISIBILITY_HELPER = iterator.hasNext() ? iterator.next() : ModuleVisibilityHelper.EMPTY.INSTANCE; MODULE_VISIBILITY_HELPER = iterator.hasNext() ? iterator.next() : ModuleVisibilityHelper.EMPTY.INSTANCE;
} }
@NotNull
private static final Map<Visibility, DescriptorVisibility> visibilitiesMapping = new HashMap<Visibility, DescriptorVisibility>();
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;
}
} }
@@ -18,10 +18,15 @@ package org.jetbrains.kotlin.descriptors
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
abstract class DescriptorVisibility protected constructor( abstract class DescriptorVisibility protected constructor() {
val name: String, abstract val delegate: Visibility
val name: String
get() = delegate.name
val isPublicAPI: Boolean val isPublicAPI: Boolean
) { get() = delegate.isPublicAPI
/** /**
* @param receiver can be used to determine callee accessibility for some special receiver value * @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 * @return null if the answer is unknown
*/ */
protected open fun compareTo(visibility: DescriptorVisibility): Int? { fun compareTo(visibility: DescriptorVisibility): Int? {
return DescriptorVisibilities.compareLocal(this, visibility) return delegate.compareTo(visibility.delegate)
} }
// internal representation for descriptors // internal representation for descriptors
open val internalDisplayName: String abstract val internalDisplayName: String
get() = name
// external representation for diagnostics // external representation for diagnostics
open val externalDisplayName: String abstract val externalDisplayName: String
get() = internalDisplayName
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 // 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())
} }
@@ -9,6 +9,8 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.isPublishedApi
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.checker.ClassicTypeCheckerContext import org.jetbrains.kotlin.types.checker.ClassicTypeCheckerContext
fun EffectiveVisibility.toDescriptorVisibility(): DescriptorVisibility = DescriptorVisibilities.toDescriptorVisibility(toVisibility())
fun DescriptorVisibility.effectiveVisibility( fun DescriptorVisibility.effectiveVisibility(
descriptor: DeclarationDescriptor, descriptor: DeclarationDescriptor,
checkPublishedApi: Boolean = false checkPublishedApi: Boolean = false
@@ -17,12 +17,9 @@
package org.jetbrains.kotlin.idea.quickfix package org.jetbrains.kotlin.idea.quickfix
import com.intellij.codeInsight.intention.IntentionAction import com.intellij.codeInsight.intention.IntentionAction
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.DescriptorWithRelation
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
import org.jetbrains.kotlin.descriptors.EffectiveVisibility.Permissiveness.LESS import org.jetbrains.kotlin.descriptors.EffectiveVisibility.Permissiveness.LESS
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities.* import org.jetbrains.kotlin.descriptors.DescriptorVisibilities.*
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory3 import org.jetbrains.kotlin.diagnostics.DiagnosticFactory3
import org.jetbrains.kotlin.idea.core.toDescriptor import org.jetbrains.kotlin.idea.core.toDescriptor
@@ -62,7 +59,7 @@ object ChangeVisibilityOnExposureFactory : KotlinIntentionActionsFactory() {
val exposedVisibility = exposedDiagnostic.c val exposedVisibility = exposedDiagnostic.c
val userVisibility = exposedDiagnostic.a val userVisibility = exposedDiagnostic.a
val (targetUserVisibility, targetExposedVisibility) = when (exposedVisibility.relation(userVisibility)) { val (targetUserVisibility, targetExposedVisibility) = when (exposedVisibility.relation(userVisibility)) {
LESS -> Pair(exposedVisibility.toVisibility(), userVisibility.toVisibility()) LESS -> Pair(exposedVisibility.toDescriptorVisibility(), userVisibility.toDescriptorVisibility())
else -> Pair(PRIVATE, PUBLIC) else -> Pair(PRIVATE, PUBLIC)
} }
val result = ArrayList<IntentionAction>() val result = ArrayList<IntentionAction>()
@@ -53,5 +53,5 @@ fun DeclarationDescriptor.shouldBeExported(config: JsConfig): Boolean =
private fun EffectiveVisibility.shouldBeExported(config: JsConfig): Boolean { private fun EffectiveVisibility.shouldBeExported(config: JsConfig): Boolean {
if (publicApi) return true if (publicApi) return true
if (config.configuration.getBoolean(JSConfigurationKeys.FRIEND_PATHS_DISABLED)) return false if (config.configuration.getBoolean(JSConfigurationKeys.FRIEND_PATHS_DISABLED)) return false
return toVisibility() == DescriptorVisibilities.INTERNAL return toVisibility() == Visibilities.Internal
} }
@@ -348,8 +348,8 @@ class NameSuggestion {
return if (absHashCode != 0) absHashCode.toString(Character.MAX_RADIX) else "" return if (absHashCode != 0) absHashCode.toString(Character.MAX_RADIX) else ""
} }
private val DeclarationDescriptorWithVisibility.ownEffectiveVisibility private val DeclarationDescriptorWithVisibility.ownEffectiveVisibility: DescriptorVisibility
get() = visibility.effectiveVisibility(this, checkPublishedApi = true).toVisibility() get() = visibility.effectiveVisibility(this, checkPublishedApi = true).toDescriptorVisibility()
@JvmStatic fun sanitizeName(name: String): String { @JvmStatic fun sanitizeName(name: String): String {
if (name.isEmpty()) return "_" if (name.isEmpty()) return "_"