mirror of
https://github.com/github/codeql.git
synced 2026-05-04 21:25:44 +02:00
Java: Add annotation tests
This commit is contained in:
committed by
Chris Smowton
parent
8c9bdeb3be
commit
37b18914ac
192
java/ql/test/library-tests/annotations/Annotatable.java
Normal file
192
java/ql/test/library-tests/annotations/Annotatable.java
Normal file
@@ -0,0 +1,192 @@
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Repeatable;
|
||||
|
||||
class Annotatable {
|
||||
@interface CustomAnnotation {}
|
||||
|
||||
@Inherited
|
||||
@interface CustomInheritedAnnotation {
|
||||
String value();
|
||||
}
|
||||
|
||||
@CustomAnnotation
|
||||
@CustomInheritedAnnotation("base")
|
||||
class WithDeclared {
|
||||
// Annotations on methods are not inherited
|
||||
@CustomInheritedAnnotation("base-method")
|
||||
void methodWithDeclared() {}
|
||||
}
|
||||
|
||||
class Subclass extends WithDeclared {
|
||||
@Override
|
||||
void methodWithDeclared() {}
|
||||
}
|
||||
|
||||
// Inheritance from super-superclass
|
||||
class SubSubclass extends Subclass {}
|
||||
|
||||
// Prevents inheriting annotation of same type
|
||||
@CustomInheritedAnnotation("sub")
|
||||
class SubclassDeclaringSameAnnotation extends WithDeclared {}
|
||||
|
||||
|
||||
// Annotations on interfaces are not inherited
|
||||
@CustomInheritedAnnotation("base")
|
||||
interface InterfaceWithDeclared {}
|
||||
|
||||
interface ExtendingInterface extends InterfaceWithDeclared {}
|
||||
|
||||
class ImplementingInterface implements InterfaceWithDeclared {}
|
||||
|
||||
|
||||
@interface ContainerAnnotation {
|
||||
RepeatableAnnotation[] value();
|
||||
}
|
||||
|
||||
@Repeatable(ContainerAnnotation.class)
|
||||
@interface RepeatableAnnotation {
|
||||
String value();
|
||||
}
|
||||
|
||||
@Inherited
|
||||
@interface InheritedContainerAnnotation {
|
||||
InheritedRepeatableAnnotation[] value();
|
||||
}
|
||||
|
||||
@Inherited
|
||||
@Repeatable(InheritedContainerAnnotation.class)
|
||||
@interface InheritedRepeatableAnnotation {
|
||||
String value();
|
||||
}
|
||||
|
||||
@Inherited
|
||||
@interface InheritedContainerAnnotation2 {
|
||||
NonInheritedRepeatableAnnotation[] value();
|
||||
}
|
||||
|
||||
// Container is marked as @Inherited, but this annotation type is not
|
||||
// This is allowed, but means that associated annotations will not be inherited,
|
||||
// see java.lang.reflect.AnnotatedElement documentation
|
||||
@Repeatable(InheritedContainerAnnotation2.class)
|
||||
@interface NonInheritedRepeatableAnnotation {
|
||||
String value();
|
||||
}
|
||||
|
||||
@RepeatableAnnotation("base")
|
||||
@InheritedRepeatableAnnotation("base")
|
||||
@NonInheritedRepeatableAnnotation("base")
|
||||
class WithAssociatedSingle {}
|
||||
|
||||
@RepeatableAnnotation("sub-1")
|
||||
@RepeatableAnnotation("sub-2")
|
||||
@InheritedRepeatableAnnotation("sub-1")
|
||||
@InheritedRepeatableAnnotation("sub-2")
|
||||
@NonInheritedRepeatableAnnotation("sub-1")
|
||||
@NonInheritedRepeatableAnnotation("sub-2")
|
||||
class SubclassWithMultiple extends WithAssociatedSingle {}
|
||||
|
||||
|
||||
// Empty container annotations have no effect; annotations are inherited from superclass
|
||||
@InheritedContainerAnnotation({})
|
||||
@InheritedContainerAnnotation2({})
|
||||
class SubclassOfSingleWithEmptyContainer extends WithAssociatedSingle {}
|
||||
|
||||
|
||||
// Annotations on interfaces are not inherited
|
||||
@InheritedRepeatableAnnotation("base-1")
|
||||
@InheritedRepeatableAnnotation("base-2")
|
||||
interface InterfaceWithAssociated {}
|
||||
|
||||
interface ExtendingInterfaceWithAssociated extends InterfaceWithAssociated {}
|
||||
|
||||
class ImplementingInterfaceWithAssociated implements InterfaceWithAssociated {}
|
||||
|
||||
|
||||
@RepeatableAnnotation("base-1")
|
||||
@RepeatableAnnotation("base-2")
|
||||
@InheritedRepeatableAnnotation("base-1")
|
||||
@InheritedRepeatableAnnotation("base-2")
|
||||
// These annotations are not inherited, but their (implicit) container annotation
|
||||
// is inherited
|
||||
@NonInheritedRepeatableAnnotation("base-1")
|
||||
@NonInheritedRepeatableAnnotation("base-2")
|
||||
class WithAssociatedMultiple {
|
||||
// Annotations on methods are not inherited
|
||||
@InheritedRepeatableAnnotation("base-method")
|
||||
void methodWithAssociatedSingle() {}
|
||||
|
||||
// Annotations on methods are not inherited
|
||||
@InheritedRepeatableAnnotation("base-method-1")
|
||||
@InheritedRepeatableAnnotation("base-method-2")
|
||||
void methodWithAssociated() {}
|
||||
}
|
||||
|
||||
class WithAssociatedSubclass extends WithAssociatedMultiple {
|
||||
@Override
|
||||
void methodWithAssociatedSingle() {}
|
||||
|
||||
@Override
|
||||
void methodWithAssociated() {}
|
||||
}
|
||||
|
||||
// Inheritance from super-superclass
|
||||
class WithAssociatedSubSubclass extends WithAssociatedSubclass {}
|
||||
|
||||
@RepeatableAnnotation("sub-1")
|
||||
@InheritedRepeatableAnnotation("sub-1")
|
||||
@NonInheritedRepeatableAnnotation("sub-1")
|
||||
class SubclassWithSingle extends WithAssociatedMultiple {}
|
||||
|
||||
|
||||
// Empty container annotations have no effect; associated annotations are inherited from superclass
|
||||
@InheritedContainerAnnotation({})
|
||||
@InheritedContainerAnnotation2({})
|
||||
class SubclassOfMultipleWithEmptyContainer extends WithAssociatedMultiple {}
|
||||
|
||||
|
||||
// This annotation exists on its own without a container
|
||||
@InheritedRepeatableAnnotation("single")
|
||||
// TODO: Has currently spurious results for ArrayInit due to https://github.com/github/codeql/issues/8647
|
||||
@InheritedContainerAnnotation({
|
||||
@InheritedRepeatableAnnotation("container-1"),
|
||||
@InheritedRepeatableAnnotation("container-2")
|
||||
})
|
||||
class ExplicitContainerAndSingleContained {}
|
||||
|
||||
class ExplicitContainerSubclass extends ExplicitContainerAndSingleContained {}
|
||||
|
||||
|
||||
@Inherited
|
||||
@interface NestedAnnotationContainer1 {
|
||||
NestedAnnotation1[] value();
|
||||
}
|
||||
|
||||
@Inherited
|
||||
@Repeatable(NestedAnnotationContainer1.class)
|
||||
@interface NestedAnnotation1 {
|
||||
NestedAnnotation2[] value();
|
||||
}
|
||||
|
||||
@Inherited
|
||||
@Repeatable(NestedAnnotation1.class)
|
||||
@interface NestedAnnotation2 {
|
||||
String value();
|
||||
}
|
||||
|
||||
// This annotation exists on its own without a container
|
||||
@NestedAnnotation2("1")
|
||||
// But these are nested inside an implicit @NestedAnnotationContainer1
|
||||
// Nested repeated annotations (@NestedAnnotation2) are not considered associated
|
||||
@NestedAnnotation1({@NestedAnnotation2("1-1"), @NestedAnnotation2("1-2")})
|
||||
@NestedAnnotation1({@NestedAnnotation2("2-1"), @NestedAnnotation2("2-2")})
|
||||
class WithNestedAssociated {}
|
||||
|
||||
class WithNestedAssociatedSubclass extends WithNestedAssociated {}
|
||||
|
||||
// Nested repeated annotations (@NestedAnnotation2) are not considered associated
|
||||
@NestedAnnotation1({@NestedAnnotation2("1-1"), @NestedAnnotation2("1-2")})
|
||||
@NestedAnnotation1({@NestedAnnotation2("2-1"), @NestedAnnotation2("2-2")})
|
||||
class WithNestedAssociatedExplicitContainers {}
|
||||
|
||||
class WithNestedAssociatedExplicitContainersSubclass extends WithNestedAssociatedExplicitContainers {}
|
||||
}
|
||||
Reference in New Issue
Block a user