/* Soot - a J*va Optimization Framework * Copyright (C) 1999-2010 Hossein Sadat-Mohtasham * * 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.toolkits.graph.pdg; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import soot.SootClass; import soot.SootMethod; import soot.Unit; import soot.toolkits.graph.Block; import soot.toolkits.graph.UnitGraph; /** * This class was originally designed to represent a weak region. Later, * PDGRegion was designed to represent a richer region representation but * since there were cases that we wanted to enforce the use of Region instead * of PDGRegion, and for some other compatibility issues, we chose not to eliminate * this class and even not to factor it into a common abstract class. * * One major contributing factor to the above is that, a Region can exist * independent from a PDG since they are generated by RegionAnalysis, whereas * a PDGRegion is generated by a PDG. * * @author Hossein Sadat-Mohtasham * Jan 2009 */ public class Region implements IRegion{ private SootClass m_class = null;; private SootMethod m_method = null; private List<Block> m_blocks = null; private List<Unit> m_units = null; private int m_id = -1; private UnitGraph m_unitGraph = null; //The following are needed to create a tree of regions based on the containment (dependency) //relation between regions. private IRegion m_parent = null; private List<IRegion> m_children = new ArrayList<IRegion>(); public Region(int id, SootMethod m, SootClass c, UnitGraph ug) { this(id, new ArrayList<Block>(), m, c, ug); } public Region(int id, List<Block> blocks, SootMethod m, SootClass c, UnitGraph ug) { this.m_blocks = blocks; this.m_id = id; this.m_method = m; this.m_class = c; this.m_unitGraph = ug; this.m_units = null; } @SuppressWarnings("unchecked") public Object clone() { Region r = new Region(this.m_id, this.m_method, this.m_class, this.m_unitGraph); r.m_blocks = (List<Block>)((ArrayList<Block>)this.m_blocks).clone(); return r; } public SootMethod getSootMethod() { return this.m_method; } public SootClass getSootClass() { return this.m_class; } public List<Block> getBlocks() { return this.m_blocks; } public UnitGraph getUnitGraph() { return this.m_unitGraph; } public List<Unit> getUnits() { if(this.m_units == null) { this.m_units = new LinkedList<Unit>(); for(Iterator<Block> itr = this.m_blocks.iterator(); itr.hasNext();) { Block b = itr.next(); for(Iterator<Unit> itr1 = b.iterator(); itr1.hasNext();) { Unit u = itr1.next(); ((LinkedList<Unit>)this.m_units).addLast(u); } } } return this.m_units; } public List<Unit> getUnits(Unit from, Unit to) { return m_units.subList(m_units.indexOf(from), m_units.indexOf(to)); } public Unit getLast() { if(this.m_units != null) if(this.m_units.size() > 0) return ((LinkedList<Unit>)this.m_units).getLast(); return null; } public Unit getFirst() { if(this.m_units != null) if(this.m_units.size() > 0) return ((LinkedList<Unit>)this.m_units).getFirst(); return null; } public void add(Block b) { //Add to the front this.m_blocks.add(0, b); } public void add2Back(Block b) { //Add to the last this.m_blocks.add(this.m_blocks.size(), b); } public void remove(Block b) { this.m_blocks.remove(b); //make the units be recalculated. this.m_units = null; } public int getID() { return this.m_id; } public boolean occursBefore(Unit u1, Unit u2) { int i = this.m_units.lastIndexOf(u1); int j = this.m_units.lastIndexOf(u2); if(i == -1 || j == -1) throw new RuntimeException("These units don't exist in the region!"); return i < j; } public void setParent(IRegion pr) { this.m_parent = pr; } public IRegion getParent() { return this.m_parent; } public void addChildRegion(IRegion chr) { if(!this.m_children.contains(chr)) this.m_children.add(chr); } public List<IRegion> getChildRegions() { return this.m_children; } public String toString() { String str = new String(); str += "Begin-----------Region: " + this.m_id + "-------------\n"; List<Unit> regionUnits = this.getUnits(); for (Iterator<Unit> itr = regionUnits.iterator(); itr.hasNext();) { Unit u = itr.next(); str += u + "\n"; } str += "End Region " + this.m_id + " -----------------------------\n"; return str; } }