JavaSymbolProvider: support different kinds of literals in annotations
Constants, enum entries, class references, arrays are covered here Related to KT-29218
This commit is contained in:
@@ -11,8 +11,11 @@ import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirNamedFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.*
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirArrayOfCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.AbstractFirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.service
|
||||
@@ -61,23 +64,75 @@ class JavaSymbolProvider(
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: use kind here
|
||||
private fun <T> List<T>.createArrayOfCall(@Suppress("UNUSED_PARAMETER") kind: IrConstKind<T>): FirArrayOfCall {
|
||||
return FirArrayOfCallImpl(session, null).apply {
|
||||
for (element in this@createArrayOfCall) {
|
||||
arguments += element.createConstant()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Any?.createConstant(): FirExpression {
|
||||
return when (this) {
|
||||
is Byte -> FirConstExpressionImpl(session, null, IrConstKind.Byte, this)
|
||||
is Short -> FirConstExpressionImpl(session, null, IrConstKind.Short, this)
|
||||
is Int -> FirConstExpressionImpl(session, null, IrConstKind.Int, this)
|
||||
is Long -> FirConstExpressionImpl(session, null, IrConstKind.Long, this)
|
||||
is Char -> FirConstExpressionImpl(session, null, IrConstKind.Char, this)
|
||||
is Float -> FirConstExpressionImpl(session, null, IrConstKind.Float, this)
|
||||
is Double -> FirConstExpressionImpl(session, null, IrConstKind.Double, this)
|
||||
is Boolean -> FirConstExpressionImpl(session, null, IrConstKind.Boolean, this)
|
||||
is String -> FirConstExpressionImpl(session, null, IrConstKind.String, this)
|
||||
null -> FirConstExpressionImpl(session, null, IrConstKind.Null, null)
|
||||
|
||||
else -> FirErrorExpressionImpl(session, null, "Unknown value in JavaLiteralAnnotationArgument: $this")
|
||||
}
|
||||
}
|
||||
|
||||
private fun JavaAnnotationArgument.toFirExpression(): FirExpression {
|
||||
// TODO: this.name
|
||||
return when (this) {
|
||||
is JavaLiteralAnnotationArgument -> when (value) {
|
||||
null -> FirConstExpressionImpl(session, null, IrConstKind.Null, null)
|
||||
else -> FirErrorExpressionImpl(session, null, "Unknown value in JavaLiteralAnnotationArgument: $value")
|
||||
is JavaLiteralAnnotationArgument -> {
|
||||
val value = value
|
||||
when (value) {
|
||||
is ByteArray -> value.toList().createArrayOfCall(IrConstKind.Byte)
|
||||
is ShortArray -> value.toList().createArrayOfCall(IrConstKind.Short)
|
||||
is IntArray -> value.toList().createArrayOfCall(IrConstKind.Int)
|
||||
is LongArray -> value.toList().createArrayOfCall(IrConstKind.Long)
|
||||
is CharArray -> value.toList().createArrayOfCall(IrConstKind.Char)
|
||||
is FloatArray -> value.toList().createArrayOfCall(IrConstKind.Float)
|
||||
is DoubleArray -> value.toList().createArrayOfCall(IrConstKind.Double)
|
||||
is BooleanArray -> value.toList().createArrayOfCall(IrConstKind.Boolean)
|
||||
else -> value.createConstant()
|
||||
}
|
||||
}
|
||||
is JavaArrayAnnotationArgument -> FirArrayOfCallImpl(session, null).apply {
|
||||
for (element in getElements()) {
|
||||
arguments += element.toFirExpression()
|
||||
}
|
||||
}
|
||||
// TODO
|
||||
//is JavaEnumValueAnnotationArgument -> {}
|
||||
is JavaEnumValueAnnotationArgument -> {
|
||||
FirFunctionCallImpl(session, null).apply {
|
||||
val classId = this@toFirExpression.enumClassId
|
||||
val entryName = this@toFirExpression.entryName
|
||||
val calleeReference = if (classId != null && entryName != null) {
|
||||
val callableSymbol = session.service<FirSymbolProvider>().getCallableSymbols(
|
||||
CallableId(classId.packageFqName, classId.relativeClassName, entryName)
|
||||
).firstOrNull()
|
||||
callableSymbol?.let {
|
||||
FirResolvedCallableReferenceImpl(session, null, entryName, it)
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
this.calleeReference = calleeReference
|
||||
?: FirErrorNamedReference(session, null, "Strange Java enum value: ${this@toFirExpression}")
|
||||
}
|
||||
}
|
||||
is JavaClassObjectAnnotationArgument -> FirGetClassCallImpl(session, null).apply {
|
||||
// TODO
|
||||
//arguments += getReferencedType().toFirType()
|
||||
val referencedType = getReferencedType()
|
||||
arguments += FirClassReferenceExpressionImpl(session, null, referencedType.toFirResolvedTypeRef())
|
||||
}
|
||||
is JavaAnnotationAsAnnotationArgument -> getAnnotation().toFirAnnotationCall()
|
||||
else -> FirErrorExpressionImpl(session, null, "Unknown JavaAnnotationArgument: ${this::class.java}")
|
||||
|
||||
Reference in New Issue
Block a user