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