Effective visibility: java package-private is now considered as equivalent to Kotlin internal #KT-9755 Fixed

This commit is contained in:
Mikhail Glukhikh
2015-10-26 14:32:42 +03:00
parent 994feafd6e
commit d0e01153ec
5 changed files with 95 additions and 12 deletions
@@ -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 <!EXPOSED_FUNCTION_RETURN_TYPE!>protected<!>() = My.foo()
// Error: public vs package-private
fun <!EXPOSED_FUNCTION_RETURN_TYPE!>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()
}
@@ -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!
}
}
@@ -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");
@@ -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;
}
};
@@ -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
}