private void check(NoteKind kind, RuntimeTypeAnnotations_attribute attr) { if (attr == null) return; for (TypeAnnotation anno: attr.annotations) { Position p = anno.position; Note note = null; if (p.offset != -1) addNote(p.offset, note = new Note(kind, anno)); if (p.lvarOffset != null) { for (int i = 0; i < p.lvarOffset.length; i++) { if (note == null) note = new Note(kind, anno); addNote(p.lvarOffset[i], note); } } } }
public void run() throws Exception { ClassFile cf = getClassFile("TypeAnnotationPropagationTest$Test.class"); Method f = null; for (Method m : cf.methods) { if (m.getName(cf.constant_pool).contains("f")) { f = m; break; } } int idx = f.attributes.getIndex(cf.constant_pool, Attribute.Code); Code_attribute cattr = (Code_attribute) f.attributes.get(idx); idx = cattr.attributes.getIndex(cf.constant_pool, Attribute.RuntimeVisibleTypeAnnotations); RuntimeVisibleTypeAnnotations_attribute attr = (RuntimeVisibleTypeAnnotations_attribute) cattr.attributes.get(idx); TypeAnnotation anno = attr.annotations[0]; assertEquals(anno.position.lvarOffset, new int[] {3}, "start_pc"); assertEquals(anno.position.lvarLength, new int[] {8}, "length"); assertEquals(anno.position.lvarIndex, new int[] {1}, "index"); }
private static void findAnnotations(ClassFile cf, Method m, String name, List<TypeAnnotation> annos) { int index = m.attributes.getIndex(cf.constant_pool, name); if (index != -1) { Attribute attr = m.attributes.get(index); assert attr instanceof RuntimeTypeAnnotations_attribute; RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; annos.addAll(Arrays.asList(tAttr.annotations)); } int cindex = m.attributes.getIndex(cf.constant_pool, Attribute.Code); if (cindex != -1) { Attribute cattr = m.attributes.get(cindex); assert cattr instanceof Code_attribute; Code_attribute cAttr = (Code_attribute)cattr; index = cAttr.attributes.getIndex(cf.constant_pool, name); if (index != -1) { Attribute attr = cAttr.attributes.get(index); assert attr instanceof RuntimeTypeAnnotations_attribute; RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; annos.addAll(Arrays.asList(tAttr.annotations)); } } }
public static boolean compare(Map<String, TypeAnnotation.Position> expectedAnnos, List<TypeAnnotation> actualAnnos, ClassFile cf) throws InvalidIndex, UnexpectedEntry { if (actualAnnos.size() != expectedAnnos.size()) { throw new ComparisionException("Wrong number of annotations", expectedAnnos, actualAnnos); } for (Map.Entry<String, TypeAnnotation.Position> e : expectedAnnos.entrySet()) { String aName = e.getKey(); TypeAnnotation.Position expected = e.getValue(); TypeAnnotation actual = findAnnotation(aName, actualAnnos, cf); if (actual == null) throw new ComparisionException("Expected annotation not found: " + aName); if (!areEquals(expected, actual.position)) { throw new ComparisionException("Unexpected position for annotation : " + aName + "\n Expected: " + expected.toString() + "\n Found: " + actual.position.toString()); } } return true; }
private Map<String, TypeAnnotation.Position> expectedOf(Method m) { TADescription ta = m.getAnnotation(TADescription.class); TADescriptions tas = m.getAnnotation(TADescriptions.class); if (ta == null && tas == null) return null; Map<String, TypeAnnotation.Position> result = new HashMap<>(); if (ta != null) result.putAll(expectedOf(ta)); if (tas != null) { for (TADescription a : tas.value()) { result.putAll(expectedOf(a)); } } return result; }
public static boolean areEquals(TypeAnnotation.Position p1, TypeAnnotation.Position p2) { if (p1 == p2) return true; if (p1 == null || p2 == null) return false; return ((p1.type == p2.type) && (p1.location.equals(p2.location)) && areEquals(p1.offset, p2.offset) && areEquals(p1.lvarOffset, p2.lvarOffset) && areEquals(p1.lvarLength, p2.lvarLength) && areEquals(p1.lvarIndex, p2.lvarIndex) && areEquals(p1.bound_index, p2.bound_index) && areEquals(p1.parameter_index, p2.parameter_index) && areEquals(p1.type_index, p2.type_index) && areEquals(p1.exception_index, p2.exception_index)); }
public static boolean compare(Map<String, TypeAnnotation.Position> expectedAnnos, List<TypeAnnotation> actualAnnos, ClassFile cf) throws InvalidIndex, UnexpectedEntry { if (actualAnnos.size() != expectedAnnos.size()) { throw new ComparisionException("Wrong number of annotations", expectedAnnos, actualAnnos); } for (Map.Entry<String, TypeAnnotation.Position> e : expectedAnnos.entrySet()) { String aName = e.getKey(); TypeAnnotation.Position expected = e.getValue(); TypeAnnotation actual = findAnnotation(aName, actualAnnos, cf); if (actual == null) throw new ComparisionException("Expected annotation not found: " + aName); // TODO: you currently get an exception if the test case does not use all necessary // annotation attributes, e.g. forgetting the offset for a local variable. // It would be nicer to give an understandable warning instead. if (!areEquals(expected, actual.position)) { throw new ComparisionException("Unexpected position for annotation : " + aName + "\n Expected: " + expected.toString() + "\n Found: " + actual.position.toString()); } } return true; }
private Map<String, TypeAnnotation.Position> expectedOf(Method m) { TADescription ta = m.getAnnotation(TADescription.class); TADescriptions tas = m.getAnnotation(TADescriptions.class); if (ta == null && tas == null) return null; Map<String, TypeAnnotation.Position> result = new HashMap<String, TypeAnnotation.Position>(); if (ta != null) result.putAll(expectedOf(ta)); if (tas != null) { for (TADescription a : tas.value()) { result.putAll(expectedOf(a)); } } return result; }
public static boolean compare(List<Pair<String, TypeAnnotation.Position>> expectedAnnos, List<TypeAnnotation> actualAnnos, ClassFile cf) throws InvalidIndex, UnexpectedEntry { if (actualAnnos.size() != expectedAnnos.size()) { throw new ComparisionException("Wrong number of annotations", expectedAnnos, actualAnnos); } for (Pair<String, TypeAnnotation.Position> e : expectedAnnos) { String aName = e.first; TypeAnnotation.Position expected = e.second; TypeAnnotation actual = findAnnotation(aName, expected, actualAnnos, cf); if (actual == null) { throw new ComparisionException("Expected annotation not found: " + aName + " position: " + expected, expectedAnnos, actualAnnos); } } return true; }
private List<Pair<String, TypeAnnotation.Position>> expectedOf(Method m) { TADescription ta = m.getAnnotation(TADescription.class); TADescriptions tas = m.getAnnotation(TADescriptions.class); if (ta == null && tas == null) return null; List<Pair<String, TypeAnnotation.Position>> result = new ArrayList<>(); if (ta != null) result.add(expectedOf(ta)); if (tas != null) { for (TADescription a : tas.value()) { result.add(expectedOf(a)); } } return result; }
private void parseTypeAnnotations(TypeAnnotation pa, Element p) { Element pta = new Element("RuntimeVisibleTypeAnnotation"); p.add(pta); Position pos = pa.position; parsePosition(pos, pta); parseAnnotation(pa.annotation, pta); }
@Override public Element visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute rvta, Element p) { Element e = new Element(x.getCpString(rvta.attribute_name_index)); for (TypeAnnotation pa : rvta.annotations) { parseTypeAnnotations(pa, e); } e.sort(); p.add(e); return null; }
@Override public Element visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute rita, Element p) { Element e = new Element(x.getCpString(rita.attribute_name_index)); for (TypeAnnotation pa : rita.annotations) { parseTypeAnnotations(pa, e); } e.sort(); p.add(e); return null; }
private static void findAnnotations(ClassFile cf, List<TypeAnnotation> annos) { findAnnotations(cf, Attribute.RuntimeVisibleTypeAnnotations, annos); findAnnotations(cf, Attribute.RuntimeInvisibleTypeAnnotations, annos); for (Field f : cf.fields) { findAnnotations(cf, f, annos); } for (Method m: cf.methods) { findAnnotations(cf, m, annos); } }
private static void findAnnotations(ClassFile cf, String name, List<TypeAnnotation> annos) { int index = cf.attributes.getIndex(cf.constant_pool, name); if (index != -1) { Attribute attr = cf.attributes.get(index); assert attr instanceof RuntimeTypeAnnotations_attribute; RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr; annos.addAll(Arrays.asList(tAttr.annotations)); } }