[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 annotationDeserializer = defaultAnnotationDeserializer ?: FirBuiltinAnnotationDeserializer(session)
|
||||
val jvmBinaryClass = (containerSource as? KotlinJvmBinarySourceElement)?.binaryClass
|
||||
val constDeserializer = if (jvmBinaryClass != null) {
|
||||
FirJvmConstDeserializer(session, jvmBinaryClass)
|
||||
} else {
|
||||
FirConstDeserializer(session)
|
||||
}
|
||||
val context =
|
||||
parentContext?.childContext(
|
||||
classProto.typeParameterList,
|
||||
@@ -79,7 +85,7 @@ fun deserializeClassToSymbol(
|
||||
if (status.isCompanion) {
|
||||
parentContext.constDeserializer
|
||||
} else {
|
||||
((containerSource as? KotlinJvmBinarySourceElement)?.binaryClass)?.let { FirConstDeserializer(session, it) }
|
||||
((containerSource as? KotlinJvmBinarySourceElement)?.binaryClass)?.let { FirJvmConstDeserializer(session, it) }
|
||||
?: parentContext.constDeserializer
|
||||
},
|
||||
status.isInner
|
||||
@@ -89,7 +95,7 @@ fun deserializeClassToSymbol(
|
||||
nameResolver,
|
||||
moduleData,
|
||||
annotationDeserializer,
|
||||
FirConstDeserializer(session, (containerSource as? KotlinJvmBinarySourceElement)?.binaryClass),
|
||||
constDeserializer,
|
||||
containerSource,
|
||||
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.builder.buildConstExpression
|
||||
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
|
||||
@@ -18,57 +17,38 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
|
||||
import org.jetbrains.kotlin.types.ConstantValueKind
|
||||
|
||||
class FirConstDeserializer(
|
||||
val session: FirSession,
|
||||
private val binaryClass: KotlinJvmBinaryClass? = null
|
||||
open class FirConstDeserializer(
|
||||
val session: FirSession
|
||||
) {
|
||||
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
|
||||
|
||||
constantCache[callableId]?.let { return it }
|
||||
|
||||
if (binaryClass == null) {
|
||||
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]
|
||||
val value = propertyProto.getExtensionOrNull(BuiltInSerializerProtocol.compileTimeValue) ?: return null
|
||||
return buildFirConstant(value, null, value.type.name, nameResolver)?.also { constantCache[callableId] = it }
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildFirConstant(
|
||||
protoValue: ProtoBuf.Annotation.Argument.Value?, sourceValue: Any?, constKind: String, nameResolver: NameResolver
|
||||
): FirExpression? {
|
||||
return when (constKind) {
|
||||
"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())
|
||||
"SHORT", "S" -> buildConstExpression(null, ConstantValueKind.Short, ((protoValue?.intValue ?: sourceValue) as Number).toShort())
|
||||
"INT", "I" -> buildConstExpression(null, ConstantValueKind.Int, protoValue?.intValue?.toInt() ?: sourceValue as Int)
|
||||
"LONG", "J" -> buildConstExpression(null, ConstantValueKind.Long, protoValue?.intValue ?: sourceValue as Long)
|
||||
"FLOAT", "F" -> buildConstExpression(null, ConstantValueKind.Float, protoValue?.floatValue ?: sourceValue as Float)
|
||||
"DOUBLE", "D" -> buildConstExpression(null, ConstantValueKind.Double, protoValue?.doubleValue ?: sourceValue as Double)
|
||||
"BOOLEAN", "Z" -> buildConstExpression(null, ConstantValueKind.Boolean, (protoValue?.intValue?.toInt() ?: sourceValue) != 0)
|
||||
"STRING", "Ljava/lang/String;" -> buildConstExpression(
|
||||
null, ConstantValueKind.String, protoValue?.stringValue?.let { nameResolver.getString(it) } ?: sourceValue as String
|
||||
)
|
||||
else -> null
|
||||
}
|
||||
fun buildFirConstant(
|
||||
protoValue: ProtoBuf.Annotation.Argument.Value?, sourceValue: Any?, constKind: String, nameResolver: NameResolver
|
||||
): FirExpression? {
|
||||
return when (constKind) {
|
||||
"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())
|
||||
"SHORT", "S" -> buildConstExpression(null, ConstantValueKind.Short, ((protoValue?.intValue ?: sourceValue) as Number).toShort())
|
||||
"INT", "I" -> buildConstExpression(null, ConstantValueKind.Int, protoValue?.intValue?.toInt() ?: sourceValue as Int)
|
||||
"LONG", "J" -> buildConstExpression(null, ConstantValueKind.Long, protoValue?.intValue ?: sourceValue as Long)
|
||||
"FLOAT", "F" -> buildConstExpression(null, ConstantValueKind.Float, protoValue?.floatValue ?: sourceValue as Float)
|
||||
"DOUBLE", "D" -> buildConstExpression(null, ConstantValueKind.Double, protoValue?.doubleValue ?: sourceValue as Double)
|
||||
"BOOLEAN", "Z" -> buildConstExpression(null, ConstantValueKind.Boolean, (protoValue?.intValue?.toInt() ?: sourceValue) != 0)
|
||||
"STRING", "Ljava/lang/String;" -> buildConstExpression(
|
||||
null, ConstantValueKind.String, protoValue?.stringValue?.let { nameResolver.getString(it) } ?: sourceValue as String
|
||||
)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun CallableId.replaceName(newName: Name): CallableId {
|
||||
return CallableId(this.packageName, this.className, newName)
|
||||
}
|
||||
}
|
||||
fun CallableId.replaceName(newName: Name): CallableId {
|
||||
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(
|
||||
packageFqName, packageProto, nameResolver, moduleData,
|
||||
JvmBinaryAnnotationDeserializer(session, kotlinJvmBinaryClass, kotlinClassFinder, byteContent),
|
||||
FirConstDeserializer(session, facadeBinaryClass ?: kotlinJvmBinaryClass),
|
||||
FirJvmConstDeserializer(session, facadeBinaryClass ?: kotlinJvmBinaryClass),
|
||||
source
|
||||
),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user