Effective visibility: separate InternalProtected and InternalProtectedBound, messages, test change

This commit is contained in:
Mikhail Glukhikh
2015-10-13 14:13:03 +03:00
parent 4dbd7e7f69
commit 8473be357f
3 changed files with 84 additions and 66 deletions
@@ -1,17 +1,12 @@
// See KT-9540 // See KT-9540
// all protected should have lower bound that is more permissive than private // all protected should have lower bound that is more permissive than private
// protected and internal should have lower bound that is more permissive than private
open class A { open class A {
private interface B private interface B
protected open class C { protected open class C {
protected interface D : <!EXPOSED_SUPER_INTERFACE!>B<!> protected interface D : <!EXPOSED_SUPER_INTERFACE!>B<!>
internal interface E : <!EXPOSED_SUPER_INTERFACE!>B<!>, <!EXPOSED_SUPER_INTERFACE!>D<!>
} }
} }
// protected and internal should have lower bound that is more permissive than private
open class AA {
private interface BB
protected open class CC {
internal interface DD : <!EXPOSED_SUPER_INTERFACE!>BB<!>
}
}
@@ -23,31 +23,11 @@ public open class A {
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
} }
}
}
public open class AA { internal interface E : A.B, A.C.D {
public constructor AA() public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
private interface BB {
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
}
protected open class CC {
public constructor CC()
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
internal interface DD : AA.BB {
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
} }
} }
} }
@@ -28,10 +28,11 @@ sealed class EffectiveVisibility(val name: String) {
// /--/ | \-------------\ // /--/ | \-------------\
// Protected(Base) | \ // Protected(Base) | \
// | Protected(Other) Internal // | Protected(Other) Internal
// Protected(Derived) | / // Protected(Derived) | / \
// | | / // | | / InternalProtected(Base)
// ProtectedBound / // ProtectedBound / \
// \InternalProtected // \ / /InternalProtected(Derived)
// \InternalProtectedBound/
// | // |
// Private // Private
@@ -48,15 +49,16 @@ sealed class EffectiveVisibility(val name: String) {
object Internal : EffectiveVisibility("internal") { object Internal : EffectiveVisibility("internal") {
override fun relation(other: EffectiveVisibility) = when (other) { override fun relation(other: EffectiveVisibility) = when (other) {
Public -> Permissiveness.LESS Public -> Permissiveness.LESS
Private, InternalProtected -> Permissiveness.MORE Private, InternalProtectedBound, is InternalProtected -> Permissiveness.MORE
Internal -> Permissiveness.SAME Internal -> 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, InternalProtected, Internal -> other Private, InternalProtectedBound, Internal, is InternalProtected -> other
ProtectedBound, is Protected -> InternalProtected is Protected -> InternalProtected(other.container)
ProtectedBound -> InternalProtectedBound
} }
} }
@@ -70,61 +72,85 @@ sealed class EffectiveVisibility(val name: String) {
override fun relation(other: EffectiveVisibility) = when (other) { override fun relation(other: EffectiveVisibility) = when (other) {
Public -> Permissiveness.LESS Public -> Permissiveness.LESS
Private, ProtectedBound, InternalProtected -> Permissiveness.MORE Private, ProtectedBound, InternalProtectedBound -> Permissiveness.MORE
is Protected -> { is Protected -> containerRelation(container, other.container)
if (container == null || other.container == null) { is InternalProtected -> when (containerRelation(container, other.container)) {
Permissiveness.UNKNOWN Permissiveness.SAME, Permissiveness.LESS -> Permissiveness.LESS
} Permissiveness.UNKNOWN, Permissiveness.MORE -> Permissiveness.UNKNOWN
else if (container == other.container) {
Permissiveness.SAME
}
else if (DescriptorUtils.isSubclass(container, other.container)) {
Permissiveness.LESS
}
else if (DescriptorUtils.isSubclass(other.container, container)) {
Permissiveness.MORE
}
else {
Permissiveness.UNKNOWN
}
} }
Internal -> Permissiveness.UNKNOWN Internal -> Permissiveness.UNKNOWN
} }
override fun lowerBound(other: EffectiveVisibility) = when (other) { override fun lowerBound(other: EffectiveVisibility) = when (other) {
Public -> this Public -> this
Private, ProtectedBound, InternalProtected -> other Private, ProtectedBound, InternalProtectedBound -> other
is Protected -> when (relation(other)) { is Protected -> when (relation(other)) {
Permissiveness.SAME, Permissiveness.MORE -> this Permissiveness.SAME, Permissiveness.MORE -> this
Permissiveness.LESS -> other Permissiveness.LESS -> other
Permissiveness.UNKNOWN -> ProtectedBound Permissiveness.UNKNOWN -> ProtectedBound
} }
Internal -> InternalProtected is InternalProtected -> when (relation(other)) {
Permissiveness.LESS -> other
else -> InternalProtectedBound
}
Internal -> InternalProtected(container)
} }
} }
// Lower bound for all protected visibilities // Lower bound for all protected visibilities
object ProtectedBound : EffectiveVisibility("protected(_)") { object ProtectedBound : EffectiveVisibility("most protected") {
override fun relation(other: EffectiveVisibility) = when (other) { override fun relation(other: EffectiveVisibility) = when (other) {
Public, is Protected -> Permissiveness.LESS Public, is Protected -> Permissiveness.LESS
Private, InternalProtected -> Permissiveness.MORE Private, InternalProtectedBound -> Permissiveness.MORE
ProtectedBound -> Permissiveness.SAME ProtectedBound -> Permissiveness.SAME
Internal -> Permissiveness.UNKNOWN Internal, 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, ProtectedBound, InternalProtected -> other Private, ProtectedBound, InternalProtectedBound -> other
Internal -> InternalProtected Internal, is InternalProtected -> InternalProtectedBound
} }
} }
// Lower bound for Internal and Protected // Lower bound for internal and protected(C)
object InternalProtected : EffectiveVisibility("internal/protected") { class InternalProtected(val container: ClassDescriptor?): EffectiveVisibility("protected & internal") {
override fun equals(other: Any?) = (other is InternalProtected && container == other.container)
override fun hashCode() = container?.hashCode() ?: 0
override fun toString() = "${super.toString()}(${container?.name ?: '?'})"
override fun relation(other: EffectiveVisibility) = when (other) { override fun relation(other: EffectiveVisibility) = when (other) {
Public, is Protected, ProtectedBound, Internal -> Permissiveness.LESS Public, Internal -> Permissiveness.LESS
Private, InternalProtectedBound -> Permissiveness.MORE
is InternalProtected -> containerRelation(container, other.container)
is Protected -> when (containerRelation(container, other.container)) {
Permissiveness.SAME, Permissiveness.MORE -> Permissiveness.MORE
Permissiveness.UNKNOWN, Permissiveness.LESS -> Permissiveness.UNKNOWN
}
ProtectedBound -> Permissiveness.UNKNOWN
}
override fun lowerBound(other: EffectiveVisibility) = when (other) {
Public, Internal -> this
Private, InternalProtectedBound -> other
is Protected, is InternalProtected -> when (relation(other)) {
Permissiveness.SAME, Permissiveness.MORE -> this
Permissiveness.LESS -> other
Permissiveness.UNKNOWN -> InternalProtectedBound
}
ProtectedBound -> InternalProtectedBound
}
}
// Lower bound for internal and protected lower bound
object InternalProtectedBound : EffectiveVisibility("most protected & internal") {
override fun relation(other: EffectiveVisibility) = when (other) {
Public, is Protected, is InternalProtected, ProtectedBound, Internal -> Permissiveness.LESS
Private -> Permissiveness.MORE Private -> Permissiveness.MORE
InternalProtected -> Permissiveness.SAME InternalProtectedBound -> Permissiveness.SAME
} }
} }
@@ -150,6 +176,23 @@ sealed class EffectiveVisibility(val name: String) {
companion object { companion object {
internal fun containerRelation(first: ClassDescriptor?, second: ClassDescriptor?): Permissiveness =
if (first == null || second == null) {
Permissiveness.UNKNOWN
}
else if (first == second) {
Permissiveness.SAME
}
else if (DescriptorUtils.isSubclass(first, second)) {
Permissiveness.LESS
}
else if (DescriptorUtils.isSubclass(second, first)) {
Permissiveness.MORE
}
else {
Permissiveness.UNKNOWN
}
private fun lowerBound(first: EffectiveVisibility, second: EffectiveVisibility) = private fun lowerBound(first: EffectiveVisibility, second: EffectiveVisibility) =
first.lowerBound(second) first.lowerBound(second)