Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /* Soot - a J*va Optimization Framework
   * Copyright (C) 1999 Patrice Pominville, Raja Vallee-Rai
   *
   * 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.
  */
 
 /*
  * Modified by the Sable Research Group and others 1997-2004.  
  * See the 'credits' file distributed with Soot for the complete list of
  * contributors.  (Soot is distributed at http://www.sable.mcgill.ca/soot)
  */
 
 
  
 
 
 
 package soot.toolkits.graph;
 
 import soot.*;
 import soot.util.*;
 import java.util.*;
 

Represents a control flow graph for a soot.Body instance where the nodes are soot.Unit instances, and where control flow associated with exceptions is taken into account.

To describe precisely the circumstances under which exceptional edges are added to the graph, we need to distinguish the exceptions thrown explicitly by a throw instruction from the exceptions which are thrown implicitly by the VM to signal an error it encounters in the course of executing an instruction, which need not be a throw.

For every ThrowInst or soot.jimple.ThrowStmt Unit which may explicitly throw an exception that would be caught by a soot.Trap in the Body, there will be an edge from the throw Unit to the Trap handler's first Unit.

For every Unit which may implicitly throw an exception that could be caught by a Trap in the Body, there will be an edge from each of the excepting Unit's predecessors to the Trap handler's first Unit (since any of those predecessors may have been the last Unit to complete execution before the handler starts execution). If the excepting Unit might have the side effect of changing some field, then there will definitely be an edge from the excepting Unit itself to its handlers, since the side effect might occur before the exception is raised. If the excepting Unit has no side effects, then parameters passed to the ExceptionalUnitGraph constructor determine whether or not there is an edge from the excepting Unit itself to the handler Unit.

 
 public class ExceptionalUnitGraph extends UnitGraph implements ExceptionalGraph<Unit>
 {
     protected Map<Unit,List<Unit>> unitToUnexceptionalSuccs// If there are no Traps within
     protected Map<Unit,List<Unit>> unitToUnexceptionalPreds// the method, these will be the
 					    // same maps as unitToSuccs and
 					    // unitToPreds.
 
     protected Map<Unit,List<Unit>> unitToExceptionalSuccs;
     protected Map<Unit,List<Unit>> unitToExceptionalPreds;
 
     protected ThrowAnalysis throwAnalysis// Cached reference to the
 					   // analysis used to generate this
 					   // graph, for generating responses
 					   // to getExceptionDests() on the
 					   // fly for nodes from which all
 					   // exceptions escape the method.
 

    
Constructs the graph for a given Body instance, using the ThrowAnalysis and omitExceptingUnitEdges value that are passed as parameters.

Parameters:
body the Body from which to build a graph.
throwAnalysis the source of information about the exceptions which each soot.Unit may throw.
omitExceptingUnitEdges indicates whether the CFG should omit edges to a handler from trapped Units which may implicitly throw an exception which the handler catches but which have no potential side effects. The CFG will contain edges to the handler from all predecessors of Units which may implicitly throw a caught exception regardless of the setting for this parameter. If this parameter is false, there will also be edges to the handler from all the potentially excepting Units themselves. If this parameter is true, there will be edges to the handler from the excepting Units themselves only if they have potential side effects (or if they are themselves the predecessors of other potentially excepting Units). A setting of true produces CFGs which allow for more precise analyses, since a Unit without side effects has no effect on the computational state when it throws an exception. Use settings of false for compatibility with more conservative analyses, or to cater to conservative bytecode verifiers.
    public ExceptionalUnitGraph(Body bodyThrowAnalysis throwAnalysis,
				boolean omitExceptingUnitEdges) {
	super(body);
	initialize(throwAnalysisomitExceptingUnitEdges);
    }


    
Constructs the graph from a given Body instance using the passed soot.toolkits.exceptions.ThrowAnalysis and a default value, provided by the soot.options.Options class, for the omitExceptingUnitEdges parameter.

Parameters:
body the soot.Body from which to build a graph.
throwAnalysis the source of information about the exceptions which each soot.Unit may throw.
    public ExceptionalUnitGraph(Body bodyThrowAnalysis throwAnalysis) {
	this(bodythrowAnalysis, Options.v().omit_excepting_unit_edges());
    }


    
Constructs the graph from a given Body instance, using the soot.Scene's default soot.toolkits.exceptions.ThrowAnalysis to estimate the set of exceptions that each soot.Unit might throw and a default value, provided by the soot.options.Options class, for the omitExceptingUnitEdges parameter.

Parameters:
body the Body from which to build a graph.
    public ExceptionalUnitGraph(Body body) {
	this(body, Scene.v().getDefaultThrowAnalysis(),
	     Options.v().omit_excepting_unit_edges());
    }


    

Allocates an ExceptionalUnitGraph object without initializing it. This “partial constructor” is provided for the benefit of subclasses whose constructors need to perform some subclass-specific processing before actually creating the graph edges (because, for example, the subclass overrides a utility method like buildExceptionDests(soot.toolkits.exceptions.ThrowAnalysis) or buildExceptionalEdges(soot.toolkits.exceptions.ThrowAnalysis,java.util.Map,java.util.Map,java.util.Map,boolean) with a replacement method that depends on additional parameters passed to the subclass's constructor). The subclass constructor is responsible for calling initialize(soot.toolkits.exceptions.ThrowAnalysis,boolean), or otherwise performing the initialization required to implement ExceptionalUnitGraph's interface.

Clients who opt to extend ExceptionalUnitGraph should be warned that the class has not been carefully designed for inheritance; code that uses the protected members of this class may need to be rewritten for each new Soot release.

@param body the Body from which to build a graph. @param ignoredBogusParameter a meaningless placeholder, which exists solely to distinguish this constructor from the public ExceptionalUnitGraph(soot.Body) constructor.
    protected ExceptionalUnitGraph(Body bodyboolean ignoredBogusParameter) {
	super(body);
    }


    
Performs the real work of constructing an ExceptionalUnitGraph, factored out of the constructors so that subclasses have the option to delay creating the graph's edges until after they have performed some subclass-specific initialization.

Parameters:
throwAnalysis the source of information about the exceptions which each soot.Unit may throw.
omitExceptingUnitEdges indicates whether the CFG should omit edges to a handler from trapped Units which may throw an exception which the handler catches but which have no potential side effects.
    protected void initialize(ThrowAnalysis throwAnalysis
			      boolean omitExceptingUnitEdges) {
	int size = .size();
	Set<UnittrapUnitsThatAreHeads = Collections.emptySet();
        
        if(Options.v().time())
            Timers.v()..start();
        
	 = new HashMap<Unit,List<Unit>>(size * 2 + 1, 0.7f);
	 = new HashMap<Unit,List<Unit>>(size * 2 + 1, 0.7f);
	this. = throwAnalysis;
	if (.getTraps().size() == 0) {
	    // No handlers, so all exceptional control flow exits the
	    // method.
             = Collections.emptyMap();
	     = Collections.emptyMap();
	     = Collections.emptyMap();
else {
	     = buildExceptionDests(throwAnalysis);
		new HashMap<Unit,List<Unit>>(.size() * 2 + 1, 0.7f);
		new HashMap<Unit,List<Unit>>(.getTraps().size() * 2 + 1, 0.7f);
	    trapUnitsThatAreHeads = buildExceptionalEdges(throwAnalysis,
						      omitExceptingUnitEdges);
	    // We'll need separate maps for the combined 
	    // exceptional and unexceptional edges:
	}
	buildHeadsAndTails(trapUnitsThatAreHeads);
        if(Options.v().time())
            Timers.v()..end();        
    }


    

Utility method used in the construction of UnitGraph variants which include exceptional control flow. It determines which soot.Units may throw exceptions that would be caught by soot.Traps within the method.

Parameters:
throwAnalysis The source of information about which exceptions each Unit may throw.
Returns:
null if no Units in the method throw any exceptions caught within the method. Otherwise, a java.util.Map from Units to java.util.Collections of ExceptionalUnitGraph.ExceptionDests.

The returned map has an idiosyncracy which is hidden from most client code, but which is exposed to subclasses extending ExceptionalUnitGraph. If a Unit throws one or more exceptions which are caught within the method, it will be mapped to a Collection of ExceptionDests describing the sets of exceptions that the Unit might throw to each soot.Trap. But if all of a Unit's exceptions escape the method, it will be mapped to nullCollection containing a single ExceptionDest with a null trap. (The special case for Units with no caught exceptions allows buildExceptionDests() to ignore completely Units which are outside the scope of all Traps.)

    protected Map<Unit,Collection<ExceptionDest>> buildExceptionDests(ThrowAnalysis throwAnalysis) {
	Chain<Unitunits = .getUnits();
	Map<UnitThrowableSetunitToUncaughtThrowables = new HashMap<UnitThrowableSet>(units.size());
	Map<Unit,Collection<ExceptionDest>> result = null;
	// Record the caught exceptions.
	for (Iterator<TraptrapIt = .getTraps().iterator(); trapIt.hasNext(); ) {
	    Trap trap = trapIt.next();
	    RefType catcher = trap.getException().getType();
	    for (Iterator<UnitunitIt = units.iterator(trap.getBeginUnit(), 
						  units.getPredOf(trap.getEndUnit()));
		 unitIt.hasNext(); ) {
		Unit unit = unitIt.next();
		ThrowableSet thrownSet = unitToUncaughtThrowables.get(unit);
		if (thrownSet == null) {
		    thrownSet = throwAnalysis.mightThrow(unit);
		}
		ThrowableSet.Pair catchableAs = thrownSet.whichCatchableAs(catcher);
		if (catchableAs.getCaught() != ThrowableSet.Manager.v().) {
		    result = addDestToMap(resultunittrapcatchableAs.getCaught());
		    unitToUncaughtThrowables.put(unitcatchableAs.getUncaught());
else {
		    // An assertion check:
		    if (thrownSet != catchableAs.getUncaught()) {
			throw new IllegalStateException("ExceptionalUnitGraph.buildExceptionDests(): catchableAs.caught == EMPTY, but catchableAs.uncaught != thrownSet" 
							+ System.getProperty("line.separator") + .getMethod().getSubSignature() + " Unit: " + unit.toString()
							+ System.getProperty("line.separator") + " catchableAs.getUncaught() == " + catchableAs.getUncaught().toString() 
							+ System.getProperty("line.separator") + " thrownSet == " + thrownSet.toString());
		    }
		}
	    }
	}
	for (Map.Entry<Unit,ThrowableSetentry : unitToUncaughtThrowables.entrySet()) {
	Unit unit = (Unitentry.getKey();
	ThrowableSet escaping = (ThrowableSetentry.getValue();
	if (escaping != ThrowableSet.Manager.v().) {
	result = addDestToMap(resultunitnullescaping);
	}
	if (result == null) {
	    result = Collections.emptyMap();
	}
	return result;
    }


    
A utility method for recording the exceptions that a Unit throws to a particular Trap. Note that this method relies on the fact that the call to add escaping exceptions for a Unit will always follow all calls for its caught exceptions.

Parameters:
map A Map from Units to Collections of ExceptionDests. null if no exceptions have been recorded yet.
u The Unit throwing the exceptions.
t The Trap which catches the exceptions, or null if the exceptions escape the method.
caught The set of exception types thrown by u which are caught by t.
Returns:
a Map which whose contents are equivalent to the input map, plus the information that u throws caught to t.
    	(Map<Unit,Collection<ExceptionDest>> mapUnit uTrap tThrowableSet caught) {
	Collection<ExceptionDestdests = (map == null ? null : map.get(u));
	if (dests == null) {
	    if (t == null) {
		// All exceptions from u escape, so don't record any.
		return map;
	    } else {
		if (map == null) {
		     map = new HashMap<Unit,Collection<ExceptionDest>>(.size() * 2 + 1);
		}
		dests = new ArrayList<ExceptionDest>(3);
		map.put(udests);
	    }
	}
	dests.add(new ExceptionDest(tcaught));
	return map;
    }


    
Method to compute the edges corresponding to exceptional control flow.

Parameters:
throwAnalysis the source of information about the exceptions which each soot.Unit may throw.
unitToExceptionDests2 A Map from soot.Units to java.util.Collections of ExceptionalUnitGraph.ExceptionDests which represent the handlers that might catch exceptions thrown by the Unit. This is an ``in parameter''.
unitToSuccs A Map from Units to java.util.Lists of Units. This is an ``out parameter''; buildExceptionalEdges will add a mapping from every Unit in the body that may throw an exception that could be caught by a soot.Trap in the body to a list of its exceptional successors.
unitToPreds A Map from Units to Lists of Units. This is an ``out parameter''; buildExceptionalEdges will add a mapping from each handler unit that may catch an exception to the list of Units whose exceptions it may catch.
omitExceptingUnitEdges Indicates whether to omit exceptional edges from excepting units which lack side effects
Returns:
a java.util.Set of trap Units that might catch exceptions thrown by the first Unit in the soot.Body associated with the graph being constructed. Such trap Units may need to be added to the list of heads (depending on your definition of heads), since they can be the first Unit in the Body which actually completes execution.
    protected Set<UnitbuildExceptionalEdges(ThrowAnalysis throwAnalysis,
					Map<UnitCollection<ExceptionDest>> unitToExceptionDests
					Map<Unit,List<Unit>> unitToSuccsMap<Unit,List<Unit>> unitToPreds,
					boolean omitExceptingUnitEdges) {
	Set<UnittrapsThatAreHeads = new ArraySet<Unit>();
	Unit entryPoint = (Unit.getFirst();
	for (Iterator<Entry<UnitCollection<ExceptionDest>>> it = unitToExceptionDests.entrySet().iterator();
	     it.hasNext(); ) {
		Entry<UnitCollection<ExceptionDest>> entry = it.next();
	    Unit thrower = (Unitentry.getKey();
	    List<UnitthrowersPreds = getUnexceptionalPredsOf(thrower);
	    Collection<ExceptionDestdests = entry.getValue();
	    // We need to recognize:
	    // - caught exceptions for which we must add edges from the 
	    //   thrower's predecessors to the catcher:
	    //     - all exceptions of non-throw instructions;
	    //     - implicit exceptions of throw instructions.
	    //
	    // - caught exceptions where we must add edges from the 
	    //   thrower itself to the catcher:
	    //     - any exception of non-throw instructions if
	    //       omitExceptingUnitEdges is not set.
	    //     - any exception of non-throw instructions with side effects.
	    //     - explicit exceptions of throw instructions
	    //     - implicit exceptions of throw instructions if 
	    //       omitExceptingUnitEdges is not set.
	    //     - implicit exceptions of throw instructions with possible
	    //       side effects (this is only possible for the grimp
	    //       IR, where the throw's argument may be an
	    //       expression---probably a NewInvokeExpr---which
	    //       might have executed partially before the
	    //       exception arose).
	    //
	    // Note that a throw instruction may be capable of throwing a given
	    // Throwable type both implicitly and explicitly.
	    //
	    // We track these situations using predThrowables and
	    // selfThrowables.  Essentially predThrowables is the set
	    // of Throwable types to whose catchers there should be
	    // edges from predecessors of the thrower, while
	    // selfThrowables is the set of Throwable types to whose
	    // catchers there should be edges from the thrower itself,
	    // but we we take some short cuts to avoid calling
	    // ThrowableSet.catchableAs() when we can avoid it.
	    boolean alwaysAddSelfEdges = ((! omitExceptingUnitEdges) || 
					  mightHaveSideEffects(thrower));
	    ThrowableSet predThrowables = null;
	    ThrowableSet selfThrowables = null;
	    if (thrower instanceof ThrowStmt) {
		ThrowStmt throwStmt = (ThrowStmtthrower;
		predThrowables = throwAnalysis.mightThrowImplicitly(throwStmt);
		selfThrowables = throwAnalysis.mightThrowExplicitly(throwStmt);
	    }
	    for (Iterator<ExceptionDestdestIt = dests.iterator(); destIt.hasNext(); ) {
		ExceptionDest dest = destIt.next();
		if (dest.getTrap() != null) {
		    Unit catcher = dest.getTrap().getHandlerUnit();
		    RefType trapsType = dest.getTrap().getException().getType();
		    if (predThrowables == null ||
			predThrowables.catchableAs(trapsType)) {
			// Add edges from the thrower's predecessors to the catcher.
			if (thrower == entryPoint) {
			    trapsThatAreHeads.add(catcher);
			}
			for (Iterator<Unitp = throwersPreds.iterator(); p.hasNext(); ) {
			    Unit pred = p.next();
			    addEdge(unitToSuccsunitToPredspredcatcher);
			}
		    }
		    if (alwaysAddSelfEdges ||
			(selfThrowables != null &&
			 selfThrowables.catchableAs(trapsType))) {
			addEdge(unitToSuccsunitToPredsthrowercatcher);
		    }
		}
	    }
	}
	// Now we have to worry about transitive exceptional
	// edges, when a handler might itself throw an exception
	// that is caught within the method.  For that we need a
	// worklist containing CFG edges that lead to such a handler.
	class CFGEdge {
	    Unit head;		// If null, represents an edge to the handler
				// from the fictitious "predecessor" of the 
				// very first unit in the chain. I.e., tail
				// is a handler which might be reached as a
				// result of an exception thrown by the
				// first Unit in the Body.
	    Unit tail;
	    CFGEdge(Unit headUnit tail) {
		if (tail == null)
		    throw new RuntimeException("invalid CFGEdge(" 
					       + head.toString() + ',' 
					       + "null" + ')');
		this. = head;
		this. = tail;
	    }
	    public boolean equals(Object rhs) {
		if (rhs == this) {
		    return true;
		}
		if (! (rhs instanceof CFGEdge)) {
		    return false;
		}
		CFGEdge rhsEdge = (CFGEdgerhs;
		return ((this. == rhsEdge.head) && 
			(this. == rhsEdge.tail));
	    }
	    public int hashCode() {
		// Following Joshua Bloch's recipe in "Effective Java", Item 8:
		int result = 17;
		result = 37 * result + this..hashCode();
		result = 37 * result + this..hashCode();
		return result;
	    }
	}
	LinkedList<CFGEdgeworkList = new LinkedList<CFGEdge>();
	for (Iterator<TraptrapIt = .getTraps().iterator(); trapIt.hasNext(); ) {
	    Trap trap = trapIt.next();
	    Unit handlerStart = trap.getHandlerUnit();
	    if (mightThrowToIntraproceduralCatcher(handlerStart)) {
		List<UnithandlerPreds = getUnexceptionalPredsOf(handlerStart);
		for (Iterator<Unitit = handlerPreds.iterator(); it.hasNext(); ) {
		    Unit pred = it.next();
		    workList.addLast(new CFGEdge(predhandlerStart));
		}
		handlerPreds = getExceptionalPredsOf(handlerStart);
		for (Iterator<Unitit = handlerPreds.iterator(); it.hasNext(); ) {
		    Unit pred = it.next();
		    workList.addLast(new CFGEdge(predhandlerStart));
		}
		if (trapsThatAreHeads.contains(handlerStart)) {
		    workList.addLast(new CFGEdge(nullhandlerStart));
		}
	    }
	}
	// Now for every CFG edge that leads to a handler that may
	// itself throw an exception catchable within the method, add
	// edges from the head of that edge to the unit that catches
	// the handler's exception.
	while (workList.size() > 0) {
	    CFGEdge edgeToThrower = workList.removeFirst();
	    Unit pred = edgeToThrower.head;
	    Unit thrower = edgeToThrower.tail;
	    Collection<ExceptionDestthrowerDests = getExceptionDests(thrower);
	    for (Iterator<ExceptionDesti = throwerDests.iterator(); i.hasNext(); ) {
		ExceptionDest dest = i.next();
		if (dest.getTrap() != null) {
		    Unit handlerStart = dest.getTrap().getHandlerUnit();
		    boolean edgeAdded = false;
		    if (pred == null) {
			if (! trapsThatAreHeads.contains(handlerStart)) {
			    trapsThatAreHeads.add(handlerStart);
			    edgeAdded = true;
			}
		    } else {
			if (! getExceptionalSuccsOf(pred).contains(handlerStart)) {
			    addEdge(unitToSuccsunitToPredspredhandlerStart);
			    edgeAdded = true;
			}
		    }
		    if (edgeAdded && 
			workList.addLast(new CFGEdge(predhandlerStart));
		    }
		}
	    }
	}
	return trapsThatAreHeads;
    }


    

Utility method for checking if a soot.Unit might have side effects. It simply returns true for any unit which invokes a method directly or which might invoke static initializers indirectly (by creating a new object or by refering to a static field; see sections 2.17.4, 2.17.5, and 5.5 of the Java Virtual Machine Specification).

mightHaveSideEffects() is declared package-private so that it is available to unit tests that are part of this package.

Parameters:
u The unit whose potential for side effects is to be checked.
Returns:
whether or not u has the potential for side effects.
    static boolean mightHaveSideEffects(Unit u) {
	    for (Iterator<ValueBoxit = u.getUseBoxes().iterator(); it.hasNext(); ) {
		Value v = it.next().getValue();
		if ((v instanceof StaticFieldRef) || 
		    (v instanceof InvokeExpr) ||
		    (v instanceof NewExpr)) {
		    return true;
		}
	    }
	return false;
    }


    
Utility method for checking if a Unit might throw an exception which may be caught by a soot.Trap within this method.

Parameters:
u The unit for whose exceptions are to be checked
Returns:
whether or not u may throw an exception which may be caught by a Trap in this method,
    private boolean mightThrowToIntraproceduralCatcher(Unit u) {
	for (Iterator<ExceptionDesti = dests.iterator(); i.hasNext(); ) {
	    ExceptionDest dest = i.next();
	    if (dest.getTrap() != null) {
		return true;
	    }
	}
	return false;
    }


    

A placeholder that overrides UnitGraph.buildHeadsAndTails() with a method which always throws an exception. The placeholder serves to indicate that ExceptionalUnitGraph does not use buildHeadsAndTails(), and to document the conditions under which ExceptionalUnitGraph considers a node to be a head or tail.

ExceptionalUnitGraph defines the graph's set of heads to include the first soot.Unit in the graph's body, together with the first Unit in any exception handler which might catch an exception thrown by the first Unit in the body (because any of those Units might be the first to successfully complete execution). ExceptionalUnitGraph defines the graph's set of tails to include all Units which represent some variety of return bytecode or an athrow bytecode whose argument might escape the method.

    protected void buildHeadsAndTails() throws IllegalStateException {
	throw new IllegalStateException("ExceptionalUnitGraph uses buildHeadsAndTails(List) instead of buildHeadsAndTails()");
    }


    
Utility method, to be called only after the unitToPreds and unitToSuccs maps have been built. It defines the graph's set of heads to include the first soot.Unit in the graph's body, together with all the Units in additionalHeads. It defines the graph's set of tails to include all Units which represent some sort of return bytecode or an athrow bytecode which may escape the method.
    private void buildHeadsAndTails(Set<UnitadditionalHeads) {
	List<UnitheadList = new ArrayList<Unit>(additionalHeads.size() + 1);
	headList.addAll(additionalHeads);
	Unit entryPoint = (Unit.getFirst();
	if (! headList.contains(entryPoint)) {
	    headList.add(entryPoint);
	}
	List<UnittailList = new ArrayList<Unit>();
	for (Iterator<Unitit = .iterator(); it.hasNext(); ) {
	    Unit u = (Unitit.next();
	    if (u instanceof soot.jimple.ReturnStmt ||
		u instanceof soot.jimple.ReturnVoidStmt) {
		tailList.add(u);
	    } else if (u instanceof soot.jimple.ThrowStmt) {
		int escapeMethodCount = 0;
		for (Iterator<ExceptionDestdestIt = dests.iterator(); destIt.hasNext(); ) {
		    ExceptionDest dest = destIt.next();
		    if (dest.getTrap() == null) {
			escapeMethodCount++;
		    }
		}
		if (escapeMethodCount > 0) {
		    tailList.add(u);
		}
	    }
	}
	 = Collections.unmodifiableList(tailList);
	 = Collections.unmodifiableList(headList);
    }


    
Returns a collection of ExceptionDest objects which represent how exceptions thrown by a specified unit will be handled.

Parameters:
u The unit for which to provide exception information. (u must be a Unit, though the parameter is declared as an Object to satisfy the interface of ExceptionalGraph.
Returns:
a collection of ExceptionDest objects describing the traps, if any, which catch the exceptions which may be thrown by u.
	if (result == null) {
	    result = new LinkedList<ExceptionDest>();
	    result.add(new ExceptionDest(null.mightThrow((Unitu)));
	}
	return result;
    }
    
    public static class ExceptionDest implements ExceptionalGraph.ExceptionDest<Unit> {
	private Trap trap;
	protected ExceptionDest(Trap trapThrowableSet throwables) {
	    this. = trap;
	    this. = throwables;
	}
	public Trap getTrap() {
	    return ;
	}
	    return ;
	}
	public Unit getHandlerNode() {
	    if ( == null) {
		return null;
	    } else {
	    }
	}
	public String toString() {
	    StringBuffer buf = new StringBuffer();
	    buf.append(.toString());
	    buf.append(" -> ");
	    if ( == null) {
		buf.append("(escapes)");
	    } else {
	    }
	    return buf.toString();
	}
    }
    public List<UnitgetUnexceptionalPredsOf(Unit u) {
	    throw new RuntimeException("Invalid unit " + u);
    }
    public List<UnitgetUnexceptionalSuccsOf(Unit u) {
	    throw new RuntimeException("Invalid unit " + u);
    }
    public List<UnitgetExceptionalPredsOf(Unit u) {
	    return Collections.emptyList();
else {
	    return (List<Unit>) .get(u);
	}
    }
    public List<UnitgetExceptionalSuccsOf(Unit u) {
	    return Collections.emptyList();
else {
	    return (List<Unit>) .get(u);
	}
    }


    

Return the soot.toolkits.exceptions.ThrowAnalysis used to construct this graph, if the graph contains no soot.Traps, or null if the graph does contain Traps. A reference to the ThrowAnalysis is kept when there are no Traps so that the graph can generate responses to getExceptionDests(soot.Unit) on the fly, rather than precomputing information that may never be needed.

This method is package-private because it exposes a detail of the implementation of ExceptionalUnitGraph so that the ExceptionalBlockGraph constructor can cache the same ThrowAnalysis for the same purpose.

Returns:
the soot.toolkits.exceptions.ThrowAnalysis used to generate this graph if the graph contains no soot.Traps, or null if the graph contains one or more soot.Traps.
    }
    public String toString() {
        Iterator<Unitit = .iterator();
        StringBuffer buf = new StringBuffer();
        while(it.hasNext()) {
            Unit u = it.next();
            
            buf.append("  preds: "+getPredsOf(u)+"\n");
            buf.append("  unexceptional preds: "+getUnexceptionalPredsOf(u)+"\n");
            buf.append("  exceptional preds: "+getExceptionalPredsOf(u)+"\n");
            buf.append(u.toString() + '\n');
	        buf.append("  exception destinations: "+getExceptionDests(u)+"\n");
            buf.append("  unexceptional succs: "+getUnexceptionalSuccsOf(u)+"\n");
            buf.append("  exceptional succs: "+getExceptionalSuccsOf(u)+"\n");
            buf.append("  succs "+getSuccsOf(u)+"\n\n");
        }
        
        return buf.toString();
    }
New to GrepCode? Check out our FAQ X