Introduce preliminary check for special annotations (allopen/noarg/samWithReceiver) (KT-21194)

This commit is contained in:
Yan Zhulanow
2017-11-13 12:02:08 +09:00
parent ecfb045790
commit 49db1bfe5d
@@ -27,12 +27,14 @@ interface AnnotationBasedExtension {
fun getAnnotationFqNames(modifierListOwner: KtModifierListOwner?): List<String>
fun DeclarationDescriptor.hasSpecialAnnotation(modifierListOwner: KtModifierListOwner?): Boolean {
if (annotations.any { it.isASpecialAnnotation(modifierListOwner) }) return true
val specialAnnotations = getAnnotationFqNames(modifierListOwner).takeIf { it.isNotEmpty() } ?: return false
if (annotations.any { it.isASpecialAnnotation(specialAnnotations) }) return true
if (this is ClassDescriptor) {
for (superType in TypeUtils.getAllSupertypes(defaultType)) {
val superTypeDescriptor = superType.constructor.declarationDescriptor as? ClassDescriptor ?: continue
if (superTypeDescriptor.annotations.any { it.isASpecialAnnotation(modifierListOwner) }) return true
if (superTypeDescriptor.annotations.any { it.isASpecialAnnotation(specialAnnotations) }) return true
}
}
@@ -40,20 +42,20 @@ interface AnnotationBasedExtension {
}
private fun AnnotationDescriptor.isASpecialAnnotation(
modifierListOwner: KtModifierListOwner?,
specialAnnotations: List<String>,
visitedAnnotations: MutableSet<String> = hashSetOf(),
allowMetaAnnotations: Boolean = true
): Boolean {
val annotationFqName = fqName?.asString() ?: return false
if (annotationFqName in visitedAnnotations) return false // Prevent infinite recursion
if (annotationFqName in getAnnotationFqNames(modifierListOwner)) return true
if (annotationFqName in specialAnnotations) return true
visitedAnnotations.add(annotationFqName)
if (allowMetaAnnotations) {
val annotationType = annotationClass ?: return false
for (metaAnnotation in annotationType.annotations) {
if (metaAnnotation.isASpecialAnnotation(modifierListOwner, visitedAnnotations, allowMetaAnnotations = true)) {
if (metaAnnotation.isASpecialAnnotation(specialAnnotations, visitedAnnotations, allowMetaAnnotations = true)) {
return true
}
}