Kapt: Calculate constant values in the similar way.
Always use originalElement in JeAnnotationValue factory. (cherry picked from commit 0ff9584)
This commit is contained in:
committed by
Yan Zhulanow
parent
4710fab49f
commit
462c7d91d2
+24
-17
@@ -17,27 +17,34 @@
|
||||
package org.jetbrains.kotlin.java.model.elements
|
||||
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.java.model.internal.calcConstantValue
|
||||
import org.jetbrains.kotlin.java.model.types.toJeType
|
||||
import javax.lang.model.element.AnnotationValue
|
||||
import javax.lang.model.element.AnnotationValueVisitor
|
||||
|
||||
fun JeAnnotationValue(psi: PsiAnnotationMemberValue): AnnotationValue = when (psi) {
|
||||
is PsiLiteral -> JeLiteralAnnotationValue(psi)
|
||||
is PsiAnnotation -> JeAnnotationAnnotationValue(psi)
|
||||
is PsiArrayInitializerMemberValue -> JeArrayAnnotationValue(psi)
|
||||
is PsiClassObjectAccessExpression -> JeTypeAnnotationValue(psi)
|
||||
is PsiReferenceExpression -> {
|
||||
// TODO check static final field -> primitive, reference to enum value
|
||||
val element = psi.resolve()
|
||||
if (element is PsiEnumConstant) {
|
||||
JeEnumValueAnnotationValue(element)
|
||||
}
|
||||
else {
|
||||
JeErrorAnnotationValue(psi)
|
||||
fun JeAnnotationValue(psi: PsiAnnotationMemberValue): AnnotationValue {
|
||||
val original = psi.originalElement
|
||||
val annotationValue = when (original) {
|
||||
is PsiLiteral -> JeLiteralAnnotationValue(original)
|
||||
is PsiAnnotation -> JeAnnotationAnnotationValue(original)
|
||||
is PsiArrayInitializerMemberValue -> JeArrayAnnotationValue(original)
|
||||
is PsiClassObjectAccessExpression -> JeTypeAnnotationValue(original)
|
||||
is PsiReferenceExpression -> {
|
||||
val element = original.resolve()
|
||||
if (element is PsiEnumConstant) {
|
||||
JeEnumValueAnnotationValue(element)
|
||||
}
|
||||
else if (element is PsiField && element.hasInitializer()) {
|
||||
JeAnnotationValue(element.initializer ?: error("Field should have an initializer"))
|
||||
}
|
||||
else {
|
||||
JeErrorAnnotationValue(psi)
|
||||
}
|
||||
}
|
||||
is PsiExpression -> JeExpressionAnnotationValue(original)
|
||||
else -> throw AssertionError("Unsupported annotation element value: $psi (original = $original)")
|
||||
}
|
||||
is PsiExpression -> JeExpressionAnnotationValue(psi)
|
||||
else -> throw AssertionError("Unsupported annotation element value: $psi")
|
||||
return annotationValue
|
||||
}
|
||||
|
||||
internal class JeAnnotationAnnotationValue(val psi: PsiAnnotation) : AnnotationValue {
|
||||
@@ -78,11 +85,11 @@ internal class JeLiteralAnnotationValue(val psi: PsiLiteral) : JePrimitiveAnnota
|
||||
}
|
||||
|
||||
internal class JeExpressionAnnotationValue(val psi: PsiExpression) : JePrimitiveAnnotationValue() {
|
||||
override fun getValue() = JavaPsiFacade.getInstance(psi.project).constantEvaluationHelper.computeConstantExpression(psi)
|
||||
override fun getValue() = psi.calcConstantValue()
|
||||
}
|
||||
|
||||
internal class JeArrayAnnotationValue(val psi: PsiArrayInitializerMemberValue) : AnnotationValue {
|
||||
override fun getValue() = psi.initializers.map { JeAnnotationValue(it) }
|
||||
override fun getValue() = psi.initializers.map(::JeAnnotationValue)
|
||||
override fun <R : Any?, P : Any?> accept(v: AnnotationValueVisitor<R, P>, p: P) = v.visitArray(value, p)
|
||||
}
|
||||
|
||||
|
||||
+2
-5
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.java.model.elements
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.java.model.*
|
||||
import org.jetbrains.kotlin.java.model.internal.calcConstantValue
|
||||
import org.jetbrains.kotlin.java.model.types.toJeType
|
||||
import javax.lang.model.element.Element
|
||||
import javax.lang.model.element.ElementKind
|
||||
@@ -37,11 +38,7 @@ class JeVariableElement(override val psi: PsiVariable) : JeElement(), VariableEl
|
||||
return containingClass?.let { JeTypeElement(it) }
|
||||
}
|
||||
|
||||
override fun getConstantValue(): Any? {
|
||||
val initializer = psi.initializer ?: return null
|
||||
val evaluationHelper = JavaPsiFacade.getInstance(psi.project).constantEvaluationHelper
|
||||
return evaluationHelper.computeConstantExpression(initializer)
|
||||
}
|
||||
override fun getConstantValue() = psi.initializer?.calcConstantValue()
|
||||
|
||||
override fun getKind() = when (psi) {
|
||||
is PsiField -> ElementKind.FIELD
|
||||
|
||||
+2
-9
@@ -74,7 +74,7 @@ private fun getConstantValue(
|
||||
|
||||
when {
|
||||
returnType == PsiType.NULL || returnType == PsiType.VOID -> unexpectedType("void")
|
||||
jReturnType == String::class.java -> return calculateConstantValue(psiValue, evaluator)
|
||||
jReturnType == String::class.java -> return (psiValue as? PsiExpression)?.calcConstantValue(evaluator)
|
||||
jReturnType == Class::class.java -> {
|
||||
val type = getObjectType(psiValue).toJeType(manager)
|
||||
return MirroredTypeExceptionProxy(type)
|
||||
@@ -105,7 +105,7 @@ private fun getConstantValue(
|
||||
?: error("$psiValue can not be resolved to enum constant")
|
||||
return AnnotationUtil.createEnumValue(jReturnType, enumConstant.name)
|
||||
}
|
||||
else -> return castPrimitiveValue(returnType, calculateConstantValue(psiValue, evaluator))
|
||||
else -> return castPrimitiveValue(returnType, (psiValue as? PsiExpression)?.calcConstantValue(evaluator))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,13 +148,6 @@ private fun longValue(value: Any?): Long = (value as? Number)?.toLong() ?: 0
|
||||
private fun floatValue(value: Any?): Float = (value as? Number)?.toFloat() ?: 0f
|
||||
private fun doubleValue(value: Any?): Double = (value as? Number)?.toDouble() ?: 0.0
|
||||
|
||||
private fun calculateConstantValue(value: PsiAnnotationMemberValue?, evaluator: PsiConstantEvaluationHelper) = when (value) {
|
||||
is PsiLiteral -> value.value
|
||||
is KtLightAnnotation.LightExpressionValue<*> -> value.getConstantValue()
|
||||
is PsiExpression -> evaluator.computeConstantExpression(value)
|
||||
else -> null
|
||||
}
|
||||
|
||||
private fun unexpectedType(type: String): Nothing = error("Unexpected type: $type")
|
||||
private fun unexpectedType(type: PsiType): Nothing = unexpectedType(type.presentableText)
|
||||
|
||||
|
||||
+13
-3
@@ -16,10 +16,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.java.model.internal
|
||||
|
||||
import com.intellij.psi.PsiModifier
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.PsiModifier.*
|
||||
import com.intellij.psi.PsiModifierList
|
||||
import com.intellij.psi.PsiModifierListOwner
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightAnnotation
|
||||
import javax.lang.model.element.Modifier
|
||||
|
||||
private val HAS_DEFAULT by lazy {
|
||||
@@ -50,6 +49,17 @@ private fun PsiModifierList.getJavaModifiers(): Set<Modifier> {
|
||||
}
|
||||
}
|
||||
|
||||
internal fun PsiExpression.calcConstantValue(evaluator: PsiConstantEvaluationHelper? = null): Any? {
|
||||
return when (this) {
|
||||
is PsiLiteral -> value
|
||||
is KtLightAnnotation.LightExpressionValue<*> -> getConstantValue()
|
||||
is PsiExpression -> (evaluator ?: getConstantEvaluator(this)).computeConstantExpression(this)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun getConstantEvaluator(expression: PsiExpression) = JavaPsiFacade.getInstance(expression.project).constantEvaluationHelper
|
||||
|
||||
internal val PsiModifierListOwner.isStatic: Boolean
|
||||
get() = hasModifierProperty(PsiModifier.STATIC)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user