Allopen, Noarg: Support transitive meta-annotations

This commit is contained in:
Yan Zhulanow
2016-12-19 15:15:13 +03:00
committed by Yan Zhulanow
parent 82dbba838a
commit f8edf51c1b
3 changed files with 46 additions and 5 deletions
@@ -41,19 +41,26 @@ interface AnnotationBasedExtension {
private fun AnnotationDescriptor.isASpecialAnnotation(
modifierListOwner: KtModifierListOwner?,
visitedAnnotations: MutableSet<String> = hashSetOf(),
allowMetaAnnotations: Boolean = true
): Boolean {
val annotationType = type.constructor.declarationDescriptor ?: return false
if (annotationType.fqNameSafe.asString() in getAnnotationFqNames(modifierListOwner)) return true
val annotationFqName = annotationType.fqNameSafe.asString()
if (annotationFqName in visitedAnnotations) return false // Prevent infinite recursion
if (annotationFqName in getAnnotationFqNames(modifierListOwner)) return true
visitedAnnotations.add(annotationFqName)
if (allowMetaAnnotations) {
for (metaAnnotation in annotationType.annotations) {
if (metaAnnotation.isASpecialAnnotation(modifierListOwner, allowMetaAnnotations = false)) {
if (metaAnnotation.isASpecialAnnotation(modifierListOwner, visitedAnnotations, allowMetaAnnotations = true)) {
return true
}
}
}
visitedAnnotations.remove(annotationFqName)
return false
}
}
@@ -3,11 +3,20 @@ annotation class AllOpen
@AllOpen
annotation class MyComponent
@MyComponent // Double-transitive annotations is not supported
@MyComponent // Double-transitive annotations is supported
annotation class OtherComponent
@OtherComponent
annotation class AnotherComponent
@java.lang.annotation.Documented
annotation class Documented
class TestWithoutAnnotations_ShouldBeFinal
@Documented
class ClassWithDocumented
@AllOpen
class TestAllOpen_ShouldBeOpen
@@ -15,7 +24,10 @@ class TestAllOpen_ShouldBeOpen
class TestMyComponent_ShouldBeOpen
@OtherComponent
class TestOtherComponent_ShouldBeFinal
class TestOtherComponent_ShouldBeOpen
@AnotherComponent
class TestAnotherComponent_ShouldBeOpen
@MyComponent
abstract class MyComponentBase
@@ -2,6 +2,22 @@
@kotlin.Metadata
public annotation class AllOpen
@OtherComponent
@java.lang.annotation.Retention
@kotlin.Metadata
public annotation class AnotherComponent
@Documented
@kotlin.Metadata
public final class ClassWithDocumented {
public method <init>(): void
}
@java.lang.annotation.Documented
@java.lang.annotation.Retention
@kotlin.Metadata
public annotation class Documented
@AllOpen
@java.lang.annotation.Retention
@kotlin.Metadata
@@ -42,6 +58,12 @@ public class TestAllOpen_ShouldBeOpen {
public method <init>(): void
}
@AnotherComponent
@kotlin.Metadata
public class TestAnotherComponent_ShouldBeOpen {
public method <init>(): void
}
@MyComponent
@kotlin.Metadata
public class TestMyComponent_ShouldBeOpen {
@@ -50,7 +72,7 @@ public class TestMyComponent_ShouldBeOpen {
@OtherComponent
@kotlin.Metadata
public final class TestOtherComponent_ShouldBeFinal {
public class TestOtherComponent_ShouldBeOpen {
public method <init>(): void
}