mirror of
https://github.com/github/codeql.git
synced 2025-12-17 09:13:20 +01:00
193 lines
6.2 KiB
Java
193 lines
6.2 KiB
Java
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 {}
|
|
}
|