Skip to content
This repository has been archived by the owner on Aug 5, 2024. It is now read-only.

Commit

Permalink
some fixes to the deserialozation (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tiagoperes authored Sep 23, 2022
1 parent 624e54e commit 1fd0527
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package br.zup.com.nimbus.compose

import com.zup.nimbus.core.deserialization.ComponentDeserializer

interface TypeDeserializer<T> {
fun deserialize(properties: ComponentDeserializer, data: ComponentData, name: String): T
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ object ClassNames {
val ComponentData = ClassName(PackageNames.nimbusCompose, "ComponentData")
val NimbusTheme = ClassName(PackageNames.nimbusCompose, "NimbusTheme")
val NimbusMode = ClassName(PackageNames.nimbusCompose, "NimbusMode")
val TypeDeserializer = ClassName(PackageNames.nimbusCompose, "TypeDeserializer")
val ComponentDeserializer = ClassName(
"${PackageNames.nimbusCore}.deserialization",
"ComponentDeserializer",
Expand Down
3 changes: 2 additions & 1 deletion processor/src/main/java/com/zup/nimbus/processor/Computed.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ import kotlin.reflect.KClass

@Retention(AnnotationRetention.SOURCE)
@Target(AnnotationTarget.VALUE_PARAMETER)
annotation class Computed<T: TypeDeserializer<*>>(val deserializer: KClass<T>)
// FIXME: typing. should be: annotation class Computed<T: TypeDeserializer<*>>(val deserializer: KClass<T>)
annotation class Computed(val deserializer: KClass<*>)
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class ParameterInfo(parameter: KSValueParameter, fn: KSFunctionDeclaration) {
val isParentName: Boolean
val deserializer: ClassName?
val arity: Int?
val isRoot: Boolean

init {
name = parameter.name?.asString() ?: throw NamelessParameterException(parameter, fn)
Expand All @@ -41,6 +42,10 @@ class ParameterInfo(parameter: KSValueParameter, fn: KSFunctionDeclaration) {
// todo: don't rely on simple name
annotation -> annotation.shortName.asString() == "ParentName"
}
isRoot = parameter.annotations.any {
// todo: don't rely on simple name
annotation -> annotation.shortName.asString() == "Root"
}
val deserializerType = parameter.annotations.find {
// todo: don't rely on simple name
annotation -> annotation.shortName.asString() == "Computed"
Expand All @@ -58,10 +63,6 @@ class ParameterInfo(parameter: KSValueParameter, fn: KSFunctionDeclaration) {
} else if (resolved.declaration.modifiers.contains(Modifier.ENUM)) {
TypeCategory.Enum
} else if (!resolved.isFunctionType && resolved.declaration is KSClassDeclaration) {
val isRoot = parameter.annotations.any {
// todo: don't rely on simple name
annotation -> annotation.shortName.asString() == "Root"
}
if (!isRoot && deserializer == null) throw NonRootEntityException(parameter, fn)
mustDeserialize.add(resolved.declaration as KSClassDeclaration)
TypeCategory.Deserializable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,36 @@ class ServerDrivenProcessor(private val environment: SymbolProcessorEnvironment)
getSymbolsWithAnnotation(kClass.qualifiedName.toString())
.filterIsInstance<KSFunctionDeclaration>()

private fun handleDeserializer(param: ParameterInfo, fnBuilder: FunSpec.Builder) {
if (param.isRoot) {
fnBuilder.addStatement(
"val %L = %L.deserialize(properties, data, %S)",
param.name,
param.deserializer!!.simpleName,
param.name,
)
} else if (param.nullable) {
fnBuilder.addCode("""
|val %L = if (properties.enter(%S, true)) {
| val result = %L.deserialize(properties, data, %S)
| properties.leave()
| result
|} else null
|""".trimMargin(),
param.name, param.name, param.deserializer!!.simpleName, param.name
)
} else {
fnBuilder.addStatement("properties.enter(%S, false)", param.name)
fnBuilder.addStatement(
"val %L = %L.deserialize(properties, data, %S)",
param.name,
param.deserializer!!.simpleName,
param.name,
)
fnBuilder.addStatement("properties.leave()", param.name)
}
}

private fun createNimbusComposable(
builder: FileSpec.Builder,
fn: KSFunctionDeclaration,
Expand All @@ -49,11 +79,7 @@ class ServerDrivenProcessor(private val environment: SymbolProcessorEnvironment)
if (it.deserializer.packageName != fn.packageName.asString()) {
builder.addClassImport(it.deserializer)
}
fnBuilder.addStatement(
"val %L = %L.deserialize(data)",
it.name,
it.deserializer.simpleName,
)
handleDeserializer(it, fnBuilder)
}
else {
when (it.category) {
Expand Down Expand Up @@ -102,7 +128,7 @@ class ServerDrivenProcessor(private val environment: SymbolProcessorEnvironment)
mustDeserialize.addAll(it.mustDeserialize)
builder.addImport(it.packageName, it.type)
fnBuilder.addStatement(
"val %L = NimbusEntityDeserializer.deserialize(properties, %L::class)",
"val %L = NimbusEntityDeserializer.deserialize(properties, data, %L::class)",
it.name,
it.type,
)
Expand Down Expand Up @@ -165,6 +191,7 @@ class ServerDrivenProcessor(private val environment: SymbolProcessorEnvironment)
.replace(".", "_")
val fnBuilder = FunSpec.builder(name)
.addParameter("properties", ClassNames.ComponentDeserializer)
.addParameter("data", ClassNames.ComponentData)
.addModifiers(KModifier.PRIVATE)
.returns(ClassName(clazz.packageName.asString(), clazz.simpleName.asString()))
val constructorInfo = FunctionInfo(
Expand All @@ -175,11 +202,7 @@ class ServerDrivenProcessor(private val environment: SymbolProcessorEnvironment)
if (it.deserializer.packageName != clazz.packageName.asString()) {
builder.addClassImport(it.deserializer)
}
fnBuilder.addStatement(
"val %L = %L.deserialize(data)",
it.name,
it.deserializer.simpleName,
)
handleDeserializer(it, fnBuilder)
}
else {
when (it.category) {
Expand Down Expand Up @@ -262,6 +285,10 @@ class ServerDrivenProcessor(private val environment: SymbolProcessorEnvironment)
ParameterSpec.builder(
"properties",
ClassNames.ComponentDeserializer,
).build(),
ParameterSpec.builder(
"data",
ClassNames.ComponentData,
).build()
),
returnType = Any::class.asTypeName(),
Expand All @@ -274,7 +301,7 @@ class ServerDrivenProcessor(private val environment: SymbolProcessorEnvironment)
"mutableMapOf(%L)",
mustDeserialize.joinToString(", ") {
val name = "${it.packageName.asString()}.${it.simpleName.asString()}"
"\"$name\" to { ${name.replace(".", "_")}(it) }"
"\"$name\" to { properties, data -> ${name.replace(".", "_")}(properties, data) }"
},
)
)
Expand All @@ -295,11 +322,12 @@ class ServerDrivenProcessor(private val environment: SymbolProcessorEnvironment)
)
)
.addParameter("properties", ClassNames.ComponentDeserializer)
.addParameter("data", ClassNames.ComponentData)
.addParameter("clazz", TypeVariableName("U"))
.returns(TypeVariableName("T"))
.addStatement(
"return deserializers.get(clazz.qualifiedName ?: \"\")?.let " +
"{ it(properties) as T } ?: throw IllegalArgumentException(%P)",
"{ it(properties, data) as T } ?: throw IllegalArgumentException(%P)",
"\${clazz.simpleName} is an invalid Server Driven entity because no " +
"deserializer has been found for it."
)
Expand Down

This file was deleted.

0 comments on commit 1fd0527

Please sign in to comment.