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
+46
-23
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.asJava.elements
|
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.TextRange
|
||||||
import com.intellij.openapi.util.text.StringUtil
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
import com.intellij.psi.*
|
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.resolve.source.getPsi
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
|
|
||||||
|
private val LOG = Logger.getInstance("#org.jetbrains.kotlin.asJava.elements.lightAnnotations")
|
||||||
|
|
||||||
abstract class KtLightAbstractAnnotation(parent: PsiElement, computeDelegate: () -> PsiAnnotation) :
|
abstract class KtLightAbstractAnnotation(parent: PsiElement, computeDelegate: () -> PsiAnnotation) :
|
||||||
KtLightElementBase(parent), PsiAnnotation, KtLightElement<KtCallElement, PsiAnnotation> {
|
KtLightElementBase(parent), PsiAnnotation, KtLightElement<KtCallElement, PsiAnnotation> {
|
||||||
override val clsDelegate by lazyPub(computeDelegate)
|
override val clsDelegate by lazyPub(computeDelegate)
|
||||||
@@ -181,13 +185,17 @@ class KtLightAnnotationForSourceEntry(
|
|||||||
valueOrigin: AnnotationValueOrigin
|
valueOrigin: AnnotationValueOrigin
|
||||||
) : LightElementValue<PsiArrayInitializerMemberValue>(delegate, parent, valueOrigin), PsiArrayInitializerMemberValue {
|
) : LightElementValue<PsiArrayInitializerMemberValue>(delegate, parent, valueOrigin), PsiArrayInitializerMemberValue {
|
||||||
private val _initializers by lazyPub {
|
private val _initializers by lazyPub {
|
||||||
delegate.initializers.mapIndexed { i, it ->
|
delegate.initializers.mapIndexed { i, memberValue ->
|
||||||
wrapAnnotationValue(it, this, {
|
wrapAnnotationValue(memberValue, this, {
|
||||||
originalExpression.let {
|
originalExpression.let { ktOrigin ->
|
||||||
when (it) {
|
when (ktOrigin) {
|
||||||
is KtCallElement -> it.valueArguments[i].getArgumentExpression()!!
|
is KtCallElement -> ktOrigin.valueArguments.getOrNull(i)?.getArgumentExpression()
|
||||||
is KtCollectionLiteralExpression -> it.getInnerExpressions()[i]
|
is KtCollectionLiteralExpression -> ktOrigin.getInnerExpressions().getOrNull(i)
|
||||||
else -> throw UnsupportedOperationException("cant process $it of type ${it?.javaClass}")
|
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
|
override fun getInitializers() = _initializers
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun wrapAnnotationValue(value: PsiAnnotationMemberValue, parent: PsiElement, ktOrigin: AnnotationValueOrigin): PsiAnnotationMemberValue {
|
private fun wrapAnnotationValue(value: PsiAnnotationMemberValue, parent: PsiElement, ktOrigin: AnnotationValueOrigin): PsiAnnotationMemberValue =
|
||||||
return when {
|
when {
|
||||||
value is PsiLiteralExpression && value.value is String -> LightStringLiteral(value, parent, ktOrigin)
|
value is PsiLiteralExpression && value.value is String -> LightStringLiteral(value, parent, ktOrigin)
|
||||||
value is PsiClassObjectAccessExpression -> LightClassLiteral(value, parent, ktOrigin)
|
value is PsiClassObjectAccessExpression -> LightClassLiteral(value, parent, ktOrigin)
|
||||||
value is PsiExpression -> LightExpressionValue(value, parent, ktOrigin)
|
value is PsiExpression -> LightExpressionValue(value, parent, ktOrigin)
|
||||||
value is PsiArrayInitializerMemberValue -> LightArrayInitializerValue(value, parent, ktOrigin)
|
value is PsiArrayInitializerMemberValue -> LightArrayInitializerValue(value, parent, ktOrigin)
|
||||||
value is PsiAnnotation -> KtLightAnnotationForSourceEntry(
|
value is PsiAnnotation -> {
|
||||||
value.qualifiedName!!,
|
val origin = ktOrigin()
|
||||||
ktOrigin().let {
|
val ktCallElement = origin?.asKtCall()
|
||||||
it?.asKtCall() ?: throw UnsupportedOperationException("cant convert $it to KtCallElement")
|
val qualifiedName = value.qualifiedName
|
||||||
},
|
if (qualifiedName != null && ktCallElement != null)
|
||||||
parent, { value }
|
KtLightAnnotationForSourceEntry(qualifiedName, ktCallElement, parent, { value })
|
||||||
)
|
else {
|
||||||
else -> LightElementValue(value, parent, ktOrigin)
|
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
|
override fun isPhysical() = true
|
||||||
|
|
||||||
@@ -303,3 +315,14 @@ private fun KtElement.getResolvedCall(): ResolvedCall<out CallableDescriptor>? {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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