diff --git a/uast/uast-common/src/org/jetbrains/uast/declarations/UAnnotation.kt b/uast/uast-common/src/org/jetbrains/uast/declarations/UAnnotation.kt index 104d7aee49ad..43b1d8e95c91 100644 --- a/uast/uast-common/src/org/jetbrains/uast/declarations/UAnnotation.kt +++ b/uast/uast-common/src/org/jetbrains/uast/declarations/UAnnotation.kt @@ -15,8 +15,12 @@ */ package org.jetbrains.uast +import com.intellij.openapi.util.text.StringUtilRt import com.intellij.psi.PsiAnnotation import com.intellij.psi.PsiClass +import com.intellij.psi.PsiElement +import com.intellij.psi.SyntaxTraverser +import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.uast.internal.acceptList import org.jetbrains.uast.internal.log import org.jetbrains.uast.visitor.UastTypedVisitor @@ -71,6 +75,31 @@ interface UAnnotation : UElement, UResolvable { visitor.visitAnnotation(this, data) } +/** + * Handy method to get psiElement for reporting warnings and putting gutters + */ +val UAnnotation?.namePsiElement: PsiElement? + get() { + if (this is UAnnotationEx) return this.uastAnchor?.sourcePsi + // A workaround for IDEA-184211 + val sourcePsiElement = this?.sourcePsiElement ?: return null + val identifier = sourcePsiElement.navigationElement ?: return null + val qualifiedName = this.qualifiedName + if (qualifiedName != null) { + val shortName = StringUtilRt.getShortName(qualifiedName) + SyntaxTraverser.psiTraverser(sourcePsiElement) + .filter { psi -> psi.references.isNotEmpty() && psi.text.contains(shortName) } + .traverse() + .first() + ?.let { + return PsiTreeUtil.getDeepestFirst(it) + } + } + + return PsiTreeUtil.getDeepestFirst(identifier) + } + + interface UAnnotationEx : UAnnotation { val uastAnchor: UElement? } \ No newline at end of file