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
This commit is contained in:
Alexander Udalov
2017-05-17 16:06:08 +03:00
parent 6d47991172
commit 7f73e9f4f7
3 changed files with 21 additions and 26 deletions
@@ -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)
}
}
@@ -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 {
@@ -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))
}