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); 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") @TestMetadata("privateFromLocal.kt")
public void testPrivateFromLocal() throws Exception { public void testPrivateFromLocal() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/exposed/privateFromLocal.kt"); String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/exposed/privateFromLocal.kt");
@@ -59,7 +59,7 @@ public class JavaVisibilities {
@NotNull @NotNull
@Override @Override
public EffectiveVisibility effectiveVisibility(@Nullable ClassDescriptor classDescriptor) { 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 // Public
// /--/ | \-------------\ // /--/ | \-------------\
// Protected(Base) | \ // Protected(Base) | \
// | Protected(Other) Internal // | Protected(Other) Internal = PackagePrivate
// Protected(Derived) | / \ // Protected(Derived) | / \
// | | / InternalProtected(Base) // | | / InternalProtected(Base)
// ProtectedBound / \ // ProtectedBound / \
@@ -53,22 +53,28 @@ sealed class EffectiveVisibility(val name: String) {
if (this == other) Permissiveness.SAME else Permissiveness.MORE 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) { override fun relation(other: EffectiveVisibility) = when (other) {
Public -> Permissiveness.LESS Public -> Permissiveness.LESS
Private, Local, InternalProtectedBound, is InternalProtected -> Permissiveness.MORE Private, Local, InternalProtectedBound, is InternalProtected -> Permissiveness.MORE
Internal -> Permissiveness.SAME is InternalOrPackage -> Permissiveness.SAME
ProtectedBound, is Protected -> Permissiveness.UNKNOWN ProtectedBound, is Protected -> Permissiveness.UNKNOWN
} }
override fun lowerBound(other: EffectiveVisibility) = when (other) { override fun lowerBound(other: EffectiveVisibility) = when (other) {
Public -> this Public -> this
Private, Local, InternalProtectedBound, Internal, is InternalProtected -> other Private, Local, InternalProtectedBound, is InternalOrPackage, is InternalProtected -> other
is Protected -> InternalProtected(other.container) is Protected -> InternalProtected(other.container)
ProtectedBound -> InternalProtectedBound ProtectedBound -> InternalProtectedBound
} }
} }
object Internal : InternalOrPackage(true)
object PackagePrivate : InternalOrPackage(false)
class Protected(val container: ClassDescriptor?) : EffectiveVisibility("protected") { class Protected(val container: ClassDescriptor?) : EffectiveVisibility("protected") {
override fun equals(other: Any?) = (other is Protected && container == other.container) 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.SAME, Permissiveness.MORE -> Permissiveness.MORE
Permissiveness.UNKNOWN, Permissiveness.LESS -> Permissiveness.UNKNOWN Permissiveness.UNKNOWN, Permissiveness.LESS -> Permissiveness.UNKNOWN
} }
Internal -> Permissiveness.UNKNOWN is InternalOrPackage -> Permissiveness.UNKNOWN
} }
override fun lowerBound(other: EffectiveVisibility) = when (other) { override fun lowerBound(other: EffectiveVisibility) = when (other) {
@@ -101,7 +107,7 @@ sealed class EffectiveVisibility(val name: String) {
Permissiveness.LESS -> other Permissiveness.LESS -> other
else -> InternalProtectedBound else -> InternalProtectedBound
} }
Internal -> InternalProtected(container) is InternalOrPackage -> InternalProtected(container)
} }
} }
@@ -111,13 +117,13 @@ sealed class EffectiveVisibility(val name: String) {
Public, is Protected -> Permissiveness.LESS Public, is Protected -> Permissiveness.LESS
Private, Local, InternalProtectedBound -> Permissiveness.MORE Private, Local, InternalProtectedBound -> Permissiveness.MORE
ProtectedBound -> Permissiveness.SAME ProtectedBound -> Permissiveness.SAME
Internal, is InternalProtected -> Permissiveness.UNKNOWN is InternalOrPackage, is InternalProtected -> Permissiveness.UNKNOWN
} }
override fun lowerBound(other: EffectiveVisibility) = when (other) { override fun lowerBound(other: EffectiveVisibility) = when (other) {
Public, is Protected -> this Public, is Protected -> this
Private, Local, ProtectedBound, InternalProtectedBound -> other 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 toString() = "${super.toString()} (in ${container?.name ?: '?'})"
override fun relation(other: EffectiveVisibility) = when (other) { override fun relation(other: EffectiveVisibility) = when (other) {
Public, Internal -> Permissiveness.LESS Public, is InternalOrPackage -> Permissiveness.LESS
Private, Local, InternalProtectedBound -> Permissiveness.MORE Private, Local, InternalProtectedBound -> Permissiveness.MORE
is InternalProtected -> containerRelation(container, other.container) is InternalProtected -> containerRelation(container, other.container)
is Protected -> when (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) { override fun lowerBound(other: EffectiveVisibility) = when (other) {
Public, Internal -> this Public, is InternalOrPackage -> this
Private, Local, InternalProtectedBound -> other Private, Local, InternalProtectedBound -> other
is Protected, is InternalProtected -> when (relation(other)) { is Protected, is InternalProtected -> when (relation(other)) {
Permissiveness.SAME, Permissiveness.MORE -> this Permissiveness.SAME, Permissiveness.MORE -> this
@@ -157,7 +163,7 @@ sealed class EffectiveVisibility(val name: String) {
// Lower bound for internal and protected lower bound // Lower bound for internal and protected lower bound
object InternalProtectedBound : EffectiveVisibility("internal & protected (in different classes)") { object InternalProtectedBound : EffectiveVisibility("internal & protected (in different classes)") {
override fun relation(other: EffectiveVisibility) = when (other) { 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 Private, Local -> Permissiveness.MORE
InternalProtectedBound -> Permissiveness.SAME InternalProtectedBound -> Permissiveness.SAME
} }