[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 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()
|
||||
|
||||
+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.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<IrSymbolOwner, IrField>()
|
||||
private val interfaceCompanionFieldDeclarations = HashMap<IrSymbolOwner, IrField>()
|
||||
@@ -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
|
||||
}
|
||||
|
||||
+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.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<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
|
||||
|
||||
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(
|
||||
|
||||
-2
@@ -1,6 +1,4 @@
|
||||
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// ^ TODO implement ProperVisibilityForCompanionObjectInstanceField feature support in JMV_IR
|
||||
|
||||
class Host {
|
||||
private companion object {
|
||||
|
||||
Vendored
-2
@@ -1,6 +1,4 @@
|
||||
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// ^ TODO implement ProperVisibilityForCompanionObjectInstanceField feature support in JMV_IR
|
||||
|
||||
// FILE: Base.kt
|
||||
package a
|
||||
|
||||
+1
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user