Skip to content

Commit

Permalink
don't use official ::kotlin.get().serializer() API — avoid kotlin r…
Browse files Browse the repository at this point in the history
…efection wrapper creation

Kotlin/kotlinx.serialization#1819

GitOrigin-RevId: 9a1bce7a70b6c68c9c6267baa53ac0509b9ff294
  • Loading branch information
develar authored and intellij-monorepo-bot committed Jan 9, 2022
1 parent 5ccf887 commit 51be4e7
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 6 deletions.
Expand Up @@ -9,6 +9,8 @@ import kotlinx.serialization.KSerializer
import kotlinx.serialization.json.Json
import org.jdom.CDATA
import org.jdom.Element
import java.lang.invoke.MethodHandles
import java.lang.invoke.MethodType

@OptIn(ExperimentalSerializationApi::class)
private val json = Json {
Expand All @@ -17,7 +19,22 @@ private val json = Json {
ignoreUnknownKeys = true
}

internal class KotlinxSerializationBinding(private val serializer: KSerializer<Any>) : NotNullDeserializeBinding() {
private val lookup = MethodHandles.lookup()
private val kotlinMethodType = MethodType.methodType(KSerializer::class.java)

internal class KotlinxSerializationBinding(aClass: Class<*>) : NotNullDeserializeBinding() {
private val serializer: KSerializer<Any>

init {
// don't use official `::kotlin.get().serializer()` API — avoid kotlin refection wrapper creation
// findStaticGetter cannot be used because type of Companion not used
val field = aClass.getDeclaredField("Companion")
field.isAccessible = true
val companion = lookup.unreflectGetter(field).invoke()
@Suppress("UNCHECKED_CAST")
serializer = lookup.findVirtual(companion.javaClass, "serializer", kotlinMethodType).invoke(companion) as KSerializer<Any>
}

override fun serialize(o: Any, context: Any?, filter: SerializationFilter?): Any {
val element = Element("state")
element.addContent(CDATA(json.encodeToString(serializer, o)))
Expand Down
6 changes: 1 addition & 5 deletions platform/object-serializer/src/xml/xmlSerializer.kt
Expand Up @@ -10,9 +10,7 @@ import com.intellij.serialization.xml.KotlinAwareBeanBinding
import com.intellij.serialization.xml.KotlinxSerializationBinding
import com.intellij.util.io.URLUtil
import com.intellij.util.xmlb.*
import kotlinx.serialization.InternalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.serializer
import org.jdom.Element
import org.jdom.JDOMException
import org.jetbrains.annotations.TestOnly
Expand Down Expand Up @@ -172,14 +170,12 @@ private abstract class OldBindingProducer<ROOT_BINDING> {
}

private class MyXmlSerializer : XmlSerializerImpl.XmlSerializerBase() {
@OptIn(InternalSerializationApi::class)
val bindingProducer = object : OldBindingProducer<Binding>() {
override fun createRootBinding(aClass: Class<*>, type: Type, cacheKey: Type, map: MutableMap<Type, Binding>): Binding {
var binding = createClassBinding(aClass, null, type)
if (binding == null) {
if (aClass.isAnnotationPresent(Serializable::class.java)) {
@Suppress("UNCHECKED_CAST")
binding = KotlinxSerializationBinding((aClass as Class<Any>)::kotlin.get().serializer())
binding = KotlinxSerializationBinding(aClass)
}
else {
binding = KotlinAwareBeanBinding(aClass)
Expand Down

0 comments on commit 51be4e7

Please sign in to comment.