@SuppressWarnings("unchecked") public static void accept(String name, Object v, AnnotationVisitor av) { if (v instanceof AnnotationNode) { AnnotationNode a = (AnnotationNode) v; AnnotationVisitor av1 = av.visitAnnotation(name, a.type); accept(a.items, av1); av1.visitEnd(); } else if (v instanceof Field) { Field e = (Field) v; av.visitEnum(name, e.getOwner(), e.getName()); } else if (v instanceof List) { List<Object> list = (List<Object>) v; AnnotationVisitor av1 = av.visitArray(name); for (Object i : list) { accept(null, i, av1); } av1.visitEnd(); } else if (v instanceof Method) { // Method method = (Method) v; // AnnotationVisitor av1 = av.visitAnnotation(item.name, "Lcom.googlecode.Method;"); // av1.visit("owner", method.getOwner()); // av1.visit("name", method.getName()); // av1.visit("desc", method.getType().getDesc()); // av1.visitEnd(); av.visit(name, v); } else if (v instanceof DexType) { av.visit(name, ((DexType) v).desc); } else { av.visit(name, v); } }
public static void visitAnnotationFields(AnnotationVisitor visitor, Map<String, Object> fields) { try { for (Map.Entry<String, Object> fieldEntry : fields.entrySet()) { Object value = fieldEntry.getValue(); String key = fieldEntry.getKey(); if (value instanceof Map) { @SuppressWarnings("unchecked") Map<Class, Map<String, Object>> nestedAnnotationMap = (Map<Class, Map<String, Object>>) value; for (Map.Entry<Class, Map<String, Object>> nestedAnnotation : nestedAnnotationMap.entrySet()) { AnnotationVisitor annotationV; annotationV = visitor.visitAnnotation( key, Type.getType(nestedAnnotation.getKey()).getDescriptor()); visitAnnotationFields(annotationV, nestedAnnotation.getValue()); annotationV.visitEnd(); } } else if (value.getClass().isArray()) { Object[] values = (Object[]) value; AnnotationVisitor arrayV = visitor.visitArray(key); for (int i = 0; i < values.length; i++) { Map<String, Object> map = new HashMap<String, Object>(); map.put(null, values[i]); visitAnnotationFields(arrayV, map); } arrayV.visitEnd(); } else if (value.getClass().isEnum()) { visitor.visitEnum(key, ci(value.getClass()), value.toString()); } else if (value instanceof Class) { visitor.visit(key, Type.getType((Class) value)); } else { visitor.visit(key, value); } } } catch (ClassCastException e) { throw new InvalidAnnotationDescriptorException( "Fields " + fields + " did not match annotation format. See CodegenUtils#visitAnnotationFields for format", e); } }
/** * Performs the writing of a given annotation value to an annotation visitor. * * @param annotationVisitor The annotation visitor the write process is to be applied on. * @param valueType The type of the annotation value. * @param name The name of the annotation type. * @param value The annotation's value. */ public static void apply( AnnotationVisitor annotationVisitor, TypeDescription valueType, String name, Object value) { if (valueType.isAnnotation()) { handle( annotationVisitor.visitAnnotation(name, valueType.getDescriptor()), (AnnotationDescription) value, AnnotationValueFilter.Default.APPEND_DEFAULTS); } else if (valueType.isEnum()) { annotationVisitor.visitEnum( name, valueType.getDescriptor(), ((EnumerationDescription) value).getValue()); } else if (valueType.isAssignableFrom(Class.class)) { annotationVisitor.visit(name, Type.getType(((TypeDescription) value).getDescriptor())); } else if (valueType.isArray()) { AnnotationVisitor arrayVisitor = annotationVisitor.visitArray(name); int length = Array.getLength(value); TypeDescription componentType = valueType.getComponentType(); for (int index = 0; index < length; index++) { apply(arrayVisitor, componentType, NO_NAME, Array.get(value, index)); } arrayVisitor.visitEnd(); } else { annotationVisitor.visit(name, value); } }