KtLightAnnotationForSourceEntry: made more verbose with errors in arrays in params (KT-21335, EA-107118)

This commit is contained in:
Nicolay Mitropolsky
2017-11-21 16:58:35 +03:00
committed by xiexed
parent e43bf90b9c
commit 23344783a5
@@ -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]"
}