diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt index d73431b1af5..bdf0ab39f65 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt @@ -69,7 +69,7 @@ class JvmBackendContext( val typeMapper = IrTypeMapper(this) val methodSignatureMapper = MethodSignatureMapper(this) - override val declarationFactory: JvmDeclarationFactory = JvmDeclarationFactory(methodSignatureMapper) + override val declarationFactory: JvmDeclarationFactory = JvmDeclarationFactory(methodSignatureMapper, state.languageVersionSettings) override val sharedVariablesManager = JvmSharedVariablesManager(state.module, builtIns, irBuiltIns) override val mapping: Mapping = DefaultMapping() diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt index 12a5f406733..76a6984a606 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt @@ -13,6 +13,8 @@ import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface import org.jetbrains.kotlin.backend.jvm.ir.replaceThisByStaticReference import org.jetbrains.kotlin.builtins.CompanionObjectMapping.isMappedIntrinsicCompanionObject import org.jetbrains.kotlin.codegen.AsmUtil +import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities @@ -33,7 +35,8 @@ import org.jetbrains.kotlin.name.Name import java.util.* class JvmDeclarationFactory( - private val methodSignatureMapper: MethodSignatureMapper + private val methodSignatureMapper: MethodSignatureMapper, + private val languageVersionSettings: LanguageVersionSettings ) : DeclarationFactory { private val singletonFieldDeclarations = HashMap() private val interfaceCompanionFieldDeclarations = HashMap() @@ -137,12 +140,21 @@ class JvmDeclarationFactory( override fun getFieldForObjectInstance(singleton: IrClass): IrField = singletonFieldDeclarations.getOrPut(singleton) { val isNotMappedCompanion = singleton.isCompanion && !isMappedIntrinsicCompanionObject(singleton.descriptor) + val useProperVisibilityForCompanion = + languageVersionSettings.supportsFeature(LanguageFeature.ProperVisibilityForCompanionObjectInstanceField) + && singleton.isCompanion + && !singleton.parentAsClass.isInterface buildField { name = if (isNotMappedCompanion) singleton.name else Name.identifier(JvmAbi.INSTANCE_FIELD) type = singleton.defaultType origin = IrDeclarationOrigin.FIELD_FOR_OBJECT_INSTANCE isFinal = true isStatic = true + visibility = when { + !useProperVisibilityForCompanion -> Visibilities.PUBLIC + singleton.visibility == Visibilities.PROTECTED -> JavaVisibilities.PROTECTED_STATIC_VISIBILITY + else -> singleton.visibility + } }.apply { parent = if (isNotMappedCompanion) singleton.parent else singleton } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt index 3839711d258..b71ca55c12a 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt @@ -38,6 +38,7 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.load.java.JavaVisibilities import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.synthetic.isVisibleOutside import org.jetbrains.kotlin.utils.addToStdlib.safeAs internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrElementTransformerVoidWithContext(), FileLoweringPass { @@ -48,7 +49,12 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle override fun lower(irFile: IrFile) { irFile.accept(object : IrInlineReferenceLocator(context) { - override fun visitInlineLambda(argument: IrFunctionReference, callee: IrFunction, parameter: IrValueParameter, scope: IrDeclaration) { + override fun visitInlineLambda( + argument: IrFunctionReference, + callee: IrFunction, + parameter: IrValueParameter, + scope: IrDeclaration + ) { inlineLambdaToCallSite[argument.symbol.owner] = LambdaCallSite(scope, parameter.isCrossinline) } }, null) @@ -167,7 +173,11 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle private fun IrDeclarationWithVisibility.accessorParent(parent: IrDeclarationParent = this.parent) = if (visibility == JavaVisibilities.PROTECTED_STATIC_VISIBILITY) { val classes = allScopes.map { it.irElement }.filterIsInstance() - classes.lastOrNull { parent is IrClass && it.isSubclassOf(parent) } ?: classes.last() + val companions = classes.mapNotNull { it.companionObject() }.filterIsInstance() + val objectsInScope = + classes.flatMap { it.declarations.filter(IrDeclaration::isAnonymousObject).filterIsInstance() } + val candidates = objectsInScope + companions + classes + candidates.lastOrNull { parent is IrClass && it.isSubclassOf(parent) } ?: classes.last() } else parent private fun IrConstructor.makeConstructorAccessor(): IrConstructorImpl { @@ -185,7 +195,9 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle accessor.returnType = source.returnType.remapTypeParameters(source, accessor) accessor.addValueParameter( - "constructor_marker".synthesizedString, context.ir.symbols.defaultConstructorMarker.defaultType, JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR + "constructor_marker".synthesizedString, + context.ir.symbols.defaultConstructorMarker.defaultType, + JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR ) accessor.body = IrExpressionBodyImpl( diff --git a/compiler/testData/codegen/bytecodeText/companion/privateCompanionObjectAccessors_after.kt b/compiler/testData/codegen/bytecodeText/companion/privateCompanionObjectAccessors_after.kt index 30e598bcc60..af71ced7add 100644 --- a/compiler/testData/codegen/bytecodeText/companion/privateCompanionObjectAccessors_after.kt +++ b/compiler/testData/codegen/bytecodeText/companion/privateCompanionObjectAccessors_after.kt @@ -1,6 +1,4 @@ // !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField -// IGNORE_BACKEND: JVM_IR -// ^ TODO implement ProperVisibilityForCompanionObjectInstanceField feature support in JMV_IR class Host { private companion object { diff --git a/compiler/testData/codegen/bytecodeText/companion/protectedCompanionObjectAccessors_after.kt b/compiler/testData/codegen/bytecodeText/companion/protectedCompanionObjectAccessors_after.kt index e18162f5f56..f184e28d40f 100644 --- a/compiler/testData/codegen/bytecodeText/companion/protectedCompanionObjectAccessors_after.kt +++ b/compiler/testData/codegen/bytecodeText/companion/protectedCompanionObjectAccessors_after.kt @@ -1,6 +1,4 @@ // !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField -// IGNORE_BACKEND: JVM_IR -// ^ TODO implement ProperVisibilityForCompanionObjectInstanceField feature support in JMV_IR // FILE: Base.kt package a diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index cb4568ba59a..3d8f81ddae8 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -6670,6 +6670,7 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/featureIntersection/inlineSuspendFinally.kt", "kotlin.coroutines"); } + @TestMetadata("interfaceMethodWithBody.kt") public void testInterfaceMethodWithBody() throws Exception { runTest("compiler/testData/codegen/box/coroutines/featureIntersection/interfaceMethodWithBody.kt");