Light classes: modifierList#findAnnotation does not trigger exact resolve

This commit is contained in:
Pavel V. Talanov
2017-04-28 20:28:51 +03:00
parent 57baaf2a50
commit 956ace3463
3 changed files with 26 additions and 4 deletions
@@ -49,7 +49,7 @@ abstract class KtLightModifierList<out T : KtLightElement<KtModifierListOwner, P
override fun addAnnotation(qualifiedName: String) = clsDelegate.addAnnotation(qualifiedName)
override fun getApplicableAnnotations(): Array<out PsiAnnotation> = annotations
override fun getAnnotations(): Array<out PsiAnnotation> = _annotations.toTypedArray()
override fun findAnnotation(qualifiedName: String) = annotations.firstOrNull { it.qualifiedName == qualifiedName }
override fun findAnnotation(qualifiedName: String) = _annotations.firstOrNull { it.fqNameMatches(qualifiedName) }
override fun getParent() = owner
override fun getText(): String? = ""
override fun getTextRange() = TextRange.EMPTY_RANGE
@@ -68,7 +68,7 @@ class KtLightSimpleModifierList(
override fun copy() = KtLightSimpleModifierList(owner, modifiers)
}
private fun computeAnnotations(lightModifierList: KtLightModifierList<*>): List<PsiAnnotation> {
private fun computeAnnotations(lightModifierList: KtLightModifierList<*>): List<KtLightAbstractAnnotation> {
val annotationsForEntries = lightAnnotationsForEntries(lightModifierList)
val modifierListOwner = lightModifierList.parent
if (modifierListOwner is KtLightClassForSourceDeclaration && modifierListOwner.isAnnotationType) {
@@ -45,6 +45,8 @@ abstract class KtLightAbstractAnnotation(parent: PsiElement, computeDelegate: ()
override fun getMetaData() = clsDelegate.metaData
override fun getParameterList() = clsDelegate.parameterList
open fun fqNameMatches(fqName: String): Boolean = qualifiedName == fqName
}
class KtLightAnnotationForSourceEntry(
@@ -226,6 +228,12 @@ class KtLightNullabilityAnnotation(member: KtLightElement<*, PsiModifierListOwne
isNullabilityAnnotation(it.qualifiedName)
} ?: KtLightNonExistentAnnotation(member)
}) {
override fun fqNameMatches(fqName: String): Boolean {
if (!isNullabilityAnnotation(fqName)) return false
return super.fqNameMatches(fqName)
}
override val kotlinOrigin get() = null
override fun <T : PsiAnnotationMemberValue?> setDeclaredAttributeValue(attributeName: String?, value: T?) = cannotModify()
@@ -279,6 +279,7 @@ object LightClassLazinessChecker {
)
private fun classInfo(psiClass: PsiClass) = with(psiClass) {
checkModifierList(modifierList!!)
ClassInfo(fields.names(), methods.names(), PsiModifier.MODIFIERS.asList().filter { modifierList!!.hasModifierProperty(it) })
}
@@ -288,7 +289,7 @@ object LightClassLazinessChecker {
)
private fun fieldInfo(field: PsiField) = with(field) {
modifierList?.annotations // check getting annotations list doesn't trigger exact resolve
checkModifierList(modifierList!!)
FieldInfo(
name!!, PsiModifier.MODIFIERS.asList().filter { modifierList!!.hasModifierProperty(it) }
@@ -304,7 +305,7 @@ object LightClassLazinessChecker {
)
private fun methodInfo(method: PsiMethod, lazinessMode: Mode) = with(method) {
modifierList.annotations // check getting annotations list doesn't trigger exact resolve
checkModifierList(method.modifierList)
MethodInfo(
name, relevantModifiers(lazinessMode),
@@ -323,6 +324,19 @@ object LightClassLazinessChecker {
lazinessMode == Mode.NoLaziness || it !in visibilityModifiers
}.filter { modifierList.hasModifierProperty(it) }
private fun checkModifierList(modifierList: PsiModifierList) {
// see org.jetbrains.kotlin.asJava.elements.KtLightNonSourceAnnotation
val isAnnotationClass = (modifierList.parent as? PsiClass)?.isAnnotationType ?: false
if (!isAnnotationClass) {
// check getting annotations list doesn't trigger exact resolve
modifierList.annotations
// check searching for non-existent annotation doesn't trigger exact resolve
modifierList.findAnnotation("some.package.MadeUpAnnotation")
}
}
private fun Array<out PsiMember>.names() = mapTo(LinkedHashSet()) { it.name!! }
}