下面列出了java.lang.annotation.Inherited#java.lang.annotation.RetentionPolicy 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Check if annotation is available at runtime and it is annotated by @Injectable annotation
*
* @param annotation the annotation to check
* @param <T> annotation type
* @return the tested annotation
* @throws org.panda_lang.utilities.inject.DependencyInjectionException when:
* <ul>
* <li>the given class is not an annotation</li>
* <li>annotation is not marked as @{@link org.panda_lang.utilities.inject.annotations.Injectable}</li>
* <li>retention policy is not defined or its value is other than the {@link java.lang.annotation.RetentionPolicy#RUNTIME} </li>
* </ul>
*/
public static <T> Class<T> testAnnotation(Class<T> annotation) throws DependencyInjectionException {
if (!annotation.isAnnotation()) {
throw new DependencyInjectionException(annotation + " is not an annotation");
}
@Nullable Retention retention = annotation.getAnnotation(Retention.class);
if (retention == null) {
throw new DependencyInjectionException(annotation + " has no specified retention policy");
}
if (retention.value() != RetentionPolicy.RUNTIME) {
throw new DependencyInjectionException(annotation + " is not marked as runtime annotation");
}
if (annotation.getAnnotation(Injectable.class) == null) {
throw new DependencyInjectionException(annotation + " is not marked as @Injectable");
}
return annotation;
}
/**
* We consider an annotation to be valid for extraction if it's not an internal annotation (i.e.
* is in the <code>com.facebook.litho</code> package and is not a source-only annotation.
*
* @return Whether or not to extract the given annotation.
*/
private static boolean isValidAnnotation(Project project, PsiAnnotation psiAnnotation) {
final String text = psiAnnotation.getQualifiedName();
if (text.startsWith("com.facebook.")) {
return false;
}
PsiClass annotationClass = PsiSearchUtils.findClass(project, psiAnnotation.getQualifiedName());
if (annotationClass == null) {
throw new RuntimeException("Annotation class not found, text is: " + text);
}
final Retention retention =
PsiAnnotationProxyUtils.findAnnotationInHierarchy(annotationClass, Retention.class);
return retention == null || retention.value() != RetentionPolicy.SOURCE;
}
public boolean hasRuntimeRetention() {
Map<String, ? extends AnnotationMirror> types = getHelper()
.getAnnotationsByType(getElement().getAnnotationMirrors());
AnnotationMirror retention = types.get(Retention.class.getCanonicalName());
if ( retention == null ) {
handleNoRetention();
return false;
}
AnnotationParser parser = AnnotationParser.create(getHelper());
parser.expectEnumConstant(AnnotationUtil.VALUE, getHelper().resolveType(
RetentionPolicy.class.getCanonicalName()), null);
String retentionPolicy = parser.parse(retention).get(AnnotationUtil.VALUE,
String.class);
return RetentionPolicy.RUNTIME.toString().equals(retentionPolicy);
}
public boolean check() {
List<? extends AnnotationMirror> annotations = getElement()
.getAnnotationMirrors();
boolean hasAnnotation = getHelper().hasAnnotation(annotations,
getAnnotation());
if (!hasAnnotation) {
// this is not subject annotation , just return false
return false;
}
if ( !hasRuntimeRetention() ){
getLogger().log(Level.WARNING, "Annotation "
+ getElement().getQualifiedName()
+ " declared as " +getAnnotation()+" but has wrong retention policy."
+ " Correct retention policy is "
+ RetentionPolicy.RUNTIME.toString());// NOI18N
return false;
}
return hasTarget();
}
public void test() throws TestFailedException {
try {
String template = getSource(getSourceFile(templateFileName));
for (int i = 0; i < 2; ++i) {
for (String repeatable : new String[] {"", "@Repeatable(Container.class)"}) {
for (RetentionPolicy policy : RetentionPolicy.values()) {
final int finalI = i;
Map<String, String> replacements = new HashMap<String, String>(){{
put("%POLICY%", policy.toString());
if (finalI != 0) {
put("default.*\n", ";\n");
}
put("%REPEATABLE%", repeatable);
}};
test(template, replacements, i == 0);
}
}
}
} catch (Throwable e) {
addFailure(e);
} finally {
checkStatus();
}
}
@Test
public void collections() {
ImmutableJdkColl coll = ImmutableJdkColl.builder()
.addInts(1)
.addInts(2, 3)
.addAllInts(Arrays.asList(4, 5, 6))
.addNavs(1, 2, 3)
.addOrds(4, 6, 5)
.addAllOrds(Arrays.asList(8, 7, 9))
.addPols(RetentionPolicy.RUNTIME, RetentionPolicy.RUNTIME)
.build();
check(coll.ints()).isOf(1, 2, 3, 4, 5, 6);
check(coll.navs()).isOf(3, 2, 1);
check(coll.ords()).isOf(4, 5, 6, 7, 8, 9);
check(coll.pols()).isOf(RetentionPolicy.RUNTIME);
}
@AstVisitor(nodes = AstNodes.EXPRESSIONS)
public void visit(Expression expr, MethodContext mc, DeclaredAnnotations da) {
if (expr.getCode() == AstCode.InvokeVirtual && expr.getArguments().size() == 2) {
MethodReference mr = (MethodReference) expr.getOperand();
if ((mr.getDeclaringType().getInternalName().startsWith("java/lang/reflect/") || mr.getDeclaringType()
.getInternalName().equals("java/lang/Class")) && mr.getName().contains("Annotation")) {
Object constant = Nodes.getConstant(expr.getArguments().get(1));
if (constant instanceof TypeReference) {
TypeReference tr = (TypeReference) constant;
DeclaredAnnotation annot = da.get(tr);
if (annot != null && annot.getPolicy() != RetentionPolicy.RUNTIME) {
mc.report("AnnotationNoRuntimeRetention", 0, expr, ANNOTATION.create(tr));
}
}
}
}
}
@Override
protected void visitType(TypeDefinition td) {
if (!td.isAnnotation())
return;
DeclaredAnnotation da = getOrCreate(td);
for (CustomAnnotation ca : td.getAnnotations()) {
if (Types.is(ca.getAnnotationType(), Retention.class)) {
for (AnnotationParameter ap : ca.getParameters()) {
if (ap.getMember().equals("value")) {
AnnotationElement value = ap.getValue();
if (value instanceof EnumAnnotationElement) {
EnumAnnotationElement enumValue = (EnumAnnotationElement) value;
if (Types.is(enumValue.getEnumType(), RetentionPolicy.class)) {
da.policy = RetentionPolicy.valueOf(enumValue.getEnumConstantName());
}
}
}
}
}
}
}
private void checkScopeAnnotationValidity(TypeElement annotation) {
if (annotation.getAnnotation(Scope.class) == null) {
error(
annotation,
"Scope Annotation %s does not contain Scope annotation.",
annotation.getQualifiedName());
return;
}
Retention retention = annotation.getAnnotation(Retention.class);
if (retention == null || retention.value() != RetentionPolicy.RUNTIME) {
error(
annotation,
"Scope Annotation %s does not have RUNTIME retention policy.",
annotation.getQualifiedName());
}
}
@SuppressWarnings("CheckReturnValue")
void use() {
// this immutable type (package style used)
ImIncludeTypes.builder().build();
// included on this type (package style used)
ImSerializable.builder().build();
// included on package (package style used)
ImTicker.builder().read(1).build();
// included in IncludeNestedTypes
ImmutableIncludeNestedTypes.Retention retention =
ImmutableIncludeNestedTypes.Retention.builder()
.value(RetentionPolicy.CLASS)
.build();
// included in IncludeNestedTypes
ImmutableIncludeNestedTypes.Target target =
ImmutableIncludeNestedTypes.Target.builder()
.value(ElementType.CONSTRUCTOR, ElementType.ANNOTATION_TYPE)
.build();
// package applied style "copyWith*" test
// see PackageStyle
retention.copyWithValue(RetentionPolicy.RUNTIME);
target.copyWithValue(ElementType.CONSTRUCTOR, ElementType.LOCAL_VARIABLE);
}
@Before
@SuppressWarnings("unchecked")
public void setUp() throws Exception {
when(fieldDescription.getActualModifiers()).thenReturn(MODIFIER);
when(fieldDescription.getInternalName()).thenReturn(FOO);
when(fieldDescription.getDescriptor()).thenReturn(BAR);
when(fieldDescription.getGenericSignature()).thenReturn(QUX);
when(fieldDescription.getDeclaredAnnotations()).thenReturn(new AnnotationList.Explicit(annotationDescription));
when(fieldDescription.getType()).thenReturn(TypeDescription.Generic.OBJECT);
when(classVisitor.visitField(MODIFIER, FOO, BAR, QUX, defaultValue)).thenReturn(fieldVisitor);
when(classVisitor.visitField(MODIFIER, FOO, BAR, QUX, FieldDescription.NO_DEFAULT_VALUE)).thenReturn(fieldVisitor);
when(annotationValueFilterFactory.on(fieldDescription)).thenReturn(valueFilter);
when(fieldVisitor.visitAnnotation(any(String.class), anyBoolean())).thenReturn(annotationVisitor);
when(annotationDescription.getAnnotationType()).thenReturn(annotationType);
when(annotationType.getDescriptor()).thenReturn(BAZ);
when(annotationType.getDeclaredMethods()).thenReturn(new MethodList.Empty<MethodDescription.InDefinedShape>());
when(annotationDescription.getRetention()).thenReturn(RetentionPolicy.RUNTIME);
}
@Pair(x = 3, y = "foo")
@Full(classValue=Full.class,
enumValue=RetentionPolicy.RUNTIME,
booleanValue=false,
stringArrayValue={"foo", "bar"},
classArrayValue={Full.class},
intArrayValue={1, 2},
enumArrayValue={RetentionPolicy.RUNTIME},
booleanArrayValue={false, true})
int getReadOnly();
@Override
public void write(ClassVisitor file) {
FieldVisitor fieldVisitor = file.visitField(modifiers, fieldDescriptor.getName(), fieldDescriptor.getType(), signature, null);
for(AnnotationCreatorImpl annotation : annotations) {
AnnotationVisitor av = fieldVisitor.visitAnnotation(DescriptorUtils.extToInt(annotation.getAnnotationType()), annotation.getRetentionPolicy() == RetentionPolicy.RUNTIME);
for(Map.Entry<String, Object> e : annotation.getValues().entrySet()) {
AnnotationUtils.visitAnnotationValue(av, e.getKey(), e.getValue());
}
av.visitEnd();
}
fieldVisitor.visitEnd();
}
/**
* @throws Exception
* @tests java.lang.annotation.RetentionPolicy#values()
*/
@SuppressWarnings("nls")
public void test_values() throws Exception {
RetentionPolicy[] values = RetentionPolicy.values();
assertTrue(values.length > 1);
Arrays.sort(values);
assertTrue(Arrays.binarySearch(values, RetentionPolicy.RUNTIME) >= 0);
}
@Advice.OnMethodEnter
@Advice.OnMethodExit
private static void advice(@Custom Object value) {
if (value != Object.class && value != RetentionPolicy.CLASS && value != null) {
throw new AssertionError();
}
}
public void addConstructor(Constructor<?> constructor) throws Exception {
List<Type> paramTypes = new ArrayList<Type>();
for (Class<?> paramType : constructor.getParameterTypes()) {
paramTypes.add(Type.getType(paramType));
}
String methodDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, paramTypes.toArray(
new Type[paramTypes.size()]));
MethodVisitor methodVisitor = visitor.visitMethod(Opcodes.ACC_PUBLIC, "<init>", methodDescriptor, signature(constructor), new String[0]);
for (Annotation annotation : constructor.getDeclaredAnnotations()) {
if (annotation.annotationType().getAnnotation(Inherited.class) != null) {
continue;
}
Retention retention = annotation.annotationType().getAnnotation(Retention.class);
AnnotationVisitor annotationVisitor = methodVisitor.visitAnnotation(Type.getType(annotation.annotationType()).getDescriptor(), retention != null && retention.value() == RetentionPolicy.RUNTIME);
annotationVisitor.visitEnd();
}
methodVisitor.visitCode();
// this.super(p0 .. pn)
methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
for (int i = 0; i < constructor.getParameterTypes().length; i++) {
methodVisitor.visitVarInsn(Type.getType(constructor.getParameterTypes()[i]).getOpcode(Opcodes.ILOAD), i + 1);
}
methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, superclassType.getInternalName(), "<init>",
methodDescriptor);
methodVisitor.visitInsn(Opcodes.RETURN);
methodVisitor.visitMaxs(0, 0);
methodVisitor.visitEnd();
}
public static Annotation getRetentionPolicyMetaAnnotation(RetentionPolicy rp) {
switch (rp) {
case CLASS: return aRetentionClass;
case RUNTIME: return aRetentionRuntime;
case SOURCE: return aRetentionSource;
default:
throw new Error("This can't happen");
}
}
@Pair(x = 3, y = "foo")
@Full(classValue=Full.class,
enumValue=RetentionPolicy.RUNTIME,
booleanValue=false,
stringArrayValue={"foo", "bar"},
classArrayValue={Full.class},
intArrayValue={1, 2},
enumArrayValue={RetentionPolicy.RUNTIME},
booleanArrayValue={false, true})
int getReadOnly();
/**
* We consider an annotation to be valid for extraction if it's not an internal annotation (i.e.
* is in the <code>com.facebook.litho</code> package and is not a source-only annotation.
*
* <p>We also do not consider the kotlin.Metadata annotation to be valid as it represents the
* metadata of the Spec class and not of the class that we are generating.
*
* @return Whether or not to extract the given annotation.
*/
private static boolean isValidAnnotation(AnnotationMirror annotation) {
final Retention retention =
annotation.getAnnotationType().asElement().getAnnotation(Retention.class);
if (retention != null && retention.value() == RetentionPolicy.SOURCE) {
return false;
}
String annotationName = annotation.getAnnotationType().toString();
return !annotationName.startsWith("com.facebook.") && !annotationName.equals("kotlin.Metadata");
}
public static Set<Annotation> getRetentionPolicyMetaAnnotationSet(RetentionPolicy rp) {
switch (rp) {
case CLASS: return asRetentionClass;
case RUNTIME: return asRetentionRuntime;
case SOURCE: return asRetentionSource;
default:
throw new Error("This can't happen");
}
}
@GetterAnnotation(policy = RetentionPolicy.CLASS,
string = "\n\"",
type = Object.class,
value = {@InnerAnnotation, @InnerAnnotation},
bval = Byte.MIN_VALUE, dval = Double.POSITIVE_INFINITY,
ival = Integer.MAX_VALUE,
fval = Float.NaN,
blval = true,
cval = 'j')
@Path("/ef")
@Value.Auxiliary
boolean ef();
@Test
public void testSourceRetentionAnnotation() throws Exception {
AnnotationVisitor annotationVisitor = mock(AnnotationVisitor.class);
when(target.visit(anyString(), anyBoolean())).thenReturn(annotationVisitor);
AnnotationDescription annotationDescription = mock(AnnotationDescription.class);
when(annotationDescription.getRetention()).thenReturn(RetentionPolicy.SOURCE);
annotationAppender.append(annotationDescription, valueFilter);
verifyZeroInteractions(valueFilter);
verifyZeroInteractions(annotationVisitor);
}
/**
* The following methods are utility methods for accessing
* information useful to asm from scene-library data structures.
*
* @return true iff tla is visible at runtime
*/
private static boolean isRuntimeRetention(Annotation tla) {
if (tla.def.retention() == null) {
return false; // TODO: temporary
}
return tla.def.retention().equals(RetentionPolicy.RUNTIME);
}
private Set<String> getRuntimeAnnotations(RetentionPolicy policy) {
return annotations.values().stream()
.filter(e -> e.policy == policy)
.map(a -> a.annotationName)
.distinct()
.collect(Collectors.toSet());
}
@Test
public void should_handle_enum() throws Exception {
class WithEnum {
RetentionPolicy retentionPolicy = RetentionPolicy.RUNTIME;
}
assertEquals("retentionPolicy = \"RUNTIME\"\n", new TomlWriter().write(new WithEnum()));
}
@Test
public void testUserEnumValue() throws Exception {
Class<?> type = new ByteBuddy()
.redefine(Sample.class)
.visit(Advice.withCustomMapping().bind(Custom.class, RetentionPolicy.CLASS).to(CustomAdvice.class).on(named(FOO)))
.make()
.load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
assertThat(type.getDeclaredMethod(FOO).invoke(type.getDeclaredConstructor().newInstance()), is((Object) FOO));
}
public void addConstructor(Constructor<?> constructor) throws Exception {
List<Type> paramTypes = new ArrayList<Type>();
for (Class<?> paramType : constructor.getParameterTypes()) {
paramTypes.add(Type.getType(paramType));
}
String methodDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, paramTypes.toArray(
new Type[paramTypes.size()]));
MethodVisitor methodVisitor = visitor.visitMethod(Opcodes.ACC_PUBLIC, "<init>", methodDescriptor, signature(constructor), new String[0]);
for (Annotation annotation : constructor.getDeclaredAnnotations()) {
if (annotation.annotationType().getAnnotation(Inherited.class) != null) {
continue;
}
Retention retention = annotation.annotationType().getAnnotation(Retention.class);
AnnotationVisitor annotationVisitor = methodVisitor.visitAnnotation(Type.getType(annotation.annotationType()).getDescriptor(), retention != null && retention.value() == RetentionPolicy.RUNTIME);
annotationVisitor.visitEnd();
}
methodVisitor.visitCode();
// this.super(p0 .. pn)
methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
for (int i = 0; i < constructor.getParameterTypes().length; i++) {
methodVisitor.visitVarInsn(Type.getType(constructor.getParameterTypes()[i]).getOpcode(Opcodes.ILOAD), i + 1);
}
methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, superclassType.getInternalName(), "<init>",
methodDescriptor);
methodVisitor.visitInsn(Opcodes.RETURN);
methodVisitor.visitMaxs(0, 0);
methodVisitor.visitEnd();
}
private static void checkAnnotationHasReasonableRetention(Class<? extends Annotation> annotationType) {
if (isRetentionSource(annotationType)) {
throw new InvalidSyntaxUsageException(String.format(
"Annotation type %s has @%s(%s), thus the information is gone after compile. "
+ "So checking this with ArchUnit is useless.",
annotationType.getName(), Retention.class.getSimpleName(), RetentionPolicy.SOURCE));
}
}
@Test
public void testSourceRetentionTypeAnnotation() throws Exception {
AnnotationVisitor annotationVisitor = mock(AnnotationVisitor.class);
when(target.visit(anyString(), anyBoolean())).thenReturn(annotationVisitor);
AnnotationDescription annotationDescription = mock(AnnotationDescription.class);
when(annotationDescription.getRetention()).thenReturn(RetentionPolicy.SOURCE);
annotationAppender.append(annotationDescription, valueFilter, 0, null);
verifyZeroInteractions(valueFilter);
verifyZeroInteractions(annotationVisitor);
}
@Pair(x = 3, y = "foo")
@Full(classValue=Full.class,
enumValue=RetentionPolicy.RUNTIME,
booleanValue=false,
stringArrayValue={"foo", "bar"},
classArrayValue={Full.class},
intArrayValue={1, 2},
enumArrayValue={RetentionPolicy.RUNTIME},
booleanArrayValue={false, true})
int getReadOnly();