Move version requirements serialization for @JvmDefault to JvmSerializerExtension
This commit is contained in:
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.*
|
|||||||
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
||||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
import org.jetbrains.kotlin.metadata.java.JavaClassProtoBuf
|
import org.jetbrains.kotlin.metadata.java.JavaClassProtoBuf
|
||||||
|
import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTable
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
||||||
@@ -28,8 +29,12 @@ import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerial
|
|||||||
|
|
||||||
// It uses BuiltInSerializerProtocol for annotations serialization
|
// It uses BuiltInSerializerProtocol for annotations serialization
|
||||||
class JavaClassesSerializerExtension : KotlinSerializerExtensionBase(BuiltInSerializerProtocol) {
|
class JavaClassesSerializerExtension : KotlinSerializerExtensionBase(BuiltInSerializerProtocol) {
|
||||||
override fun serializeClass(descriptor: ClassDescriptor, proto: ProtoBuf.Class.Builder) {
|
override fun serializeClass(
|
||||||
super.serializeClass(descriptor, proto)
|
descriptor: ClassDescriptor,
|
||||||
|
proto: ProtoBuf.Class.Builder,
|
||||||
|
versionRequirementTable: MutableVersionRequirementTable
|
||||||
|
) {
|
||||||
|
super.serializeClass(descriptor, proto, versionRequirementTable)
|
||||||
if (descriptor.visibility == JavaVisibilities.PACKAGE_VISIBILITY) {
|
if (descriptor.visibility == JavaVisibilities.PACKAGE_VISIBILITY) {
|
||||||
proto.setExtension(JavaClassProtoBuf.isPackagePrivateClass, true)
|
proto.setExtension(JavaClassProtoBuf.isPackagePrivateClass, true)
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-1
@@ -19,12 +19,16 @@ import org.jetbrains.kotlin.metadata.ProtoBuf
|
|||||||
import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf
|
import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf
|
||||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.ClassMapperLite
|
import org.jetbrains.kotlin.metadata.jvm.deserialization.ClassMapperLite
|
||||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
|
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
|
||||||
|
import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTable
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.protobuf.GeneratedMessageLite
|
import org.jetbrains.kotlin.protobuf.GeneratedMessageLite
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface
|
||||||
|
import org.jetbrains.kotlin.resolve.annotations.hasJvmDefaultAnnotation
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.nonSourceAnnotations
|
import org.jetbrains.kotlin.resolve.descriptorUtil.nonSourceAnnotations
|
||||||
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
import org.jetbrains.kotlin.serialization.DescriptorSerializer
|
||||||
|
import org.jetbrains.kotlin.serialization.DescriptorSerializer.Companion.writeVersionRequirement
|
||||||
import org.jetbrains.kotlin.serialization.SerializerExtension
|
import org.jetbrains.kotlin.serialization.SerializerExtension
|
||||||
import org.jetbrains.kotlin.types.FlexibleType
|
import org.jetbrains.kotlin.types.FlexibleType
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
@@ -45,7 +49,11 @@ class JvmSerializerExtension(private val bindings: JvmSerializationBindings, sta
|
|||||||
return useTypeTable
|
return useTypeTable
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun serializeClass(descriptor: ClassDescriptor, proto: ProtoBuf.Class.Builder) {
|
override fun serializeClass(
|
||||||
|
descriptor: ClassDescriptor,
|
||||||
|
proto: ProtoBuf.Class.Builder,
|
||||||
|
versionRequirementTable: MutableVersionRequirementTable
|
||||||
|
) {
|
||||||
if (moduleName != JvmAbi.DEFAULT_MODULE_NAME) {
|
if (moduleName != JvmAbi.DEFAULT_MODULE_NAME) {
|
||||||
proto.setExtension(JvmProtoBuf.classModuleName, stringTable.getStringIndex(moduleName))
|
proto.setExtension(JvmProtoBuf.classModuleName, stringTable.getStringIndex(moduleName))
|
||||||
}
|
}
|
||||||
@@ -53,6 +61,26 @@ class JvmSerializerExtension(private val bindings: JvmSerializationBindings, sta
|
|||||||
val containerAsmType =
|
val containerAsmType =
|
||||||
if (DescriptorUtils.isInterface(descriptor)) typeMapper.mapDefaultImpls(descriptor) else typeMapper.mapClass(descriptor)
|
if (DescriptorUtils.isInterface(descriptor)) typeMapper.mapDefaultImpls(descriptor) else typeMapper.mapClass(descriptor)
|
||||||
writeLocalProperties(proto, containerAsmType, JvmProtoBuf.classLocalVariable)
|
writeLocalProperties(proto, containerAsmType, JvmProtoBuf.classLocalVariable)
|
||||||
|
writeVersionRequirementForJvmDefaultIfNeeded(descriptor, proto, versionRequirementTable)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interfaces which have @JvmDefault members somewhere in the hierarchy need the compiler 1.2.40+
|
||||||
|
// so that the generated bridges in subclasses would call the super members correctly
|
||||||
|
private fun writeVersionRequirementForJvmDefaultIfNeeded(
|
||||||
|
classDescriptor: ClassDescriptor,
|
||||||
|
builder: ProtoBuf.Class.Builder,
|
||||||
|
versionRequirementTable: MutableVersionRequirementTable
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
isInterface(classDescriptor) &&
|
||||||
|
classDescriptor.unsubstitutedMemberScope.getContributedDescriptors().any {
|
||||||
|
it is CallableMemberDescriptor && it.hasJvmDefaultAnnotation()
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
assert(!builder.hasVersionRequirement()) { "VersionRequirement should be empty for $classDescriptor" }
|
||||||
|
builder.versionRequirement =
|
||||||
|
writeVersionRequirement(1, 2, 40, ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION, versionRequirementTable)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun serializePackage(packageFqName: FqName, proto: ProtoBuf.Package.Builder) {
|
override fun serializePackage(packageFqName: FqName, proto: ProtoBuf.Package.Builder) {
|
||||||
|
|||||||
+23
-29
@@ -20,8 +20,7 @@ import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTabl
|
|||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumEntry
|
import org.jetbrains.kotlin.resolve.DescriptorUtils.*
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface
|
|
||||||
import org.jetbrains.kotlin.resolve.MemberComparator
|
import org.jetbrains.kotlin.resolve.MemberComparator
|
||||||
import org.jetbrains.kotlin.resolve.RequireKotlinNames
|
import org.jetbrains.kotlin.resolve.RequireKotlinNames
|
||||||
import org.jetbrains.kotlin.resolve.annotations.hasJvmDefaultAnnotation
|
import org.jetbrains.kotlin.resolve.annotations.hasJvmDefaultAnnotation
|
||||||
@@ -144,16 +143,14 @@ class DescriptorSerializer private constructor(
|
|||||||
val requirement = serializeVersionRequirement(classDescriptor)
|
val requirement = serializeVersionRequirement(classDescriptor)
|
||||||
if (requirement != null) {
|
if (requirement != null) {
|
||||||
builder.versionRequirement = requirement
|
builder.versionRequirement = requirement
|
||||||
} else {
|
|
||||||
writeVersionRequirementForJvmDefaultIfNeeded(classDescriptor, builder)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension.serializeClass(classDescriptor, builder, versionRequirementTable)
|
||||||
|
|
||||||
val versionRequirementTableProto = versionRequirementTable.serialize()
|
val versionRequirementTableProto = versionRequirementTable.serialize()
|
||||||
if (versionRequirementTableProto != null) {
|
if (versionRequirementTableProto != null) {
|
||||||
builder.versionRequirementTable = versionRequirementTableProto
|
builder.versionRequirementTable = versionRequirementTableProto
|
||||||
}
|
}
|
||||||
|
|
||||||
extension.serializeClass(classDescriptor, builder)
|
|
||||||
return builder
|
return builder
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -622,19 +619,6 @@ class DescriptorSerializer private constructor(
|
|||||||
return builder
|
return builder
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interfaces which have @JvmDefault members somewhere in the hierarchy need the compiler 1.2.40+
|
|
||||||
// so that the generated bridges in subclasses would call the super members correctly
|
|
||||||
private fun writeVersionRequirementForJvmDefaultIfNeeded(classDescriptor: ClassDescriptor, builder: ProtoBuf.Class.Builder) {
|
|
||||||
if (
|
|
||||||
isInterface(classDescriptor) &&
|
|
||||||
classDescriptor.unsubstitutedMemberScope.getContributedDescriptors().any {
|
|
||||||
it is CallableMemberDescriptor && it.hasJvmDefaultAnnotation()
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
builder.versionRequirement = writeVersionRequirement(1, 2, 40, ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun writeVersionRequirement(languageFeature: LanguageFeature): Int {
|
private fun writeVersionRequirement(languageFeature: LanguageFeature): Int {
|
||||||
val languageVersion = languageFeature.sinceVersion!!
|
val languageVersion = languageFeature.sinceVersion!!
|
||||||
return writeVersionRequirement(
|
return writeVersionRequirement(
|
||||||
@@ -644,16 +628,7 @@ class DescriptorSerializer private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun writeVersionRequirement(major: Int, minor: Int, patch: Int, versionKind: ProtoBuf.VersionRequirement.VersionKind): Int {
|
private fun writeVersionRequirement(major: Int, minor: Int, patch: Int, versionKind: ProtoBuf.VersionRequirement.VersionKind): Int {
|
||||||
val requirement = ProtoBuf.VersionRequirement.newBuilder().apply {
|
return writeVersionRequirement(major, minor, patch, versionKind, versionRequirementTable)
|
||||||
VersionRequirement.Version(major, minor, patch).encode(
|
|
||||||
writeVersion = { version = it },
|
|
||||||
writeVersionFull = { versionFull = it }
|
|
||||||
)
|
|
||||||
if (versionKind != defaultInstanceForType.versionKind) {
|
|
||||||
this.versionKind = versionKind
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return versionRequirementTable[requirement]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns index into versionRequirementTable, or null if there's no @RequireKotlin on the descriptor
|
// Returns index into versionRequirementTable, or null if there's no @RequireKotlin on the descriptor
|
||||||
@@ -782,5 +757,24 @@ class DescriptorSerializer private constructor(
|
|||||||
//NOTE: the exact comparator does matter here
|
//NOTE: the exact comparator does matter here
|
||||||
Collections.sort(this, MemberComparator.INSTANCE)
|
Collections.sort(this, MemberComparator.INSTANCE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun writeVersionRequirement(
|
||||||
|
major: Int,
|
||||||
|
minor: Int,
|
||||||
|
patch: Int,
|
||||||
|
versionKind: ProtoBuf.VersionRequirement.VersionKind,
|
||||||
|
versionRequirementTable: MutableVersionRequirementTable
|
||||||
|
): Int {
|
||||||
|
val requirement = ProtoBuf.VersionRequirement.newBuilder().apply {
|
||||||
|
VersionRequirement.Version(major, minor, patch).encode(
|
||||||
|
writeVersion = { version = it },
|
||||||
|
writeVersionFull = { versionFull = it }
|
||||||
|
)
|
||||||
|
if (versionKind != defaultInstanceForType.versionKind) {
|
||||||
|
this.versionKind = versionKind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return versionRequirementTable[requirement]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-1
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.serialization
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
|
import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTable
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.types.FlexibleType
|
import org.jetbrains.kotlin.types.FlexibleType
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
@@ -27,7 +28,11 @@ abstract class SerializerExtension {
|
|||||||
get() = null
|
get() = null
|
||||||
|
|
||||||
|
|
||||||
open fun serializeClass(descriptor: ClassDescriptor, proto: ProtoBuf.Class.Builder) {
|
open fun serializeClass(
|
||||||
|
descriptor: ClassDescriptor,
|
||||||
|
proto: ProtoBuf.Class.Builder,
|
||||||
|
versionRequirementTable: MutableVersionRequirementTable
|
||||||
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun serializePackage(packageFqName: FqName, proto: ProtoBuf.Package.Builder) {
|
open fun serializePackage(packageFqName: FqName, proto: ProtoBuf.Package.Builder) {
|
||||||
|
|||||||
+6
-1
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.serialization
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
|
import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTable
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.resolve.constants.NullValue
|
import org.jetbrains.kotlin.resolve.constants.NullValue
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.nonSourceAnnotations
|
import org.jetbrains.kotlin.resolve.descriptorUtil.nonSourceAnnotations
|
||||||
@@ -26,7 +27,11 @@ import org.jetbrains.kotlin.types.KotlinType
|
|||||||
open class KotlinSerializerExtensionBase(private val protocol: SerializerExtensionProtocol) : SerializerExtension() {
|
open class KotlinSerializerExtensionBase(private val protocol: SerializerExtensionProtocol) : SerializerExtension() {
|
||||||
override val stringTable = StringTableImpl()
|
override val stringTable = StringTableImpl()
|
||||||
|
|
||||||
override fun serializeClass(descriptor: ClassDescriptor, proto: ProtoBuf.Class.Builder) {
|
override fun serializeClass(
|
||||||
|
descriptor: ClassDescriptor,
|
||||||
|
proto: ProtoBuf.Class.Builder,
|
||||||
|
versionRequirementTable: MutableVersionRequirementTable
|
||||||
|
) {
|
||||||
for (annotation in descriptor.nonSourceAnnotations) {
|
for (annotation in descriptor.nonSourceAnnotations) {
|
||||||
proto.addExtension(protocol.classAnnotation, annotationSerializer.serializeAnnotation(annotation))
|
proto.addExtension(protocol.classAnnotation, annotationSerializer.serializeAnnotation(annotation))
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-2
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
|
|||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
import org.jetbrains.kotlin.metadata.js.JsProtoBuf
|
import org.jetbrains.kotlin.metadata.js.JsProtoBuf
|
||||||
|
import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTable
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite
|
import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite
|
||||||
@@ -41,12 +42,16 @@ class KotlinJavascriptSerializerExtension(
|
|||||||
lowerProto.flexibleTypeCapabilitiesId = stringTable.getStringIndex(DynamicTypeDeserializer.id)
|
lowerProto.flexibleTypeCapabilitiesId = stringTable.getStringIndex(DynamicTypeDeserializer.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun serializeClass(descriptor: ClassDescriptor, proto: ProtoBuf.Class.Builder) {
|
override fun serializeClass(
|
||||||
|
descriptor: ClassDescriptor,
|
||||||
|
proto: ProtoBuf.Class.Builder,
|
||||||
|
versionRequirementTable: MutableVersionRequirementTable
|
||||||
|
) {
|
||||||
val id = getFileId(descriptor)
|
val id = getFileId(descriptor)
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
proto.setExtension(JsProtoBuf.classContainingFileId, id)
|
proto.setExtension(JsProtoBuf.classContainingFileId, id)
|
||||||
}
|
}
|
||||||
super.serializeClass(descriptor, proto)
|
super.serializeClass(descriptor, proto, versionRequirementTable)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun serializeProperty(descriptor: PropertyDescriptor, proto: ProtoBuf.Property.Builder) {
|
override fun serializeProperty(descriptor: PropertyDescriptor, proto: ProtoBuf.Property.Builder) {
|
||||||
|
|||||||
Reference in New Issue
Block a user