J2K serialization: fix compilation and prettify

This commit is contained in:
Alexander Udalov
2016-06-07 15:42:07 +03:00
parent 6692aca5f3
commit 0c0a451d20
5 changed files with 161 additions and 231 deletions
@@ -25,66 +25,62 @@ import org.jetbrains.kotlin.serialization.ProtoBuf.Annotation.Argument.Value.Typ
import org.jetbrains.kotlin.types.ErrorUtils
class AnnotationSerializer(private val stringTable: StringTable) {
fun serializeAnnotation(annotation: AnnotationDescriptor): ProtoBuf.Annotation {
return with(ProtoBuf.Annotation.newBuilder()) {
val annotationClass = annotation.type.constructor.declarationDescriptor as? ClassDescriptor
?: error("Annotation type is not a class: ${annotation.type}")
if (ErrorUtils.isError(annotationClass)) {
error("Unresolved annotation type: ${annotation.type}")
}
setId(stringTable.getFqNameIndex(annotationClass))
for ((parameter, value) in annotation.allValueArguments) {
val argument = ProtoBuf.Annotation.Argument.newBuilder()
argument.setNameId(stringTable.getStringIndex(parameter.name.asString()))
argument.setValue(valueProto(value))
addArgument(argument)
}
build()
fun serializeAnnotation(annotation: AnnotationDescriptor): ProtoBuf.Annotation = ProtoBuf.Annotation.newBuilder().apply {
val annotationClass = annotation.type.constructor.declarationDescriptor as? ClassDescriptor
?: error("Annotation type is not a class: ${annotation.type}")
if (ErrorUtils.isError(annotationClass)) {
error("Unresolved annotation type: ${annotation.type}")
}
}
fun valueProto(constant: ConstantValue<*>): Value.Builder = with(Value.newBuilder()) {
id = stringTable.getFqNameIndex(annotationClass)
for ((parameter, value) in annotation.allValueArguments) {
val argument = ProtoBuf.Annotation.Argument.newBuilder()
argument.nameId = stringTable.getStringIndex(parameter.name.asString())
argument.setValue(valueProto(value))
addArgument(argument)
}
}.build()
fun valueProto(constant: ConstantValue<*>): Value.Builder = Value.newBuilder().apply {
constant.accept(object : AnnotationArgumentVisitor<Unit, Unit> {
override fun visitAnnotationValue(value: AnnotationValue, data: Unit) {
setType(Type.ANNOTATION)
setAnnotation(serializeAnnotation(value.value))
type = Type.ANNOTATION
annotation = serializeAnnotation(value.value)
}
override fun visitArrayValue(value: ArrayValue, data: Unit) {
setType(Type.ARRAY)
type = Type.ARRAY
for (element in value.value) {
addArrayElement(valueProto(element).build())
}
}
override fun visitBooleanValue(value: BooleanValue, data: Unit) {
setType(Type.BOOLEAN)
type = Type.BOOLEAN
setIntValue(if (value.value) 1 else 0)
}
override fun visitByteValue(value: ByteValue, data: Unit) {
setType(Type.BYTE)
setIntValue(value.value.toLong())
type = Type.BYTE
intValue = value.value.toLong()
}
override fun visitCharValue(value: CharValue, data: Unit) {
setType(Type.CHAR)
setIntValue(value.value.toLong())
type = Type.CHAR
intValue = value.value.toLong()
}
override fun visitDoubleValue(value: DoubleValue, data: Unit) {
setType(Type.DOUBLE)
setDoubleValue(value.value)
type = Type.DOUBLE
doubleValue = value.value
}
override fun visitEnumValue(value: EnumValue, data: Unit) {
setType(Type.ENUM)
type = Type.ENUM
val enumEntry = value.value
setClassId(stringTable.getFqNameIndex(enumEntry.containingDeclaration as ClassDescriptor))
setEnumValueId(stringTable.getStringIndex(enumEntry.name.asString()))
classId = stringTable.getFqNameIndex(enumEntry.containingDeclaration as ClassDescriptor)
enumValueId = stringTable.getStringIndex(enumEntry.name.asString())
}
override fun visitErrorValue(value: ErrorValue, data: Unit) {
@@ -92,13 +88,13 @@ class AnnotationSerializer(private val stringTable: StringTable) {
}
override fun visitFloatValue(value: FloatValue, data: Unit) {
setType(Type.FLOAT)
setFloatValue(value.value)
type = Type.FLOAT
floatValue = value.value
}
override fun visitIntValue(value: IntValue, data: Unit) {
setType(Type.INT)
setIntValue(value.value.toLong())
type = Type.INT
intValue = value.value.toLong()
}
override fun visitKClassValue(value: KClassValue?, data: Unit?) {
@@ -107,8 +103,8 @@ class AnnotationSerializer(private val stringTable: StringTable) {
}
override fun visitLongValue(value: LongValue, data: Unit) {
setType(Type.LONG)
setIntValue(value.value)
type = Type.LONG
intValue = value.value
}
override fun visitNullValue(value: NullValue, data: Unit) {
@@ -116,16 +112,14 @@ class AnnotationSerializer(private val stringTable: StringTable) {
}
override fun visitShortValue(value: ShortValue, data: Unit) {
setType(Type.SHORT)
setIntValue(value.value.toLong())
type = Type.SHORT
intValue = value.value.toLong()
}
override fun visitStringValue(value: StringValue, data: Unit) {
setType(Type.STRING)
setStringValue(stringTable.getStringIndex(value.value))
type = Type.STRING
stringValue = stringTable.getStringIndex(value.value)
}
}, Unit)
this
}
}
@@ -27,9 +27,7 @@ import org.jetbrains.kotlin.resolve.MemberComparator
import org.jetbrains.kotlin.resolve.constants.NullValue
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.utils.Interner
import org.jetbrains.kotlin.utils.rethrow
import java.io.ByteArrayOutputStream
import java.io.IOException
import java.util.*
class DescriptorSerializer private constructor(
@@ -37,38 +35,30 @@ class DescriptorSerializer private constructor(
private val typeParameters: Interner<TypeParameterDescriptor>,
private val extension: SerializerExtension,
private val typeTable: MutableTypeTable,
private val serializeTypeTableToFunction: Boolean) {
private val serializeTypeTableToFunction: Boolean
) {
fun serialize(message: MessageLite): ByteArray {
try {
val result = ByteArrayOutputStream()
stringTable.serializeTo(result)
message.writeTo(result)
return result.toByteArray()
}
catch (e: IOException) {
throw rethrow(e)
}
return ByteArrayOutputStream().apply {
stringTable.serializeTo(this)
message.writeTo(this)
}.toByteArray()
}
private fun createChildSerializer(callable: CallableDescriptor): DescriptorSerializer {
return DescriptorSerializer(callable, Interner(typeParameters), extension, typeTable, false)
}
private fun createChildSerializer(callable: CallableDescriptor): DescriptorSerializer =
DescriptorSerializer(callable, Interner(typeParameters), extension, typeTable, serializeTypeTableToFunction = false)
val stringTable: StringTable
get() = extension.stringTable
private fun useTypeTable(): Boolean {
return extension.shouldUseTypeTable()
}
private fun useTypeTable(): Boolean = extension.shouldUseTypeTable()
fun classProto(classDescriptor: ClassDescriptor): ProtoBuf.Class.Builder {
val builder = ProtoBuf.Class.newBuilder()
val flags = Flags.getClassFlags(hasAnnotations(classDescriptor), classDescriptor.visibility, classDescriptor.modality,
classDescriptor.kind, classDescriptor.isInner, classDescriptor.isCompanionObject,
classDescriptor.isData)
val flags = Flags.getClassFlags(
hasAnnotations(classDescriptor), classDescriptor.visibility, classDescriptor.modality, classDescriptor.kind,
classDescriptor.isInner, classDescriptor.isCompanionObject, classDescriptor.isData
)
if (flags != builder.flags) {
builder.flags = flags
}
@@ -99,11 +89,9 @@ class DescriptorSerializer private constructor(
if (descriptor is CallableMemberDescriptor) {
if (descriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) continue
if (descriptor is PropertyDescriptor) {
builder.addProperty(propertyProto(descriptor))
}
else if (descriptor is FunctionDescriptor) {
builder.addFunction(functionProto(descriptor))
when (descriptor) {
is PropertyDescriptor -> builder.addProperty(propertyProto(descriptor))
is FunctionDescriptor -> builder.addFunction(functionProto(descriptor))
}
}
}
@@ -149,37 +137,32 @@ class DescriptorSerializer private constructor(
val isConst = descriptor.isConst
val compileTimeConstant = descriptor.compileTimeInitializer
val hasConstant = !(compileTimeConstant == null || compileTimeConstant is NullValue)
val hasConstant = compileTimeConstant != null && compileTimeConstant !is NullValue
val hasAnnotations = !descriptor.annotations.getAllAnnotations().isEmpty()
val hasAnnotations = descriptor.annotations.getAllAnnotations().isNotEmpty()
val propertyFlags = Flags.getAccessorFlags(
hasAnnotations,
descriptor.visibility,
descriptor.modality,
false,
false)
val propertyFlags = Flags.getAccessorFlags(hasAnnotations, descriptor.visibility, descriptor.modality, false, false)
val getter = descriptor.getGetter()
val getter = descriptor.getter
if (getter != null) {
hasGetter = true
val accessorFlags = getAccessorFlags(getter!!)
val accessorFlags = getAccessorFlags(getter)
if (accessorFlags != propertyFlags) {
builder.getterFlags = accessorFlags
}
}
val setter = descriptor.getSetter()
val setter = descriptor.setter
if (setter != null) {
hasSetter = true
val accessorFlags = getAccessorFlags(setter!!)
val accessorFlags = getAccessorFlags(setter)
if (accessorFlags != propertyFlags) {
builder.setterFlags = accessorFlags
}
if (!setter!!.isDefault()) {
val setterLocal = local.createChildSerializer(setter!!)
for (valueParameterDescriptor in setter!!.getValueParameters()) {
if (!setter.isDefault) {
val setterLocal = local.createChildSerializer(setter)
for (valueParameterDescriptor in setter.valueParameters) {
builder.setSetterValueParameter(setterLocal.valueParameter(valueParameterDescriptor))
}
}
@@ -187,7 +170,8 @@ class DescriptorSerializer private constructor(
val flags = Flags.getPropertyFlags(
hasAnnotations, descriptor.visibility, descriptor.modality, descriptor.kind, descriptor.isVar,
hasGetter, hasSetter, hasConstant, isConst, lateInit)
hasGetter, hasSetter, hasConstant, isConst, lateInit
)
if (flags != builder.flags) {
builder.flags = flags
}
@@ -226,9 +210,8 @@ class DescriptorSerializer private constructor(
val local = createChildSerializer(descriptor)
val flags = Flags.getFunctionFlags(
hasAnnotations(descriptor), descriptor.visibility, descriptor.modality, descriptor.kind,
descriptor.isOperator, descriptor.isInfix, descriptor.isInline, descriptor.isTailrec,
descriptor.isExternal, descriptor.isSuspend
hasAnnotations(descriptor), descriptor.visibility, descriptor.modality, descriptor.kind, descriptor.isOperator,
descriptor.isInfix, descriptor.isInline, descriptor.isTailrec, descriptor.isExternal, descriptor.isSuspend
)
if (flags != builder.flags) {
builder.flags = flags
@@ -237,11 +220,9 @@ class DescriptorSerializer private constructor(
builder.name = getSimpleNameIndex(descriptor.name)
if (useTypeTable()) {
//noinspection ConstantConditions
builder.returnTypeId = local.typeId(descriptor.returnType!!)
}
else {
//noinspection ConstantConditions
builder.setReturnType(local.type(descriptor.returnType!!))
}
@@ -337,8 +318,10 @@ class DescriptorSerializer private constructor(
private fun valueParameter(descriptor: ValueParameterDescriptor): ProtoBuf.ValueParameter.Builder {
val builder = ProtoBuf.ValueParameter.newBuilder()
val flags = Flags.getValueParameterFlags(hasAnnotations(descriptor), descriptor.declaresDefaultValue(),
descriptor.isCrossinline, descriptor.isNoinline, descriptor.isCoroutine)
val flags = Flags.getValueParameterFlags(
hasAnnotations(descriptor), descriptor.declaresDefaultValue(),
descriptor.isCrossinline, descriptor.isNoinline, descriptor.isCoroutine
)
if (flags != builder.flags) {
builder.flags = flags
}
@@ -399,9 +382,7 @@ class DescriptorSerializer private constructor(
return builder
}
private fun typeId(type: KotlinType): Int {
return typeTable[type(type)]
}
private fun typeId(type: KotlinType): Int = typeTable[type(type)]
private fun type(type: KotlinType): ProtoBuf.Type.Builder {
val builder = ProtoBuf.Type.newBuilder()
@@ -416,7 +397,7 @@ class DescriptorSerializer private constructor(
val lowerBound = type(flexibleType.lowerBound)
val upperBound = type(flexibleType.upperBound)
extension.serializeFlexibleType(flexibleType, lowerBound, upperBound);
extension.serializeFlexibleType(flexibleType, lowerBound, upperBound)
if (useTypeTable()) {
lowerBound.flexibleUpperBoundId = typeTable[upperBound]
}
@@ -427,24 +408,21 @@ class DescriptorSerializer private constructor(
}
val descriptor = type.constructor.declarationDescriptor
if (descriptor is ClassDescriptor) {
val possiblyInnerType = type.buildPossiblyInnerType() ?: error("possiblyInnerType should not be null in case of class")
fillFromPossiblyInnerType(builder, possiblyInnerType)
}
else if (descriptor is TypeParameterDescriptor) {
if (descriptor.containingDeclaration === containingDeclaration) {
builder.typeParameterName = getSimpleNameIndex(descriptor.name)
}
else {
builder.typeParameter = getTypeParameterId(descriptor)
when (descriptor) {
is ClassDescriptor, is TypeAliasDescriptor -> {
val possiblyInnerType = type.buildPossiblyInnerType() ?: error("possiblyInnerType should not be null: $type")
fillFromPossiblyInnerType(builder, possiblyInnerType)
}
is TypeParameterDescriptor -> {
if (descriptor.containingDeclaration === containingDeclaration) {
builder.typeParameterName = getSimpleNameIndex(descriptor.name)
}
else {
builder.typeParameter = getTypeParameterId(descriptor)
}
assert(type.arguments.isEmpty()) { "Found arguments for type constructor build on type parameter: " + descriptor }
}
else if (descriptor is TypeAliasDescriptor) {
val possiblyInnerType = type.buildPossiblyInnerType() ?: error("possiblyInnerType should not be null in case of type alias")
fillFromPossiblyInnerType(builder, possiblyInnerType)
assert(type.arguments.isEmpty()) { "Found arguments for type constructor build on type parameter: $descriptor" }
}
}
if (type.isMarkedNullable != builder.nullable) {
@@ -466,16 +444,12 @@ class DescriptorSerializer private constructor(
return builder
}
private fun fillFromPossiblyInnerType(
builder: ProtoBuf.Type.Builder,
type: PossiblyInnerType) {
private fun fillFromPossiblyInnerType(builder: ProtoBuf.Type.Builder, type: PossiblyInnerType) {
val classifierDescriptor = type.classifierDescriptor
val classifierId = getClassifierId(classifierDescriptor)
if (classifierDescriptor is ClassDescriptor) {
builder.className = classifierId
}
else if (classifierDescriptor is TypeAliasDescriptor) {
builder.typeAliasName = classifierId
when (classifierDescriptor) {
is ClassDescriptor -> builder.className = classifierId
is TypeAliasDescriptor -> builder.typeAliasName = classifierId
}
for (projection in type.arguments) {
@@ -491,7 +465,6 @@ class DescriptorSerializer private constructor(
else {
builder.setOuterType(outerBuilder)
}
}
}
@@ -519,24 +492,22 @@ class DescriptorSerializer private constructor(
return builder
}
@JvmOverloads fun packageProto(
fragments: Collection<PackageFragmentDescriptor>,
skip: Function1<DeclarationDescriptor, Boolean>? = null): ProtoBuf.Package.Builder {
@JvmOverloads
fun packageProto(
fragments: Collection<PackageFragmentDescriptor>, skip: ((DeclarationDescriptor) -> Boolean)? = null
): ProtoBuf.Package.Builder {
val builder = ProtoBuf.Package.newBuilder()
val members = ArrayList<DeclarationDescriptor>()
for (fragment in fragments) {
members.addAll(DescriptorUtils.getAllDescriptors(fragment.getMemberScope()))
val members = fragments.flatMap { fragment ->
DescriptorUtils.getAllDescriptors(fragment.getMemberScope())
}
for (declaration in sort(members)) {
if (skip != null && skip.invoke(declaration)) continue
if (skip?.invoke(declaration) == true) continue
if (declaration is PropertyDescriptor) {
builder.addProperty(propertyProto(declaration))
}
else if (declaration is FunctionDescriptor) {
builder.addFunction(functionProto(declaration))
when (declaration) {
is PropertyDescriptor -> builder.addProperty(propertyProto(declaration))
is FunctionDescriptor -> builder.addFunction(functionProto(declaration))
}
}
@@ -554,14 +525,10 @@ class DescriptorSerializer private constructor(
val builder = ProtoBuf.Package.newBuilder()
for (declaration in sort(members)) {
if (declaration is PropertyDescriptor) {
builder.addProperty(propertyProto(declaration))
}
else if (declaration is FunctionDescriptor) {
builder.addFunction(functionProto(declaration))
}
else if (declaration is TypeAliasDescriptor) {
builder.addTypeAlias(typeAliasProto(declaration))
when (declaration) {
is PropertyDescriptor -> builder.addProperty(propertyProto(declaration))
is FunctionDescriptor -> builder.addFunction(functionProto(declaration))
is TypeAliasDescriptor -> builder.addTypeAlias(typeAliasProto(declaration))
}
}
@@ -575,27 +542,24 @@ class DescriptorSerializer private constructor(
return builder
}
private fun getClassifierId(descriptor: ClassifierDescriptorWithTypeParameters): Int {
return stringTable.getFqNameIndex(descriptor)
}
private fun getClassifierId(descriptor: ClassifierDescriptorWithTypeParameters): Int =
stringTable.getFqNameIndex(descriptor)
private fun getSimpleNameIndex(name: Name): Int {
return stringTable.getStringIndex(name.asString())
}
private fun getSimpleNameIndex(name: Name): Int =
stringTable.getStringIndex(name.asString())
private fun getTypeParameterId(descriptor: TypeParameterDescriptor): Int {
return typeParameters.intern(descriptor)
}
private fun getTypeParameterId(descriptor: TypeParameterDescriptor): Int =
typeParameters.intern(descriptor)
companion object {
@JvmStatic
fun createTopLevel(extension: SerializerExtension): DescriptorSerializer {
return DescriptorSerializer(null, Interner<TypeParameterDescriptor>(), extension, MutableTypeTable(), false)
return DescriptorSerializer(null, Interner(), extension, MutableTypeTable(), serializeTypeTableToFunction = false)
}
@JvmStatic
fun createForLambda(extension: SerializerExtension): DescriptorSerializer {
return DescriptorSerializer(null, Interner<TypeParameterDescriptor>(), extension, MutableTypeTable(), true)
return DescriptorSerializer(null, Interner(), extension, MutableTypeTable(), serializeTypeTableToFunction = true)
}
@JvmStatic
@@ -614,7 +578,8 @@ class DescriptorSerializer private constructor(
Interner(parentSerializer.typeParameters),
parentSerializer.extension,
MutableTypeTable(),
false)
serializeTypeTableToFunction = false
)
for (typeParameter in descriptor.declaredTypeParameters) {
serializer.typeParameters.intern(typeParameter)
}
@@ -627,37 +592,28 @@ class DescriptorSerializer private constructor(
accessor.visibility,
accessor.modality,
!accessor.isDefault,
accessor.isExternal)
accessor.isExternal
)
}
private fun variance(variance: Variance): ProtoBuf.TypeParameter.Variance {
when (variance) {
Variance.INVARIANT -> return ProtoBuf.TypeParameter.Variance.INV
Variance.IN_VARIANCE -> return ProtoBuf.TypeParameter.Variance.IN
Variance.OUT_VARIANCE -> return ProtoBuf.TypeParameter.Variance.OUT
}
throw IllegalStateException("Unknown variance: " + variance)
private fun variance(variance: Variance): ProtoBuf.TypeParameter.Variance = when (variance) {
Variance.INVARIANT -> ProtoBuf.TypeParameter.Variance.INV
Variance.IN_VARIANCE -> ProtoBuf.TypeParameter.Variance.IN
Variance.OUT_VARIANCE -> ProtoBuf.TypeParameter.Variance.OUT
}
private fun projection(projectionKind: Variance): ProtoBuf.Type.Argument.Projection {
when (projectionKind) {
Variance.INVARIANT -> return ProtoBuf.Type.Argument.Projection.INV
Variance.IN_VARIANCE -> return ProtoBuf.Type.Argument.Projection.IN
Variance.OUT_VARIANCE -> return ProtoBuf.Type.Argument.Projection.OUT
}
throw IllegalStateException("Unknown projectionKind: " + projectionKind)
private fun projection(projectionKind: Variance): ProtoBuf.Type.Argument.Projection = when (projectionKind) {
Variance.INVARIANT -> ProtoBuf.Type.Argument.Projection.INV
Variance.IN_VARIANCE -> ProtoBuf.Type.Argument.Projection.IN
Variance.OUT_VARIANCE -> ProtoBuf.Type.Argument.Projection.OUT
}
private fun hasAnnotations(descriptor: Annotated): Boolean {
return !descriptor.annotations.isEmpty()
}
private fun hasAnnotations(descriptor: Annotated): Boolean = !descriptor.annotations.isEmpty()
fun <T : DeclarationDescriptor> sort(descriptors: Collection<T>): List<T> {
val result = ArrayList(descriptors)
//NOTE: the exact comparator does matter here
Collections.sort(result, MemberComparator.INSTANCE)
return result
}
fun <T : DeclarationDescriptor> sort(descriptors: Collection<T>): List<T> =
ArrayList(descriptors).apply {
//NOTE: the exact comparator does matter here
Collections.sort(this, MemberComparator.INSTANCE)
}
}
}
@@ -23,9 +23,7 @@ import org.jetbrains.kotlin.types.KotlinType
abstract class SerializerExtension {
abstract val stringTable: StringTable
open fun shouldUseTypeTable(): Boolean {
return false
}
open fun shouldUseTypeTable(): Boolean = false
open fun serializeClass(descriptor: ClassDescriptor, proto: ProtoBuf.Class.Builder) {
}
@@ -58,6 +56,6 @@ abstract class SerializerExtension {
}
open fun serializeErrorType(type: KotlinType, builder: ProtoBuf.Type.Builder) {
throw IllegalStateException("Cannot serialize error type: " + type)
throw IllegalStateException("Cannot serialize error type: $type")
}
}
@@ -21,11 +21,9 @@ import org.jetbrains.kotlin.resolve.constants.NullValue
import org.jetbrains.kotlin.types.KotlinType
open class KotlinSerializerExtensionBase(private val protocol: SerializerExtensionProtocol) : SerializerExtension() {
private val stringTable = StringTableImpl()
override final val stringTable = StringTableImpl()
private val annotationSerializer = AnnotationSerializer(stringTable)
override fun getStringTable(): StringTableImpl = stringTable
override fun serializeClass(descriptor: ClassDescriptor, proto: ProtoBuf.Class.Builder) {
for (annotation in descriptor.annotations) {
proto.addExtension(protocol.classAnnotation, annotationSerializer.serializeAnnotation(annotation))
@@ -77,4 +75,4 @@ open class KotlinSerializerExtensionBase(private val protocol: SerializerExtensi
proto.addExtension(protocol.typeParameterAnnotation, annotationSerializer.serializeAnnotation(annotation))
}
}
}
}
@@ -18,22 +18,16 @@ package org.jetbrains.kotlin.serialization
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.utils.*
import org.jetbrains.kotlin.utils.Interner
import java.io.IOException
import java.io.OutputStream
import org.jetbrains.kotlin.serialization.ProtoBuf.QualifiedNameTable.QualifiedName
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.utils.Interner
import java.io.OutputStream
class StringTableImpl : StringTable {
private class FqNameProto(val fqName: QualifiedName.Builder) {
override fun hashCode(): Int {
var result = 13
result = 31 * result + fqName.parentQualifiedName
@@ -42,47 +36,43 @@ class StringTableImpl : StringTable {
return result
}
override fun equals(obj: Any?): Boolean {
if (obj == null || javaClass != obj.javaClass) return false
override fun equals(other: Any?): Boolean {
if (other == null || other !is FqNameProto) return false
val other = (obj as FqNameProto).fqName
return fqName.parentQualifiedName == other.parentQualifiedName
&& fqName.shortName == other.shortName
&& fqName.kind == other.kind
val otherFqName = other.fqName
return fqName.parentQualifiedName == otherFqName.parentQualifiedName
&& fqName.shortName == otherFqName.shortName
&& fqName.kind == otherFqName.kind
}
}
private val strings = Interner<String>()
private val qualifiedNames = Interner<FqNameProto>()
fun getSimpleNameIndex(name: Name): Int {
return getStringIndex(name.asString())
}
fun getSimpleNameIndex(name: Name): Int = getStringIndex(name.asString())
override fun getStringIndex(string: String): Int {
return strings.intern(string)
}
override fun getStringIndex(string: String): Int = strings.intern(string)
override fun getFqNameIndex(descriptor: ClassifierDescriptorWithTypeParameters): Int {
if (ErrorUtils.isError(descriptor)) {
throw IllegalStateException("Cannot get FQ name of error class: " + descriptor)
throw IllegalStateException("Cannot get FQ name of error class: $descriptor")
}
val builder = QualifiedName.newBuilder()
builder.kind = QualifiedName.Kind.CLASS
val containingDeclaration = descriptor.containingDeclaration
if (containingDeclaration is PackageFragmentDescriptor) {
val packageFqName = containingDeclaration.fqName
if (!packageFqName.isRoot) {
builder.parentQualifiedName = getPackageFqNameIndex(packageFqName)
when (containingDeclaration) {
is PackageFragmentDescriptor -> {
val packageFqName = containingDeclaration.fqName
if (!packageFqName.isRoot) {
builder.parentQualifiedName = getPackageFqNameIndex(packageFqName)
}
}
}
else if (containingDeclaration is ClassDescriptor) {
builder.parentQualifiedName = getFqNameIndex(containingDeclaration)
}
else {
throw IllegalStateException("Cannot get FQ name of local class: " + descriptor)
is ClassDescriptor -> {
builder.parentQualifiedName = getFqNameIndex(containingDeclaration)
}
else -> throw IllegalStateException("Cannot get FQ name of local class: " + descriptor)
}
builder.shortName = getStringIndex(descriptor.name.asString())
@@ -118,14 +108,8 @@ class StringTableImpl : StringTable {
}
override fun serializeTo(output: OutputStream) {
try {
val protos = buildProto()
protos.first.writeDelimitedTo(output)
protos.second.writeDelimitedTo(output)
}
catch (e: IOException) {
throw rethrow(e)
}
val (strings, qualifiedNames) = buildProto()
strings.writeDelimitedTo(output)
qualifiedNames.writeDelimitedTo(output)
}
}