[FIR] Extract FirJvmConstDeserializer
Attempts to separate JVM and non-JVM entities more clearly.
This commit is contained in:
+8
-2
@@ -67,6 +67,12 @@ fun deserializeClassToSymbol(
|
|||||||
}
|
}
|
||||||
val isSealed = modality == Modality.SEALED
|
val isSealed = modality == Modality.SEALED
|
||||||
val annotationDeserializer = defaultAnnotationDeserializer ?: FirBuiltinAnnotationDeserializer(session)
|
val annotationDeserializer = defaultAnnotationDeserializer ?: FirBuiltinAnnotationDeserializer(session)
|
||||||
|
val jvmBinaryClass = (containerSource as? KotlinJvmBinarySourceElement)?.binaryClass
|
||||||
|
val constDeserializer = if (jvmBinaryClass != null) {
|
||||||
|
FirJvmConstDeserializer(session, jvmBinaryClass)
|
||||||
|
} else {
|
||||||
|
FirConstDeserializer(session)
|
||||||
|
}
|
||||||
val context =
|
val context =
|
||||||
parentContext?.childContext(
|
parentContext?.childContext(
|
||||||
classProto.typeParameterList,
|
classProto.typeParameterList,
|
||||||
@@ -79,7 +85,7 @@ fun deserializeClassToSymbol(
|
|||||||
if (status.isCompanion) {
|
if (status.isCompanion) {
|
||||||
parentContext.constDeserializer
|
parentContext.constDeserializer
|
||||||
} else {
|
} else {
|
||||||
((containerSource as? KotlinJvmBinarySourceElement)?.binaryClass)?.let { FirConstDeserializer(session, it) }
|
((containerSource as? KotlinJvmBinarySourceElement)?.binaryClass)?.let { FirJvmConstDeserializer(session, it) }
|
||||||
?: parentContext.constDeserializer
|
?: parentContext.constDeserializer
|
||||||
},
|
},
|
||||||
status.isInner
|
status.isInner
|
||||||
@@ -89,7 +95,7 @@ fun deserializeClassToSymbol(
|
|||||||
nameResolver,
|
nameResolver,
|
||||||
moduleData,
|
moduleData,
|
||||||
annotationDeserializer,
|
annotationDeserializer,
|
||||||
FirConstDeserializer(session, (containerSource as? KotlinJvmBinarySourceElement)?.binaryClass),
|
constDeserializer,
|
||||||
containerSource,
|
containerSource,
|
||||||
symbol
|
symbol
|
||||||
)
|
)
|
||||||
|
|||||||
+27
-47
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.fir.FirSession
|
|||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.buildConstExpression
|
import org.jetbrains.kotlin.fir.expressions.builder.buildConstExpression
|
||||||
import org.jetbrains.kotlin.name.CallableId
|
import org.jetbrains.kotlin.name.CallableId
|
||||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
|
|
||||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
import org.jetbrains.kotlin.metadata.deserialization.Flags
|
import org.jetbrains.kotlin.metadata.deserialization.Flags
|
||||||
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
|
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
|
||||||
@@ -18,57 +17,38 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
|
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
|
||||||
import org.jetbrains.kotlin.types.ConstantValueKind
|
import org.jetbrains.kotlin.types.ConstantValueKind
|
||||||
|
|
||||||
class FirConstDeserializer(
|
open class FirConstDeserializer(
|
||||||
val session: FirSession,
|
val session: FirSession
|
||||||
private val binaryClass: KotlinJvmBinaryClass? = null
|
|
||||||
) {
|
) {
|
||||||
private val constantCache = mutableMapOf<CallableId, FirExpression>()
|
protected val constantCache = mutableMapOf<CallableId, FirExpression>()
|
||||||
|
|
||||||
fun loadConstant(propertyProto: ProtoBuf.Property, callableId: CallableId, nameResolver: NameResolver): FirExpression? {
|
open fun loadConstant(propertyProto: ProtoBuf.Property, callableId: CallableId, nameResolver: NameResolver): FirExpression? {
|
||||||
if (!Flags.HAS_CONSTANT.get(propertyProto.flags)) return null
|
if (!Flags.HAS_CONSTANT.get(propertyProto.flags)) return null
|
||||||
|
|
||||||
constantCache[callableId]?.let { return it }
|
constantCache[callableId]?.let { return it }
|
||||||
|
val value = propertyProto.getExtensionOrNull(BuiltInSerializerProtocol.compileTimeValue) ?: return null
|
||||||
if (binaryClass == null) {
|
return buildFirConstant(value, null, value.type.name, nameResolver)?.also { constantCache[callableId] = it }
|
||||||
val value = propertyProto.getExtensionOrNull(BuiltInSerializerProtocol.compileTimeValue) ?: return null
|
|
||||||
return buildFirConstant(value, null, value.type.name, nameResolver)?.apply { constantCache[callableId] = this }
|
|
||||||
}
|
|
||||||
|
|
||||||
binaryClass.visitMembers(object : KotlinJvmBinaryClass.MemberVisitor {
|
|
||||||
override fun visitMethod(name: Name, desc: String): KotlinJvmBinaryClass.MethodAnnotationVisitor? = null
|
|
||||||
|
|
||||||
override fun visitField(name: Name, desc: String, initializer: Any?): KotlinJvmBinaryClass.AnnotationVisitor? {
|
|
||||||
if (initializer != null) {
|
|
||||||
val constant = buildFirConstant(null, initializer, desc, nameResolver)
|
|
||||||
constant?.let { constantCache[callableId.replaceName(name)] = it }
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}, null)
|
|
||||||
|
|
||||||
return constantCache[callableId]
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun buildFirConstant(
|
fun buildFirConstant(
|
||||||
protoValue: ProtoBuf.Annotation.Argument.Value?, sourceValue: Any?, constKind: String, nameResolver: NameResolver
|
protoValue: ProtoBuf.Annotation.Argument.Value?, sourceValue: Any?, constKind: String, nameResolver: NameResolver
|
||||||
): FirExpression? {
|
): FirExpression? {
|
||||||
return when (constKind) {
|
return when (constKind) {
|
||||||
"BYTE", "B" -> buildConstExpression(null, ConstantValueKind.Byte, ((protoValue?.intValue ?: sourceValue) as Number).toByte())
|
"BYTE", "B" -> buildConstExpression(null, ConstantValueKind.Byte, ((protoValue?.intValue ?: sourceValue) as Number).toByte())
|
||||||
"CHAR", "C" -> buildConstExpression(null, ConstantValueKind.Char, ((protoValue?.intValue ?: sourceValue) as Number).toInt().toChar())
|
"CHAR", "C" -> buildConstExpression(null, ConstantValueKind.Char, ((protoValue?.intValue ?: sourceValue) as Number).toInt().toChar())
|
||||||
"SHORT", "S" -> buildConstExpression(null, ConstantValueKind.Short, ((protoValue?.intValue ?: sourceValue) as Number).toShort())
|
"SHORT", "S" -> buildConstExpression(null, ConstantValueKind.Short, ((protoValue?.intValue ?: sourceValue) as Number).toShort())
|
||||||
"INT", "I" -> buildConstExpression(null, ConstantValueKind.Int, protoValue?.intValue?.toInt() ?: sourceValue as Int)
|
"INT", "I" -> buildConstExpression(null, ConstantValueKind.Int, protoValue?.intValue?.toInt() ?: sourceValue as Int)
|
||||||
"LONG", "J" -> buildConstExpression(null, ConstantValueKind.Long, protoValue?.intValue ?: sourceValue as Long)
|
"LONG", "J" -> buildConstExpression(null, ConstantValueKind.Long, protoValue?.intValue ?: sourceValue as Long)
|
||||||
"FLOAT", "F" -> buildConstExpression(null, ConstantValueKind.Float, protoValue?.floatValue ?: sourceValue as Float)
|
"FLOAT", "F" -> buildConstExpression(null, ConstantValueKind.Float, protoValue?.floatValue ?: sourceValue as Float)
|
||||||
"DOUBLE", "D" -> buildConstExpression(null, ConstantValueKind.Double, protoValue?.doubleValue ?: sourceValue as Double)
|
"DOUBLE", "D" -> buildConstExpression(null, ConstantValueKind.Double, protoValue?.doubleValue ?: sourceValue as Double)
|
||||||
"BOOLEAN", "Z" -> buildConstExpression(null, ConstantValueKind.Boolean, (protoValue?.intValue?.toInt() ?: sourceValue) != 0)
|
"BOOLEAN", "Z" -> buildConstExpression(null, ConstantValueKind.Boolean, (protoValue?.intValue?.toInt() ?: sourceValue) != 0)
|
||||||
"STRING", "Ljava/lang/String;" -> buildConstExpression(
|
"STRING", "Ljava/lang/String;" -> buildConstExpression(
|
||||||
null, ConstantValueKind.String, protoValue?.stringValue?.let { nameResolver.getString(it) } ?: sourceValue as String
|
null, ConstantValueKind.String, protoValue?.stringValue?.let { nameResolver.getString(it) } ?: sourceValue as String
|
||||||
)
|
)
|
||||||
else -> null
|
else -> null
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun CallableId.replaceName(newName: Name): CallableId {
|
fun CallableId.replaceName(newName: Name): CallableId {
|
||||||
return CallableId(this.packageName, this.className, newName)
|
return CallableId(this.packageName, this.className, newName)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.deserialization
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
|
import org.jetbrains.kotlin.name.CallableId
|
||||||
|
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
|
||||||
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
|
import org.jetbrains.kotlin.metadata.deserialization.Flags
|
||||||
|
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
|
class FirJvmConstDeserializer(
|
||||||
|
session: FirSession,
|
||||||
|
private val binaryClass: KotlinJvmBinaryClass,
|
||||||
|
) : FirConstDeserializer(session) {
|
||||||
|
override fun loadConstant(propertyProto: ProtoBuf.Property, callableId: CallableId, nameResolver: NameResolver): FirExpression? {
|
||||||
|
if (!Flags.HAS_CONSTANT.get(propertyProto.flags)) return null
|
||||||
|
constantCache[callableId]?.let { return it }
|
||||||
|
|
||||||
|
binaryClass.visitMembers(object : KotlinJvmBinaryClass.MemberVisitor {
|
||||||
|
override fun visitMethod(name: Name, desc: String): KotlinJvmBinaryClass.MethodAnnotationVisitor? = null
|
||||||
|
|
||||||
|
override fun visitField(name: Name, desc: String, initializer: Any?): KotlinJvmBinaryClass.AnnotationVisitor? {
|
||||||
|
if (initializer != null) {
|
||||||
|
val constant = buildFirConstant(null, initializer, desc, nameResolver)
|
||||||
|
constant?.let { constantCache[callableId.replaceName(name)] = it }
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}, null)
|
||||||
|
|
||||||
|
return constantCache[callableId]
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -81,7 +81,7 @@ class JvmClassFileBasedSymbolProvider(
|
|||||||
FirDeserializationContext.createForPackage(
|
FirDeserializationContext.createForPackage(
|
||||||
packageFqName, packageProto, nameResolver, moduleData,
|
packageFqName, packageProto, nameResolver, moduleData,
|
||||||
JvmBinaryAnnotationDeserializer(session, kotlinJvmBinaryClass, kotlinClassFinder, byteContent),
|
JvmBinaryAnnotationDeserializer(session, kotlinJvmBinaryClass, kotlinClassFinder, byteContent),
|
||||||
FirConstDeserializer(session, facadeBinaryClass ?: kotlinJvmBinaryClass),
|
FirJvmConstDeserializer(session, facadeBinaryClass ?: kotlinJvmBinaryClass),
|
||||||
source
|
source
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user