diff --git a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/serializationUtil.kt b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/serializationUtil.kt index 1a38e4cc33d..139db951ac4 100644 --- a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/serializationUtil.kt +++ b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/serializationUtil.kt @@ -6,12 +6,10 @@ package org.jetbrains.kotlin.fir.serialization import org.jetbrains.kotlin.builtins.functions.FunctionTypeKind +import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.FirAnnotationContainer import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.declarations.FirClass -import org.jetbrains.kotlin.fir.declarations.FirDeclaration -import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration -import org.jetbrains.kotlin.fir.declarations.nonSourceAnnotations +import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.isExpect import org.jetbrains.kotlin.fir.declarations.utils.isInterface import org.jetbrains.kotlin.fir.declarations.utils.visibility @@ -60,9 +58,11 @@ fun FirMemberDeclaration.isNotExpectOrShouldBeSerialized(actualizedExpectDeclara } fun FirMemberDeclaration.isNotPrivateOrShouldBeSerialized(produceHeaderKlib: Boolean): Boolean { - return !produceHeaderKlib || visibility.isPublicAPI + return !produceHeaderKlib || visibility.isPublicAPI || visibility == Visibilities.Internal // Always keep private interfaces as they can be part of public type hierarchies. - || (this as? FirClass)?.isInterface == true + // We also keep private type aliases as they leak into public signatures (KT-17229). + // TODO: stop preserving private type aliases once KT-17229 is fixed. + || (this as? FirClass)?.isInterface == true || this is FirTypeAlias } fun < diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt index 36a1ca221fc..8e04e028f13 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.serialization.encodings.* import org.jetbrains.kotlin.backend.common.serialization.proto.IrSimpleTypeNullability import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.DescriptorVisibilities.INTERNAL import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrFileEntry import org.jetbrains.kotlin.ir.declarations.* @@ -1107,9 +1108,9 @@ open class IrFileSerializer( .setBase(serializeIrDeclarationBase(property, PropertyFlags.encode(property))) .setName(serializeName(property.name)) - property.backingField?.let { proto.backingField = serializeIrField(it) } - property.getter?.let { proto.getter = serializeIrFunction(it) } - property.setter?.let { proto.setter = serializeIrFunction(it) } + property.backingField?.takeUnless { skipIfPrivate(it) }?.let { proto.backingField = serializeIrField(it) } + property.getter?.takeUnless { skipIfPrivate(it) }?.let { proto.getter = serializeIrFunction(it) } + property.setter?.takeUnless { skipIfPrivate(it) }?.let { proto.setter = serializeIrFunction(it) } return proto.build() } @@ -1269,9 +1270,9 @@ open class IrFileSerializer( open fun backendSpecificMetadata(irFile: IrFile): FileBackendSpecificMetadata? = null private fun skipIfPrivate(declaration: IrDeclaration) = - skipPrivateApi && (declaration as? IrDeclarationWithVisibility)?.visibility?.isPublicAPI != true - // Always keep private interfaces as they can be part of public type hierarchies. - && (declaration as? IrClass)?.isInterface != true + skipPrivateApi && (declaration as? IrDeclarationWithVisibility)?.let { !it.visibility.isPublicAPI && it.visibility != INTERNAL } == true + // Always keep private interfaces and type aliases as they can be part of public type hierarchies. + && (declaration as? IrClass)?.isInterface != true && declaration !is IrTypeAlias open fun memberNeedsSerialization(member: IrDeclaration): Boolean { val parent = member.parent diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataSerializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataSerializer.kt index 749dd19aaa6..161cc18afb7 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataSerializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataSerializer.kt @@ -113,9 +113,10 @@ abstract class KlibMetadataSerializer( private fun Sequence.filterPrivate(): Sequence = if (produceHeaderKlib) { - // We keep all interfaces since publicly accessible classes can inherit from private interfaces. this.filter { - it is ClassDescriptor && it.kind.isInterface || it is DeclarationDescriptorWithVisibility && it.effectiveVisibility().publicApi + val isPublicOrInternal = it is DeclarationDescriptorWithVisibility + && (it.visibility.isPublicAPI || it.visibility.delegate == Visibilities.Internal) + it is ClassDescriptor && it.kind.isInterface || isPublicOrInternal } } else this diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataSerializerExtension.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataSerializerExtension.kt index e18deff283d..96172fb4a5c 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataSerializerExtension.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataSerializerExtension.kt @@ -42,7 +42,7 @@ class KlibMetadataSerializerExtension( DescriptorUtils.getAllDescriptors(classDescriptor.defaultType.memberScope) .filterIsInstance() .filter { it.kind != CallableMemberDescriptor.Kind.FAKE_OVERRIDE } - .filter { it.visibility.isPublicAPI || classDescriptor.isInlineClass() } + .filter { it.visibility.isPublicAPI || it.visibility.delegate == Visibilities.Internal || classDescriptor.isInlineClass() } ) } else super.customClassMembersProducer diff --git a/native/native.tests/testData/klib/header-klibs/comparison/classPrivateMembers/sameAbi/A.kt b/native/native.tests/testData/klib/header-klibs/comparison/classPrivateMembers/sameAbi/A.kt index 8cadf0f42fe..47a87928f80 100644 --- a/native/native.tests/testData/klib/header-klibs/comparison/classPrivateMembers/sameAbi/A.kt +++ b/native/native.tests/testData/klib/header-klibs/comparison/classPrivateMembers/sameAbi/A.kt @@ -4,8 +4,8 @@ class A { val publicVal = 0 fun publicMethod() = 0 - internal val internalVal = 42 - internal fun internalMethod() = 42 + internal val internalVal = 0 + internal fun internalMethod() = 0 protected val protectedVal = 0 protected fun protectedMethod() = 0 diff --git a/native/native.tests/testData/klib/header-klibs/comparison/privateInterface/base/test.kt b/native/native.tests/testData/klib/header-klibs/comparison/privateInterface/base/test.kt index 6398d40d5ce..2e34ba3efb7 100644 --- a/native/native.tests/testData/klib/header-klibs/comparison/privateInterface/base/test.kt +++ b/native/native.tests/testData/klib/header-klibs/comparison/privateInterface/base/test.kt @@ -1,7 +1,7 @@ package test private interface A { - fun foo() = 0 + fun foo(): Int { if (true) return 1 else return 0 } fun bar(): String } diff --git a/native/native.tests/testData/klib/header-klibs/comparison/privateInterface/sameAbi/test.kt b/native/native.tests/testData/klib/header-klibs/comparison/privateInterface/sameAbi/test.kt index ffde83123f6..a2bf4b5959e 100644 --- a/native/native.tests/testData/klib/header-klibs/comparison/privateInterface/sameAbi/test.kt +++ b/native/native.tests/testData/klib/header-klibs/comparison/privateInterface/sameAbi/test.kt @@ -1,7 +1,7 @@ package test private interface A { - fun foo() = 42 + fun foo(): Int { if (true) return 0 else return 1 } fun bar(): String } diff --git a/native/native.tests/testData/klib/header-klibs/comparison/privateTypealias/sameAbi/typealiases.kt b/native/native.tests/testData/klib/header-klibs/comparison/privateTypealias/differentAbi/typealiases.kt similarity index 100% rename from native/native.tests/testData/klib/header-klibs/comparison/privateTypealias/sameAbi/typealiases.kt rename to native/native.tests/testData/klib/header-klibs/comparison/privateTypealias/differentAbi/typealiases.kt diff --git a/native/native.tests/testData/klib/header-klibs/comparison/syntheticAccessors/base/test.kt b/native/native.tests/testData/klib/header-klibs/comparison/syntheticAccessors/base/test.kt index 7f35cefcfbd..02de7df8c6e 100644 --- a/native/native.tests/testData/klib/header-klibs/comparison/syntheticAccessors/base/test.kt +++ b/native/native.tests/testData/klib/header-klibs/comparison/syntheticAccessors/base/test.kt @@ -4,4 +4,4 @@ private val x = 1 object A { fun f() = x } -val y = 2 +val y = (0..20).random() diff --git a/native/native.tests/testData/klib/header-klibs/comparison/syntheticAccessors/sameAbi/test.kt b/native/native.tests/testData/klib/header-klibs/comparison/syntheticAccessors/sameAbi/test.kt index f7917a1690c..6c0fc80611f 100644 --- a/native/native.tests/testData/klib/header-klibs/comparison/syntheticAccessors/sameAbi/test.kt +++ b/native/native.tests/testData/klib/header-klibs/comparison/syntheticAccessors/sameAbi/test.kt @@ -2,4 +2,4 @@ package test object A { fun f() = 1 } -val y = 2 +val y = (30..50).random() diff --git a/native/native.tests/testData/klib/header-klibs/comparison/topLevelPrivateMembers/base/utils.kt b/native/native.tests/testData/klib/header-klibs/comparison/topLevelPrivateMembers/base/utils.kt index 9a80bf38e00..97ab05b1944 100644 --- a/native/native.tests/testData/klib/header-klibs/comparison/topLevelPrivateMembers/base/utils.kt +++ b/native/native.tests/testData/klib/header-klibs/comparison/topLevelPrivateMembers/base/utils.kt @@ -1,12 +1,7 @@ package test -val publicVal = 0 -const val publicConst = 0 -fun publicFun() = 0 - -internal val internalVal = 0 -internal const val internalConst = 0 -internal fun internalFun() = 0 +val publicVal = (0..10).random() +fun publicFun() = (0..10).random() private val privateVal = 0 private const val privateConst = 0 diff --git a/native/native.tests/testData/klib/header-klibs/comparison/topLevelPrivateMembers/sameAbi/utils.kt b/native/native.tests/testData/klib/header-klibs/comparison/topLevelPrivateMembers/sameAbi/utils.kt index 323c16dee50..6ee5f8c00a1 100644 --- a/native/native.tests/testData/klib/header-klibs/comparison/topLevelPrivateMembers/sameAbi/utils.kt +++ b/native/native.tests/testData/klib/header-klibs/comparison/topLevelPrivateMembers/sameAbi/utils.kt @@ -1,9 +1,4 @@ package test -val publicVal = 0 -const val publicConst = 0 -fun publicFun() = 0 - -internal val internalVal = 0 -internal const val internalConst = 0 -internal fun internalFun() = 0 \ No newline at end of file +val publicVal = (0..20).random() +fun publicFun() = (0..20).random() \ No newline at end of file