diff --git a/compiler/testData/diagnostics/tests/exposed/packagePrivate.kt b/compiler/testData/diagnostics/tests/exposed/packagePrivate.kt new file mode 100644 index 00000000000..7d66d3a7cd7 --- /dev/null +++ b/compiler/testData/diagnostics/tests/exposed/packagePrivate.kt @@ -0,0 +1,35 @@ +// FILE: test/My.java + +package test; + +class Internal {} + +public class My { + static public Internal foo() { return new Internal(); } +} + +// FILE: test/His.kt + +package test + +class His { + // Ok: private vs package-private + private fun private() = My.foo() + // Ok: internal vs package-private in same package + internal fun internal() = My.foo() + // Error: protected vs package-private + protected fun protected() = My.foo() + // Error: public vs package-private + fun public() = My.foo() +} + +// FILE: other/Your.kt + +package other + +import test.My + +class Your { + // Ok but dangerous: internal vs package-private in different package + internal fun bar() = My.foo() +} diff --git a/compiler/testData/diagnostics/tests/exposed/packagePrivate.txt b/compiler/testData/diagnostics/tests/exposed/packagePrivate.txt new file mode 100644 index 00000000000..9a0bc288c88 --- /dev/null +++ b/compiler/testData/diagnostics/tests/exposed/packagePrivate.txt @@ -0,0 +1,36 @@ +package + +package other { + + public final class Your { + public constructor Your() + internal final fun bar(): test.Internal! + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +package test { + + public final class His { + public constructor His() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + internal final fun internal(): test.Internal! + private final fun private(): test.Internal! + protected final fun protected(): test.Internal! + public final fun public(): test.Internal! + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + public open class My { + public constructor My() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public open fun foo(): test.Internal! + } +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index c8aa765edc8..ff097a41d8f 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -5943,6 +5943,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("packagePrivate.kt") + public void testPackagePrivate() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/exposed/packagePrivate.kt"); + doTest(fileName); + } + @TestMetadata("privateFromLocal.kt") public void testPrivateFromLocal() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/exposed/privateFromLocal.kt"); diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JavaVisibilities.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JavaVisibilities.java index 5008e2703ff..444a2533de4 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JavaVisibilities.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JavaVisibilities.java @@ -59,7 +59,7 @@ public class JavaVisibilities { @NotNull @Override public EffectiveVisibility effectiveVisibility(@Nullable ClassDescriptor classDescriptor) { - return EffectiveVisibility.Companion.effectiveVisibility(Visibilities.PRIVATE, classDescriptor); + return EffectiveVisibility.PackagePrivate.INSTANCE; } }; diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibility.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibility.kt index 03018a18d75..187b0dbb285 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibility.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibility.kt @@ -27,7 +27,7 @@ sealed class EffectiveVisibility(val name: String) { // Public // /--/ | \-------------\ // Protected(Base) | \ - // | Protected(Other) Internal + // | Protected(Other) Internal = PackagePrivate // Protected(Derived) | / \ // | | / InternalProtected(Base) // ProtectedBound / \ @@ -53,22 +53,28 @@ sealed class EffectiveVisibility(val name: String) { if (this == other) Permissiveness.SAME else Permissiveness.MORE } - object Internal : EffectiveVisibility("internal") { + abstract class InternalOrPackage protected constructor(internal: Boolean) : EffectiveVisibility( + if (internal) "internal" else "public/*package*/" + ) { override fun relation(other: EffectiveVisibility) = when (other) { Public -> Permissiveness.LESS Private, Local, InternalProtectedBound, is InternalProtected -> Permissiveness.MORE - Internal -> Permissiveness.SAME + is InternalOrPackage -> Permissiveness.SAME ProtectedBound, is Protected -> Permissiveness.UNKNOWN } override fun lowerBound(other: EffectiveVisibility) = when (other) { Public -> this - Private, Local, InternalProtectedBound, Internal, is InternalProtected -> other + Private, Local, InternalProtectedBound, is InternalOrPackage, is InternalProtected -> other is Protected -> InternalProtected(other.container) ProtectedBound -> InternalProtectedBound } } + object Internal : InternalOrPackage(true) + + object PackagePrivate : InternalOrPackage(false) + class Protected(val container: ClassDescriptor?) : EffectiveVisibility("protected") { override fun equals(other: Any?) = (other is Protected && container == other.container) @@ -86,7 +92,7 @@ sealed class EffectiveVisibility(val name: String) { Permissiveness.SAME, Permissiveness.MORE -> Permissiveness.MORE Permissiveness.UNKNOWN, Permissiveness.LESS -> Permissiveness.UNKNOWN } - Internal -> Permissiveness.UNKNOWN + is InternalOrPackage -> Permissiveness.UNKNOWN } override fun lowerBound(other: EffectiveVisibility) = when (other) { @@ -101,7 +107,7 @@ sealed class EffectiveVisibility(val name: String) { Permissiveness.LESS -> other else -> InternalProtectedBound } - Internal -> InternalProtected(container) + is InternalOrPackage -> InternalProtected(container) } } @@ -111,13 +117,13 @@ sealed class EffectiveVisibility(val name: String) { Public, is Protected -> Permissiveness.LESS Private, Local, InternalProtectedBound -> Permissiveness.MORE ProtectedBound -> Permissiveness.SAME - Internal, is InternalProtected -> Permissiveness.UNKNOWN + is InternalOrPackage, is InternalProtected -> Permissiveness.UNKNOWN } override fun lowerBound(other: EffectiveVisibility) = when (other) { Public, is Protected -> this Private, Local, ProtectedBound, InternalProtectedBound -> other - Internal, is InternalProtected -> InternalProtectedBound + is InternalOrPackage, is InternalProtected -> InternalProtectedBound } } @@ -131,7 +137,7 @@ sealed class EffectiveVisibility(val name: String) { override fun toString() = "${super.toString()} (in ${container?.name ?: '?'})" override fun relation(other: EffectiveVisibility) = when (other) { - Public, Internal -> Permissiveness.LESS + Public, is InternalOrPackage -> Permissiveness.LESS Private, Local, InternalProtectedBound -> Permissiveness.MORE is InternalProtected -> containerRelation(container, other.container) is Protected -> when (containerRelation(container, other.container)) { @@ -143,7 +149,7 @@ sealed class EffectiveVisibility(val name: String) { } override fun lowerBound(other: EffectiveVisibility) = when (other) { - Public, Internal -> this + Public, is InternalOrPackage -> this Private, Local, InternalProtectedBound -> other is Protected, is InternalProtected -> when (relation(other)) { Permissiveness.SAME, Permissiveness.MORE -> this @@ -157,7 +163,7 @@ sealed class EffectiveVisibility(val name: String) { // Lower bound for internal and protected lower bound object InternalProtectedBound : EffectiveVisibility("internal & protected (in different classes)") { override fun relation(other: EffectiveVisibility) = when (other) { - Public, is Protected, is InternalProtected, ProtectedBound, Internal -> Permissiveness.LESS + Public, is Protected, is InternalProtected, ProtectedBound, is InternalOrPackage -> Permissiveness.LESS Private, Local -> Permissiveness.MORE InternalProtectedBound -> Permissiveness.SAME }