diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt index 420d3863fed..02976f25a44 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt @@ -13,6 +13,8 @@ import org.jetbrains.kotlin.backend.jvm.lower.hasAssertionsDisabledField import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.inline.* import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.config.LanguageVersionSettings +import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.DescriptorVisibility import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.builders.declarations.buildFun @@ -260,7 +262,7 @@ abstract class ClassCodegen protected constructor( if (field.origin == IrDeclarationOrigin.PROPERTY_DELEGATE) null else context.methodSignatureMapper.mapFieldSignature(field) val fieldName = field.name.asString() - val flags = field.flags + val flags = field.computeFieldFlags(state.languageVersionSettings) val fv = visitor.newField( field.OtherOrigin, flags, fieldName, fieldType.descriptor, fieldSignature, (field.initializer?.expression as? IrConst<*>)?.value @@ -400,15 +402,23 @@ private val IrClass.flags: Int else -> Opcodes.ACC_SUPER or modality.flags } -private val IrField.flags: Int - get() = origin.flags or visibility.flags or +private fun IrField.computeFieldFlags(languageVersionSettings: LanguageVersionSettings): Int = + origin.flags or visibility.flags or this.specialDeprecationFlag or (correspondingPropertySymbol?.owner?.deprecationFlags ?: 0) or (if (annotations.hasAnnotation(KOTLIN_DEPRECATED)) Opcodes.ACC_DEPRECATED else 0) or (if (isFinal) Opcodes.ACC_FINAL else 0) or (if (isStatic) Opcodes.ACC_STATIC else 0) or (if (hasAnnotation(VOLATILE_ANNOTATION_FQ_NAME)) Opcodes.ACC_VOLATILE else 0) or (if (hasAnnotation(TRANSIENT_ANNOTATION_FQ_NAME)) Opcodes.ACC_TRANSIENT else 0) or - (if (hasAnnotation(JVM_SYNTHETIC_ANNOTATION_FQ_NAME)) Opcodes.ACC_SYNTHETIC else 0) + (if (hasAnnotation(JVM_SYNTHETIC_ANNOTATION_FQ_NAME) || + isPrivateCompanionFieldInInterface(languageVersionSettings) + ) Opcodes.ACC_SYNTHETIC else 0) + +private fun IrField.isPrivateCompanionFieldInInterface(languageVersionSettings: LanguageVersionSettings): Boolean = + origin == IrDeclarationOrigin.FIELD_FOR_OBJECT_INSTANCE && + languageVersionSettings.supportsFeature(LanguageFeature.ProperVisibilityForCompanionObjectInstanceField) && + parentAsClass.isJvmInterface && + DescriptorVisibilities.isPrivate(parentAsClass.companionObject()!!.visibility) private val IrField.specialDeprecationFlag: Int get() = if (shouldHaveSpecialDeprecationFlag()) Opcodes.ACC_DEPRECATED else 0 diff --git a/compiler/testData/codegen/bytecodeListing/companionObjectVisibility_after.kt b/compiler/testData/codegen/bytecodeListing/companionObjectVisibility_after.kt index 1f3c1e13f78..8b59362762c 100644 --- a/compiler/testData/codegen/bytecodeListing/companionObjectVisibility_after.kt +++ b/compiler/testData/codegen/bytecodeListing/companionObjectVisibility_after.kt @@ -1,5 +1,4 @@ // !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField -// IGNORE_BACKEND: JVM_IR open class TestProtectedCompanionInClass { protected companion object @@ -15,4 +14,4 @@ class TestPrivateCompanionInClass { interface TestPrivateCompanionInInterface { private companion object -} \ No newline at end of file +} diff --git a/compiler/testData/codegen/bytecodeListing/companionObjectVisibility_after_ir.txt b/compiler/testData/codegen/bytecodeListing/companionObjectVisibility_after_ir.txt new file mode 100644 index 00000000000..f83d7ffed9d --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/companionObjectVisibility_after_ir.txt @@ -0,0 +1,67 @@ +@kotlin.Metadata +public final class TestInternalCompanionInClass$Companion { + // source: 'companionObjectVisibility_after.kt' + private method (): void + public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void + public final inner class TestInternalCompanionInClass$Companion +} + +@kotlin.Metadata +public final class TestInternalCompanionInClass { + // source: 'companionObjectVisibility_after.kt' + public final static @org.jetbrains.annotations.NotNull field Companion: TestInternalCompanionInClass$Companion + static method (): void + public method (): void + public final inner class TestInternalCompanionInClass$Companion +} + +@kotlin.Metadata +final class TestPrivateCompanionInClass$Companion { + // source: 'companionObjectVisibility_after.kt' + private method (): void + public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void + private final inner class TestPrivateCompanionInClass$Companion +} + +@kotlin.Metadata +public final class TestPrivateCompanionInClass { + // source: 'companionObjectVisibility_after.kt' + private final static @org.jetbrains.annotations.NotNull field Companion: TestPrivateCompanionInClass$Companion + static method (): void + public method (): void + private final inner class TestPrivateCompanionInClass$Companion +} + +@kotlin.Metadata +final class TestPrivateCompanionInInterface$Companion { + // source: 'companionObjectVisibility_after.kt' + synthetic final static field $$INSTANCE: TestPrivateCompanionInInterface$Companion + static method (): void + private method (): void + public final inner class TestPrivateCompanionInInterface$Companion +} + +@kotlin.Metadata +public interface TestPrivateCompanionInInterface { + // source: 'companionObjectVisibility_after.kt' + public synthetic final static field Companion: TestPrivateCompanionInInterface$Companion + static method (): void + public final inner class TestPrivateCompanionInInterface$Companion +} + +@kotlin.Metadata +public final class TestProtectedCompanionInClass$Companion { + // source: 'companionObjectVisibility_after.kt' + private method (): void + public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void + protected final inner class TestProtectedCompanionInClass$Companion +} + +@kotlin.Metadata +public class TestProtectedCompanionInClass { + // source: 'companionObjectVisibility_after.kt' + protected final static @org.jetbrains.annotations.NotNull field Companion: TestProtectedCompanionInClass$Companion + static method (): void + public method (): void + protected final inner class TestProtectedCompanionInClass$Companion +}