/* Soot - a J*va Optimization Framework * Copyright (C) 2004 Jennifer Lhotak * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ package soot.xml; import soot.*; import soot.tagkit.*; import java.util.*; import java.io.*; import soot.jimple.spark.ondemand.genericutil.Predicate; public class TagCollector { private final ArrayList<Attribute> attributes; private final ArrayList<Key> keys; public TagCollector(){ attributes = new ArrayList<Attribute>(); keys = new ArrayList<Key>(); } public boolean isEmpty() { return attributes.isEmpty() && keys.isEmpty(); } /** Convenience function for <code>collectTags(sc, true)</code>. */ public void collectTags(SootClass sc){ collectTags(sc, true); } /** Collect tags from all fields and methods of <code>sc</code>. * If <code>includeBodies</code> is true, then tags are also collected * from method bodies. * @param sc The class from which to collect the tags. */ public void collectTags(SootClass sc, boolean includeBodies){ // tag the class collectClassTags(sc); // tag fields Iterator fit = sc.getFields().iterator(); while (fit.hasNext()){ SootField sf = (SootField)fit.next(); collectFieldTags(sf); } // tag methods Iterator it = sc.getMethods().iterator(); while (it.hasNext()) { SootMethod sm = (SootMethod)it.next(); collectMethodTags(sm); if (!includeBodies || !sm.hasActiveBody()) continue; Body b = sm.getActiveBody(); collectBodyTags(b); } } public void collectKeyTags(SootClass sc){ Iterator it = sc.getTags().iterator(); while (it.hasNext()){ Object next = it.next(); if (next instanceof KeyTag){ KeyTag kt = (KeyTag)next; Key k = new Key(kt.red(), kt.green(), kt.blue(), kt.key()); k.aType(kt.analysisType()); keys.add(k); } } } public void printKeys(PrintWriter writerOut){ Iterator<Key> it = keys.iterator(); while (it.hasNext()){ Key k = it.next(); k.print(writerOut); } } private void addAttribute(Attribute a){ if ( !a.isEmpty() ) attributes.add(a); } private void collectHostTags(Host h) { Predicate<Tag> p = Predicate.truePred(); collectHostTags(h, p); } private void collectHostTags(Host h, Predicate<Tag> include){ if (!h.getTags().isEmpty()){ Iterator tags = h.getTags().iterator(); Attribute a = new Attribute(); while (tags.hasNext()){ Tag t = (Tag)tags.next(); if (include.test(t)) a.addTag(t); } addAttribute(a); } } public void collectClassTags(SootClass sc) { // All classes are tagged with their source files which // is not worth outputing because it can be inferred from // other information (like the name of the XML file). Predicate<Tag> noSFTags = new Predicate<Tag>() { public boolean test (Tag t) { return !(t instanceof SourceFileTag); } }; collectHostTags(sc, noSFTags); } public void collectFieldTags(SootField sf) { collectHostTags(sf); } public void collectMethodTags(SootMethod sm){ if (sm.hasActiveBody()) collectHostTags(sm); } public void collectBodyTags(Body b){ Iterator itUnits = b.getUnits().iterator(); while (itUnits.hasNext()) { Unit u = (Unit)itUnits.next(); Iterator itTags = u.getTags().iterator(); Attribute ua = new Attribute(); JimpleLineNumberTag jlnt = null; while (itTags.hasNext()) { Tag t = (Tag)itTags.next(); ua.addTag(t); if (t instanceof JimpleLineNumberTag){ jlnt = (JimpleLineNumberTag)t; } //System.out.println("adding unit tag: "+t); } addAttribute(ua); Iterator valBoxIt = u.getUseAndDefBoxes().iterator(); while (valBoxIt.hasNext()){ ValueBox vb = (ValueBox)valBoxIt.next(); //PosColorAttribute attr = new PosColorAttribute(); if (!vb.getTags().isEmpty()){ Iterator tagsIt = vb.getTags().iterator(); Attribute va = new Attribute(); while (tagsIt.hasNext()) { Tag t = (Tag)tagsIt.next(); //System.out.println("adding vb tag: "+t); va.addTag(t); //System.out.println("vb: "+vb.getValue()+" tag: "+t); if (jlnt != null) { va.addTag(jlnt); } } // also here add line tags of the unit addAttribute(va); //System.out.println("added att: "+va); } } } } public void printTags(PrintWriter writerOut){ Iterator<Attribute> it = attributes.iterator(); while (it.hasNext()){ Attribute a = it.next(); //System.out.println("will print attr: "+a); a.print(writerOut); } } }