JVM_IR: Deprecation cycle for companion object instance visibility
This commit is contained in:
@@ -218,6 +218,13 @@ class JvmSymbols(
|
|||||||
klass.addFunction("desiredAssertionStatus", irBuiltIns.booleanType)
|
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 =
|
private val javaLangAssertionError: IrClassSymbol =
|
||||||
createClass(FqName("java.lang.AssertionError"), classModality = Modality.OPEN) { klass ->
|
createClass(FqName("java.lang.AssertionError"), classModality = Modality.OPEN) { klass ->
|
||||||
klass.addConstructor().apply {
|
klass.addConstructor().apply {
|
||||||
|
|||||||
+11
-1
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
|
|||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||||
import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_SYNTHETIC_ANNOTATION_FQ_NAME
|
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
|
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 (isFinal) Opcodes.ACC_FINAL else 0) or
|
||||||
(if (isStatic) Opcodes.ACC_STATIC 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(VOLATILE_ANNOTATION_FQ_NAME)) Opcodes.ACC_VOLATILE else 0) or
|
||||||
(if (hasAnnotation(TRANSIENT_ANNOTATION_FQ_NAME)) Opcodes.ACC_TRANSIENT 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)) 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
|
private val IrDeclarationOrigin.flags: Int
|
||||||
get() = (if (isSynthetic) Opcodes.ACC_SYNTHETIC else 0) or
|
get() = (if (isSynthetic) Opcodes.ACC_SYNTHETIC else 0) or
|
||||||
(if (this == IrDeclarationOrigin.FIELD_FOR_ENUM_ENTRY) Opcodes.ACC_ENUM else 0)
|
(if (this == IrDeclarationOrigin.FIELD_FOR_ENUM_ENTRY) Opcodes.ACC_ENUM else 0)
|
||||||
|
|||||||
-14
@@ -392,20 +392,6 @@ fun IrClass.isOptionalAnnotationClass(): Boolean =
|
|||||||
isAnnotationClass &&
|
isAnnotationClass &&
|
||||||
hasAnnotation(ExpectedActualDeclarationChecker.OPTIONAL_EXPECTATION_FQ_NAME)
|
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
|
val IrAnnotationContainer.deprecationFlags: Int
|
||||||
get() {
|
get() {
|
||||||
val annotation = annotations.findAnnotation(FQ_NAMES.deprecated) ?: return 0
|
val annotation = annotations.findAnnotation(FQ_NAMES.deprecated) ?: return 0
|
||||||
|
|||||||
+4
-2
@@ -146,6 +146,7 @@ class JvmDeclarationFactory(
|
|||||||
|
|
||||||
override fun getFieldForObjectInstance(singleton: IrClass): IrField =
|
override fun getFieldForObjectInstance(singleton: IrClass): IrField =
|
||||||
singletonFieldDeclarations.getOrPut(singleton) {
|
singletonFieldDeclarations.getOrPut(singleton) {
|
||||||
|
val originalVisibility = singleton.visibility
|
||||||
val isNotMappedCompanion = singleton.isCompanion && !isMappedIntrinsicCompanionObject(singleton.descriptor)
|
val isNotMappedCompanion = singleton.isCompanion && !isMappedIntrinsicCompanionObject(singleton.descriptor)
|
||||||
val useProperVisibilityForCompanion =
|
val useProperVisibilityForCompanion =
|
||||||
languageVersionSettings.supportsFeature(LanguageFeature.ProperVisibilityForCompanionObjectInstanceField)
|
languageVersionSettings.supportsFeature(LanguageFeature.ProperVisibilityForCompanionObjectInstanceField)
|
||||||
@@ -159,9 +160,10 @@ class JvmDeclarationFactory(
|
|||||||
isStatic = true
|
isStatic = true
|
||||||
visibility = when {
|
visibility = when {
|
||||||
!useProperVisibilityForCompanion -> Visibilities.PUBLIC
|
!useProperVisibilityForCompanion -> Visibilities.PUBLIC
|
||||||
singleton.visibility == Visibilities.PROTECTED -> JavaVisibilities.PROTECTED_STATIC_VISIBILITY
|
originalVisibility == Visibilities.PROTECTED -> JavaVisibilities.PROTECTED_STATIC_VISIBILITY
|
||||||
else -> singleton.visibility
|
else -> originalVisibility
|
||||||
}
|
}
|
||||||
|
|
||||||
}.apply {
|
}.apply {
|
||||||
parent = if (isNotMappedCompanion) singleton.parent else singleton
|
parent = if (isNotMappedCompanion) singleton.parent else singleton
|
||||||
}
|
}
|
||||||
|
|||||||
+13
@@ -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.phaser.makeIrFilePhase
|
||||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
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.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.builders.irCall
|
import org.jetbrains.kotlin.ir.builders.irCall
|
||||||
import org.jetbrains.kotlin.ir.builders.irExprBody
|
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 {
|
pendingTransformations.add {
|
||||||
(publicInstanceField.parent as IrDeclarationContainer).declarations.add(0, publicInstanceField)
|
(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
|
|
||||||
}
|
|
||||||
-5
@@ -44,11 +44,6 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
|
|||||||
runTest("compiler/testData/codegen/bytecodeListing/companionObjectVisibility_before.kt");
|
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")
|
@TestMetadata("defaultImpls.kt")
|
||||||
public void testDefaultImpls() throws Exception {
|
public void testDefaultImpls() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeListing/defaultImpls.kt");
|
runTest("compiler/testData/codegen/bytecodeListing/defaultImpls.kt");
|
||||||
|
|||||||
-5
@@ -44,11 +44,6 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes
|
|||||||
runTest("compiler/testData/codegen/bytecodeListing/companionObjectVisibility_before.kt");
|
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")
|
@TestMetadata("defaultImpls.kt")
|
||||||
public void testDefaultImpls() throws Exception {
|
public void testDefaultImpls() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeListing/defaultImpls.kt");
|
runTest("compiler/testData/codegen/bytecodeListing/defaultImpls.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user