Fix 1.2.50 compatibility
Updated version to 0.5.1 Fix resolving serializers for classes from other modules (Kotlin/kotlinx.serialization/153) Respect @SerialName on classes Add support for @SerialInfo on class-level
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
<groupId>org.jetbrains.kotlinx</groupId>
|
||||
<artifactId>kotlinx-maven-serialization-plugin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>0.5.0</version>
|
||||
<version>0.5.2-SNAPSHOT</version>
|
||||
<description>Serialization plugin for Maven</description>
|
||||
|
||||
<repositories>
|
||||
|
||||
@@ -8,7 +8,7 @@ configureJvmProject(project)
|
||||
configurePublishing(project)
|
||||
|
||||
group = 'org.jetbrains.kotlinx'
|
||||
version = '0.5.0'
|
||||
version = '0.5.2'
|
||||
if (!project.hasProperty("deploy")) {
|
||||
version = "$version-SNAPSHOT"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ Compiler plugins are uploaded on bintray: https://bintray.com/kotlin/kotlinx/kot
|
||||
## Building and usage
|
||||
|
||||
### Prerequisites:
|
||||
Before all, follow the instructions from root README.md to download dependencies and build Kotlin compiler. (`ant -f update_dependencies.xml && ./gradlew dist`)
|
||||
Before all, follow the instructions from root README.md to download dependencies and build Kotlin compiler. (`./gradlew dist`)
|
||||
|
||||
**Plugin works only with IntelliJIDEA 2017.2 and higher.**
|
||||
|
||||
@@ -29,5 +29,5 @@ Run `./gradlew :kotlinx-gradle-serialization-plugin:install`
|
||||
|
||||
## Building maven plugin
|
||||
|
||||
Go to `$kotlin_root/libraries/tools/kotlin-maven-serialization`. Run `mvn install`
|
||||
Make all prerequisites from libraries' README.md for Maven projects. Go to `$kotlin_root/libraries/tools/kotlin-maven-serialization`. Run `mvn install`
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<idea-plugin url="https://github.com/Kotlin/kotlinx.serialization" >
|
||||
<name>Kotlin-serialization</name>
|
||||
<id>org.jetbrains.kotlinx.serialization</id>
|
||||
<version>0.5.0</version>
|
||||
<version>0.5.2-SNAPSHOT</version>
|
||||
|
||||
<depends>org.jetbrains.kotlin</depends>
|
||||
<idea-version since-build="172"/>
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ import org.jetbrains.kotlinx.serialization.compiler.resolve.KSerializerDescripto
|
||||
abstract class SerializerCodegen(declaration: KtPureClassOrObject, bindingContext: BindingContext) {
|
||||
protected val serializerDescriptor: ClassDescriptor = declaration.findClassDescriptor(bindingContext)
|
||||
protected val serializableDescriptor: ClassDescriptor = getSerializableClassDescriptorBySerializer(serializerDescriptor)!!
|
||||
protected val serialName: String = serializableDescriptor.fqNameUnsafe.asString()
|
||||
protected val serialName: String = serializableDescriptor.annotations.serialNameValue ?: serializableDescriptor.fqNameUnsafe.asString()
|
||||
protected val properties = SerializableProperties(serializableDescriptor, bindingContext)
|
||||
protected val orderedProperties = properties.serializableProperties
|
||||
|
||||
|
||||
+16
-8
@@ -18,6 +18,7 @@ package org.jetbrains.kotlinx.serialization.compiler.backend.js
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
||||
@@ -26,7 +27,6 @@ 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.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtPureClassOrObject
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||
@@ -67,6 +67,7 @@ class SerializerJsTranslator(declaration: KtPureClassOrObject,
|
||||
// adding elements via serialDesc.addElement(...)
|
||||
val addFunc = serialDescImplClass.getFuncDesc("addElement").single()
|
||||
val pushFunc = serialDescImplClass.getFuncDesc("pushAnnotation").single()
|
||||
val pushClassFunc = serialDescImplClass.getFuncDesc("pushClassAnnotation").single()
|
||||
val serialClassDescRef = JsNameRef(context.getNameForDescriptor(serialDescPropertyDescriptor), JsThisRef())
|
||||
|
||||
for (prop in orderedProperties) {
|
||||
@@ -74,14 +75,21 @@ class SerializerJsTranslator(declaration: KtPureClassOrObject,
|
||||
val call = JsInvocation(JsNameRef(context.getNameForDescriptor(addFunc), serialClassDescRef), JsStringLiteral(prop.name))
|
||||
translator.addInitializerStatement(call.makeStmt())
|
||||
// serialDesc.pushAnnotation(...)
|
||||
for ((annotationClass , args, _) in prop.annotationsWithArguments) {
|
||||
val argExprs = args.map { arg ->
|
||||
Translation.translateAsExpression(arg.getArgumentExpression()!!, context)
|
||||
}
|
||||
val classRef = context.translateQualifiedReference(annotationClass)
|
||||
val invok = JsInvocation(JsNameRef(context.getNameForDescriptor(pushFunc), serialClassDescRef), JsNew(classRef, argExprs))
|
||||
translator.addInitializerStatement(invok.makeStmt())
|
||||
pushAnnotationsInto(prop.descriptor, pushFunc, serialClassDescRef)
|
||||
}
|
||||
|
||||
// push class annotations
|
||||
pushAnnotationsInto(serializableDescriptor, pushClassFunc, serialClassDescRef)
|
||||
}
|
||||
|
||||
private fun pushAnnotationsInto(annotated: Annotated, pushFunction: DeclarationDescriptor, intoRef: JsNameRef) {
|
||||
for ((annotationClass , args, _) in annotated.annotationsWithArguments()) {
|
||||
val argExprs = args.map { arg ->
|
||||
Translation.translateAsExpression(arg.getArgumentExpression()!!, context)
|
||||
}
|
||||
val classRef = context.translateQualifiedReference(annotationClass)
|
||||
val invok = JsInvocation(JsNameRef(context.getNameForDescriptor(pushFunction), intoRef), JsNew(classRef, argExprs))
|
||||
translator.addInitializerStatement(invok.makeStmt())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+34
-19
@@ -17,15 +17,14 @@
|
||||
package org.jetbrains.kotlinx.serialization.compiler.backend.jvm
|
||||
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.psi.ValueArgument
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializerCodegen
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.KSerializerDescriptorResolver
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.KSerializerDescriptorResolver.typeArgPrefix
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.annotationsWithArguments
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.getSerializableClassDescriptorBySerializer
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.isInternalSerializable
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
@@ -91,29 +90,45 @@ class SerializerCodegenImpl(
|
||||
for ((annotationClass, args, consParams) in property.annotationsWithArguments) {
|
||||
if (args.size != consParams.size) throw IllegalArgumentException("Can't use arguments with defaults for serializable annotations yet")
|
||||
load(classDescVar, descImplType)
|
||||
val implType = codegen.typeMapper.mapType(annotationClass).internalName + "\$" + KSerializerDescriptorResolver.IMPL_NAME.identifier
|
||||
// new Annotation$Impl(...)
|
||||
anew(Type.getObjectType(implType))
|
||||
dup()
|
||||
val sb = StringBuilder("(")
|
||||
for (i in consParams.indices) {
|
||||
val decl = args[i]
|
||||
val desc = consParams[i]
|
||||
val valAsmType = codegen.typeMapper.mapType(desc.type)
|
||||
expr.gen(decl.getArgumentExpression(), valAsmType)
|
||||
sb.append(valAsmType.descriptor)
|
||||
}
|
||||
sb.append(")V")
|
||||
invokespecial(implType, "<init>", sb.toString(), false)
|
||||
// serialDesc.pushAnnotation(..)
|
||||
expr.generateSyntheticAnnotationOnStack(annotationClass, args, consParams)
|
||||
invokevirtual(descImplType.internalName, "pushAnnotation", "(Ljava/lang/annotation/Annotation;)V", false)
|
||||
}
|
||||
}
|
||||
// add annotations on class itself
|
||||
for ((annotationClass, args, consParams) in serializableDescriptor.annotationsWithArguments()) {
|
||||
if (args.size != consParams.size) throw IllegalArgumentException("Can't use arguments with defaults for serializable annotations yet")
|
||||
load(classDescVar, descImplType)
|
||||
expr.generateSyntheticAnnotationOnStack(annotationClass, args, consParams)
|
||||
invokevirtual(descImplType.internalName, "pushClassAnnotation", "(Ljava/lang/annotation/Annotation;)V", false)
|
||||
}
|
||||
load(classDescVar, descImplType)
|
||||
putstatic(serializerAsmType.internalName, serialDescField, descType.descriptor)
|
||||
}
|
||||
}
|
||||
|
||||
private fun ExpressionCodegen.generateSyntheticAnnotationOnStack(
|
||||
annotationClass: ClassDescriptor,
|
||||
args: List<ValueArgument>,
|
||||
ctorParams: List<ValueParameterDescriptor>
|
||||
) {
|
||||
val implType = codegen.typeMapper.mapType(annotationClass).internalName + "\$" + KSerializerDescriptorResolver.IMPL_NAME.identifier
|
||||
with(v) {
|
||||
// new Annotation$Impl(...)
|
||||
anew(Type.getObjectType(implType))
|
||||
dup()
|
||||
val sb = StringBuilder("(")
|
||||
for (i in ctorParams.indices) {
|
||||
val decl = args[i]
|
||||
val desc = ctorParams[i]
|
||||
val valAsmType = codegen.typeMapper.mapType(desc.type)
|
||||
this@generateSyntheticAnnotationOnStack.gen(decl.getArgumentExpression(), valAsmType)
|
||||
sb.append(valAsmType.descriptor)
|
||||
}
|
||||
sb.append(")V")
|
||||
invokespecial(implType, "<init>", sb.toString(), false)
|
||||
}
|
||||
}
|
||||
|
||||
private fun InstructionAdapter.serialCLassDescToLocalVar(classDescVar: Int) {
|
||||
getstatic(serializerAsmType.internalName, serialDescField, descType.descriptor)
|
||||
store(classDescVar, descType)
|
||||
|
||||
+16
-1
@@ -18,10 +18,12 @@ package org.jetbrains.kotlinx.serialization.compiler.resolve
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.ValueArgument
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotationDescriptor
|
||||
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
|
||||
@@ -124,8 +126,10 @@ val KotlinType?.toClassDescriptor: ClassDescriptor?
|
||||
val ClassDescriptor.isInternalSerializable: Boolean //todo normal checking
|
||||
get() {
|
||||
if (!annotations.hasAnnotation(serializableAnnotationFqName)) return false
|
||||
// If provided descriptor is lazy, carefully look at psi in order not to trigger full resolve which may be recursive.
|
||||
// Otherwise, this descriptor is deserialized from another module and it is OK to check value right away.
|
||||
val lazyDesc = annotations.findAnnotation(serializableAnnotationFqName)
|
||||
as? LazyAnnotationDescriptor ?: return false
|
||||
as? LazyAnnotationDescriptor ?: return (annotations.serializableWith == null)
|
||||
val psi = lazyDesc.annotationEntry
|
||||
return psi.valueArguments.isEmpty()
|
||||
}
|
||||
@@ -232,3 +236,14 @@ fun ClassDescriptor.getClassFromInternalSerializationPackage(classSimpleName: St
|
||||
module.getClassFromInternalSerializationPackage(classSimpleName)
|
||||
|
||||
fun ClassDescriptor.toSimpleType(nullable: Boolean = true) = KotlinTypeFactory.simpleType(Annotations.EMPTY, this.typeConstructor, emptyList(), nullable)
|
||||
|
||||
fun Annotated.annotationsWithArguments(): List<Triple<ClassDescriptor, List<ValueArgument>, List<ValueParameterDescriptor>>> =
|
||||
annotations.asSequence()
|
||||
.filter { it.type.toClassDescriptor?.annotations?.hasAnnotation(serialInfoFqName) == true }
|
||||
.filterIsInstance<LazyAnnotationDescriptor>()
|
||||
.mapNotNull { annDesc ->
|
||||
annDesc.type.toClassDescriptor?.let {
|
||||
Triple(it, annDesc.annotationEntry.valueArguments, it.unsubstitutedPrimaryConstructor?.valueParameters.orEmpty())
|
||||
}
|
||||
}
|
||||
.toList()
|
||||
|
||||
+2
-2
@@ -19,7 +19,6 @@ package org.jetbrains.kotlinx.serialization.compiler.resolve
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasOwnParametersWithDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
|
||||
class SerializableProperties(private val serializableClass: ClassDescriptor, val bindingContext: BindingContext) {
|
||||
@@ -71,5 +70,6 @@ class SerializableProperties(private val serializableClass: ClassDescriptor, val
|
||||
operator fun get(index: Int) = serializableProperties[index]
|
||||
operator fun iterator() = serializableProperties.iterator()
|
||||
|
||||
val primaryConstructorWithDefaults = serializableClass.unsubstitutedPrimaryConstructor?.hasOwnParametersWithDefaultValue() ?: false
|
||||
val primaryConstructorWithDefaults = serializableClass.unsubstitutedPrimaryConstructor
|
||||
?.original?.valueParameters?.any { it.declaresDefaultValue() } ?: false
|
||||
}
|
||||
+1
-10
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.psi.ValueArgument
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotationDescriptor
|
||||
|
||||
class SerializableProperty(val descriptor: PropertyDescriptor, val isConstructorParameterWithDefault: Boolean) {
|
||||
val name = descriptor.annotations.serialNameValue ?: descriptor.name.asString()
|
||||
@@ -32,13 +31,5 @@ class SerializableProperty(val descriptor: PropertyDescriptor, val isConstructor
|
||||
val optional = descriptor.annotations.serialOptional
|
||||
val transient = descriptor.annotations.serialTransient
|
||||
val annotationsWithArguments: List<Triple<ClassDescriptor, List<ValueArgument>, List<ValueParameterDescriptor>>> =
|
||||
descriptor.annotations.asSequence()
|
||||
.filter { it.type.toClassDescriptor?.annotations?.hasAnnotation(serialInfoFqName) == true }
|
||||
.filterIsInstance<LazyAnnotationDescriptor>()
|
||||
.mapNotNull { annDesc ->
|
||||
annDesc.type.toClassDescriptor?.let {
|
||||
Triple(it, annDesc.annotationEntry.valueArguments, it.unsubstitutedPrimaryConstructor?.valueParameters.orEmpty())
|
||||
}
|
||||
}
|
||||
.toList()
|
||||
descriptor.annotationsWithArguments()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user