Fix serialization of type parameters inner generic class
The call to `createTopLevel` instead of `create` (which creates
serializers for outer classes properly, with correct type parameter
contexts) caused MetadataSerializer to write type parameter metadata
incorrectly. For example, in the following case:
class A<E> {
inner class B<T, E> { ... }
}
A's type parameter E would get id 0, and B's type parameters T and E
would get ids 0 and 1. This is a problem because ids are supposed to be
unique for each class including its outer classes, and deserializer,
decompiler and stub builder rely on this assumption.
JVM metadata is unaffected because `create` is called correctly there,
see MemberCodegen#generateKotlinClassMetadataAnnotation
#KT-24944 Fixed
This commit is contained in:
+6
-6
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.serialization.js
|
||||
|
||||
import org.jetbrains.kotlin.config.AnalysisFlag
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.isPreRelease
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
@@ -197,15 +196,16 @@ object KotlinJavascriptSerializationUtil {
|
||||
}
|
||||
|
||||
val fileRegistry = KotlinFileRegistry()
|
||||
val serializerExtension = KotlinJavascriptSerializerExtension(fileRegistry)
|
||||
val serializer = DescriptorSerializer.createTopLevel(serializerExtension)
|
||||
val extension = KotlinJavascriptSerializerExtension(fileRegistry)
|
||||
|
||||
val classDescriptors = scope.filterIsInstance<ClassDescriptor>().sortedBy { it.fqNameSafe.asString() }
|
||||
|
||||
fun serializeClasses(descriptors: Collection<DeclarationDescriptor>) {
|
||||
fun serializeClass(classDescriptor: ClassDescriptor) {
|
||||
if (skip(classDescriptor)) return
|
||||
val classProto = serializer.classProto(classDescriptor).build() ?: error("Class not serialized: $classDescriptor")
|
||||
val classProto =
|
||||
DescriptorSerializer.create(classDescriptor, extension).classProto(classDescriptor).build()
|
||||
?: error("Class not serialized: $classDescriptor")
|
||||
builder.addClass_(classProto)
|
||||
serializeClasses(classDescriptor.unsubstitutedInnerClassesScope.getContributedDescriptors())
|
||||
}
|
||||
@@ -219,10 +219,10 @@ object KotlinJavascriptSerializationUtil {
|
||||
|
||||
serializeClasses(classDescriptors)
|
||||
|
||||
val stringTable = serializerExtension.stringTable
|
||||
val stringTable = extension.stringTable
|
||||
|
||||
val members = scope.filterNot(skip)
|
||||
builder.`package` = serializer.packagePartProto(fqName, members).build()
|
||||
builder.`package` = DescriptorSerializer.createTopLevel(extension).packagePartProto(fqName, members).build()
|
||||
|
||||
builder.setExtension(
|
||||
JsProtoBuf.packageFragmentFiles,
|
||||
|
||||
Reference in New Issue
Block a user