JVM_IR: Deprecation cycle for companion object instance visibility

This commit is contained in:
Dmitry Petrov
2020-06-19 16:55:00 +03:00
parent 230f2f5ce0
commit a493b21c7c
9 changed files with 35 additions and 102 deletions
@@ -218,6 +218,13 @@ class JvmSymbols(
klass.addFunction("desiredAssertionStatus", irBuiltIns.booleanType)
}
private val javaLangDeprecated: IrClassSymbol =
createClass(FqName("java.lang.Deprecated")) { klass ->
klass.addConstructor { isPrimary = true }
}
val javaLangDeprecatedConstructor = javaLangDeprecated.constructors.single()
private val javaLangAssertionError: IrClassSymbol =
createClass(FqName("java.lang.AssertionError"), classModality = Modality.OPEN) { klass ->
klass.addConstructor().apply {
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_SYNTHETIC_ANNOTATION_FQ_NAME
@@ -359,13 +360,22 @@ private val IrClass.flags: Int
}
private val IrField.flags: Int
get() = origin.flags or visibility.flags or (correspondingPropertySymbol?.owner?.deprecationFlags ?: 0) or
get() = origin.flags or visibility.flags or
this.specialDeprecationFlag or (correspondingPropertySymbol?.owner?.deprecationFlags ?: 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)
private val IrField.specialDeprecationFlag: Int
get() = if (shouldHaveSpecialDeprecationFlag()) Opcodes.ACC_DEPRECATED else 0
private fun IrField.shouldHaveSpecialDeprecationFlag(): Boolean {
return origin == IrDeclarationOrigin.FIELD_FOR_OBJECT_INSTANCE &&
annotations.hasAnnotation(FqName("java.lang.Deprecated"))
}
private val IrDeclarationOrigin.flags: Int
get() = (if (isSynthetic) Opcodes.ACC_SYNTHETIC else 0) or
(if (this == IrDeclarationOrigin.FIELD_FOR_ENUM_ENTRY) Opcodes.ACC_ENUM else 0)
@@ -392,20 +392,6 @@ fun IrClass.isOptionalAnnotationClass(): Boolean =
isAnnotationClass &&
hasAnnotation(ExpectedActualDeclarationChecker.OPTIONAL_EXPECTATION_FQ_NAME)
//@JvmOverloads
//fun OtherOriginForIr(element: PsiElement?, descriptor: DeclarationDescriptor? = null) =
// if (element == null && descriptor == null)
// JvmDeclarationOrigin.NO_ORIGIN
// else
// object : JvmDeclarationOrigin(JvmDeclarationOriginKind.OTHER, element, descriptor) {
// override val element get() =
// error("Access to PsiElement")
// override val descriptor get() =
// error("Access to descriptor")
// }
// JvmDeclarationOrigin(OTHER, element, descriptor)
val IrAnnotationContainer.deprecationFlags: Int
get() {
val annotation = annotations.findAnnotation(FQ_NAMES.deprecated) ?: return 0
@@ -146,6 +146,7 @@ class JvmDeclarationFactory(
override fun getFieldForObjectInstance(singleton: IrClass): IrField =
singletonFieldDeclarations.getOrPut(singleton) {
val originalVisibility = singleton.visibility
val isNotMappedCompanion = singleton.isCompanion && !isMappedIntrinsicCompanionObject(singleton.descriptor)
val useProperVisibilityForCompanion =
languageVersionSettings.supportsFeature(LanguageFeature.ProperVisibilityForCompanionObjectInstanceField)
@@ -159,9 +160,10 @@ class JvmDeclarationFactory(
isStatic = true
visibility = when {
!useProperVisibilityForCompanion -> Visibilities.PUBLIC
singleton.visibility == Visibilities.PROTECTED -> JavaVisibilities.PROTECTED_STATIC_VISIBILITY
else -> singleton.visibility
originalVisibility == Visibilities.PROTECTED -> JavaVisibilities.PROTECTED_STATIC_VISIBILITY
else -> originalVisibility
}
}.apply {
parent = if (isNotMappedCompanion) singleton.parent else singleton
}
@@ -10,6 +10,8 @@ import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.builders.irCall
import org.jetbrains.kotlin.ir.builders.irExprBody
@@ -64,6 +66,17 @@ private class ObjectClassLowering(val context: JvmBackendContext) : IrElementTra
}
}
// Mark object instance field as deprecated if the object visibility is private or protected,
// and ProperVisibilityForCompanionObjectInstanceField language feature is not enabled.
if (!context.state.languageVersionSettings.supportsFeature(LanguageFeature.ProperVisibilityForCompanionObjectInstanceField) &&
(irClass.visibility == Visibilities.PRIVATE || irClass.visibility == Visibilities.PROTECTED)
) {
context.createIrBuilder(irClass.symbol).run {
publicInstanceField.annotations +=
irCall(this@ObjectClassLowering.context.ir.symbols.javaLangDeprecatedConstructor)
}
}
pendingTransformations.add {
(publicInstanceField.parent as IrDeclarationContainer).declarations.add(0, publicInstanceField)
}
@@ -1,16 +0,0 @@
// IGNORE_BACKEND: JVM_IR
open class TestProtectedCompanionInClass {
protected companion object
}
class TestInternalCompanionInClass {
internal companion object
}
class TestPrivateCompanionInClass {
private companion object
}
interface TestPrivateCompanionInInterface {
private companion object
}
@@ -1,59 +0,0 @@
@kotlin.Metadata
public final class TestInternalCompanionInClass$Companion {
inner class TestInternalCompanionInClass$Companion
private method <init>(): void
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
}
@kotlin.Metadata
public final class TestInternalCompanionInClass {
public final static field Companion: TestInternalCompanionInClass$Companion
inner class TestInternalCompanionInClass$Companion
static method <clinit>(): void
public method <init>(): void
}
@kotlin.Metadata
final class TestPrivateCompanionInClass$Companion {
inner class TestPrivateCompanionInClass$Companion
private method <init>(): void
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
}
@kotlin.Metadata
public final class TestPrivateCompanionInClass {
private final static field Companion: TestPrivateCompanionInClass$Companion
inner class TestPrivateCompanionInClass$Companion
static method <clinit>(): void
public method <init>(): void
}
@kotlin.Metadata
final class TestPrivateCompanionInInterface$Companion {
synthetic final static field $$INSTANCE: TestPrivateCompanionInInterface$Companion
inner class TestPrivateCompanionInInterface$Companion
static method <clinit>(): void
private method <init>(): void
}
@kotlin.Metadata
public interface TestPrivateCompanionInInterface {
public synthetic final static field Companion: TestPrivateCompanionInInterface$Companion
inner class TestPrivateCompanionInInterface$Companion
static method <clinit>(): void
}
@kotlin.Metadata
public final class TestProtectedCompanionInClass$Companion {
inner class TestProtectedCompanionInClass$Companion
private method <init>(): void
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
}
@kotlin.Metadata
public class TestProtectedCompanionInClass {
protected final static field Companion: TestProtectedCompanionInClass$Companion
inner class TestProtectedCompanionInClass$Companion
static method <clinit>(): void
public method <init>(): void
}
@@ -44,11 +44,6 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
runTest("compiler/testData/codegen/bytecodeListing/companionObjectVisibility_before.kt");
}
@TestMetadata("companionObjectVisibility_lv13.kt")
public void testCompanionObjectVisibility_lv13() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/companionObjectVisibility_lv13.kt");
}
@TestMetadata("defaultImpls.kt")
public void testDefaultImpls() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/defaultImpls.kt");
@@ -44,11 +44,6 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes
runTest("compiler/testData/codegen/bytecodeListing/companionObjectVisibility_before.kt");
}
@TestMetadata("companionObjectVisibility_lv13.kt")
public void testCompanionObjectVisibility_lv13() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/companionObjectVisibility_lv13.kt");
}
@TestMetadata("defaultImpls.kt")
public void testDefaultImpls() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/defaultImpls.kt");