diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 09a664d67a9..4b390ea2a13 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -399,9 +399,6 @@ public interface Errors { DiagnosticFactory0 USELESS_VARARG_ON_PARAMETER = DiagnosticFactory0.create(WARNING); - DiagnosticFactory1 FUNCTION_RETURN_TYPE_DEPENDS_ON_LOCAL_CLASS = DiagnosticFactory1.create(ERROR, DECLARATION_RETURN_TYPE); - DiagnosticFactory1 PROPERTY_TYPE_DEPENDS_ON_LOCAL_CLASS = DiagnosticFactory1.create(ERROR, DECLARATION_RETURN_TYPE); - // Named parameters DiagnosticFactory0 DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE = DiagnosticFactory0.create(ERROR, PARAMETER_DEFAULT_VALUE); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index 08c46fc6a46..c01f4a5cffe 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -270,8 +270,6 @@ public class DefaultErrorMessages { MAP.put(UNUSED_CHANGED_VALUE, "The value changed at ''{0}'' is never used", ELEMENT_TEXT); MAP.put(UNUSED_EXPRESSION, "The expression is unused"); MAP.put(UNUSED_FUNCTION_LITERAL, "The function literal is unused. If you mean block, you can use 'run { ... }'"); - MAP.put(FUNCTION_RETURN_TYPE_DEPENDS_ON_LOCAL_CLASS, "Function return type depends on local class or object {0}", NAME); - MAP.put(PROPERTY_TYPE_DEPENDS_ON_LOCAL_CLASS, "Property type depends on local class or object {0}", NAME); MAP.put(VAL_REASSIGNMENT, "Val cannot be reassigned", NAME); MAP.put(SETTER_PROJECTED_OUT, "Setter for ''{0}'' is removed by type projection", NAME); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java index 76a13b015eb..e95c9cb48ea 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java @@ -689,58 +689,6 @@ public class DeclarationsChecker { } } - private void checkLocalTypesInFunctionReturnType(@NotNull JetFunction function, @NotNull FunctionDescriptor functionDescriptor) { - if (functionDescriptor instanceof ConstructorDescriptor) return; - if (!isExposedAsPublicAPI(functionDescriptor)) return; - JetType returnType = functionDescriptor.getReturnType(); - if (returnType == null) return; - checkLocalTypesExposedInType(function, functionDescriptor, returnType, - FUNCTION_RETURN_TYPE_DEPENDS_ON_LOCAL_CLASS, - new HashSet()); - } - - private void checkLocalTypesInPropertyType(@NotNull JetProperty property, @NotNull PropertyDescriptor propertyDescriptor) { - if (!isExposedAsPublicAPI(propertyDescriptor)) return; - JetType propertyType = propertyDescriptor.getType(); - checkLocalTypesExposedInType(property, propertyDescriptor, propertyType, - PROPERTY_TYPE_DEPENDS_ON_LOCAL_CLASS, - new HashSet()); - } - - private static boolean isExposedAsPublicAPI(@NotNull DeclarationDescriptor descriptor) { - for (DeclarationDescriptor finger = descriptor; finger != null; finger = finger.getContainingDeclaration()) { - if (finger instanceof DeclarationDescriptorWithVisibility) { - Visibility visibility = ((DeclarationDescriptorWithVisibility) finger).getVisibility(); - if (Visibilities.isPrivate(visibility) || visibility == Visibilities.LOCAL) { - return false; - } - } - } - return true; - } - - private void checkLocalTypesExposedInType( - @NotNull D reportOnDeclaration, - @NotNull DeclarationDescriptor parentDeclarationDescriptor, - @NotNull JetType type, - @NotNull DiagnosticFactory1 diagnostic, - @NotNull Set visitedTypes - ) { - visitedTypes.add(type); - ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(type); - if (classDescriptor != null) { - if (DescriptorUtils.isLocal(classDescriptor) && DescriptorUtils.isAncestor(parentDeclarationDescriptor, classDescriptor, true)) { - trace.report(diagnostic.on(reportOnDeclaration, classDescriptor)); - } - } - for (TypeProjection projection : type.getArguments()) { - JetType projectedType = projection.getType(); - if (!visitedTypes.contains(projectedType)) { - checkLocalTypesExposedInType(reportOnDeclaration, parentDeclarationDescriptor, projectedType, diagnostic, visitedTypes); - } - } - } - private void checkPropertyExposedType(@NotNull JetProperty property, @NotNull PropertyDescriptor propertyDescriptor) { EffectiveVisibility propertyVisibility = EffectiveVisibility.Companion.forMember(propertyDescriptor); EffectiveVisibility typeVisibility = EffectiveVisibility.Companion.forType(propertyDescriptor.getType()); @@ -748,7 +696,6 @@ public class DeclarationsChecker { trace.report(EXPOSED_PROPERTY_TYPE.on(property, propertyVisibility, typeVisibility)); } checkMemberReceiverExposedType(property.getReceiverTypeReference(), propertyDescriptor); - checkLocalTypesInPropertyType(property, propertyDescriptor); } protected void checkFunction(JetNamedFunction function, SimpleFunctionDescriptor functionDescriptor) { @@ -818,7 +765,6 @@ public class DeclarationsChecker { i++; } checkMemberReceiverExposedType(function.getReceiverTypeReference(), functionDescriptor); - checkLocalTypesInFunctionReturnType(function, functionDescriptor); } private void checkAccessors(@NotNull JetProperty property, @NotNull PropertyDescriptor propertyDescriptor) { diff --git a/compiler/testData/diagnostics/tests/declarationChecks/ambiguousObjectExpressionType.kt b/compiler/testData/diagnostics/tests/declarationChecks/ambiguousObjectExpressionType.kt index e12826cbafe..0853172d660 100644 --- a/compiler/testData/diagnostics/tests/declarationChecks/ambiguousObjectExpressionType.kt +++ b/compiler/testData/diagnostics/tests/declarationChecks/ambiguousObjectExpressionType.kt @@ -16,13 +16,13 @@ class Foo { privateProperty.f2() } - protected val protectedProperty = object : MyClass(), MyTrait {} + protected val protectedProperty = object : MyClass(), MyTrait {} - val internalProperty = object : MyClass(), MyTrait {} + val internalProperty = object : MyClass(), MyTrait {} - internal val internal2Property = object : MyClass(), MyTrait {} + internal val internal2Property = object : MyClass(), MyTrait {} - public val publicProperty = object : MyClass(), MyTrait {} + public val publicProperty = object : MyClass(), MyTrait {} private fun privateFunction() = object : MyClass(), MyTrait {} @@ -32,13 +32,13 @@ class Foo { privateFunction().f2() } - protected fun protectedFunction() = object : MyClass(), MyTrait {} + protected fun protectedFunction() = object : MyClass(), MyTrait {} - fun internalFunction() = object : MyClass(), MyTrait {} + fun internalFunction() = object : MyClass(), MyTrait {} - internal fun internal2Function() = object : MyClass(), MyTrait {} + internal fun internal2Function() = object : MyClass(), MyTrait {} - public fun publicFunction() = object : MyClass(), MyTrait {} + public fun publicFunction() = object : MyClass(), MyTrait {} @@ -50,13 +50,13 @@ class Foo { privatePropertyInner.f2() } - protected val protectedProperty = object : MyClass(), MyTrait {} + protected val protectedProperty = object : MyClass(), MyTrait {} - val internalProperty = object : MyClass(), MyTrait {} + val internalProperty = object : MyClass(), MyTrait {} - internal val internal2Property = object : MyClass(), MyTrait {} + internal val internal2Property = object : MyClass(), MyTrait {} - public val publicProperty = object : MyClass(), MyTrait {} + public val publicProperty = object : MyClass(), MyTrait {} private fun privateFunctionInner() = object : MyClass(), MyTrait {} @@ -66,13 +66,13 @@ class Foo { privateFunctionInner().f2() } - protected fun protectedFunction() = object : MyClass(), MyTrait {} + protected fun protectedFunction() = object : MyClass(), MyTrait {} - fun internalFunction() = object : MyClass(), MyTrait {} + fun internalFunction() = object : MyClass(), MyTrait {} - internal fun internal2Function() = object : MyClass(), MyTrait {} + internal fun internal2Function() = object : MyClass(), MyTrait {} - public fun publicFunction() = object : MyClass(), MyTrait {} + public fun publicFunction() = object : MyClass(), MyTrait {} } @@ -90,21 +90,21 @@ class Foo { private val packagePrivateProperty = object : MyClass(), MyTrait {} -protected val packageProtectedProperty = object : MyClass(), MyTrait {} +protected val packageProtectedProperty = object : MyClass(), MyTrait {} -val packageInternalProperty = object : MyClass(), MyTrait {} +val packageInternalProperty = object : MyClass(), MyTrait {} -internal val packageInternal2Property = object : MyClass(), MyTrait {} +internal val packageInternal2Property = object : MyClass(), MyTrait {} -public val packagePublicProperty = object : MyClass(), MyTrait {} +public val packagePublicProperty = object : MyClass(), MyTrait {} -protected fun packageProtectedFunction() = object : MyClass(), MyTrait {} +protected fun packageProtectedFunction() = object : MyClass(), MyTrait {} -fun packageInternalFunction() = object : MyClass(), MyTrait {} +fun packageInternalFunction() = object : MyClass(), MyTrait {} -internal fun packageInternal2Function() = object : MyClass(), MyTrait {} +internal fun packageInternal2Function() = object : MyClass(), MyTrait {} -public fun packagePublicFunction() = object : MyClass(), MyTrait {} +public fun packagePublicFunction() = object : MyClass(), MyTrait {} fun fooPackage() { val packageLocalVar = object : MyClass(), MyTrait {} diff --git a/compiler/testData/diagnostics/tests/exposed/internalFromLocal.kt b/compiler/testData/diagnostics/tests/exposed/internalFromLocal.kt new file mode 100644 index 00000000000..3c7043385f6 --- /dev/null +++ b/compiler/testData/diagnostics/tests/exposed/internalFromLocal.kt @@ -0,0 +1,10 @@ +interface Your + +class My { + internal val x = object : Your {} + + internal fun foo() = { + class Local + Local() + }() +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/exposed/internalFromLocal.txt b/compiler/testData/diagnostics/tests/exposed/internalFromLocal.txt new file mode 100644 index 00000000000..e58b13686fb --- /dev/null +++ b/compiler/testData/diagnostics/tests/exposed/internalFromLocal.txt @@ -0,0 +1,16 @@ +package + +public final class My { + public constructor My() + internal final val x: Your + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + internal final fun foo(): My.foo..Local + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface Your { + 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 +} diff --git a/compiler/testData/diagnostics/tests/exposed/local.kt b/compiler/testData/diagnostics/tests/exposed/local.kt index bd067eda702..fd896c741c4 100644 --- a/compiler/testData/diagnostics/tests/exposed/local.kt +++ b/compiler/testData/diagnostics/tests/exposed/local.kt @@ -3,13 +3,13 @@ fun run(f: () -> T): T { } // invalid, depends on local class -fun foo() = run { +fun foo() = run { class A A() } // invalid, depends on local class -fun gav() = { +fun gav() = { class B B() } diff --git a/compiler/testData/diagnostics/tests/exposed/localFromInternal.kt b/compiler/testData/diagnostics/tests/exposed/localFromInternal.kt new file mode 100644 index 00000000000..89521bdd0dc --- /dev/null +++ b/compiler/testData/diagnostics/tests/exposed/localFromInternal.kt @@ -0,0 +1,7 @@ +class My { + internal open class ThreadLocal + // Private from local: ??? + private val values = + // Local from internal: Ok + object: ThreadLocal() {} +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/exposed/localFromInternal.txt b/compiler/testData/diagnostics/tests/exposed/localFromInternal.txt new file mode 100644 index 00000000000..ae2d04bfb78 --- /dev/null +++ b/compiler/testData/diagnostics/tests/exposed/localFromInternal.txt @@ -0,0 +1,16 @@ +package + +public final class My { + public constructor My() + private final val values: My.values. + 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 open class ThreadLocal { + public constructor ThreadLocal() + 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 + } +} diff --git a/compiler/testData/diagnostics/tests/exposed/localFromPrivate.kt b/compiler/testData/diagnostics/tests/exposed/localFromPrivate.kt new file mode 100644 index 00000000000..9156292343b --- /dev/null +++ b/compiler/testData/diagnostics/tests/exposed/localFromPrivate.kt @@ -0,0 +1,15 @@ +class A { + private open class B + fun f() { + // Local from private: Ok + class C : B() + } +} + +private open class D + +fun f(): Int { + // Local from private: Ok + val x = object : D() { } + return x.hashCode() +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/exposed/localFromPrivate.txt b/compiler/testData/diagnostics/tests/exposed/localFromPrivate.txt new file mode 100644 index 00000000000..32c1d2f96dd --- /dev/null +++ b/compiler/testData/diagnostics/tests/exposed/localFromPrivate.txt @@ -0,0 +1,25 @@ +package + +public fun f(): kotlin.Int + +public final class A { + public constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun f(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + private open class B { + public constructor B() + 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 + } +} + +private open class D { + public constructor D() + 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 +} diff --git a/compiler/testData/diagnostics/tests/exposed/localInFunReturnType.kt b/compiler/testData/diagnostics/tests/exposed/localInFunReturnType.kt index 8729e367f53..80f2caab66b 100644 --- a/compiler/testData/diagnostics/tests/exposed/localInFunReturnType.kt +++ b/compiler/testData/diagnostics/tests/exposed/localInFunReturnType.kt @@ -6,21 +6,21 @@ class My(val value: T) open class Base -fun invalid1() = run { +fun invalid1() = run { class Local My(Local()) } -fun invalid2() = My(object {}) +fun invalid2() = My(object {}) -fun invalid3() = My(object : Base() {}) +fun invalid3() = My(object : Base() {}) -fun invalid4() = run { +fun invalid4() = run { class Local My(My(Local())) } -fun invalid5() = run { +fun invalid5() = run { fun invalid5a() = run { class Local Local() diff --git a/compiler/testData/diagnostics/tests/exposed/localInMemberType.kt b/compiler/testData/diagnostics/tests/exposed/localInMemberType.kt index 2d81a039dd1..27b35ddcb7f 100644 --- a/compiler/testData/diagnostics/tests/exposed/localInMemberType.kt +++ b/compiler/testData/diagnostics/tests/exposed/localInMemberType.kt @@ -7,9 +7,9 @@ class Something { internal val internalVal1 = object { override fun toString() = "!" } private val privateVal1 = object { override fun toString() = "!" } - public val publicVal2 = run { class A; A() } - protected val protectedVal2 = run { class A; A() } - internal val internalVal2 = run { class A; A() } + public val publicVal2 = run { class A; A() } + protected val protectedVal2 = run { class A; A() } + internal val internalVal2 = run { class A; A() } private val privateVal2 = run { class A; A() } public fun publicFun1() = object { override fun toString() = "!" } @@ -17,8 +17,8 @@ class Something { internal fun internalFun1() = object { override fun toString() = "!" } private fun privateFun1() = object { override fun toString() = "!" } - public fun publicFun2() = run { class A; A() } - protected fun protectedFun2() = run { class A; A() } - internal fun internalFun2() = run { class A; A() } + public fun publicFun2() = run { class A; A() } + protected fun protectedFun2() = run { class A; A() } + internal fun internalFun2() = run { class A; A() } private fun privateFun2() = run { class A; A() } } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/exposed/localInPropertyType.kt b/compiler/testData/diagnostics/tests/exposed/localInPropertyType.kt index 695fc8830b4..f9d4fbc7030 100644 --- a/compiler/testData/diagnostics/tests/exposed/localInPropertyType.kt +++ b/compiler/testData/diagnostics/tests/exposed/localInPropertyType.kt @@ -6,27 +6,27 @@ class My(val value: T) open class Base -val invalid1 = run { +val invalid1 = run { class Local My(Local()) -} +} -val invalid2 = My(object {}) +val invalid2 = My(object {}) -val invalid3 = My(object : Base() {}) +val invalid3 = My(object : Base() {}) -val invalid4 = run { +val invalid4 = run { class Local My(My(Local())) -} +} -val invalid5 = run { +val invalid5 = run { fun invalid5a() = run { class Local Local() } My(invalid5a()) -} +} // Valid: effectively Any val valid1 = object {} diff --git a/compiler/testData/diagnostics/tests/exposed/privateFromLocal.kt b/compiler/testData/diagnostics/tests/exposed/privateFromLocal.kt new file mode 100644 index 00000000000..73d344637d5 --- /dev/null +++ b/compiler/testData/diagnostics/tests/exposed/privateFromLocal.kt @@ -0,0 +1,12 @@ +interface Your + +class My { + // private from local: ??? + private val x = object : Your {} + + // private from local: ??? + private fun foo() = { + class Local + Local() + }() +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/exposed/privateFromLocal.txt b/compiler/testData/diagnostics/tests/exposed/privateFromLocal.txt new file mode 100644 index 00000000000..038090f637b --- /dev/null +++ b/compiler/testData/diagnostics/tests/exposed/privateFromLocal.txt @@ -0,0 +1,16 @@ +package + +public final class My { + public constructor My() + private final val x: My.x. + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + private final fun foo(): My.foo..Local + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface Your { + 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 +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index b64a735ae4c..8ed4a3f1072 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -5808,12 +5808,30 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("internalFromLocal.kt") + public void testInternalFromLocal() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/exposed/internalFromLocal.kt"); + doTest(fileName); + } + @TestMetadata("local.kt") public void testLocal() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/exposed/local.kt"); doTest(fileName); } + @TestMetadata("localFromInternal.kt") + public void testLocalFromInternal() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/exposed/localFromInternal.kt"); + doTest(fileName); + } + + @TestMetadata("localFromPrivate.kt") + public void testLocalFromPrivate() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/exposed/localFromPrivate.kt"); + doTest(fileName); + } + @TestMetadata("localInFunReturnType.kt") public void testLocalInFunReturnType() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/exposed/localInFunReturnType.kt"); @@ -5838,6 +5856,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("privateFromLocal.kt") + public void testPrivateFromLocal() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/exposed/privateFromLocal.kt"); + doTest(fileName); + } + @TestMetadata("protected.kt") public void testProtected() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/exposed/protected.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibility.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibility.kt index c01deb575f7..fa8d3dc79b9 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibility.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibility.kt @@ -34,11 +34,18 @@ sealed class EffectiveVisibility(val name: String) { // \ / /InternalProtected(Derived) // \InternalProtectedBound/ // | - // Private + // Private = Local + object Private : EffectiveVisibility("private") { override fun relation(other: EffectiveVisibility) = - if (this == other) Permissiveness.SAME else Permissiveness.LESS + if (this == other || Local == other) Permissiveness.SAME else Permissiveness.LESS + } + + // Effectively same as Private + object Local : EffectiveVisibility("local") { + override fun relation(other: EffectiveVisibility) = + if (this == other || Private == other) Permissiveness.SAME else Permissiveness.LESS } object Public : EffectiveVisibility("public") { @@ -49,14 +56,14 @@ sealed class EffectiveVisibility(val name: String) { object Internal : EffectiveVisibility("internal") { override fun relation(other: EffectiveVisibility) = when (other) { Public -> Permissiveness.LESS - Private, InternalProtectedBound, is InternalProtected -> Permissiveness.MORE + Private, Local, InternalProtectedBound, is InternalProtected -> Permissiveness.MORE Internal -> Permissiveness.SAME ProtectedBound, is Protected -> Permissiveness.UNKNOWN } override fun lowerBound(other: EffectiveVisibility) = when (other) { Public -> this - Private, InternalProtectedBound, Internal, is InternalProtected -> other + Private, Local, InternalProtectedBound, Internal, is InternalProtected -> other is Protected -> InternalProtected(other.container) ProtectedBound -> InternalProtectedBound } @@ -72,7 +79,7 @@ sealed class EffectiveVisibility(val name: String) { override fun relation(other: EffectiveVisibility) = when (other) { Public -> Permissiveness.LESS - Private, ProtectedBound, InternalProtectedBound -> Permissiveness.MORE + Private, Local, ProtectedBound, InternalProtectedBound -> Permissiveness.MORE is Protected -> containerRelation(container, other.container) is InternalProtected -> when (containerRelation(container, other.container)) { // Protected never can be less permissive than internal & protected @@ -84,7 +91,7 @@ sealed class EffectiveVisibility(val name: String) { override fun lowerBound(other: EffectiveVisibility) = when (other) { Public -> this - Private, ProtectedBound, InternalProtectedBound -> other + Private, Local, ProtectedBound, InternalProtectedBound -> other is Protected -> when (relation(other)) { Permissiveness.SAME, Permissiveness.MORE -> this Permissiveness.LESS -> other @@ -102,14 +109,14 @@ sealed class EffectiveVisibility(val name: String) { object ProtectedBound : EffectiveVisibility("protected (in different classes)") { override fun relation(other: EffectiveVisibility) = when (other) { Public, is Protected -> Permissiveness.LESS - Private, InternalProtectedBound -> Permissiveness.MORE + Private, Local, InternalProtectedBound -> Permissiveness.MORE ProtectedBound -> Permissiveness.SAME Internal, is InternalProtected -> Permissiveness.UNKNOWN } override fun lowerBound(other: EffectiveVisibility) = when (other) { Public, is Protected -> this - Private, ProtectedBound, InternalProtectedBound -> other + Private, Local, ProtectedBound, InternalProtectedBound -> other Internal, is InternalProtected -> InternalProtectedBound } } @@ -125,7 +132,7 @@ sealed class EffectiveVisibility(val name: String) { override fun relation(other: EffectiveVisibility) = when (other) { Public, Internal -> Permissiveness.LESS - Private, InternalProtectedBound -> Permissiveness.MORE + Private, Local, InternalProtectedBound -> Permissiveness.MORE is InternalProtected -> containerRelation(container, other.container) is Protected -> when (containerRelation(container, other.container)) { // Internal & protected never can be more permissive than just protected @@ -137,7 +144,7 @@ sealed class EffectiveVisibility(val name: String) { override fun lowerBound(other: EffectiveVisibility) = when (other) { Public, Internal -> this - Private, InternalProtectedBound -> other + Private, Local, InternalProtectedBound -> other is Protected, is InternalProtected -> when (relation(other)) { Permissiveness.SAME, Permissiveness.MORE -> this Permissiveness.LESS -> other @@ -151,7 +158,7 @@ sealed class EffectiveVisibility(val name: String) { object InternalProtectedBound : EffectiveVisibility("internal & protected (in different classes)") { override fun relation(other: EffectiveVisibility) = when (other) { Public, is Protected, is InternalProtected, ProtectedBound, Internal -> Permissiveness.LESS - Private -> Permissiveness.MORE + Private, Local -> Permissiveness.MORE InternalProtectedBound -> Permissiveness.SAME } } @@ -206,8 +213,7 @@ sealed class EffectiveVisibility(val name: String) { Visibilities.PROTECTED -> Protected(descriptor) Visibilities.INTERNAL -> Internal Visibilities.PUBLIC -> Public - // Considered effectively public - Visibilities.LOCAL -> Public + Visibilities.LOCAL -> Local else -> this.effectiveVisibility(descriptor) }