KtLightAnnotationForSourceEntry: made more verbose with errors in arrays in params (KT-21335, EA-107118)
This commit is contained in:
committed by
xiexed
parent
e43bf90b9c
commit
23344783a5
+47
-24
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.asJava.elements
|
||||
|
||||
import com.intellij.openapi.diagnostic.Attachment
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.psi.*
|
||||
@@ -37,6 +39,8 @@ import org.jetbrains.kotlin.resolve.calls.model.VarargValueArgument
|
||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
|
||||
private val LOG = Logger.getInstance("#org.jetbrains.kotlin.asJava.elements.lightAnnotations")
|
||||
|
||||
abstract class KtLightAbstractAnnotation(parent: PsiElement, computeDelegate: () -> PsiAnnotation) :
|
||||
KtLightElementBase(parent), PsiAnnotation, KtLightElement<KtCallElement, PsiAnnotation> {
|
||||
override val clsDelegate by lazyPub(computeDelegate)
|
||||
@@ -181,13 +185,17 @@ class KtLightAnnotationForSourceEntry(
|
||||
valueOrigin: AnnotationValueOrigin
|
||||
) : LightElementValue<PsiArrayInitializerMemberValue>(delegate, parent, valueOrigin), PsiArrayInitializerMemberValue {
|
||||
private val _initializers by lazyPub {
|
||||
delegate.initializers.mapIndexed { i, it ->
|
||||
wrapAnnotationValue(it, this, {
|
||||
originalExpression.let {
|
||||
when (it) {
|
||||
is KtCallElement -> it.valueArguments[i].getArgumentExpression()!!
|
||||
is KtCollectionLiteralExpression -> it.getInnerExpressions()[i]
|
||||
else -> throw UnsupportedOperationException("cant process $it of type ${it?.javaClass}")
|
||||
delegate.initializers.mapIndexed { i, memberValue ->
|
||||
wrapAnnotationValue(memberValue, this, {
|
||||
originalExpression.let { ktOrigin ->
|
||||
when (ktOrigin) {
|
||||
is KtCallElement -> ktOrigin.valueArguments.getOrNull(i)?.getArgumentExpression()
|
||||
is KtCollectionLiteralExpression -> ktOrigin.getInnerExpressions().getOrNull(i)
|
||||
else -> null
|
||||
}.also {
|
||||
if (it == null)
|
||||
LOG.error("error wrapping ${memberValue.javaClass} for ${ktOrigin?.javaClass} in ${ktOrigin?.containingFile}",
|
||||
Attachment("source_fragments.txt", "origin: '${psiReport(ktOrigin)}', delegate: ${psiReport(delegate)}"))
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -197,22 +205,26 @@ class KtLightAnnotationForSourceEntry(
|
||||
override fun getInitializers() = _initializers
|
||||
}
|
||||
|
||||
private fun wrapAnnotationValue(value: PsiAnnotationMemberValue, parent: PsiElement, ktOrigin: AnnotationValueOrigin): PsiAnnotationMemberValue {
|
||||
return when {
|
||||
value is PsiLiteralExpression && value.value is String -> LightStringLiteral(value, parent, ktOrigin)
|
||||
value is PsiClassObjectAccessExpression -> LightClassLiteral(value, parent, ktOrigin)
|
||||
value is PsiExpression -> LightExpressionValue(value, parent, ktOrigin)
|
||||
value is PsiArrayInitializerMemberValue -> LightArrayInitializerValue(value, parent, ktOrigin)
|
||||
value is PsiAnnotation -> KtLightAnnotationForSourceEntry(
|
||||
value.qualifiedName!!,
|
||||
ktOrigin().let {
|
||||
it?.asKtCall() ?: throw UnsupportedOperationException("cant convert $it to KtCallElement")
|
||||
},
|
||||
parent, { value }
|
||||
)
|
||||
else -> LightElementValue(value, parent, ktOrigin)
|
||||
}
|
||||
}
|
||||
private fun wrapAnnotationValue(value: PsiAnnotationMemberValue, parent: PsiElement, ktOrigin: AnnotationValueOrigin): PsiAnnotationMemberValue =
|
||||
when {
|
||||
value is PsiLiteralExpression && value.value is String -> LightStringLiteral(value, parent, ktOrigin)
|
||||
value is PsiClassObjectAccessExpression -> LightClassLiteral(value, parent, ktOrigin)
|
||||
value is PsiExpression -> LightExpressionValue(value, parent, ktOrigin)
|
||||
value is PsiArrayInitializerMemberValue -> LightArrayInitializerValue(value, parent, ktOrigin)
|
||||
value is PsiAnnotation -> {
|
||||
val origin = ktOrigin()
|
||||
val ktCallElement = origin?.asKtCall()
|
||||
val qualifiedName = value.qualifiedName
|
||||
if (qualifiedName != null && ktCallElement != null)
|
||||
KtLightAnnotationForSourceEntry(qualifiedName, ktCallElement, parent, { value })
|
||||
else {
|
||||
LOG.error("can't convert ${origin?.javaClass} to KtCallElement in ${origin?.containingFile} (value = ${value.javaClass})",
|
||||
Attachment("source_fragments.txt", "origin: '${psiReport(origin)}', value: '${psiReport(value)}'"))
|
||||
LightElementValue(value, parent, ktOrigin) // or maybe create a LightErrorAnnotationMemberValue instead?
|
||||
}
|
||||
}
|
||||
else -> LightElementValue(value, parent, ktOrigin)
|
||||
}
|
||||
|
||||
override fun isPhysical() = true
|
||||
|
||||
@@ -302,4 +314,15 @@ private fun KtElement.getResolvedCall(): ResolvedCall<out CallableDescriptor>? {
|
||||
return this.getResolvedCall(context)
|
||||
}
|
||||
|
||||
private fun PsiElement.asKtCall(): KtCallElement? = (this as? KtElement)?.getResolvedCall()?.call?.callElement as? KtCallElement
|
||||
private fun PsiElement.asKtCall(): KtCallElement? = (this as? KtElement)?.getResolvedCall()?.call?.callElement as? KtCallElement
|
||||
|
||||
private fun psiReport(psiElement: PsiElement?): String {
|
||||
if (psiElement == null) return "null"
|
||||
val text = try {
|
||||
psiElement.text
|
||||
}
|
||||
catch (e: Exception) {
|
||||
"${e.javaClass.simpleName}:${e.message}"
|
||||
}
|
||||
return "${psiElement.javaClass.canonicalName}[$text]"
|
||||
}
|
||||
Reference in New Issue
Block a user