[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:
+4
-2
@@ -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++
|
||||
|
||||
+35
-22
@@ -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 {
|
||||
|
||||
+3
-3
@@ -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
|
||||
|
||||
+66
@@ -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)
|
||||
}
|
||||
+12
-25
@@ -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 {
|
||||
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2023 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
|
||||
package org.jetbrains.kotlin.constant
|
||||
|
||||
internal abstract class AnnotationArgumentVisitor<R, D> {
|
||||
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
|
||||
+40
-62
@@ -1,21 +1,20 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2023 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
|
||||
package org.jetbrains.kotlin.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
|
||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||
|
||||
internal sealed class ConstantValue<out T>(open val value: T) {
|
||||
// Note 1: can be combined with org.jetbrains.kotlin.resolve.constants.ConstantValue but where is some questions to `AnnotationValue`.
|
||||
// Note 2: if we are not going to implement previous idea, then this class can be moved to `fir` module.
|
||||
// The problem here is that `ConstantValue` somehow must be accessible to `EvaluatedConstTracker`
|
||||
// which in turn must be accessible to `CommonConfigurationKeys`.
|
||||
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
|
||||
@@ -27,30 +26,40 @@ internal sealed class ConstantValue<out T>(open val value: T) {
|
||||
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)
|
||||
abstract class IntegerValueConstant<out T> protected constructor(value: T) : ConstantValue<T>(value)
|
||||
abstract class UnsignedValueConstant<out T> protected constructor(value: T) : ConstantValue<T>(value)
|
||||
|
||||
class AnnotationValue private constructor(value: Value) : ConstantValue<AnnotationValue.Value>(value) {
|
||||
class Value(val type: KotlinTypeMarker, val argumentsMapping: Map<Name, ConstantValue<*>?>)
|
||||
|
||||
internal class AnnotationValue(value: FirAnnotation) : ConstantValue<FirAnnotation>(value) {
|
||||
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D): R = visitor.visitAnnotationValue(this, data)
|
||||
|
||||
companion object {
|
||||
fun create(type: KotlinTypeMarker, argumentsMapping: Map<Name, ConstantValue<*>?>): AnnotationValue {
|
||||
return AnnotationValue(
|
||||
Value(type, argumentsMapping)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class ArrayValue(
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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))
|
||||
@@ -76,13 +85,13 @@ internal class CharValue(value: Char) : IntegerValueConstant<Char>(value) {
|
||||
}
|
||||
}
|
||||
|
||||
internal class DoubleValue(value: Double) : ConstantValue<Double>(value) {
|
||||
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(
|
||||
class EnumValue(
|
||||
val enumClassId: ClassId,
|
||||
val enumEntryName: Name
|
||||
) : ConstantValue<Pair<ClassId, Name>>(enumClassId to enumEntryName) {
|
||||
@@ -91,7 +100,7 @@ internal class EnumValue(
|
||||
override fun toString(): String = "${enumClassId.shortClassName}.$enumEntryName"
|
||||
}
|
||||
|
||||
internal abstract class ErrorValue : ConstantValue<Unit>(Unit) {
|
||||
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()
|
||||
@@ -109,87 +118,56 @@ internal abstract class ErrorValue : ConstantValue<Unit>(Unit) {
|
||||
}
|
||||
}
|
||||
|
||||
internal class FloatValue(value: Float) : ConstantValue<Float>(value) {
|
||||
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) {
|
||||
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) {
|
||||
class KClassValue private constructor(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()
|
||||
data class LocalClass(val type: KotlinTypeMarker) : 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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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()"
|
||||
@@ -197,7 +175,7 @@ internal class UByteValue(byteValue: Byte) : UnsignedValueConstant<Byte>(byteVal
|
||||
override fun stringTemplateValue(): String = (value.toInt() and 0xFF).toString()
|
||||
}
|
||||
|
||||
internal class UShortValue(shortValue: Short) : UnsignedValueConstant<Short>(shortValue) {
|
||||
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()"
|
||||
@@ -205,7 +183,7 @@ internal class UShortValue(shortValue: Short) : UnsignedValueConstant<Short>(sho
|
||||
override fun stringTemplateValue(): String = (value.toInt() and 0xFFFF).toString()
|
||||
}
|
||||
|
||||
internal class UIntValue(intValue: Int) : UnsignedValueConstant<Int>(intValue) {
|
||||
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()"
|
||||
@@ -213,7 +191,7 @@ internal class UIntValue(intValue: Int) : UnsignedValueConstant<Int>(intValue) {
|
||||
override fun stringTemplateValue(): String = (value.toLong() and 0xFFFFFFFFL).toString()
|
||||
}
|
||||
|
||||
internal class ULongValue(longValue: Long) : UnsignedValueConstant<Long>(longValue) {
|
||||
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()"
|
||||
Reference in New Issue
Block a user