JVM IR: generate field for private companion object in interface as synthetic

This commit is contained in:
Alexander Udalov
2020-09-10 21:23:01 +02:00
parent fc141a52da
commit 9250d86915
3 changed files with 82 additions and 6 deletions
@@ -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
@@ -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
}
}
@@ -0,0 +1,67 @@
@kotlin.Metadata
public final class TestInternalCompanionInClass$Companion {
// source: 'companionObjectVisibility_after.kt'
private method <init>(): void
public synthetic method <init>(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 <clinit>(): void
public method <init>(): void
public final inner class TestInternalCompanionInClass$Companion
}
@kotlin.Metadata
final class TestPrivateCompanionInClass$Companion {
// source: 'companionObjectVisibility_after.kt'
private method <init>(): void
public synthetic method <init>(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 <clinit>(): void
public method <init>(): 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 <clinit>(): void
private method <init>(): 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 <clinit>(): void
public final inner class TestPrivateCompanionInInterface$Companion
}
@kotlin.Metadata
public final class TestProtectedCompanionInClass$Companion {
// source: 'companionObjectVisibility_after.kt'
private method <init>(): void
public synthetic method <init>(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 <clinit>(): void
public method <init>(): void
protected final inner class TestProtectedCompanionInClass$Companion
}