From 7f73e9f4f7a5eb8e2e125e7f2e45897668c58c02 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 17 May 2017 16:06:08 +0300 Subject: [PATCH] Improve hack in BuiltInsSerializerExtension for ranges Serialize class names as qualified names in the string table, not as simple strings. Otherwise NameResolverImpl crashes on deserialization because it expects that all class names are indices into QualifiedName table --- .../builtins/BuiltInsSerializerExtension.kt | 18 +++++++------ .../kotlin/serialization/StringTable.kt | 2 -- .../kotlin/serialization/StringTableImpl.kt | 27 ++++++++----------- 3 files changed, 21 insertions(+), 26 deletions(-) diff --git a/compiler/builtins-serializer/src/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializerExtension.kt b/compiler/builtins-serializer/src/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializerExtension.kt index 338b57e3159..c18ad7465c2 100644 --- a/compiler/builtins-serializer/src/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializerExtension.kt +++ b/compiler/builtins-serializer/src/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializerExtension.kt @@ -17,17 +17,19 @@ package org.jetbrains.kotlin.serialization.builtins import org.jetbrains.kotlin.builtins.BuiltInSerializerProtocol +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.serialization.KotlinSerializerExtensionBase import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.UnresolvedType class BuiltInsSerializerExtension : KotlinSerializerExtensionBase(BuiltInSerializerProtocol) { - private val shortNameToFullName = mapOf( - "IntRange" to "kotlin/ranges/IntRange", - "LongRange" to "kotlin/ranges/LongRange", - "CharRange" to "kotlin/ranges/CharRange" - ) + private val shortNameToClassId = mapOf( + "IntRange" to "kotlin.ranges.IntRange", + "LongRange" to "kotlin.ranges.LongRange", + "CharRange" to "kotlin.ranges.CharRange" + ).mapValues { (_, value) -> ClassId.topLevel(FqName(value)) } override fun shouldUseTypeTable(): Boolean = true @@ -37,9 +39,9 @@ class BuiltInsSerializerExtension : KotlinSerializerExtensionBase(BuiltInSeriali throw UnsupportedOperationException("Error types which are not UnresolvedType instances are not supported here: $unwrapped") } - val fullName = shortNameToFullName[unwrapped.presentableName] - ?: throw UnsupportedOperationException("Unsupported unresolved type: $unwrapped") + val classId = shortNameToClassId[unwrapped.presentableName] + ?: throw UnsupportedOperationException("Unsupported unresolved type: $unwrapped") - builder.className = stringTable.getStringIndex(fullName) + builder.className = stringTable.getClassIdIndex(classId) } } diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/StringTable.kt b/compiler/serialization/src/org/jetbrains/kotlin/serialization/StringTable.kt index d96eee8272d..e711050db90 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/StringTable.kt +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/StringTable.kt @@ -16,9 +16,7 @@ package org.jetbrains.kotlin.serialization -import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters - import java.io.OutputStream interface StringTable { diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/StringTableImpl.kt b/compiler/serialization/src/org/jetbrains/kotlin/serialization/StringTableImpl.kt index 864c4760384..427139e58a5 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/StringTableImpl.kt +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/StringTableImpl.kt @@ -16,11 +16,11 @@ package org.jetbrains.kotlin.serialization -import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters -import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor +import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.descriptorUtil.classId import org.jetbrains.kotlin.serialization.ProtoBuf.QualifiedNameTable.QualifiedName import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.utils.Interner @@ -58,24 +58,19 @@ open class StringTableImpl : StringTable { throw IllegalStateException("Cannot get FQ name of error class: $descriptor") } + val classId = descriptor.classId ?: return getFqNameIndexOfLocalAnonymousClass(descriptor) + return getClassIdIndex(classId) + } + + fun getClassIdIndex(classId: ClassId): Int { val builder = QualifiedName.newBuilder() builder.kind = QualifiedName.Kind.CLASS - val containingDeclaration = descriptor.containingDeclaration - when (containingDeclaration) { - is PackageFragmentDescriptor -> { - val packageFqName = containingDeclaration.fqName - if (!packageFqName.isRoot) { - builder.parentQualifiedName = getPackageFqNameIndex(packageFqName) - } - } - is ClassDescriptor -> { - builder.parentQualifiedName = getFqNameIndex(containingDeclaration) - } - else -> return getFqNameIndexOfLocalAnonymousClass(descriptor) - } + builder.parentQualifiedName = + classId.outerClassId?.let(this::getClassIdIndex) + ?: getPackageFqNameIndex(classId.packageFqName) - builder.shortName = getStringIndex(descriptor.name.asString()) + builder.shortName = getStringIndex(classId.shortClassName.asString()) return qualifiedNames.intern(FqNameProto(builder)) }