[JVM IR] ProperVisibilityForCompanionObjectInstanceField
- Uncomment tests
- Add proper visibility to companion field
+ Make exception for interfaces -> they need to respect language versions 1.8
before they can put private members there.
- Adjust synthetic accessor lowering to look for enclosing classes with access
via companion object.
This commit is contained in:
committed by
Dmitry Petrov
parent
a67d97bdf8
commit
f782ea075b
@@ -69,7 +69,7 @@ class JvmBackendContext(
|
|||||||
val typeMapper = IrTypeMapper(this)
|
val typeMapper = IrTypeMapper(this)
|
||||||
val methodSignatureMapper = MethodSignatureMapper(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 sharedVariablesManager = JvmSharedVariablesManager(state.module, builtIns, irBuiltIns)
|
||||||
|
|
||||||
override val mapping: Mapping = DefaultMapping()
|
override val mapping: Mapping = DefaultMapping()
|
||||||
|
|||||||
+13
-1
@@ -13,6 +13,8 @@ import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
|||||||
import org.jetbrains.kotlin.backend.jvm.ir.replaceThisByStaticReference
|
import org.jetbrains.kotlin.backend.jvm.ir.replaceThisByStaticReference
|
||||||
import org.jetbrains.kotlin.builtins.CompanionObjectMapping.isMappedIntrinsicCompanionObject
|
import org.jetbrains.kotlin.builtins.CompanionObjectMapping.isMappedIntrinsicCompanionObject
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
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.ClassKind
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
@@ -33,7 +35,8 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class JvmDeclarationFactory(
|
class JvmDeclarationFactory(
|
||||||
private val methodSignatureMapper: MethodSignatureMapper
|
private val methodSignatureMapper: MethodSignatureMapper,
|
||||||
|
private val languageVersionSettings: LanguageVersionSettings
|
||||||
) : DeclarationFactory {
|
) : DeclarationFactory {
|
||||||
private val singletonFieldDeclarations = HashMap<IrSymbolOwner, IrField>()
|
private val singletonFieldDeclarations = HashMap<IrSymbolOwner, IrField>()
|
||||||
private val interfaceCompanionFieldDeclarations = HashMap<IrSymbolOwner, IrField>()
|
private val interfaceCompanionFieldDeclarations = HashMap<IrSymbolOwner, IrField>()
|
||||||
@@ -137,12 +140,21 @@ class JvmDeclarationFactory(
|
|||||||
override fun getFieldForObjectInstance(singleton: IrClass): IrField =
|
override fun getFieldForObjectInstance(singleton: IrClass): IrField =
|
||||||
singletonFieldDeclarations.getOrPut(singleton) {
|
singletonFieldDeclarations.getOrPut(singleton) {
|
||||||
val isNotMappedCompanion = singleton.isCompanion && !isMappedIntrinsicCompanionObject(singleton.descriptor)
|
val isNotMappedCompanion = singleton.isCompanion && !isMappedIntrinsicCompanionObject(singleton.descriptor)
|
||||||
|
val useProperVisibilityForCompanion =
|
||||||
|
languageVersionSettings.supportsFeature(LanguageFeature.ProperVisibilityForCompanionObjectInstanceField)
|
||||||
|
&& singleton.isCompanion
|
||||||
|
&& !singleton.parentAsClass.isInterface
|
||||||
buildField {
|
buildField {
|
||||||
name = if (isNotMappedCompanion) singleton.name else Name.identifier(JvmAbi.INSTANCE_FIELD)
|
name = if (isNotMappedCompanion) singleton.name else Name.identifier(JvmAbi.INSTANCE_FIELD)
|
||||||
type = singleton.defaultType
|
type = singleton.defaultType
|
||||||
origin = IrDeclarationOrigin.FIELD_FOR_OBJECT_INSTANCE
|
origin = IrDeclarationOrigin.FIELD_FOR_OBJECT_INSTANCE
|
||||||
isFinal = true
|
isFinal = true
|
||||||
isStatic = true
|
isStatic = true
|
||||||
|
visibility = when {
|
||||||
|
!useProperVisibilityForCompanion -> Visibilities.PUBLIC
|
||||||
|
singleton.visibility == Visibilities.PROTECTED -> JavaVisibilities.PROTECTED_STATIC_VISIBILITY
|
||||||
|
else -> singleton.visibility
|
||||||
|
}
|
||||||
}.apply {
|
}.apply {
|
||||||
parent = if (isNotMappedCompanion) singleton.parent else singleton
|
parent = if (isNotMappedCompanion) singleton.parent else singleton
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-3
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
|||||||
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.synthetic.isVisibleOutside
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrElementTransformerVoidWithContext(), FileLoweringPass {
|
internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrElementTransformerVoidWithContext(), FileLoweringPass {
|
||||||
@@ -48,7 +49,12 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
|||||||
|
|
||||||
override fun lower(irFile: IrFile) {
|
override fun lower(irFile: IrFile) {
|
||||||
irFile.accept(object : IrInlineReferenceLocator(context) {
|
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)
|
inlineLambdaToCallSite[argument.symbol.owner] = LambdaCallSite(scope, parameter.isCrossinline)
|
||||||
}
|
}
|
||||||
}, null)
|
}, null)
|
||||||
@@ -167,7 +173,11 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
|||||||
private fun IrDeclarationWithVisibility.accessorParent(parent: IrDeclarationParent = this.parent) =
|
private fun IrDeclarationWithVisibility.accessorParent(parent: IrDeclarationParent = this.parent) =
|
||||||
if (visibility == JavaVisibilities.PROTECTED_STATIC_VISIBILITY) {
|
if (visibility == JavaVisibilities.PROTECTED_STATIC_VISIBILITY) {
|
||||||
val classes = allScopes.map { it.irElement }.filterIsInstance<IrClass>()
|
val classes = allScopes.map { it.irElement }.filterIsInstance<IrClass>()
|
||||||
classes.lastOrNull { parent is IrClass && it.isSubclassOf(parent) } ?: classes.last()
|
val companions = classes.mapNotNull { it.companionObject() }.filterIsInstance<IrClass>()
|
||||||
|
val objectsInScope =
|
||||||
|
classes.flatMap { it.declarations.filter(IrDeclaration::isAnonymousObject).filterIsInstance<IrClass>() }
|
||||||
|
val candidates = objectsInScope + companions + classes
|
||||||
|
candidates.lastOrNull { parent is IrClass && it.isSubclassOf(parent) } ?: classes.last()
|
||||||
} else parent
|
} else parent
|
||||||
|
|
||||||
private fun IrConstructor.makeConstructorAccessor(): IrConstructorImpl {
|
private fun IrConstructor.makeConstructorAccessor(): IrConstructorImpl {
|
||||||
@@ -185,7 +195,9 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
|||||||
accessor.returnType = source.returnType.remapTypeParameters(source, accessor)
|
accessor.returnType = source.returnType.remapTypeParameters(source, accessor)
|
||||||
|
|
||||||
accessor.addValueParameter(
|
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(
|
accessor.body = IrExpressionBodyImpl(
|
||||||
|
|||||||
-2
@@ -1,6 +1,4 @@
|
|||||||
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
|
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
|
||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// ^ TODO implement ProperVisibilityForCompanionObjectInstanceField feature support in JMV_IR
|
|
||||||
|
|
||||||
class Host {
|
class Host {
|
||||||
private companion object {
|
private companion object {
|
||||||
|
|||||||
Vendored
-2
@@ -1,6 +1,4 @@
|
|||||||
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
|
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
|
||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// ^ TODO implement ProperVisibilityForCompanionObjectInstanceField feature support in JMV_IR
|
|
||||||
|
|
||||||
// FILE: Base.kt
|
// FILE: Base.kt
|
||||||
package a
|
package a
|
||||||
|
|||||||
+1
@@ -6670,6 +6670,7 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/featureIntersection/inlineSuspendFinally.kt", "kotlin.coroutines");
|
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/featureIntersection/inlineSuspendFinally.kt", "kotlin.coroutines");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@TestMetadata("interfaceMethodWithBody.kt")
|
@TestMetadata("interfaceMethodWithBody.kt")
|
||||||
public void testInterfaceMethodWithBody() throws Exception {
|
public void testInterfaceMethodWithBody() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/interfaceMethodWithBody.kt");
|
runTest("compiler/testData/codegen/box/coroutines/featureIntersection/interfaceMethodWithBody.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user