JVM IR: do not use origin DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY(_SYNTHETIC)

It was only used to generate deprecation in codegen, but it's annotated
with `javaLangDeprecatedConstructorWithDeprecatedFlag`, and a similar
annotation for IrField results in ACC_DEPRECATED. Adapt codegen to
generate this flag for functions too.
This commit is contained in:
Alexander Udalov
2020-11-19 21:42:46 +01:00
parent 697b2b02f1
commit 988cc52174
9 changed files with 36 additions and 57 deletions
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.jvm
import org.jetbrains.kotlin.backend.common.ir.copyParameterDeclarationsFrom
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
import org.jetbrains.kotlin.backend.common.ir.createStaticFunctionWithReceivers
import org.jetbrains.kotlin.backend.jvm.codegen.AnnotationCodegen.Companion.annotationClass
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.ir.copyCorrespondingPropertyFrom
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
@@ -167,15 +168,9 @@ class JvmCachedDeclarations(
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_WITH_MOVED_RECEIVERS
}
interfaceFun.resolveFakeOverride()!!.origin.isSynthetic ->
if (forCompatibilityMode)
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY_SYNTHETIC
else
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_TO_SYNTHETIC
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_TO_SYNTHETIC
else ->
if (forCompatibilityMode)
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY
else
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE
}
// Interface functions are public or private, with one exception: clone in Cloneable, which is protected.
@@ -198,11 +193,12 @@ class JvmCachedDeclarations(
typeParametersFromContext = parent.typeParameters
).also {
it.copyCorrespondingPropertyFrom(interfaceFun)
if (it.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY &&
!it.annotations.hasAnnotation(DeprecationResolver.JAVA_DEPRECATED)
) {
if (forCompatibilityMode && !interfaceFun.resolveFakeOverride()!!.origin.isSynthetic) {
context.createJvmIrBuilder(it.symbol).run {
it.annotations += irCall(irSymbols.javaLangDeprecatedConstructorWithDeprecatedFlag)
it.annotations = it.annotations
.filterNot { it.annotationClass.hasEqualFqName(DeprecationResolver.JAVA_DEPRECATED) }
.plus(irCall(irSymbols.javaLangDeprecatedConstructorWithDeprecatedFlag))
}
}
@@ -15,9 +15,7 @@ interface JvmLoweredDeclarationOrigin : IrDeclarationOrigin {
object DEFAULT_IMPLS_WITH_MOVED_RECEIVERS_SYNTHETIC :
IrDeclarationOriginImpl("STATIC_WITH_MOVED_RECEIVERS_SYNTHETIC", isSynthetic = true)
object DEFAULT_IMPLS_BRIDGE : IrDeclarationOriginImpl("DEFAULT_IMPLS_BRIDGE")
object DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY : IrDeclarationOriginImpl("DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY")
object DEFAULT_IMPLS_BRIDGE_TO_SYNTHETIC : IrDeclarationOriginImpl("DEFAULT_IMPLS_BRIDGE_TO_SYNTHETIC", isSynthetic = true)
object DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY_SYNTHETIC : IrDeclarationOriginImpl("DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY_SYNTHETIC", isSynthetic = true)
object FIELD_FOR_OUTER_THIS : IrDeclarationOriginImpl("FIELD_FOR_OUTER_THIS")
object LAMBDA_IMPL : IrDeclarationOriginImpl("LAMBDA_IMPL")
object FUNCTION_REFERENCE_IMPL : IrDeclarationOriginImpl("FUNCTION_REFERENCE_IMPL", isSynthetic = true)
@@ -457,9 +457,8 @@ private val IrClass.flags: Int
private fun IrField.computeFieldFlags(context: JvmBackendContext, languageVersionSettings: LanguageVersionSettings): Int =
origin.flags or visibility.flags or
(if (isDeprecatedCallable ||
correspondingPropertySymbol?.owner?.isDeprecatedCallable == true ||
shouldHaveSpecialDeprecationFlag(context)
(if (isDeprecatedCallable(context) ||
correspondingPropertySymbol?.owner?.isDeprecatedCallable(context) == true
) Opcodes.ACC_DEPRECATED else 0) or
(if (isFinal) Opcodes.ACC_FINAL else 0) or
(if (isStatic) Opcodes.ACC_STATIC else 0) or
@@ -475,10 +474,6 @@ private fun IrField.isPrivateCompanionFieldInInterface(languageVersionSettings:
parentAsClass.isJvmInterface &&
DescriptorVisibilities.isPrivate(parentAsClass.companionObject()!!.visibility)
fun IrField.shouldHaveSpecialDeprecationFlag(context: JvmBackendContext): Boolean {
return annotations.any { it.symbol == context.ir.symbols.javaLangDeprecatedConstructorWithDeprecatedFlag }
}
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)
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.backend.common.lower.LocalDeclarationsLowering
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.ir.isStaticInlineClassReplacement
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.InlineClassAbi
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.unboxInlineClass
import org.jetbrains.kotlin.backend.jvm.lower.isMultifileBridge
import org.jetbrains.kotlin.backend.jvm.lower.suspendFunctionOriginal
@@ -147,9 +146,7 @@ internal fun IrFunction.shouldContainSuspendMarkers(): Boolean = !isInvokeSuspen
origin != JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR &&
origin != JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR_FOR_HIDDEN_CONSTRUCTOR &&
origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE &&
origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY &&
origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_TO_SYNTHETIC &&
origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY_SYNTHETIC &&
origin != IrDeclarationOrigin.BRIDGE &&
origin != IrDeclarationOrigin.BRIDGE_SPECIAL &&
origin != IrDeclarationOrigin.DELEGATED_MEMBER &&
@@ -146,7 +146,7 @@ class FunctionCodegen(
private fun IrFunction.calculateMethodFlags(): Int {
if (origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER) {
return getVisibilityForDefaultArgumentStub() or Opcodes.ACC_SYNTHETIC or
(if (isDeprecatedFunction) Opcodes.ACC_DEPRECATED else 0) or
(if (isDeprecatedFunction(context)) Opcodes.ACC_DEPRECATED else 0) or
(if (this is IrConstructor) 0 else Opcodes.ACC_STATIC)
}
@@ -173,7 +173,7 @@ class FunctionCodegen(
val isSynchronized = hasAnnotation(SYNCHRONIZED_ANNOTATION_FQ_NAME)
return getVisibilityAccessFlag() or modalityFlag or
(if (isDeprecatedFunction) Opcodes.ACC_DEPRECATED else 0) or
(if (isDeprecatedFunction(context)) Opcodes.ACC_DEPRECATED else 0) or
(if (isStatic) Opcodes.ACC_STATIC else 0) or
(if (isVararg) Opcodes.ACC_VARARGS else 0) or
(if (isExternal) Opcodes.ACC_NATIVE else 0) or
@@ -188,9 +188,7 @@ class JvmSignatureClashDetector(
IrDeclarationOrigin.IR_BUILTINS_STUB,
JvmLoweredDeclarationOrigin.TO_ARRAY,
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE,
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY,
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_TO_SYNTHETIC,
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY_SYNTHETIC
)
val PREDEFINED_SIGNATURES = listOf(
@@ -14,14 +14,13 @@ import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.lower.MultifileFacadeFileEntry
import org.jetbrains.kotlin.builtins.StandardNames.FqNames
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.FrameMapBase
import org.jetbrains.kotlin.codegen.OwnerKind
import org.jetbrains.kotlin.codegen.SourceInfo
import org.jetbrains.kotlin.codegen.classFileContainsMethod
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.inline.SourceMapper
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrCall
@@ -346,8 +345,9 @@ fun IrClass.isOptionalAnnotationClass(): Boolean =
val IrDeclaration.isAnnotatedWithDeprecated: Boolean
get() = annotations.hasAnnotation(FqNames.deprecated)
val IrDeclaration.isDeprecatedCallable: Boolean
get() = isAnnotatedWithDeprecated || origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY
internal fun IrDeclaration.isDeprecatedCallable(context: JvmBackendContext): Boolean =
isAnnotatedWithDeprecated ||
annotations.any { it.symbol == context.ir.symbols.javaLangDeprecatedConstructorWithDeprecatedFlag }
// We can't check for JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS because for interface methods
// moved to DefaultImpls, origin is changed to DEFAULT_IMPLS
@@ -355,11 +355,11 @@ val IrDeclaration.isDeprecatedCallable: Boolean
val IrFunction.isSyntheticMethodForProperty: Boolean
get() = name.asString().endsWith(JvmAbi.ANNOTATED_PROPERTY_METHOD_NAME_SUFFIX)
val IrFunction.isDeprecatedFunction: Boolean
get() = isSyntheticMethodForProperty || isDeprecatedCallable ||
(this as? IrSimpleFunction)?.correspondingPropertySymbol?.owner?.isDeprecatedCallable == true ||
internal fun IrFunction.isDeprecatedFunction(context: JvmBackendContext): Boolean =
isSyntheticMethodForProperty || isDeprecatedCallable(context) ||
(this as? IrSimpleFunction)?.correspondingPropertySymbol?.owner?.isDeprecatedCallable(context) == true ||
isAccessorForDeprecatedPropertyImplementedByDelegation ||
isAccessorForDeprecatedJvmStaticProperty
isAccessorForDeprecatedJvmStaticProperty(context)
private val IrFunction.isAccessorForDeprecatedPropertyImplementedByDelegation: Boolean
get() =
@@ -367,20 +367,19 @@ private val IrFunction.isAccessorForDeprecatedPropertyImplementedByDelegation: B
this is IrSimpleFunction &&
correspondingPropertySymbol != null &&
overriddenSymbols.any {
it.owner.correspondingPropertySymbol?.owner?.isDeprecatedCallable == true
it.owner.correspondingPropertySymbol?.owner?.isAnnotatedWithDeprecated == true
}
private val IrFunction.isAccessorForDeprecatedJvmStaticProperty: Boolean
get() {
if (origin != JvmLoweredDeclarationOrigin.JVM_STATIC_WRAPPER) return false
val irExpressionBody = this.body as? IrExpressionBody
?: throw AssertionError("IrExpressionBody expected for JvmStatic wrapper:\n${this.dump()}")
val irCall = irExpressionBody.expression as? IrCall
?: throw AssertionError("IrCall expected inside JvmStatic wrapper:\n${this.dump()}")
val callee = irCall.symbol.owner
val property = callee.correspondingPropertySymbol?.owner ?: return false
return property.isDeprecatedCallable
}
private fun IrFunction.isAccessorForDeprecatedJvmStaticProperty(context: JvmBackendContext): Boolean {
if (origin != JvmLoweredDeclarationOrigin.JVM_STATIC_WRAPPER) return false
val irExpressionBody = this.body as? IrExpressionBody
?: throw AssertionError("IrExpressionBody expected for JvmStatic wrapper:\n${this.dump()}")
val irCall = irExpressionBody.expression as? IrCall
?: throw AssertionError("IrCall expected inside JvmStatic wrapper:\n${this.dump()}")
val callee = irCall.symbol.owner
val property = callee.correspondingPropertySymbol?.owner ?: return false
return property.isDeprecatedCallable(context)
}
@OptIn(ObsoleteDescriptorBasedAPI::class)
val IrDeclaration.psiElement: PsiElement?
@@ -359,9 +359,7 @@ private val defaultImplsOrigins = setOf(
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_WITH_MOVED_RECEIVERS,
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_WITH_MOVED_RECEIVERS_SYNTHETIC,
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE,
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY,
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_TO_SYNTHETIC,
JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY_SYNTHETIC
)
private val IrSimpleFunction.isDefaultImplsFunction: Boolean
@@ -262,9 +262,7 @@ private class InterfaceObjectCallsLowering(val context: JvmBackendContext) : IrE
*/
private fun isDefaultImplsBridge(f: IrSimpleFunction) =
f.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE ||
f.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY ||
f.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_TO_SYNTHETIC ||
f.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_FOR_COMPATIBILITY_SYNTHETIC
f.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS_BRIDGE_TO_SYNTHETIC
internal fun IrSimpleFunction.findInterfaceImplementation(jvmDefaultMode: JvmDefaultMode): IrSimpleFunction? {
if (!isFakeOverride) return null