Allopen, Noarg: Support transitive meta-annotations
This commit is contained in:
committed by
Yan Zhulanow
parent
82dbba838a
commit
f8edf51c1b
@@ -41,19 +41,26 @@ interface AnnotationBasedExtension {
|
|||||||
|
|
||||||
private fun AnnotationDescriptor.isASpecialAnnotation(
|
private fun AnnotationDescriptor.isASpecialAnnotation(
|
||||||
modifierListOwner: KtModifierListOwner?,
|
modifierListOwner: KtModifierListOwner?,
|
||||||
|
visitedAnnotations: MutableSet<String> = hashSetOf(),
|
||||||
allowMetaAnnotations: Boolean = true
|
allowMetaAnnotations: Boolean = true
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val annotationType = type.constructor.declarationDescriptor ?: return false
|
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) {
|
if (allowMetaAnnotations) {
|
||||||
for (metaAnnotation in annotationType.annotations) {
|
for (metaAnnotation in annotationType.annotations) {
|
||||||
if (metaAnnotation.isASpecialAnnotation(modifierListOwner, allowMetaAnnotations = false)) {
|
if (metaAnnotation.isASpecialAnnotation(modifierListOwner, visitedAnnotations, allowMetaAnnotations = true)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
visitedAnnotations.remove(annotationFqName)
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,11 +3,20 @@ annotation class AllOpen
|
|||||||
@AllOpen
|
@AllOpen
|
||||||
annotation class MyComponent
|
annotation class MyComponent
|
||||||
|
|
||||||
@MyComponent // Double-transitive annotations is not supported
|
@MyComponent // Double-transitive annotations is supported
|
||||||
annotation class OtherComponent
|
annotation class OtherComponent
|
||||||
|
|
||||||
|
@OtherComponent
|
||||||
|
annotation class AnotherComponent
|
||||||
|
|
||||||
|
@java.lang.annotation.Documented
|
||||||
|
annotation class Documented
|
||||||
|
|
||||||
class TestWithoutAnnotations_ShouldBeFinal
|
class TestWithoutAnnotations_ShouldBeFinal
|
||||||
|
|
||||||
|
@Documented
|
||||||
|
class ClassWithDocumented
|
||||||
|
|
||||||
@AllOpen
|
@AllOpen
|
||||||
class TestAllOpen_ShouldBeOpen
|
class TestAllOpen_ShouldBeOpen
|
||||||
|
|
||||||
@@ -15,7 +24,10 @@ class TestAllOpen_ShouldBeOpen
|
|||||||
class TestMyComponent_ShouldBeOpen
|
class TestMyComponent_ShouldBeOpen
|
||||||
|
|
||||||
@OtherComponent
|
@OtherComponent
|
||||||
class TestOtherComponent_ShouldBeFinal
|
class TestOtherComponent_ShouldBeOpen
|
||||||
|
|
||||||
|
@AnotherComponent
|
||||||
|
class TestAnotherComponent_ShouldBeOpen
|
||||||
|
|
||||||
@MyComponent
|
@MyComponent
|
||||||
abstract class MyComponentBase
|
abstract class MyComponentBase
|
||||||
|
|||||||
@@ -2,6 +2,22 @@
|
|||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public annotation class AllOpen
|
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
|
@AllOpen
|
||||||
@java.lang.annotation.Retention
|
@java.lang.annotation.Retention
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
@@ -42,6 +58,12 @@ public class TestAllOpen_ShouldBeOpen {
|
|||||||
public method <init>(): void
|
public method <init>(): void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@AnotherComponent
|
||||||
|
@kotlin.Metadata
|
||||||
|
public class TestAnotherComponent_ShouldBeOpen {
|
||||||
|
public method <init>(): void
|
||||||
|
}
|
||||||
|
|
||||||
@MyComponent
|
@MyComponent
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public class TestMyComponent_ShouldBeOpen {
|
public class TestMyComponent_ShouldBeOpen {
|
||||||
@@ -50,7 +72,7 @@ public class TestMyComponent_ShouldBeOpen {
|
|||||||
|
|
||||||
@OtherComponent
|
@OtherComponent
|
||||||
@kotlin.Metadata
|
@kotlin.Metadata
|
||||||
public final class TestOtherComponent_ShouldBeFinal {
|
public class TestOtherComponent_ShouldBeOpen {
|
||||||
public method <init>(): void
|
public method <init>(): void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user