From a493b21c7c4d2df87a99ebea9bc86009bb0e6015 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Fri, 19 Jun 2020 16:55:00 +0300 Subject: [PATCH] JVM_IR: Deprecation cycle for companion object instance visibility --- .../kotlin/backend/jvm/JvmSymbols.kt | 7 +++ .../backend/jvm/codegen/ClassCodegen.kt | 12 +++- .../backend/jvm/codegen/irCodegenUtils.kt | 14 ----- .../jvm/descriptors/JvmDeclarationFactory.kt | 6 +- .../backend/jvm/lower/ObjectClassLowering.kt | 13 ++++ .../companionObjectVisibility_lv13.kt | 16 ----- .../companionObjectVisibility_lv13.txt | 59 ------------------- .../codegen/BytecodeListingTestGenerated.java | 5 -- .../ir/IrBytecodeListingTestGenerated.java | 5 -- 9 files changed, 35 insertions(+), 102 deletions(-) delete mode 100644 compiler/testData/codegen/bytecodeListing/companionObjectVisibility_lv13.kt delete mode 100644 compiler/testData/codegen/bytecodeListing/companionObjectVisibility_lv13.txt diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt index e817e1624fa..3b850abe43a 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmSymbols.kt @@ -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 { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt index babb642a9a1..5ed2d23d429 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt @@ -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) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt index be47cfde0a5..ca66f2b11fc 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/irCodegenUtils.kt @@ -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 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 d0bd1a8789a..59b081fb04e 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 @@ -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 } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/ObjectClassLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/ObjectClassLowering.kt index 9c4c2a444d9..068665e6992 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/ObjectClassLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/ObjectClassLowering.kt @@ -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) } diff --git a/compiler/testData/codegen/bytecodeListing/companionObjectVisibility_lv13.kt b/compiler/testData/codegen/bytecodeListing/companionObjectVisibility_lv13.kt deleted file mode 100644 index b0596804cc5..00000000000 --- a/compiler/testData/codegen/bytecodeListing/companionObjectVisibility_lv13.kt +++ /dev/null @@ -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 -} diff --git a/compiler/testData/codegen/bytecodeListing/companionObjectVisibility_lv13.txt b/compiler/testData/codegen/bytecodeListing/companionObjectVisibility_lv13.txt deleted file mode 100644 index f27d67b748c..00000000000 --- a/compiler/testData/codegen/bytecodeListing/companionObjectVisibility_lv13.txt +++ /dev/null @@ -1,59 +0,0 @@ -@kotlin.Metadata -public final class TestInternalCompanionInClass$Companion { - inner class TestInternalCompanionInClass$Companion - private method (): void - public synthetic method (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 (): void - public method (): void -} - -@kotlin.Metadata -final class TestPrivateCompanionInClass$Companion { - inner class TestPrivateCompanionInClass$Companion - private method (): void - public synthetic method (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 (): void - public method (): void -} - -@kotlin.Metadata -final class TestPrivateCompanionInInterface$Companion { - synthetic final static field $$INSTANCE: TestPrivateCompanionInInterface$Companion - inner class TestPrivateCompanionInInterface$Companion - static method (): void - private method (): void -} - -@kotlin.Metadata -public interface TestPrivateCompanionInInterface { - public synthetic final static field Companion: TestPrivateCompanionInInterface$Companion - inner class TestPrivateCompanionInInterface$Companion - static method (): void -} - -@kotlin.Metadata -public final class TestProtectedCompanionInClass$Companion { - inner class TestProtectedCompanionInClass$Companion - private method (): void - public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void -} - -@kotlin.Metadata -public class TestProtectedCompanionInClass { - protected final static field Companion: TestProtectedCompanionInClass$Companion - inner class TestProtectedCompanionInClass$Companion - static method (): void - public method (): void -} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java index a566aedf865..822d5f609ed 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java @@ -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"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java index c54d5fcd780..e6ee18688d1 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java @@ -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");