From 3f5fea05de6cea96916094d0a371f157fdcc2d57 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Tue, 3 Apr 2018 14:38:56 +0200 Subject: [PATCH] Write 'RequireKotlin' annotation on @JvmDefault members --- .../kotlin/resolve/jvm/annotationUtil.kt | 3 ++- .../resolve/jvm/checkers/JvmDefaultChecker.kt | 12 +++++------- .../jetbrains/kotlin/resolve/AnnotationUtil.kt | 7 +++++++ .../serialization/DescriptorSerializer.kt | 18 ++++++++++++++++-- 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/annotationUtil.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/annotationUtil.kt index 85be67ce3ee..eb99ce917ff 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/annotationUtil.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/annotationUtil.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.annotations.hasJvmDefaultAnnotation import org.jetbrains.kotlin.resolve.jvm.checkers.JvmDefaultChecker fun DeclarationDescriptor.findJvmOverloadsAnnotation() = annotations.findAnnotation(FqName("kotlin.jvm.JvmOverloads")) @@ -31,7 +32,7 @@ fun DeclarationDescriptor.hasJvmFieldAnnotation(): Boolean { } fun CallableMemberDescriptor.hasJvmDefaultAnnotation() = - DescriptorUtils.getDirectMember(this).annotations.hasAnnotation(JvmDefaultChecker.JVM_DEFAULT_FQ_NAME) + hasJvmDefaultAnnotation() fun DeclarationDescriptor.isCallableMemberWithJvmDefaultAnnotation() = diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmDefaultChecker.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmDefaultChecker.kt index 6480ca39cd8..a06b9e08654 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmDefaultChecker.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmDefaultChecker.kt @@ -7,11 +7,14 @@ package org.jetbrains.kotlin.resolve.jvm.checkers import org.jetbrains.kotlin.config.AnalysisFlag import org.jetbrains.kotlin.config.JvmTarget -import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.annotations.JVM_DEFAULT_FQ_NAME import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperInterfaces @@ -20,11 +23,6 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm class JvmDefaultChecker(val jvmTarget: JvmTarget) : DeclarationChecker { - companion object { - val JVM_DEFAULT_FQ_NAME = FqName("kotlin.jvm.JvmDefault") - } - - override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) { val enableJvmDefault = context.languageVersionSettings.getFlag(AnalysisFlag.enableJvmDefault) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationUtil.kt index 103e33a8190..822b5badd6c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationUtil.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.resolve.annotations +import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.name.FqName @@ -28,6 +29,12 @@ val JVM_STATIC_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.JvmStatic") val JVM_FIELD_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.JvmField") +val JVM_DEFAULT_FQ_NAME = FqName("kotlin.jvm.JvmDefault") + +fun CallableMemberDescriptor.hasJvmDefaultAnnotation() = + DescriptorUtils.getDirectMember(this).annotations.hasAnnotation(JVM_DEFAULT_FQ_NAME) + + fun DeclarationDescriptor.hasJvmStaticAnnotation(): Boolean { return annotations.findAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME) != null } diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt b/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt index dc5f02bd583..6f709538272 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumEntry import org.jetbrains.kotlin.resolve.MemberComparator import org.jetbrains.kotlin.resolve.RequireKotlinNames +import org.jetbrains.kotlin.resolve.annotations.hasJvmDefaultAnnotation import org.jetbrains.kotlin.resolve.calls.components.isActualParameterWithAnyExpectedDefault import org.jetbrains.kotlin.resolve.checkers.KotlinVersionStringAnnotationValueChecker import org.jetbrains.kotlin.resolve.constants.EnumValue @@ -238,6 +239,8 @@ class DescriptorSerializer private constructor( } else if (descriptor.isSuspendOrHasSuspendTypesInSignature()) { builder.versionRequirement = writeVersionRequirement(LanguageFeature.Coroutines) + } else if (descriptor.hasJvmDefaultAnnotation()) { + builder.versionRequirement = writeVersionRequirement(1, 2, 40) } extension.serializeProperty(descriptor, builder) @@ -306,9 +309,10 @@ class DescriptorSerializer private constructor( val requirement = serializeVersionRequirement(descriptor) if (requirement != null) { builder.versionRequirement = requirement - } - else if (descriptor.isSuspendOrHasSuspendTypesInSignature()) { + } else if (descriptor.isSuspendOrHasSuspendTypesInSignature()) { builder.versionRequirement = writeVersionRequirement(LanguageFeature.Coroutines) + } else if (descriptor.hasJvmDefaultAnnotation()) { + builder.versionRequirement = writeVersionRequirement(1, 2, 40) } contractSerializer.serializeContractOfFunctionIfAny(descriptor, builder, this) @@ -626,6 +630,16 @@ class DescriptorSerializer private constructor( return versionRequirementTable[requirement] } + private fun writeVersionRequirement(major: Int, minor: Int, patch: Int): Int { + val requirement = ProtoBuf.VersionRequirement.newBuilder().apply { + VersionRequirement.Version(major, minor, patch).encode( + writeVersion = { version = it }, + writeVersionFull = { versionFull = it } + ) + } + return versionRequirementTable[requirement] + } + // Returns index into versionRequirementTable, or null if there's no @RequireKotlin on the descriptor private fun serializeVersionRequirement(descriptor: DeclarationDescriptor): Int? { val annotation = descriptor.annotations.findAnnotation(RequireKotlinNames.FQ_NAME) ?: return null