diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index 51f26dfd35f..9dc2dd6d1ef 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -9275,6 +9275,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/exposed/privateFromLocal.kt"); } + @Test + @TestMetadata("privateInFile.kt") + public void testPrivateInFile() throws Exception { + runTest("compiler/testData/diagnostics/tests/exposed/privateInFile.kt"); + } + @Test @TestMetadata("privatePropertyInPrivateConstructor.kt") public void testPrivatePropertyInPrivateConstructor() throws Exception { diff --git a/compiler/testData/diagnostics/tests/exposed/privateInFile.fir.kt b/compiler/testData/diagnostics/tests/exposed/privateInFile.fir.kt new file mode 100644 index 00000000000..15607efc369 --- /dev/null +++ b/compiler/testData/diagnostics/tests/exposed/privateInFile.fir.kt @@ -0,0 +1,28 @@ +class Public { + private open class NestedPrivate + + fun test1() = NestedPrivate() + fun test2(p: NestedPrivate) {} + fun NestedPrivate.test3() {} + val test4 = NestedPrivate() + class Test5 : NestedPrivate() +} + +private class PrivateInFileClass { + private open class NestedPrivate + + fun test1() = NestedPrivate() + fun test2(p: NestedPrivate) {} + fun NestedPrivate.test3() {} + val test4 = NestedPrivate() + class Test5 : NestedPrivate() +} + +private interface PrivateInFile { + private class Private + + fun expose() = Private() +} + +// Exposes 'PrivateInFile$Private' via 'expose' +class Derived : PrivateInFile diff --git a/compiler/testData/diagnostics/tests/exposed/privateInFile.kt b/compiler/testData/diagnostics/tests/exposed/privateInFile.kt new file mode 100644 index 00000000000..fcd5a4ba323 --- /dev/null +++ b/compiler/testData/diagnostics/tests/exposed/privateInFile.kt @@ -0,0 +1,28 @@ +class Public { + private open class NestedPrivate + + fun test1() = NestedPrivate() + fun test2(p: NestedPrivate) {} + fun NestedPrivate.test3() {} + val test4 = NestedPrivate() + class Test5 : NestedPrivate() +} + +private class PrivateInFileClass { + private open class NestedPrivate + + fun test1() = NestedPrivate() + fun test2(p: NestedPrivate) {} + fun NestedPrivate.test3() {} + val test4 = NestedPrivate() + class Test5 : NestedPrivate() +} + +private interface PrivateInFile { + private class Private + + fun expose() = Private() +} + +// Exposes 'PrivateInFile$Private' via 'expose' +class Derived : PrivateInFile diff --git a/compiler/testData/diagnostics/tests/exposed/privateInFile.txt b/compiler/testData/diagnostics/tests/exposed/privateInFile.txt new file mode 100644 index 00000000000..93be0535614 --- /dev/null +++ b/compiler/testData/diagnostics/tests/exposed/privateInFile.txt @@ -0,0 +1,73 @@ +package + +public final class Derived : PrivateInFile { + public constructor Derived() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun expose(): PrivateInFile.Private + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +private interface PrivateInFile { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open fun expose(): PrivateInFile.Private + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + private final class Private { + public constructor Private() + 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 final class PrivateInFileClass { + public constructor PrivateInFileClass() + public final val test4: PrivateInFileClass.NestedPrivate + 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 final fun test1(): PrivateInFileClass.NestedPrivate + public final fun test2(/*0*/ p: PrivateInFileClass.NestedPrivate): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + public final fun PrivateInFileClass.NestedPrivate.test3(): kotlin.Unit + + private open class NestedPrivate { + public constructor NestedPrivate() + 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 + } + + public final class Test5 : PrivateInFileClass.NestedPrivate { + public constructor Test5() + 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 + } +} + +public final class Public { + public constructor Public() + public final val test4: Public.NestedPrivate + 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 final fun test1(): Public.NestedPrivate + public final fun test2(/*0*/ p: Public.NestedPrivate): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + public final fun Public.NestedPrivate.test3(): kotlin.Unit + + private open class NestedPrivate { + public constructor NestedPrivate() + 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 + } + + public final class Test5 : Public.NestedPrivate { + public constructor Test5() + 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/imports/PrivateClassReferencedError.kt b/compiler/testData/diagnostics/tests/imports/PrivateClassReferencedError.kt index 9be9ddb70ef..64877e3ae21 100644 --- a/compiler/testData/diagnostics/tests/imports/PrivateClassReferencedError.kt +++ b/compiler/testData/diagnostics/tests/imports/PrivateClassReferencedError.kt @@ -11,4 +11,4 @@ package a import pack1.SomeClass.* -private class X : N() +private class X : N() diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index b346fa6b536..f6b81daddb0 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -9281,6 +9281,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/exposed/privateFromLocal.kt"); } + @Test + @TestMetadata("privateInFile.kt") + public void testPrivateInFile() throws Exception { + runTest("compiler/testData/diagnostics/tests/exposed/privateInFile.kt"); + } + @Test @TestMetadata("privatePropertyInPrivateConstructor.kt") public void testPrivatePropertyInPrivateConstructor() throws Exception { diff --git a/core/compiler.common/src/org/jetbrains/kotlin/descriptors/EffectiveVisibility.kt b/core/compiler.common/src/org/jetbrains/kotlin/descriptors/EffectiveVisibility.kt index c04a568c733..f80962a2685 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/descriptors/EffectiveVisibility.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/descriptors/EffectiveVisibility.kt @@ -24,6 +24,8 @@ sealed class EffectiveVisibility(val name: String, val publicApi: Boolean = fals // \ / /InternalProtected(Derived) // \InternalProtectedBound/ // | + // PrivateInFile + // | // Private = Local @@ -42,6 +44,17 @@ sealed class EffectiveVisibility(val name: String, val publicApi: Boolean = fals override fun toVisibility(): Visibility = Visibilities.Local } + object PrivateInFile : EffectiveVisibility("private-in-file", privateApi = true) { + override fun relation(other: EffectiveVisibility, typeCheckerContextProvider: TypeCheckerProviderContext): Permissiveness = + when (other) { + this -> Permissiveness.SAME + Private, Local -> Permissiveness.MORE + else -> Permissiveness.LESS + } + + override fun toVisibility(): Visibility = Visibilities.Private + } + object Public : EffectiveVisibility("public", publicApi = true) { override fun relation(other: EffectiveVisibility, typeCheckerContextProvider: TypeCheckerProviderContext): Permissiveness = if (this == other) Permissiveness.SAME else Permissiveness.MORE @@ -55,7 +68,7 @@ sealed class EffectiveVisibility(val name: String, val publicApi: Boolean = fals override fun relation(other: EffectiveVisibility, typeCheckerContextProvider: TypeCheckerProviderContext): Permissiveness = when (other) { Public -> Permissiveness.LESS - Private, Local, InternalProtectedBound, is InternalProtected -> Permissiveness.MORE + Private, PrivateInFile, Local, InternalProtectedBound, is InternalProtected -> Permissiveness.MORE is InternalOrPackage -> Permissiveness.SAME ProtectedBound, is Protected -> Permissiveness.UNKNOWN } @@ -63,7 +76,7 @@ sealed class EffectiveVisibility(val name: String, val publicApi: Boolean = fals override fun lowerBound(other: EffectiveVisibility, typeCheckerContextProvider: TypeCheckerProviderContext): EffectiveVisibility = when (other) { Public -> this - Private, Local, InternalProtectedBound, is InternalOrPackage, is InternalProtected -> other + Private, PrivateInFile, Local, InternalProtectedBound, is InternalOrPackage, is InternalProtected -> other is Protected -> InternalProtected(other.containerTypeConstructor) ProtectedBound -> InternalProtectedBound } @@ -88,7 +101,7 @@ sealed class EffectiveVisibility(val name: String, val publicApi: Boolean = fals override fun relation(other: EffectiveVisibility, typeCheckerContextProvider: TypeCheckerProviderContext): Permissiveness = when (other) { Public -> Permissiveness.LESS - Private, Local, ProtectedBound, InternalProtectedBound -> Permissiveness.MORE + Private, PrivateInFile, Local, ProtectedBound, InternalProtectedBound -> Permissiveness.MORE is Protected -> containerRelation(containerTypeConstructor, other.containerTypeConstructor, typeCheckerContextProvider) is InternalProtected -> when (containerRelation( containerTypeConstructor, @@ -105,7 +118,7 @@ sealed class EffectiveVisibility(val name: String, val publicApi: Boolean = fals override fun lowerBound(other: EffectiveVisibility, typeCheckerContextProvider: TypeCheckerProviderContext): EffectiveVisibility = when (other) { Public -> this - Private, Local, ProtectedBound, InternalProtectedBound -> other + Private, PrivateInFile, Local, ProtectedBound, InternalProtectedBound -> other is Protected -> when (relation(other, typeCheckerContextProvider)) { Permissiveness.SAME, Permissiveness.MORE -> this Permissiveness.LESS -> other @@ -126,7 +139,7 @@ sealed class EffectiveVisibility(val name: String, val publicApi: Boolean = fals override fun relation(other: EffectiveVisibility, typeCheckerContextProvider: TypeCheckerProviderContext): Permissiveness = when (other) { Public, is Protected -> Permissiveness.LESS - Private, Local, InternalProtectedBound -> Permissiveness.MORE + Private, PrivateInFile, Local, InternalProtectedBound -> Permissiveness.MORE ProtectedBound -> Permissiveness.SAME is InternalOrPackage, is InternalProtected -> Permissiveness.UNKNOWN } @@ -134,7 +147,7 @@ sealed class EffectiveVisibility(val name: String, val publicApi: Boolean = fals override fun lowerBound(other: EffectiveVisibility, typeCheckerContextProvider: TypeCheckerProviderContext): EffectiveVisibility = when (other) { Public, is Protected -> this - Private, Local, ProtectedBound, InternalProtectedBound -> other + Private, PrivateInFile, Local, ProtectedBound, InternalProtectedBound -> other is InternalOrPackage, is InternalProtected -> InternalProtectedBound } @@ -155,7 +168,7 @@ sealed class EffectiveVisibility(val name: String, val publicApi: Boolean = fals override fun relation(other: EffectiveVisibility, typeCheckerContextProvider: TypeCheckerProviderContext): Permissiveness = when (other) { Public, is InternalOrPackage -> Permissiveness.LESS - Private, Local, InternalProtectedBound -> Permissiveness.MORE + Private, PrivateInFile, Local, InternalProtectedBound -> Permissiveness.MORE is InternalProtected -> containerRelation( containerTypeConstructor, other.containerTypeConstructor, @@ -176,7 +189,7 @@ sealed class EffectiveVisibility(val name: String, val publicApi: Boolean = fals override fun lowerBound(other: EffectiveVisibility, typeCheckerContextProvider: TypeCheckerProviderContext): EffectiveVisibility = when (other) { Public, is InternalOrPackage -> this - Private, Local, InternalProtectedBound -> other + Private, PrivateInFile, Local, InternalProtectedBound -> other is Protected, is InternalProtected -> when (relation(other, typeCheckerContextProvider)) { Permissiveness.SAME, Permissiveness.MORE -> this Permissiveness.LESS -> other @@ -193,7 +206,7 @@ sealed class EffectiveVisibility(val name: String, val publicApi: Boolean = fals override fun relation(other: EffectiveVisibility, typeCheckerContextProvider: TypeCheckerProviderContext): Permissiveness = when (other) { Public, is Protected, is InternalProtected, ProtectedBound, is InternalOrPackage -> Permissiveness.LESS - Private, Local -> Permissiveness.MORE + Private, PrivateInFile, Local -> Permissiveness.MORE InternalProtectedBound -> Permissiveness.SAME } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibilityUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibilityUtils.kt index 02679625181..d7ea0853275 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibilityUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/EffectiveVisibilityUtils.kt @@ -20,7 +20,10 @@ fun DescriptorVisibility.effectiveVisibility( private fun DescriptorVisibility.forVisibility(descriptor: DeclarationDescriptor, checkPublishedApi: Boolean = false): EffectiveVisibility = when (this) { - DescriptorVisibilities.PRIVATE, DescriptorVisibilities.PRIVATE_TO_THIS, DescriptorVisibilities.INVISIBLE_FAKE -> EffectiveVisibility.Private + DescriptorVisibilities.PRIVATE_TO_THIS, DescriptorVisibilities.INVISIBLE_FAKE -> EffectiveVisibility.Private + DescriptorVisibilities.PRIVATE -> if (descriptor is ClassDescriptor && + descriptor.containingDeclaration is PackageFragmentDescriptor + ) EffectiveVisibility.PrivateInFile else EffectiveVisibility.Private DescriptorVisibilities.PROTECTED -> EffectiveVisibility.Protected( (descriptor.containingDeclaration as? ClassDescriptor)?.defaultType?.constructor ) diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/MemberVisibilityCanBePrivateInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/MemberVisibilityCanBePrivateInspection.kt index d4f19abead3..034c4ad8e6d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/MemberVisibilityCanBePrivateInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/MemberVisibilityCanBePrivateInspection.kt @@ -86,7 +86,7 @@ class MemberVisibilityCanBePrivateInspection : AbstractKotlinInspection() { val descriptor = (declaration.toDescriptor() as? DeclarationDescriptorWithVisibility) ?: return false when (descriptor.effectiveVisibility()) { - EffectiveVisibility.Private, EffectiveVisibility.Local -> return false + EffectiveVisibility.Private, EffectiveVisibility.PrivateInFile, EffectiveVisibility.Local -> return false } val entryPointsManager = EntryPointsManager.getInstance(declaration.project) as EntryPointsManagerBase diff --git a/idea/testData/checker/ExposedInferredType.kt b/idea/testData/checker/ExposedInferredType.kt index b331234ed08..6c5e12646ee 100644 --- a/idea/testData/checker/ExposedInferredType.kt +++ b/idea/testData/checker/ExposedInferredType.kt @@ -2,18 +2,18 @@ private class A open class B(val x: T) -class C(x: A): B(x) +class C(x: A): B(x) private class D { class E } -fun create() = A() +fun create() = A() -fun create(a: A) = B(a) +fun create(a: A) = B(a) -val x = create() +val x = create() -val y = create(x) +val y = create(x) -val z: B? = null +val z: B? = null diff --git a/jps-plugin/testData/incremental/classHierarchyAffected/classBecamePrivate/build.log b/jps-plugin/testData/incremental/classHierarchyAffected/classBecamePrivate/build.log index 0831b069e1d..0ce14b0effb 100644 --- a/jps-plugin/testData/incremental/classHierarchyAffected/classBecamePrivate/build.log +++ b/jps-plugin/testData/incremental/classHierarchyAffected/classBecamePrivate/build.log @@ -53,22 +53,22 @@ Exit code: ABORT ------------------------------------------ COMPILATION FAILED Cannot access 'A': it is private in file -'public' subclass exposes its 'private' supertype A -'public' generic exposes its 'private' parameter bound type A +'public' subclass exposes its 'private-in-file' supertype A +'public' generic exposes its 'private-in-file' parameter bound type A Cannot access 'A': it is private in file Cannot access 'A': it is private in file -'public' function exposes its 'private' parameter type A +'public' function exposes its 'private-in-file' parameter type A Cannot access 'A': it is private in file Cannot access 'A': it is private in file -'public' function exposes its 'private' return type A +'public' function exposes its 'private-in-file' return type A Cannot access 'A': it is private in file Cannot access 'A': it is private in file Cannot access 'A': it is private in file Cannot access 'A': it is private in file -'public' function exposes its 'private' return type A +'public' function exposes its 'private-in-file' return type A Cannot access 'A': it is private in file Cannot access 'A': it is private in file -'public' function exposes its 'private' return type A +'public' function exposes its 'private-in-file' return type A ================ Step #2 ================= diff --git a/jps-plugin/testData/incremental/classHierarchyAffected/flagsAndMemberInSameClassChanged/build.log b/jps-plugin/testData/incremental/classHierarchyAffected/flagsAndMemberInSameClassChanged/build.log index 7a8cb0584da..354e1d4a717 100644 --- a/jps-plugin/testData/incremental/classHierarchyAffected/flagsAndMemberInSameClassChanged/build.log +++ b/jps-plugin/testData/incremental/classHierarchyAffected/flagsAndMemberInSameClassChanged/build.log @@ -35,8 +35,8 @@ Exit code: ABORT ------------------------------------------ COMPILATION FAILED Cannot access 'A': it is private in file -'public' subclass exposes its 'private' supertype A -'public' function exposes its 'private' return type A +'public' subclass exposes its 'private-in-file' supertype A +'public' function exposes its 'private-in-file' return type A Cannot access 'A': it is private in file Cannot access 'A': it is private in file Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type Any? diff --git a/jps-plugin/testData/incremental/multiModule/common/exportedDependency/build.log b/jps-plugin/testData/incremental/multiModule/common/exportedDependency/build.log index f829e13b976..6f49ab1fbd3 100644 --- a/jps-plugin/testData/incremental/multiModule/common/exportedDependency/build.log +++ b/jps-plugin/testData/incremental/multiModule/common/exportedDependency/build.log @@ -29,7 +29,7 @@ Exit code: ABORT ------------------------------------------ COMPILATION FAILED Cannot access 'A': it is private in file -'public' subclass exposes its 'private' supertype A +'public' subclass exposes its 'private-in-file' supertype A ================ Step #2 ================= diff --git a/jps-plugin/testData/incremental/multiModule/common/exportedDependency/js-jps-build.log b/jps-plugin/testData/incremental/multiModule/common/exportedDependency/js-jps-build.log index 816dfac52a2..8bdfe131699 100644 --- a/jps-plugin/testData/incremental/multiModule/common/exportedDependency/js-jps-build.log +++ b/jps-plugin/testData/incremental/multiModule/common/exportedDependency/js-jps-build.log @@ -31,7 +31,7 @@ Exit code: ABORT ------------------------------------------ COMPILATION FAILED Cannot access 'A': it is private in file -'public' subclass exposes its 'private' supertype A +'public' subclass exposes its 'private-in-file' supertype A ================ Step #2 ================= diff --git a/jps-plugin/testData/incremental/multiModule/common/simple/build.log b/jps-plugin/testData/incremental/multiModule/common/simple/build.log index a28b1b225ab..fe9147abedf 100644 --- a/jps-plugin/testData/incremental/multiModule/common/simple/build.log +++ b/jps-plugin/testData/incremental/multiModule/common/simple/build.log @@ -29,7 +29,7 @@ Exit code: ABORT ------------------------------------------ COMPILATION FAILED Cannot access 'A': it is private in file -'public' subclass exposes its 'private' supertype A +'public' subclass exposes its 'private-in-file' supertype A Cannot access 'A': it is private in file ================ Step #2 ================= diff --git a/jps-plugin/testData/incremental/multiModule/common/simple/js-jps-build.log b/jps-plugin/testData/incremental/multiModule/common/simple/js-jps-build.log index a2a9f9051e7..0fbb2d98f96 100644 --- a/jps-plugin/testData/incremental/multiModule/common/simple/js-jps-build.log +++ b/jps-plugin/testData/incremental/multiModule/common/simple/js-jps-build.log @@ -31,7 +31,7 @@ Exit code: ABORT ------------------------------------------ COMPILATION FAILED Cannot access 'A': it is private in file -'public' subclass exposes its 'private' supertype A +'public' subclass exposes its 'private-in-file' supertype A Cannot access 'A': it is private in file ================ Step #2 =================