[K2] Move ConstantValue from fir-serialization to compiler.common

This is needed to be able to save `ConstantValue` in map of
evaluated constants.
This commit is contained in:
Ivan Kylchik
2023-04-05 23:00:50 +02:00
committed by Space Team
parent fe989d0ba7
commit 297b6ae64b
7 changed files with 163 additions and 117 deletions
@@ -5,7 +5,9 @@
package org.jetbrains.kotlin.fir.serialization
import org.jetbrains.kotlin.constant.*
import org.jetbrains.kotlin.fir.serialization.constant.*
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.arrayElementType
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.Flags
@@ -13,7 +15,7 @@ import org.jetbrains.kotlin.metadata.deserialization.Flags
internal object FirAnnotationArgumentVisitor : AnnotationArgumentVisitor<Unit, FirAnnotationArgumentVisitorData>() {
override fun visitAnnotationValue(value: AnnotationValue, data: FirAnnotationArgumentVisitorData) {
data.builder.type = ProtoBuf.Annotation.Argument.Value.Type.ANNOTATION
data.builder.annotation = data.serializer.serializeAnnotation(value.value)
data.builder.annotation = data.serializer.serializeAnnotation(value)
}
override fun visitArrayValue(value: ArrayValue, data: FirAnnotationArgumentVisitorData) {
@@ -76,7 +78,7 @@ internal object FirAnnotationArgumentVisitor : AnnotationArgumentVisitor<Unit, F
}
is KClassValue.Value.LocalClass -> {
var arrayDimensions = 0
var type = classValue.type
var type = classValue.coneType<ConeKotlinType>()
while (true) {
type = type.arrayElementType() ?: break
arrayDimensions++
@@ -5,40 +5,53 @@
package org.jetbrains.kotlin.fir.serialization
import org.jetbrains.kotlin.constant.AnnotationValue
import org.jetbrains.kotlin.constant.ConstantValue
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.serialization.constant.ConstantValue
import org.jetbrains.kotlin.fir.serialization.constant.toConstantValue
import org.jetbrains.kotlin.fir.serialization.constant.coneTypeSafe
import org.jetbrains.kotlin.fir.serialization.constant.convertToConstantValues
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.coneTypeSafe
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.name.Name
class FirAnnotationSerializer(private val session: FirSession, internal val stringTable: FirElementAwareStringTable) {
fun serializeAnnotation(annotation: FirAnnotation): ProtoBuf.Annotation = ProtoBuf.Annotation.newBuilder().apply {
val lookupTag = annotation.typeRef.coneTypeSafe<ConeClassLikeType>()?.lookupTag
?: error { "Annotation without proper lookup tag: ${annotation.annotationTypeRef.coneType}" }
fun serializeAnnotation(annotation: FirAnnotation): ProtoBuf.Annotation {
return serializeAnnotation(
annotation.typeRef.coneTypeSafe<ConeClassLikeType>(),
annotation.argumentMapping.mapping.convertToConstantValues(session)
)
}
id = lookupTag.toSymbol(session)?.let { stringTable.getFqNameIndex(it.fir) }
?: stringTable.getQualifiedClassNameIndex(lookupTag.classId)
fun serializeAnnotation(annotation: AnnotationValue): ProtoBuf.Annotation {
return serializeAnnotation(annotation.coneTypeSafe<ConeClassLikeType>(), annotation.value.argumentsMapping)
}
fun addArgument(argumentExpression: FirExpression, parameterName: Name) {
val argument = ProtoBuf.Annotation.Argument.newBuilder()
argument.nameId = stringTable.getStringIndex(parameterName.asString())
val constantValue = argumentExpression.toConstantValue(session)
?: error("Cannot convert expression ${argumentExpression.render()} to constant")
argument.setValue(valueProto(constantValue))
addArgument(argument)
}
private fun serializeAnnotation(coneType: ConeClassLikeType?, argumentsMapping: Map<Name, ConstantValue<*>?>): ProtoBuf.Annotation {
return ProtoBuf.Annotation.newBuilder().apply {
val lookupTag = coneType?.lookupTag
?: error { "Annotation without proper lookup tag: $coneType" }
for ((name, argument) in annotation.argumentMapping.mapping) {
addArgument(argument, name)
}
}.build()
id = lookupTag.toSymbol(session)?.let { stringTable.getFqNameIndex(it.fir) }
?: stringTable.getQualifiedClassNameIndex(lookupTag.classId)
fun addArgument(argumentExpression: ConstantValue<*>?, parameterName: Name) {
if (argumentExpression == null) {
error("Cannot use null argument expression for parameter $parameterName")
}
val argument = ProtoBuf.Annotation.Argument.newBuilder()
argument.nameId = stringTable.getStringIndex(parameterName.asString())
argument.setValue(valueProto(argumentExpression))
addArgument(argument)
}
for ((name, argument) in argumentsMapping) {
addArgument(argument, name)
}
}.build()
}
internal fun valueProto(constant: ConstantValue<*>): ProtoBuf.Annotation.Argument.Value.Builder =
ProtoBuf.Annotation.Argument.Value.newBuilder().apply {
@@ -9,6 +9,9 @@ import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.builtins.functions.FunctionTypeKind
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.constant.EnumValue
import org.jetbrains.kotlin.constant.IntValue
import org.jetbrains.kotlin.constant.StringValue
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fir.*
@@ -29,9 +32,6 @@ import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.scopes.*
import org.jetbrains.kotlin.fir.serialization.constant.*
import org.jetbrains.kotlin.fir.serialization.constant.EnumValue
import org.jetbrains.kotlin.fir.serialization.constant.IntValue
import org.jetbrains.kotlin.fir.serialization.constant.StringValue
import org.jetbrains.kotlin.fir.serialization.constant.toConstantValue
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
@@ -1,28 +0,0 @@
/*
* 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.serialization.constant
internal abstract class AnnotationArgumentVisitor<R, D> {
abstract fun visitLongValue(value: LongValue, data: D): R
abstract fun visitIntValue(value: IntValue, data: D): R
abstract fun visitErrorValue(value: ErrorValue, data: D): R
abstract fun visitShortValue(value: ShortValue, data: D): R
abstract fun visitByteValue(value: ByteValue, data: D): R
abstract fun visitDoubleValue(value: DoubleValue, data: D): R
abstract fun visitFloatValue(value: FloatValue, data: D): R
abstract fun visitBooleanValue(value: BooleanValue, data: D): R
abstract fun visitCharValue(value: CharValue, data: D): R
abstract fun visitStringValue(value: StringValue, data: D): R
abstract fun visitNullValue(value: NullValue, data: D): R
abstract fun visitEnumValue(value: EnumValue, data: D): R
abstract fun visitArrayValue(value: ArrayValue, data: D): R
abstract fun visitAnnotationValue(value: AnnotationValue, data: D): R
abstract fun visitKClassValue(value: KClassValue, data: D): R
abstract fun visitUByteValue(value: UByteValue, data: D): R
abstract fun visitUShortValue(value: UShortValue, data: D): R
abstract fun visitUIntValue(value: UIntValue, data: D): R
abstract fun visitULongValue(value: ULongValue, data: D): R
}
@@ -1,229 +0,0 @@
/*
* 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.serialization.constant
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.resolve.defaultType
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.constants.ClassLiteralValue
internal sealed class ConstantValue<out T>(open val value: T) {
abstract fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D): R
override fun equals(other: Any?): Boolean = this === other || value == (other as? ConstantValue<*>)?.value
override fun hashCode(): Int = value?.hashCode() ?: 0
override fun toString(): String = value.toString()
open fun stringTemplateValue(): String = value.toString()
}
internal abstract class IntegerValueConstant<out T> protected constructor(value: T) : ConstantValue<T>(value)
internal abstract class UnsignedValueConstant<out T> protected constructor(value: T) : ConstantValue<T>(value)
internal class AnnotationValue(value: FirAnnotation) : ConstantValue<FirAnnotation>(value) {
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D): R = visitor.visitAnnotationValue(this, data)
}
internal class ArrayValue(
value: List<ConstantValue<*>>,
) : ConstantValue<List<ConstantValue<*>>>(value) {
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D): R = visitor.visitArrayValue(this, data)
}
internal class BooleanValue(value: Boolean) : ConstantValue<Boolean>(value) {
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D): R = visitor.visitBooleanValue(this, data)
}
internal class ByteValue(value: Byte) : IntegerValueConstant<Byte>(value) {
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D): R = visitor.visitByteValue(this, data)
override fun toString(): String = "$value.toByte()"
}
internal class CharValue(value: Char) : IntegerValueConstant<Char>(value) {
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D): R = visitor.visitCharValue(this, data)
override fun toString(): String = "\\u%04X ('%s')".format(value.code, getPrintablePart(value))
private fun getPrintablePart(c: Char): String = when (c) {
'\b' -> "\\b"
'\t' -> "\\t"
'\n' -> "\\n"
'\u000c' -> "\\f"
'\r' -> "\\r"
else -> if (isPrintableUnicode(c)) c.toString() else "?"
}
private fun isPrintableUnicode(c: Char): Boolean {
val t = Character.getType(c).toByte()
return t != Character.UNASSIGNED &&
t != Character.LINE_SEPARATOR &&
t != Character.PARAGRAPH_SEPARATOR &&
t != Character.CONTROL &&
t != Character.FORMAT &&
t != Character.PRIVATE_USE &&
t != Character.SURROGATE
}
}
internal class DoubleValue(value: Double) : ConstantValue<Double>(value) {
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D): R = visitor.visitDoubleValue(this, data)
override fun toString(): String = "$value.toDouble()"
}
internal class EnumValue(
val enumClassId: ClassId,
val enumEntryName: Name
) : ConstantValue<Pair<ClassId, Name>>(enumClassId to enumEntryName) {
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D): R = visitor.visitEnumValue(this, data)
override fun toString(): String = "${enumClassId.shortClassName}.$enumEntryName"
}
internal abstract class ErrorValue : ConstantValue<Unit>(Unit) {
@Deprecated("Should not be called, for this is not a real value, but a indication of an error", level = DeprecationLevel.HIDDEN)
override val value: Unit
get() = throw UnsupportedOperationException()
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D): R = visitor.visitErrorValue(this, data)
class ErrorValueWithMessage(val message: String) : ErrorValue() {
override fun toString(): String = message
}
companion object {
fun create(message: String): ErrorValue {
return ErrorValueWithMessage(message)
}
}
}
internal class FloatValue(value: Float) : ConstantValue<Float>(value) {
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D): R = visitor.visitFloatValue(this, data)
override fun toString(): String = "$value.toFloat()"
}
internal class IntValue(value: Int) : IntegerValueConstant<Int>(value) {
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D): R = visitor.visitIntValue(this, data)
}
internal class KClassValue(value: Value) : ConstantValue<KClassValue.Value>(value) {
sealed class Value {
data class NormalClass(val value: ClassLiteralValue) : Value() {
val classId: ClassId get() = value.classId
val arrayDimensions: Int get() = value.arrayNestedness
}
data class LocalClass(val type: ConeKotlinType) : Value()
}
constructor(value: ClassLiteralValue) : this(Value.NormalClass(value))
constructor(classId: ClassId, arrayDimensions: Int) : this(ClassLiteralValue(classId, arrayDimensions))
fun getArgumentType(session: FirSession): ConeKotlinType? {
when (value) {
is Value.LocalClass -> return value.type
is Value.NormalClass -> {
val (classId, arrayDimensions) = value.value
val klass = session.symbolProvider.getClassLikeSymbolByClassId(classId)?.fir as? FirRegularClass ?: return null
var type: ConeClassLikeType = klass.defaultType().replaceArgumentsWithStarProjections()
repeat(arrayDimensions) {
type = type.createArrayType()
}
return type
}
}
}
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D): R = visitor.visitKClassValue(this, data)
companion object {
fun create(argumentType: ConeKotlinType): ConstantValue<*>? {
if (argumentType is ConeErrorType) return null
if (argumentType !is ConeClassLikeType) return null
var type = argumentType
var arrayDimensions = 0
while (true) {
if (type.isPrimitiveArray) break
type = type.arrayElementType() ?: break
arrayDimensions++
}
val classId = type.classId ?: return null
return KClassValue(classId, arrayDimensions)
}
}
}
internal class LongValue(value: Long) : IntegerValueConstant<Long>(value) {
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D): R = visitor.visitLongValue(this, data)
override fun toString(): String = "$value.toLong()"
}
internal object NullValue : ConstantValue<Nothing?>(null) {
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D): R = visitor.visitNullValue(this, data)
}
internal class ShortValue(value: Short) : IntegerValueConstant<Short>(value) {
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D): R = visitor.visitShortValue(this, data)
override fun toString(): String = "$value.toShort()"
}
internal class StringValue(value: String) : ConstantValue<String>(value) {
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D): R = visitor.visitStringValue(this, data)
override fun toString(): String = "\"$value\""
}
internal class UByteValue(byteValue: Byte) : UnsignedValueConstant<Byte>(byteValue) {
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D): R = visitor.visitUByteValue(this, data)
override fun toString(): String = "$value.toUByte()"
override fun stringTemplateValue(): String = (value.toInt() and 0xFF).toString()
}
internal class UShortValue(shortValue: Short) : UnsignedValueConstant<Short>(shortValue) {
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D): R = visitor.visitUShortValue(this, data)
override fun toString(): String = "$value.toUShort()"
override fun stringTemplateValue(): String = (value.toInt() and 0xFFFF).toString()
}
internal class UIntValue(intValue: Int) : UnsignedValueConstant<Int>(intValue) {
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D): R = visitor.visitUIntValue(this, data)
override fun toString(): String = "$value.toUInt()"
override fun stringTemplateValue(): String = (value.toLong() and 0xFFFFFFFFL).toString()
}
internal class ULongValue(longValue: Long) : UnsignedValueConstant<Long>(longValue) {
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D): R = visitor.visitULongValue(this, data)
override fun toString(): String = "$value.toULong()"
override fun stringTemplateValue(): String {
if (value >= 0) return value.toString()
val div10 = (value ushr 1) / 5
val mod10 = value - 10 * div10
return "$div10$mod10"
}
}
@@ -0,0 +1,66 @@
/*
* 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.serialization.constant
import org.jetbrains.kotlin.constant.AnnotationValue
import org.jetbrains.kotlin.constant.ConstantValue
import org.jetbrains.kotlin.constant.KClassValue
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.resolve.defaultType
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.name.Name
internal fun Map<Name, FirExpression>.convertToConstantValues(session: FirSession): Map<Name, ConstantValue<*>?> {
return this.map { (name, firExpression) ->
name to firExpression.toConstantValue(session)
}.toMap()
}
internal fun LinkedHashMap<FirExpression, FirValueParameter>.convertToConstantValues(session: FirSession): Map<Name, ConstantValue<*>?> {
return this.map { (firExpression, firValueParameter) -> firValueParameter.name to firExpression }
.toMap().convertToConstantValues(session)
}
inline fun <reified T : ConeKotlinType> AnnotationValue.coneTypeSafe(): T? {
return this.value.type as? T
}
inline fun <reified T : ConeKotlinType> KClassValue.Value.LocalClass.coneType(): T {
return this.type as T
}
internal fun KClassValue.getArgumentType(session: FirSession): ConeKotlinType? {
when (val castedValue = value) {
is KClassValue.Value.LocalClass -> return castedValue.type as ConeKotlinType
is KClassValue.Value.NormalClass -> {
val (classId, arrayDimensions) = castedValue.value
val klass = session.symbolProvider.getClassLikeSymbolByClassId(classId)?.fir as? FirRegularClass ?: return null
var type: ConeClassLikeType = klass.defaultType().replaceArgumentsWithStarProjections()
repeat(arrayDimensions) {
type = type.createArrayType()
}
return type
}
}
}
internal fun create(argumentType: ConeKotlinType): ConstantValue<*>? {
if (argumentType is ConeErrorType) return null
if (argumentType !is ConeClassLikeType) return null
var type = argumentType
var arrayDimensions = 0
while (true) {
if (type.isPrimitiveArray) break
type = type.arrayElementType() ?: break
arrayDimensions++
}
val classId = type.classId ?: return null
return KClassValue(classId, arrayDimensions)
}
@@ -5,25 +5,23 @@
package org.jetbrains.kotlin.fir.serialization.constant
import org.jetbrains.kotlin.constant.*
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.containingClassLookupTag
import org.jetbrains.kotlin.fir.declarations.FirEnumEntry
import org.jetbrains.kotlin.fir.declarations.utils.isConst
import org.jetbrains.kotlin.fir.declarations.utils.isFinal
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotationArgumentMapping
import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotationCall
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
import org.jetbrains.kotlin.fir.references.builder.buildSimpleNamedReference
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirArrayOfCallTransformer
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirArrayOfCallTransformer.Companion.isArrayOfCall
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.classId
import org.jetbrains.kotlin.fir.types.coneTypeSafe
import org.jetbrains.kotlin.fir.types.coneTypeUnsafe
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
import org.jetbrains.kotlin.types.ConstantValueKind
@@ -92,7 +90,8 @@ private abstract class FirToConstantValueTransformer(
annotation: FirAnnotation,
data: FirSession
): ConstantValue<*> {
return AnnotationValue(annotation)
val mapping = annotation.argumentMapping.mapping.convertToConstantValues(data)
return AnnotationValue.create(annotation.annotationTypeRef.coneType, mapping)
}
override fun visitAnnotationCall(annotationCall: FirAnnotationCall, data: FirSession): ConstantValue<*> {
@@ -103,7 +102,7 @@ private abstract class FirToConstantValueTransformer(
getClassCall: FirGetClassCall,
data: FirSession
): ConstantValue<*>? {
return KClassValue.create(getClassCall.argument.typeRef.coneTypeUnsafe())
return create(getClassCall.argument.typeRef.coneTypeUnsafe())
}
override fun visitQualifiedAccessExpression(
@@ -136,20 +135,8 @@ private abstract class FirToConstantValueTransformer(
val constructedClassSymbol = symbol.containingClassLookupTag()?.toFirRegularClassSymbol(data) ?: return null
if (constructedClassSymbol.classKind != ClassKind.ANNOTATION_CLASS) return null
return AnnotationValue(
buildAnnotationCall {
argumentMapping = buildAnnotationArgumentMapping {
constructorCall.resolvedArgumentMapping?.forEach { (firExpression, firValueParameter) ->
mapping[firValueParameter.name] = firExpression
}
}
annotationTypeRef = qualifiedAccessExpression.typeRef
calleeReference = buildSimpleNamedReference {
source = qualifiedAccessExpression.source
name = qualifiedAccessExpression.calleeReference.name
}
}
)
val mapping = constructorCall.resolvedArgumentMapping?.convertToConstantValues(data) ?: return null
return AnnotationValue.create(qualifiedAccessExpression.typeRef.coneType, mapping)
}
symbol.callableId.packageName.asString() == "kotlin" -> {
@@ -240,7 +227,7 @@ internal object FirToConstantValueChecker : FirDefaultVisitor<Boolean, FirSessio
override fun visitAnnotationCall(annotationCall: FirAnnotationCall, data: FirSession): Boolean = true
override fun visitGetClassCall(getClassCall: FirGetClassCall, data: FirSession): Boolean {
return KClassValue.create(getClassCall.argument.typeRef.coneTypeUnsafe()) != null
return create(getClassCall.argument.typeRef.coneTypeUnsafe()) != null
}
override fun visitQualifiedAccessExpression(qualifiedAccessExpression: FirQualifiedAccessExpression, data: FirSession): Boolean {