Updates for new API

This commit is contained in:
Leonid Startsev
2018-07-20 19:10:19 +03:00
parent 2e50e4e816
commit 566e5ce603
9 changed files with 62 additions and 43 deletions
@@ -8,7 +8,7 @@ configureJvmProject(project)
configurePublishing(project)
group = 'org.jetbrains.kotlinx'
version = '0.5.2'
version = '0.6.2'
if (!project.hasProperty("deploy")) {
version = "$version-SNAPSHOT"
}
@@ -45,7 +45,7 @@ class SerializationKotlinGradleSubplugin : KotlinGradleSubplugin<AbstractCompile
}
private val log = Logging.getLogger(this.javaClass)
private val pluginVersion = findPluginVersion(log)
private val pluginVersion = "0.6.2-SNAPSHOT"
override fun isApplicable(project: Project, task: AbstractCompile) = SerializationGradleSubplugin.isEnabled(project)
@@ -69,8 +69,14 @@ abstract class SerializerCodegen(
return !found
}
protected val serialDescPropertyDescriptor = getPropertyToGenerate(serializerDescriptor, SerialEntityNames.SERIAL_DESC_FIELD,
protected val generatedSerialDescPropertyDescriptor = getPropertyToGenerate(
serializerDescriptor, SerialEntityNames.SERIAL_DESC_FIELD,
serializerDescriptor::checkSerializableClassPropertyResult)
protected val anySerialDescProperty = getProperty(
serializerDescriptor, SerialEntityNames.SERIAL_DESC_FIELD,
serializerDescriptor::checkSerializableClassPropertyResult
) { true }
protected abstract fun generateSerialDesc()
protected abstract fun generateGenericFieldsAndConstructor(typedConstructorDescriptor: ConstructorDescriptor)
@@ -82,7 +88,7 @@ abstract class SerializerCodegen(
protected abstract fun generateLoad(function: FunctionDescriptor)
private fun generateSerializableClassPropertyIfNeeded(): Boolean {
val property = serialDescPropertyDescriptor
val property = generatedSerialDescPropertyDescriptor
?: return false
generateSerializableClassProperty(property)
return true
@@ -108,14 +114,29 @@ abstract class SerializerCodegen(
classDescriptor: ClassDescriptor,
name: String,
isReturnTypeOk: (PropertyDescriptor) -> Boolean
): PropertyDescriptor? =
classDescriptor.unsubstitutedMemberScope.getContributedVariables(Name.identifier(name), NoLookupLocation.FROM_BACKEND)
.singleOrNull { property ->
property.kind.let { kind -> kind == CallableMemberDescriptor.Kind.SYNTHESIZED || kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE } &&
property.modality != Modality.FINAL &&
property.returnType != null &&
isReturnTypeOk(property)
}
): PropertyDescriptor? = getProperty(
classDescriptor,
name,
isReturnTypeOk
) { kind ->
kind == CallableMemberDescriptor.Kind.SYNTHESIZED || kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE
}
fun getProperty(
classDescriptor: ClassDescriptor,
name: String,
isReturnTypeOk: (PropertyDescriptor) -> Boolean,
isKindOk: (CallableMemberDescriptor.Kind) -> Boolean
): PropertyDescriptor? = classDescriptor.unsubstitutedMemberScope.getContributedVariables(
Name.identifier(name),
NoLookupLocation.FROM_BACKEND
)
.singleOrNull { property ->
isKindOk(property.kind) &&
property.modality != Modality.FINAL &&
property.returnType != null &&
isReturnTypeOk(property)
}
protected fun ClassDescriptor.getFuncDesc(funcName: String): Sequence<FunctionDescriptor> =
unsubstitutedMemberScope.getDescriptorsFiltered { it == Name.identifier(funcName) }.asSequence().filterIsInstance<FunctionDescriptor>()
@@ -49,7 +49,7 @@ class SerializerIrGenerator(val irClass: IrClass, override val compilerContext:
override val translator: TypeTranslator = TypeTranslator(compilerContext.symbolTable)
override fun generateSerialDesc() {
val desc: PropertyDescriptor = serialDescPropertyDescriptor ?: return
val desc: PropertyDescriptor = generatedSerialDescPropertyDescriptor ?: return
val serialDescImplClass = serializerDescriptor
.getClassFromInternalSerializationPackage(SERIAL_DESCRIPTOR_CLASS_IMPL)
val serialDescImplConstructor = serialDescImplClass
@@ -97,7 +97,7 @@ class SerializerIrGenerator(val irClass: IrClass, override val compilerContext:
+irSetField(
generateReceiverExpressionForFieldAccess(
thisAsReceiverParameter.symbol,
serialDescPropertyDescriptor
generatedSerialDescPropertyDescriptor
),
prop.backingField!!,
irGet(localDesc)
@@ -168,7 +168,7 @@ class SerializerIrGenerator(val irClass: IrClass, override val compilerContext:
val kOutputClass = serializerDescriptor.getClassFromSerializationPackage(STRUCTURE_ENCODER_CLASS)
val descriptorGetterSymbol = compilerContext.symbolTable.referenceFunction(serialDescPropertyDescriptor?.getter!!)
val descriptorGetterSymbol = compilerContext.symbolTable.referenceFunction(anySerialDescProperty?.getter!!)
val localSerialDesc = irTemporary(irGet(descriptorGetterSymbol.owner.returnType, irThis(), descriptorGetterSymbol), "desc")
@@ -256,7 +256,7 @@ class SerializerIrGenerator(val irClass: IrClass, override val compilerContext:
fun IrVariable.get() = irGet(this)
val inputClass = serializerDescriptor.getClassFromSerializationPackage(STRUCTURE_DECODER_CLASS)
val descriptorGetterSymbol = compilerContext.symbolTable.referenceFunction(serialDescPropertyDescriptor?.getter!!)
val descriptorGetterSymbol = compilerContext.symbolTable.referenceFunction(anySerialDescProperty?.getter!!)
val localSerialDesc = irTemporary(irGet(descriptorGetterSymbol.owner.returnType, irThis(), descriptorGetterSymbol), "desc")
// workaround due to unavailability of labels (KT-25386)
@@ -27,10 +27,8 @@ import org.jetbrains.kotlin.js.translate.declaration.DefaultPropertyTranslator
import org.jetbrains.kotlin.js.translate.general.Translation
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtPureClassOrObject
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.builtIns
import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializerCodegen
@@ -41,7 +39,6 @@ import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.enumSerializerId
import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.referenceArraySerializerId
import org.jetbrains.kotlinx.serialization.compiler.resolve.*
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.SERIAL_DESCRIPTOR_CLASS_IMPL
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.STRUCTURE_ENCODER_CLASS
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.typeArgPrefix
class SerializerJsTranslator(declaration: KtPureClassOrObject,
@@ -55,7 +52,7 @@ class SerializerJsTranslator(declaration: KtPureClassOrObject,
override fun generateSerialDesc() {
val desc = serialDescPropertyDescriptor ?: return
val desc = generatedSerialDescPropertyDescriptor ?: return
val serialDescImplClass = serializerDescriptor
.getClassFromInternalSerializationPackage(SERIAL_DESCRIPTOR_CLASS_IMPL)
val serialDescImplConstructor = serialDescImplClass
@@ -70,7 +67,7 @@ class SerializerJsTranslator(declaration: KtPureClassOrObject,
val addFunc = serialDescImplClass.getFuncDesc(CallingConventions.addElement).single()
val pushFunc = serialDescImplClass.getFuncDesc(CallingConventions.addAnnotation).single()
val pushClassFunc = serialDescImplClass.getFuncDesc(CallingConventions.addClassAnnotation).single()
val serialClassDescRef = JsNameRef(context.getNameForDescriptor(serialDescPropertyDescriptor), JsThisRef())
val serialClassDescRef = JsNameRef(context.getNameForDescriptor(generatedSerialDescPropertyDescriptor), JsThisRef())
for (prop in orderedProperties) {
if (prop.transient) continue
@@ -96,7 +93,7 @@ class SerializerJsTranslator(declaration: KtPureClassOrObject,
}
override fun generateSerializableClassProperty(property: PropertyDescriptor) {
val propDesc = serialDescPropertyDescriptor ?: return
val propDesc = generatedSerialDescPropertyDescriptor ?: return
val propTranslator = DefaultPropertyTranslator(propDesc, context,
translator.getBackingFieldReference(propDesc))
val getterDesc = propDesc.getter!!
@@ -122,10 +119,11 @@ class SerializerJsTranslator(declaration: KtPureClassOrObject,
}
override fun generateSave(function: FunctionDescriptor) = generateFunction(function) { jsFun, ctx ->
val encoderClass = serializerDescriptor.getClassFromSerializationPackage(SerialEntityNames.ENCODER_CLASS)
val kOutputClass = serializerDescriptor.getClassFromSerializationPackage(SerialEntityNames.STRUCTURE_ENCODER_CLASS)
val wBeginFunc = ctx.getNameForDescriptor(
kOutputClass.getFuncDesc(CallingConventions.begin).single { it.valueParameters.size == 2 })
val serialClassDescRef = JsNameRef(context.getNameForDescriptor(serialDescPropertyDescriptor!!), JsThisRef())
encoderClass.getFuncDesc(CallingConventions.begin).single { it.valueParameters.size == 2 })
val serialClassDescRef = JsNameRef(context.getNameForDescriptor(anySerialDescProperty!!), JsThisRef())
// output.writeBegin(desc, [])
val typeParams = serializableDescriptor.declaredTypeParameters.mapIndexed { idx, _ ->
@@ -212,7 +210,8 @@ class SerializerJsTranslator(declaration: KtPureClassOrObject,
override fun generateLoad(function: FunctionDescriptor) = generateFunction(function) { jsFun, context ->
val inputClass = serializerDescriptor.getClassFromSerializationPackage(SerialEntityNames.STRUCTURE_DECODER_CLASS)
val serialClassDescRef = JsNameRef(context.getNameForDescriptor(serialDescPropertyDescriptor!!), JsThisRef())
val decoderClass = serializerDescriptor.getClassFromSerializationPackage(SerialEntityNames.DECODER_CLASS)
val serialClassDescRef = JsNameRef(context.getNameForDescriptor(anySerialDescProperty!!), JsThisRef())
// var index = -1, readAll = false
val indexVar = JsNameRef(jsFun.scope.declareFreshName("index"))
@@ -236,7 +235,7 @@ class SerializerJsTranslator(declaration: KtPureClassOrObject,
JsNameRef(context.scope().declareName("$typeArgPrefix$idx"), JsThisRef())
}
val inputVar = JsNameRef(jsFun.scope.declareFreshName("input"))
val readBeginF = inputClass.getFuncDesc(CallingConventions.begin).single()
val readBeginF = decoderClass.getFuncDesc(CallingConventions.begin).single()
val call = JsInvocation(JsNameRef(context.getNameForDescriptor(readBeginF), JsNameRef(jsFun.parameters[0].name)),
serialClassDescRef, JsArrayLiteral(typeParams))
+JsVars(JsVars.JsVar(inputVar.name, call))
@@ -312,12 +311,7 @@ class SerializerJsTranslator(declaration: KtPureClassOrObject,
}
// char unboxing crutch
if (KotlinBuiltIns.isCharOrNullableChar(property.type)) {
// can't use KotlinCompilerVersion.VERSION because javac inlines final string literal :(
val coerceTo = if (KotlinVersion.CURRENT.run { major == 1 && minor == 2 && patch in (0..10) }) {
context.currentModule.builtIns.charType
} else {
TranslationUtils.getReturnTypeForCoercion(property.descriptor)
}
val coerceTo = TranslationUtils.getReturnTypeForCoercion(property.descriptor)
+JsAstUtils.assignment(
localProps[i],
TranslationUtils.coerce(context, localProps[i], coerceTo)
@@ -30,6 +30,8 @@ import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerialTypeInfo
import org.jetbrains.kotlinx.serialization.compiler.backend.common.findTypeSerializer
import org.jetbrains.kotlinx.serialization.compiler.resolve.*
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.DECODER_CLASS
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.ENCODER_CLASS
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.KSERIALIZER_CLASS
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.MISSING_FIELD_EXC
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.SERIAL_CTOR_MARKER_NAME
@@ -51,6 +53,8 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
internal val descType = Type.getObjectType("kotlinx/serialization/$SERIAL_DESCRIPTOR_CLASS")
internal val descImplType = Type.getObjectType("kotlinx/serialization/internal/$SERIAL_DESCRIPTOR_CLASS_IMPL")
internal val kOutputType = Type.getObjectType("kotlinx/serialization/$STRUCTURE_ENCODER_CLASS")
internal val encoderType = Type.getObjectType("kotlinx/serialization/$ENCODER_CLASS")
internal val decoderType = Type.getObjectType("kotlinx/serialization/$DECODER_CLASS")
internal val kInputType = Type.getObjectType("kotlinx/serialization/$STRUCTURE_DECODER_CLASS")
@@ -198,7 +202,7 @@ internal fun stackValueSerializerInstance(codegen: ClassBodyCodegen, module: Mod
assert(stackValueSerializerInstance(codegen, module, argType, argSerializer, this, argType.genericIndex, genericSerializerFieldGetter))
// wrap into nullable serializer if argType is nullable
if (argType.isMarkedNullable) {
invokestatic("kotlinx/serialization/internal/BuiltinSerializersKt", "makeNullable", // todo: extract?
invokestatic("kotlinx/serialization/internal/NullableSerializerKt", "makeNullable", // todo: extract?
"(" + kSerializerType.descriptor + ")" + kSerializerType.descriptor, false)
}
@@ -160,11 +160,11 @@ class SerializerCodegenImpl(
serialCLassDescToLocalVar(descVar)
val objType = signature.valueParameters[1].asmType
// output = output.writeBegin(classDesc, new KSerializer[0])
load(outputVar, kOutputType)
load(outputVar, encoderType)
load(descVar, descType)
genArrayOfTypeParametersSerializers()
invokeinterface(
kOutputType.internalName, CallingConventions.begin,
encoderType.internalName, CallingConventions.begin,
"(" + descType.descriptor + kSerializerArrayType.descriptor +
")" + kOutputType.descriptor)
store(outputVar, kOutputType)
@@ -253,11 +253,11 @@ class SerializerCodegenImpl(
propVar += propertyType.size
}
// input = input.readBegin(classDesc, new KSerializer[0])
load(inputVar, kInputType)
load(inputVar, decoderType)
load(descVar, descType)
genArrayOfTypeParametersSerializers()
invokeinterface(
kInputType.internalName, CallingConventions.begin,
decoderType.internalName, CallingConventions.begin,
"(" + descType.descriptor + kSerializerArrayType.descriptor +
")" + kInputType.descriptor)
store(inputVar, kInputType)
@@ -148,7 +148,7 @@ fun getSerializableClassDescriptorBySerializer(serializerDescriptor: ClassDescri
}
fun ClassDescriptor.checkSerializableClassPropertyResult(prop: PropertyDescriptor): Boolean =
prop.returnType!!.isSubtypeOf(getClassFromSerializationPackage("SerialDescriptor").toSimpleType(false)) // todo: cache lookup
prop.returnType!!.isSubtypeOf(getClassFromSerializationPackage(SerialEntityNames.SERIAL_DESCRIPTOR_CLASS).toSimpleType(false)) // todo: cache lookup
// todo: serialization: do an actual check better that just number of parameters
fun ClassDescriptor.checkSaveMethodParameters(parameters: List<ValueParameterDescriptor>): Boolean =
@@ -33,12 +33,12 @@ object SerialEntityNames {
val IMPL_NAME = Name.identifier("Impl")
const val ENCODER_CLASS = "Encoder"
const val STRUCTURE_ENCODER_CLASS = "StructureEncoder"
const val STRUCTURE_ENCODER_CLASS = "CompositeEncoder"
const val DECODER_CLASS = "Decoder"
const val STRUCTURE_DECODER_CLASS = "StructureDecoder"
const val STRUCTURE_DECODER_CLASS = "CompositeDecoder"
const val SERIAL_SAVER_CLASS = "SerializationStrategy"
const val SERIAL_LOADER_CLASS = "SerializationStrategy"
const val SERIAL_LOADER_CLASS = "DeserializationStrategy"
const val SERIAL_DESCRIPTOR_CLASS = "SerialDescriptor"
const val SERIAL_DESCRIPTOR_CLASS_IMPL = "SerialClassDescImpl"
@@ -75,8 +75,8 @@ object CallingConventions {
const val decode = "decode"
const val update = "update"
const val encode = "encode"
const val decodeElementIndex = "decodeElement"
const val elementPostfix = "ElementValue"
const val decodeElementIndex = "decodeElementIndex"
const val elementPostfix = "Element"
const val addElement = "addElement"
const val addAnnotation = "pushAnnotation"