Support mixed compilation of new default with non-default or @JvmDefault

This commit is contained in:
Mikhael Bogdanov
2020-02-06 09:43:47 +01:00
committed by Mikhail Bogdanov
parent a3f930d2e4
commit e45a892499
8 changed files with 142 additions and 6 deletions
@@ -8,13 +8,17 @@ package org.jetbrains.kotlin.resolve.jvm.annotations
import org.jetbrains.kotlin.config.JvmDefaultMode
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotated
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.load.java.JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
val JVM_DEFAULT_FQ_NAME = FqName("kotlin.jvm.JvmDefault")
val JVM_OVERLOADS_FQ_NAME = FqName("kotlin.jvm.JvmOverloads")
@@ -44,8 +48,15 @@ fun DeclarationDescriptor.hasJvmFieldAnnotation(): Boolean =
fun DeclarationDescriptor.isCallableMemberCompiledToJvmDefaultIfNoAbstract(jvmDefault: JvmDefaultMode): Boolean =
this is CallableMemberDescriptor && isCompiledToJvmDefaultIfNoAbstract(jvmDefault)
fun CallableMemberDescriptor.isCompiledToJvmDefaultIfNoAbstract(jvmDefault: JvmDefaultMode): Boolean =
jvmDefault.forAllMehtodsWithBody || DescriptorUtils.getDirectMember(this).annotations.hasAnnotation(JVM_DEFAULT_FQ_NAME)
fun CallableMemberDescriptor.isCompiledToJvmDefaultIfNoAbstract(jvmDefault: JvmDefaultMode): Boolean {
val directMember = DescriptorUtils.getDirectMember(this)
val clazz = directMember.containingDeclaration
if (directMember.annotations.hasAnnotation(JVM_DEFAULT_FQ_NAME)) return true
if (clazz !is DeserializedClassDescriptor) return jvmDefault.forAllMethodsWithBody
return JvmProtoBufUtil.isNewPlaceForBodyGeneration(clazz.classProto)
}
fun CallableMemberDescriptor.hasJvmDefaultAnnotation(): Boolean =
DescriptorUtils.getDirectMember(this).annotations.hasAnnotation(JVM_DEFAULT_FQ_NAME)