Kapt: Support inherited annotations
(cherry picked from commit 02a3e6b)
This commit is contained in:
committed by
Yan Zhulanow
parent
9d340e1b83
commit
8c4fb0a709
+7
-6
@@ -16,18 +16,19 @@
|
||||
|
||||
package org.jetbrains.kotlin.java.model
|
||||
|
||||
import com.intellij.psi.PsiAnnotationOwner
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiModifierListOwner
|
||||
import org.jetbrains.kotlin.java.model.elements.JeAnnotationMirror
|
||||
import org.jetbrains.kotlin.java.model.internal.KotlinAnnotationProxyMaker
|
||||
import org.jetbrains.kotlin.java.model.internal.getAnnotationsWithInherited
|
||||
import javax.lang.model.element.AnnotationMirror
|
||||
import javax.lang.model.element.Element
|
||||
import java.lang.reflect.Array as RArray
|
||||
|
||||
interface JeAnnotationOwner : Element {
|
||||
val annotationOwner: PsiAnnotationOwner?
|
||||
interface JeAnnotationOwner : JeElement {
|
||||
override val psi: PsiModifierListOwner
|
||||
|
||||
override fun getAnnotationMirrors() = annotationOwner?.annotations?.map { JeAnnotationMirror(it) } ?: emptyList()
|
||||
override fun getAnnotationMirrors() = psi.getAnnotationsWithInherited().map(::JeAnnotationMirror)
|
||||
|
||||
override fun <A : Annotation> getAnnotation(annotationClass: Class<A>): A? {
|
||||
return getAnnotationsByType(annotationClass, onlyFirst = true).firstOrNull()
|
||||
@@ -49,11 +50,11 @@ interface JeAnnotationOwner : Element {
|
||||
|
||||
val annotationFqName = annotationClass.canonicalName
|
||||
|
||||
val allAnnotations = annotationOwner?.annotations?.filter { it.qualifiedName == annotationFqName } ?: return emptyList()
|
||||
val allAnnotations = psi.getAnnotationsWithInherited().filter { it.qualifiedName == annotationFqName }
|
||||
if (allAnnotations.isEmpty()) return emptyList()
|
||||
|
||||
val annotations = if (onlyFirst) listOf(allAnnotations.first()) else allAnnotations
|
||||
|
||||
|
||||
val annotationDeclarations = annotations.map { it to it.nameReferenceElement?.resolve() as? PsiClass }.filter { it.second != null }
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
|
||||
@@ -19,6 +19,6 @@ package org.jetbrains.kotlin.java.model
|
||||
import com.intellij.psi.PsiElement
|
||||
import javax.lang.model.element.Element
|
||||
|
||||
abstract class JeElement : Element {
|
||||
abstract val psi: PsiElement
|
||||
interface JeElement : Element {
|
||||
val psi: PsiElement
|
||||
}
|
||||
+1
-1
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.java.model.types.JeNoneType
|
||||
import javax.lang.model.element.*
|
||||
import javax.lang.model.type.TypeMirror
|
||||
|
||||
class JeClassInitializerExecutableElement(override val psi: PsiClassInitializer) : JeElement(),
|
||||
class JeClassInitializerExecutableElement(override val psi: PsiClassInitializer) : JeElement,
|
||||
ExecutableElement, JeNoAnnotations, JeModifierListOwner
|
||||
{
|
||||
val isStaticInitializer = psi.isStatic
|
||||
|
||||
+4
-10
@@ -16,10 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.java.model.elements
|
||||
|
||||
import com.intellij.psi.PsiAnnotationMethod
|
||||
import com.intellij.psi.PsiAnnotationOwner
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.PsiModifier
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.util.PsiTypesUtil
|
||||
import org.jetbrains.kotlin.java.model.*
|
||||
import org.jetbrains.kotlin.java.model.internal.isStatic
|
||||
@@ -29,8 +26,8 @@ import org.jetbrains.kotlin.java.model.types.toJeType
|
||||
import javax.lang.model.element.*
|
||||
import javax.lang.model.type.TypeMirror
|
||||
|
||||
class JeMethodExecutableElement(override val psi: PsiMethod) : JeElement(), ExecutableElement, JeModifierListOwner, JeAnnotationOwner {
|
||||
override fun getEnclosingElement() = psi.containingClass?.let { JeTypeElement(it) }
|
||||
class JeMethodExecutableElement(override val psi: PsiMethod) : JeElement, ExecutableElement, JeModifierListOwner, JeAnnotationOwner {
|
||||
override fun getEnclosingElement() = psi.containingClass?.let(::JeTypeElement)
|
||||
|
||||
override fun getSimpleName(): JeName {
|
||||
if (psi.isConstructor) return JeName.INIT
|
||||
@@ -41,7 +38,7 @@ class JeMethodExecutableElement(override val psi: PsiMethod) : JeElement(), Exec
|
||||
|
||||
override fun getTypeParameters() = psi.typeParameters.map { JeTypeParameterElement(it, this) }
|
||||
|
||||
override fun getParameters() = psi.parameterList.parameters.map { JeVariableElement(it) }
|
||||
override fun getParameters() = psi.parameterList.parameters.map(::JeVariableElement)
|
||||
|
||||
override fun getDefaultValue(): AnnotationValue? {
|
||||
val annotationMethod = psi as? PsiAnnotationMethod ?: return null
|
||||
@@ -68,9 +65,6 @@ class JeMethodExecutableElement(override val psi: PsiMethod) : JeElement(), Exec
|
||||
|
||||
override fun getEnclosedElements() = emptyList<Element>()
|
||||
|
||||
override val annotationOwner: PsiAnnotationOwner?
|
||||
get() = psi.modifierList
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other?.javaClass != javaClass) return false
|
||||
|
||||
+2
-2
@@ -26,7 +26,7 @@ import javax.lang.model.element.ElementKind
|
||||
import javax.lang.model.element.ElementVisitor
|
||||
import javax.lang.model.element.PackageElement
|
||||
|
||||
class JePackageElement(override val psi: PsiPackage) : JeElement(), PackageElement, JeModifierListOwner, JeNoAnnotations {
|
||||
class JePackageElement(override val psi: PsiPackage) : JeElement, PackageElement, JeModifierListOwner, JeNoAnnotations {
|
||||
override fun getEnclosingElement() = null
|
||||
|
||||
override fun getSimpleName() = JeName(psi.name)
|
||||
@@ -39,7 +39,7 @@ class JePackageElement(override val psi: PsiPackage) : JeElement(), PackageEleme
|
||||
|
||||
override fun getQualifiedName() = JeName(psi.qualifiedName)
|
||||
|
||||
override fun getEnclosedElements() = psi.classes.map { JeTypeElement(it) }
|
||||
override fun getEnclosedElements() = psi.classes.map(::JeTypeElement)
|
||||
|
||||
override fun asType() = JePackageTypeMirror
|
||||
|
||||
|
||||
+2
-5
@@ -25,16 +25,13 @@ import org.jetbrains.kotlin.java.model.types.toJeType
|
||||
import javax.lang.model.element.*
|
||||
import javax.lang.model.type.TypeMirror
|
||||
|
||||
class JeTypeElement(override val psi: PsiClass) : JeElement(), TypeElement, JeAnnotationOwner, JeModifierListOwner {
|
||||
class JeTypeElement(override val psi: PsiClass) : JeElement, TypeElement, JeAnnotationOwner, JeModifierListOwner {
|
||||
override fun getEnclosingElement(): Element? {
|
||||
psi.containingClass?.let { return JeTypeElement(it) }
|
||||
val javaFile = psi.containingFile as? PsiJavaFile ?: return null
|
||||
return JavaPsiFacade.getInstance(psi.project).findPackage(javaFile.packageName)?.let { JePackageElement(it) }
|
||||
return JavaPsiFacade.getInstance(psi.project).findPackage(javaFile.packageName)?.let(::JePackageElement)
|
||||
}
|
||||
|
||||
override val annotationOwner: PsiAnnotationOwner?
|
||||
get() = psi.modifierList
|
||||
|
||||
override fun getSimpleName() = JeName(psi.name)
|
||||
|
||||
override fun getQualifiedName() = JeName(psi.qualifiedName)
|
||||
|
||||
+2
-4
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.java.model.elements
|
||||
|
||||
import com.intellij.psi.PsiAnnotationOwner
|
||||
import com.intellij.psi.PsiModifierListOwner
|
||||
import com.intellij.psi.PsiTypeParameter
|
||||
import com.intellij.psi.util.PsiTypesUtil
|
||||
import org.jetbrains.kotlin.java.model.JeAnnotationOwner
|
||||
@@ -32,7 +33,7 @@ import javax.lang.model.element.TypeParameterElement
|
||||
class JeTypeParameterElement(
|
||||
override val psi: PsiTypeParameter,
|
||||
val parent: JeElement?
|
||||
) : JeElement(), TypeParameterElement, JeAnnotationOwner, JeModifierListOwner {
|
||||
) : JeElement, TypeParameterElement, JeAnnotationOwner, JeModifierListOwner {
|
||||
override fun getSimpleName() = JeName(psi.name)
|
||||
|
||||
override fun getEnclosingElement() = parent
|
||||
@@ -49,9 +50,6 @@ class JeTypeParameterElement(
|
||||
|
||||
override fun getGenericElement() = parent
|
||||
|
||||
override val annotationOwner: PsiAnnotationOwner?
|
||||
get() = psi.modifierList
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other?.javaClass != javaClass) return false
|
||||
|
||||
+2
-5
@@ -26,7 +26,7 @@ import javax.lang.model.element.ElementKind
|
||||
import javax.lang.model.element.ElementVisitor
|
||||
import javax.lang.model.element.VariableElement
|
||||
|
||||
class JeVariableElement(override val psi: PsiVariable) : JeElement(), VariableElement, JeModifierListOwner, JeAnnotationOwner {
|
||||
class JeVariableElement(override val psi: PsiVariable) : JeElement, VariableElement, JeModifierListOwner, JeAnnotationOwner {
|
||||
override fun getSimpleName() = JeName(psi.name)
|
||||
|
||||
override fun getEnclosingElement(): JeElement? {
|
||||
@@ -35,7 +35,7 @@ class JeVariableElement(override val psi: PsiVariable) : JeElement(), VariableEl
|
||||
}
|
||||
|
||||
val containingClass = (psi as? PsiMember)?.containingClass ?: PsiTreeUtil.getParentOfType(psi, PsiClass::class.java)
|
||||
return containingClass?.let { JeTypeElement(it) }
|
||||
return containingClass?.let(::JeTypeElement)
|
||||
}
|
||||
|
||||
override fun getConstantValue() = psi.initializer?.calcConstantValue()
|
||||
@@ -52,9 +52,6 @@ class JeVariableElement(override val psi: PsiVariable) : JeElement(), VariableEl
|
||||
|
||||
override fun getEnclosedElements() = emptyList<Element>()
|
||||
|
||||
override val annotationOwner: PsiAnnotationOwner?
|
||||
get() = psi.modifierList
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other?.javaClass != javaClass) return false
|
||||
|
||||
+30
-1
@@ -66,4 +66,33 @@ internal val PsiModifierListOwner.isStatic: Boolean
|
||||
internal val PsiModifierListOwner.isFinal: Boolean
|
||||
get() = hasModifierProperty(PsiModifier.FINAL)
|
||||
|
||||
fun PsiModifierListOwner.getJavaModifiers() = modifierList?.getJavaModifiers() ?: emptySet()
|
||||
fun PsiModifierListOwner.getJavaModifiers() = modifierList?.getJavaModifiers() ?: emptySet()
|
||||
|
||||
fun PsiModifierListOwner.getAnnotationsWithInherited(): List<PsiAnnotation> {
|
||||
val annotations = modifierList?.annotations?.toMutableList() ?: mutableListOf()
|
||||
|
||||
if (this is PsiClass) {
|
||||
var superClass = superClass
|
||||
while (superClass != null) {
|
||||
superClass.modifierList?.annotations?.let { superClassAnnotations ->
|
||||
for (annotation in superClassAnnotations) {
|
||||
// Do not add the inherited annotation from the superclass
|
||||
// if the current class has an annotation with the same qualified name
|
||||
if (!annotation.isInherited()
|
||||
|| annotations.any { it.qualifiedName == annotation.qualifiedName }) continue
|
||||
annotations += annotation
|
||||
}
|
||||
}
|
||||
|
||||
superClass = superClass.superClass
|
||||
}
|
||||
}
|
||||
|
||||
return annotations
|
||||
}
|
||||
|
||||
private fun PsiAnnotation.isInherited(): Boolean {
|
||||
val annotationClass = nameReferenceElement?.resolve() as? PsiClass ?: return false
|
||||
val annotations = annotationClass.modifierList?.annotations ?: return false
|
||||
return annotations.any { it.qualifiedName == "java.lang.annotation.Inherited" }
|
||||
}
|
||||
Reference in New Issue
Block a user