public void internalTransform(String phaseName, Map opts) { Iterator it = Scene.v().getApplicationClasses().iterator(); while (it.hasNext()) { SootClass sc = (SootClass) it.next(); // make map of first line to each method HashMap<Integer, SootMethod> lineToMeth = new HashMap<Integer, SootMethod>(); Iterator methIt = sc.getMethods().iterator(); while (methIt.hasNext()) { SootMethod meth = (SootMethod) methIt.next(); if (!meth.isConcrete()) continue; Body body = meth.retrieveActiveBody(); Stmt s = (Stmt) body.getUnits().getFirst(); while (s instanceof IdentityStmt) { s = (Stmt) body.getUnits().getSuccOf(s); } if (s.hasTag("LineNumberTag")) { LineNumberTag tag = (LineNumberTag) s.getTag("LineNumberTag"); lineToMeth.put(new Integer(tag.getLineNumber()), meth); } } Iterator methIt2 = sc.getMethods().iterator(); while (methIt2.hasNext()) { SootMethod meth = (SootMethod) methIt2.next(); if (!meth.isConcrete()) continue; Body body = meth.retrieveActiveBody(); Stmt s = (Stmt) body.getUnits().getFirst(); while (s instanceof IdentityStmt) { s = (Stmt) body.getUnits().getSuccOf(s); } if (s.hasTag("LineNumberTag")) { LineNumberTag tag = (LineNumberTag) s.getTag("LineNumberTag"); int line_num = tag.getLineNumber() - 1; // already taken if (lineToMeth.containsKey(new Integer(line_num))) { meth.addTag(new LineNumberTag(line_num + 1)); } // still available - so use it for this meth else { meth.addTag(new LineNumberTag(line_num)); } } } } }
void handleClassAnnotation(ClassDef classDef) { Set<? extends Annotation> aSet = classDef.getAnnotations(); if (aSet == null || aSet.isEmpty()) return; List<Tag> tags = handleAnnotation(aSet, classDef.getType()); if (tags == null) return; InnerClassAttribute ica = null; for (Tag t : tags) if (t != null) { if (t instanceof InnerClassTag) { if (ica == null) { // Do we already have an InnerClassAttribute? ica = (InnerClassAttribute) clazz.getTag("InnerClassAttribute"); // If not, create one if (ica == null) { ica = new InnerClassAttribute(); clazz.addTag(ica); } } ica.add((InnerClassTag) t); } else if (t instanceof VisibilityAnnotationTag) { // If a dalvik/annotation/AnnotationDefault tag is present // in a class, its AnnotationElements must be propagated // to methods through the creation of new AnnotationDefaultTag. VisibilityAnnotationTag vt = (VisibilityAnnotationTag) t; for (AnnotationTag a : vt.getAnnotations()) { if (a.getType().equals("Ldalvik/annotation/AnnotationDefault;")) { for (AnnotationElem ae : a.getElems()) { if (ae instanceof AnnotationAnnotationElem) { AnnotationAnnotationElem aae = (AnnotationAnnotationElem) ae; AnnotationTag at = aae.getValue(); // extract default elements Map<String, AnnotationElem> defaults = new HashMap<String, AnnotationElem>(); for (AnnotationElem aelem : at.getElems()) { defaults.put(aelem.getName(), aelem); } // create default tags containing default elements // and add tags on methods for (SootMethod sm : clazz.getMethods()) { String methodName = sm.getName(); if (defaults.containsKey(methodName)) { AnnotationElem e = defaults.get(methodName); // Okay, the name is the same, but is it actually the same type? Type annotationType = getSootType(e); boolean isCorrectType = false; if (annotationType == null) { // we do not know the type of the annotation, so we guess it's the correct // type. isCorrectType = true; } else { if (annotationType.equals(sm.getReturnType())) { isCorrectType = true; } else if (annotationType.equals(ARRAY_TYPE)) { if (sm.getReturnType() instanceof ArrayType) isCorrectType = true; } } if (isCorrectType && sm.getParameterCount() == 0) { e.setName("default"); AnnotationDefaultTag d = new AnnotationDefaultTag(e); sm.addTag(d); // In case there is more than one matching method, we only use the first one defaults.remove(sm.getName()); } } } for (Entry<String, AnnotationElem> leftOverEntry : defaults.entrySet()) { // We were not able to find a matching method for the tag, because the return // signature // does not match SootMethod found = clazz.getMethodByNameUnsafe(leftOverEntry.getKey()); AnnotationElem element = leftOverEntry.getValue(); if (found != null) { element.setName("default"); AnnotationDefaultTag d = new AnnotationDefaultTag(element); found.addTag(d); } } } } } } if (!(vt.getVisibility() == AnnotationConstants.RUNTIME_INVISIBLE)) clazz.addTag(vt); } else { clazz.addTag(t); } Debug.printDbg("add class annotation: ", t, " type: ", t.getClass()); } }