Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /* Soot - a J*va Optimization Framework
    * Copyright (C) 2003 John Jorgensen
    *
    * This library is free software; you can redistribute it and/or
    * modify it under the terms of the GNU Library General Public
    * License as published by the Free Software Foundation; either
    * version 2 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
   * Library General Public License for more details.
   *
   * You should have received a copy of the GNU Library 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.exceptions;
  
  import soot.*;
  
  import java.util.*;

A class for representing the set of exceptions that an instruction may throw.

ThrowableSet does not implement the java.util.Set interface, so perhaps it is misnamed. Instead, it provides only the operations that we require for determining whether a given statement might throw an exception that would be caught by a given handler.

There is a limitation on the combinations of operations permitted on a ThrowableSet. The ThrowableSets returned by whichCatchableAs(soot.RefType) cannot be involved in subsequent add() or whichCatchableAs() operations. That is, given

p = s.whichCatchableAs(r)
for any ThrowableSet s and RefType r, and
t == p.getUncaught() or t == p.getCaught()
then calls to t.add(r), t.add(a), and s.add(t), will throw an ThrowableSet.AlreadyHasExclusionsException, for any RefType r, soot.AnySubType a, and ThrowableSet t.

Actually the restrictions implemented are not quite so strict (there are some combinations of whichCatchableAs() followed by add() which will not raise an exception), but a more accurate description would require reference to the internals of the current implementation. The restrictions should not be too onerous for ThrowableSet's anticipated uses: we expect ThrowableSets to grow by accumulating all the exception types that a given soot.Unit may throw, then, shrink as the types caught by different exception handlers are removed to yield the sets representing exceptions which escape those handlers.

The ThrowableSet class is intended to be immutable (hence the final modifier on its declaration). It does not take the step of guaranteeing immutability by cloning the RefLikeType objects it contains, though, because we trust soot.Scene to enforce the existence of only one RefLikeType instance with a given name.

  
  
  public final class ThrowableSet {
  
      private static final boolean INSTRUMENTING = true;

    
Singleton class for fields and initializers common to all ThrowableSet objects (i.e., these would be static fields and initializers, in the absence of soot's soot.G and soot.Singletons classes).
  
      public static class Manager {

Map from java.lang.Integers representing set size to all ThrowableSets of that size.
  
  	private final Map<IntegerListsizeToSets = new HashMap<IntegerList>();

ThrowableSet containing no exception classes.
 
 	public final ThrowableSet EMPTY;

ThrowableSet representing all possible Throwables.
 
ThrowableSet containing all the asynchronous and virtual machine errors, which may be thrown by any bytecode instruction at any point in the computation.
 
ThrowableSet containing all the exceptions that may be thrown in the course of resolving a reference to another class, including the process of loading, preparing, and verifying the referenced class.
 
ThrowableSet containing all the exceptions that may be thrown in the course of resolving a reference to a field.
 
ThrowableSet containing all the exceptions that may be thrown in the course of resolving a reference to a non-static method.
 
ThrowableSet containing all the exceptions which may be thrown by instructions that have the potential to cause a new class to be loaded and initialized (including UnsatisfiedLinkError, which is raised at runtime rather than linking type).
 
 
 
 	// counts for instrumenting:
 	private int registeredSets = 0;
 	private int addsOfRefType = 0;
 	private int addsOfAnySubType = 0;
 	private int addsOfSet = 0;
 	private int addsInclusionFromMap = 0;
 	private int addsInclusionFromMemo = 0;
 	private int addsInclusionFromSearch = 0;
 	private int addsInclusionInterrupted = 0;
 	private int addsExclusionWithSearch = 0;
 	private int addsExclusionWithoutSearch = 0;
 	private int removesOfAnySubType = 0;
 	private final int removesFromMap = 0;
 	private final int removesFromMemo = 0;
 	private int removesFromSearch = 0;
 	private int registrationCalls = 0;
 	private int catchableAsQueries = 0;
 	private int catchableAsFromMap = 0;
 	private int catchableAsFromSearch = 0;

Constructs a ThrowableSet.Manager for inclusion in Soot's global variable manager, soot.G.

Parameters:
g guarantees that the constructor may only be called from soot.Singletons.
 
 	public ManagerSingletons.Global g ) {
 	    // First ensure the Exception classes are represented in Soot.
 
 	    // Runtime errors:
 	     =
 		Scene.v().getRefType("java.lang.RuntimeException");
 		Scene.v().getRefType("java.lang.ArithmeticException");
 	     = 
 		Scene.v().getRefType("java.lang.ArrayStoreException");
 		Scene.v().getRefType("java.lang.ClassCastException");
              = 
                 Scene.v().getRefType("java.lang.IllegalMonitorStateException");
 		Scene.v().getRefType("java.lang.IndexOutOfBoundsException");
 		Scene.v().getRefType("java.lang.ArrayIndexOutOfBoundsException");
 		Scene.v().getRefType("java.lang.NegativeArraySizeException");	    
 		Scene.v().getRefType("java.lang.NullPointerException");
 
 		Scene.v().getRefType("java.lang.InstantiationError");
 
 	     = registerSetIfNew(nullnull);
 
 	    Set allThrowablesSet = new HashSet();
 	    allThrowablesSet.add(AnySubType.v(Scene.v().getRefType("java.lang.Throwable")));
 	     = registerSetIfNew(allThrowablesSetnull);
 
 	    Set vmErrorSet = new HashSet();
 	    vmErrorSet.add(Scene.v().getRefType("java.lang.InternalError"));
 	    vmErrorSet.add(Scene.v().getRefType("java.lang.OutOfMemoryError"));
 	    vmErrorSet.add(Scene.v().getRefType("java.lang.StackOverflowError"));
 	    vmErrorSet.add(Scene.v().getRefType("java.lang.UnknownError"));
 
 	    // The Java library's deprecated Thread.stop(Throwable) method
 	    // would actually allow _any_ Throwable to be delivered
 	    // asynchronously, not just java.lang.ThreadDeath.
 	    vmErrorSet.add(Scene.v().getRefType("java.lang.ThreadDeath"));
 
 	     = registerSetIfNew(vmErrorSetnull);
 
 	    Set resolveClassErrorSet = new HashSet();
 	    resolveClassErrorSet.add(Scene.v().getRefType("java.lang.ClassCircularityError"));
 	    // We add AnySubType(ClassFormatError) so that we can
 	    // avoid adding its subclass,
 	    // UnsupportedClassVersionError, explicitly.  This is a
 	    // hack to allow Soot to analyze older class libraries 
 	    // (UnsupportedClassVersionError was added in JDK 1.2).
 	    if(!Options.v().j2me()) 
 	    	resolveClassErrorSet.add(AnySubType.v(Scene.v().getRefType("java.lang.ClassFormatError")));
 	    resolveClassErrorSet.add(Scene.v().getRefType("java.lang.IllegalAccessError"));
 	    resolveClassErrorSet.add(Scene.v().getRefType("java.lang.IncompatibleClassChangeError"));
 	    resolveClassErrorSet.add(Scene.v().getRefType("java.lang.LinkageError"));
 	    resolveClassErrorSet.add(Scene.v().getRefType("java.lang.NoClassDefFoundError"));
 	    resolveClassErrorSet.add(Scene.v().getRefType("java.lang.VerifyError"));
 	     = registerSetIfNew(resolveClassErrorSetnull);
 
 	    Set resolveFieldErrorSet = new HashSet(resolveClassErrorSet);
 	    resolveFieldErrorSet.add(Scene.v().getRefType("java.lang.NoSuchFieldError"));
 	     = registerSetIfNew(resolveFieldErrorSetnull);
 
 	    Set resolveMethodErrorSet = new HashSet(resolveClassErrorSet);
 	    resolveMethodErrorSet.add(Scene.v().getRefType("java.lang.AbstractMethodError"));
 	    resolveMethodErrorSet.add(Scene.v().getRefType("java.lang.NoSuchMethodError"));
 	    resolveMethodErrorSet.add(Scene.v().getRefType("java.lang.UnsatisfiedLinkError"));
 	     = registerSetIfNew(resolveMethodErrorSetnull);
 
 	    // The static initializers of a newly loaded class might
 	    // throw any Error (if they threw an Exception---even a
 	    // RuntimeException---it would be replaced by an
 	    // ExceptionInInitializerError):
 	    //
 	    Set initializationErrorSet = new HashSet();
 	    initializationErrorSet.add(AnySubType.v(Scene.v().getRefType("java.lang.Error")));
 	     = registerSetIfNew(initializationErrorSetnull);
 	}


Returns the single instance of ThrowableSet.Manager.

Returns:
Soot's ThrowableSet.Manager.
 
 	public static Manager v() { 
 	}


Returns a ThrowableSet representing the set of exceptions included in include minus the set of exceptions included in exclude. Creates a new ThrowableSet only if there was not already one whose contents correspond to include - exclude.

Parameters:
include A set of soot.RefLikeType objects representing exception types included in the result; may be null if there are no included types.
exclude A set of soot.AnySubType objects representing exception types excluded from the result; may be null if there are no excluded types.
Returns:
a ThrowableSet representing the set of exceptions corresponding to include - exclude.
 
 	private ThrowableSet registerSetIfNew(Set includeSet exclude) {
 	    if () {
 	    }
 	    if (include == null) {
 		include = .;
 	    }
 	    if (exclude == null) {
 		exclude = .;
 	    }
 	    int size = include.size() + exclude.size();
 	    Integer sizeKey = new Integer(size);
 
 	    List<ThrowableSetsizeList = .get(sizeKey);
 	    if (sizeList == null) {
 		sizeList = new LinkedList<ThrowableSet>();
 		.put(sizeKeysizeList);
 	    }
 	    for (ThrowableSet set : sizeList) {
 		if (set.exceptionsIncluded.equals(include
 		    && set.exceptionsExcluded.equals(exclude)) {
 		    return set;
 		}
 	    }
 	    if () {
 	    }
 	    ThrowableSet result = new ThrowableSet(includeexclude);
 	    sizeList.add(result);
 	    return result;
 	}


Report the counts collected by instrumentation (for now, at least, there is no need to provide access to the individual values as numbers).

Returns:
a string listing the counts.
 
 	    int setCount = 0;
 	    for (List sizeList : .values()) {
 		setCount += sizeList.size();
 	    }
 	    if (setCount != ) {
 		throw new IllegalStateException("ThrowableSet.reportInstrumentation() assertion failure: registeredSets != list count");
 	    }
 	    StringBuffer buf = new StringBuffer("registeredSets: ")
 		.append(setCount)
 		.append("\naddsOfRefType: ")
 		.append("\naddsOfAnySubType: ")
 		.append("\naddsOfSet: ")
 		.append("\naddsInclusionFromMap: ")
 		.append("\naddsInclusionFromMemo: ")
 		.append("\naddsInclusionFromSearch: ")
 		.append("\naddsInclusionInterrupted: ")
 		.append("\naddsExclusionWithoutSearch: ")
 		.append("\naddsExclusionWithSearch: ")
 		.append("\nremovesOfAnySubType: ")
 		.append("\nremovesFromMap: ")
 		.append("\nremovesFromMemo: ")
 		.append("\nremovesFromSearch: ")
 		.append("\nregistrationCalls: ")
 		.append("\ncatchableAsQueries: ")
 		.append("\ncatchableAsFromMap: ")
 		.append("\ncatchableAsFromSearch: ")
 		.append('\n');
 	    return buf.toString();
 	}

A package-private method to provide unit tests with access to the collection of ThrowableSets.
 
 	    return Manager.v().;
 	}
     }
 
 
     public static class AlreadyHasExclusionsException extends IllegalStateException {
 	    super(s);
 	}
     }


    
Set of exception types included within the set.
 
     private final Set exceptionsIncluded;

    
Set of exception types which, though members of exceptionsIncluded, are to be excluded from the types represented by this ThrowableSet. To simplify the implementation, once a ThrowableSet has any excluded types, the various add() methods of this class must bar additions of subtypes of those excluded types.
 
     private final Set exceptionsExcluded;

    
A map from (soot.RefLikeType \\union ThrowableSet) to ThrowableSet. If the mapping (k,v) is in memoizedAdds and k is a ThrowableSet, then v is the set that results from adding all elements in k to this. If (k,v) is in memoizedAdds and k is a soot.RefLikeType, then v is the set that results from adding k to this.
 
     private Map<Object,ThrowableSetmemoizedAdds;
 
     private ThrowableSet getMemoizedAdds(Object key) {
 	if ( == null) {
 	     = new HashMap();
 	}
 	return .get(key);
     }


    
Constructs a ThrowableSet which contains the exception types represented in include, except for those which are also in exclude. The constructor is private to ensure that the only way to get a new ThrowableSet is by adding elements to or removing them from an existing set.

Parameters:
include The set of soot.RefType and soot.AnySubType objects representing the types to be included in the set.
exclude The set of soot.AnySubType objects representing the types to be excluded from the set.
 
     private ThrowableSet(Set includeSet exclude) {
 	 = Collections.unmodifiableSet(include);
 	 = Collections.unmodifiableSet(exclude);
 	// We don't need to clone include and exclude to guarantee
 	// immutability since ThrowableSet(Set,Set) is private to this
 	// class, where it is only called (via
 	// Manager.v().registerSetIfNew()) with arguments which the
 	// callers do not subsequently modify.
     }


    
Returns a ThrowableSet which contains e in addition to the exceptions in this ThrowableSet.

Add e as a soot.RefType when you know that the run-time class of the exception you are representing is necessarily e and cannot be a subclass of e.

For example, if you were recording the type of the exception thrown by

 throw new IOException("Permission denied");
 
you would call
 add(Scene.v().getRefType("java.lang.Exception.IOException"))
 
since the class of the exception is necessarily IOException.

Parameters:
e the exception class
Returns:
a set containing e as well as the exceptions in this set.
Throws:
ThrowableSet.IllegalStateException if this ThrowableSet is the result of a whichCatchableAs(soot.RefType) operation and, thus, unable to represent the addition of e.
 
     public ThrowableSet add(RefType e
 	if () {
 	    Manager.v().++;
 	}
 	if (this..contains(e)) {
 	    if () {
 		Manager.v().++;
 	    }
 	    return this
 	} else {
 	    ThrowableSet result = getMemoizedAdds(e);
 	    if (result != null) {
 		if () {
 		    Manager.v().++;
 		    Manager.v().++;
 		}
 		return result;
 	    } else {
 		if () {
 		    Manager.v().++;
 		    if (.size() != 0) {
 		    } else {
 		    }
 		}
 		FastHierarchy hierarchy = Scene.v().getOrMakeFastHierarchy();
 
 		for (Iterator i = .iterator(); i.hasNext(); ) {
 		    RefType exclusionBase = ((AnySubTypei.next()).getBase();
 		    if (hierarchy.canStoreType(eexclusionBase)) {
 			    "ThrowableSet.add(RefType): adding" + e.toString() 
 			    + " to the set [ " + this.toString()
 			    + "] where " + exclusionBase.toString() 
 			    + " is excluded.");
 		    }
 		}
 
 		for (Iterator i = .iterator(); i.hasNext() ; ) {
 		    RefLikeType incumbent = (RefLikeTypei.next();
 		    if (incumbent instanceof AnySubType) {
 			// Need to use incumbent.getBase() because
 			// hierarchy.canStoreType() assumes that parent
 			// is not an AnySubType.
 			RefType incumbentBase = ((AnySubTypeincumbent).getBase();
 			if (hierarchy.canStoreType(eincumbentBase)) {
 			    .put(ethis);
 			    return this;
 			}
 		    } else if (! (incumbent instanceof RefType)) {
 			// assertion failure.
 			throw new IllegalStateException("ThrowableSet.add(RefType): Set element " +
 							incumbent.toString() +
 							" is neither a RefType nor an AnySubType.");
 		    }
 		}
 		Set  resultSet = new HashSet(this.);
 		resultSet.add(e);
 		result = Manager.v().registerSetIfNew(resultSet
 						      this.);
 		.put(eresult);
 		return result;
 	    }
 	}
     }


    
Returns a ThrowableSet which contains e and all of its subclasses as well as the exceptions in this set.

e should be an instance of soot.AnySubType if you know that the compile-time type of the exception you are representing is e, but the exception may be instantiated at run-time by a subclass of e.

For example, if you were recording the type of the exception thrown by

 catch (IOException e) {
    throw e;
 }
 
you would call
 add(AnySubtype.v(Scene.v().getRefType("java.lang.Exception.IOException")))
 
since the handler might rethrow any subclass of IOException.

Parameters:
e represents a subtree of the exception class hierarchy to add to this set.
Returns:
a set containing e and all its subclasses, as well as the exceptions represented by this set.
Throws:
ThrowableSet.AlreadyHasExclusionsException if this ThrowableSet is the result of a whichCatchableAs(soot.RefType) operation and, thus, unable to represent the addition of e.
 
     public ThrowableSet add(AnySubType e
 	if () {
 	    Manager.v().++;
 	}
 
 	ThrowableSet result = getMemoizedAdds(e);
 	if (result != null) {
 	    if () {
 		Manager.v().++;
 	    }
 	    return result;
 	} else {
 	    FastHierarchy hierarchy = Scene.v().getOrMakeFastHierarchy();
 	    RefType newBase = e.getBase(); 
 
 	    if () {
 		if (.size() != 0) {
 		    Manager.v().++;
 		} else {
 		    Manager.v().++;
 		}
 	    }
 	    for (Iterator i = .iterator(); i.hasNext(); ) {
 		RefType exclusionBase = ((AnySubTypei.next()).getBase();
 		if (hierarchy.canStoreType(newBaseexclusionBase)
 		    || hierarchy.canStoreType(exclusionBasenewBase)) {
 		    if () {
 			// To ensure that the subcategories total properly:
 		    }
 		    throw new AlreadyHasExclusionsException(
 			"ThrowableSet.add(" + e.toString() 
 			+ ") to the set [ " + this.toString()
 			+ "] where " + exclusionBase.toString() 
 			+ " is excluded.");
 		}
 	    }
 
 	    if (this..contains(e)) {
 		if () {
 		    Manager.v().++;
 		}
 		return this
 
 	    } else {
 		if () {
 		    Manager.v().++;
 		}
 
 		int changes = 0;
 		boolean addNewException = true;
 		Set  resultSet = new HashSet();
 
 		for (Iterator i = this..iterator(); i.hasNext() ; ) {
 		    RefLikeType incumbent = (RefLikeTypei.next();
 		    if (incumbent instanceof RefType) {
 			if (hierarchy.canStoreType(incumbentnewBase)) {
 			    // Omit incumbent from result.
 			    changes++;
 			} else {
 			    resultSet.add(incumbent);
 			}
 		    } else if (incumbent instanceof AnySubType) {
 			RefType incumbentBase = ((AnySubTypeincumbent).getBase();
 			// We have to use the base types in these hierarchy calls
 			// because we want to know if _all_ possible
 			// types represented by e can be represented by
 			// the incumbent, or vice versa.
 			if (hierarchy.canStoreType(newBaseincumbentBase)) {
 			    addNewException = false;
 			    resultSet.add(incumbent);
 			} else if (hierarchy.canStoreType(incumbentBasenewBase)) {
 			    // Omit incumbent from result;
 			    changes++;
 			} else {
 			    resultSet.add(incumbent);
 			}
 		    } else { // assertion failure.
 			throw new IllegalStateException("ThrowableSet.add(AnySubType): Set element " +
 							incumbent.toString() + 
 							" is neither a RefType nor an AnySubType.");
 		    }
 		}
 		if (addNewException) {
 		    resultSet.add(e);
 		    changes++;
 		}
 		if (changes > 0) {
 		    result = Manager.v().registerSetIfNew(resultSet
 							  this.);
 		} else {
 		    result = this;
 		}
 		.put(eresult);
 		return result;
 	    }
 	}
     }


    
Returns a ThrowableSet which contains all the exceptions in s in addition to those in this ThrowableSet.

Parameters:
s set of exceptions to add to this set.
Returns:
the union of this set with s
Throws:
ThrowableSet.AlreadyHasExclusionsException if this ThrowableSet or s is the result of a whichCatchableAs(soot.RefType) operation, so that it is not possible to represent the addition of s to this ThrowableSet.
 
     public ThrowableSet add(ThrowableSet s)
 	if () {
 	    Manager.v().++;
 	}
 	if (.size() > 0 || s.exceptionsExcluded.size() > 0) {
 	    throw new AlreadyHasExclusionsException("ThrowableSet.Add(ThrowableSet): attempt to add to [" + this.toString() + "] after removals recorded.");
 	}
 	ThrowableSet result = getMemoizedAdds(s);
 	if (result == null) {
 	    if () {
 	    }
 	    result = this.add(s.exceptionsIncluded);
 	    .put(sresult);
 	} else if () {
 	    Manager.v().++;
 	    Manager.v().++;
 	}
 	return result;
     }


    
Returns a ThrowableSet which contains all the exceptions in addedExceptions in addition to those in this ThrowableSet.

Parameters:
addedExceptions a set of soot.RefLikeType and soot.AnySubType objects to be added to the types included in this ThrowableSet.
Returns:
a set containing all the addedExceptions as well as the exceptions in this set.
 
     private ThrowableSet add(Set addedExceptions) {
 	Set resultSet = new HashSet(this.);
 	int changes = 0;
 	FastHierarchy hierarchy = Scene.v().getOrMakeFastHierarchy();
 
 	// This algorithm is O(n m), where n and m are the sizes of the
 	// two sets, so hope that the sets are small.
 
 	for (Iterator i = addedExceptions.iterator(); i.hasNext(); ) {
 	    RefLikeType newType = (RefLikeTypei.next();
 	    if (! resultSet.contains(newType)) {
 		boolean addNewType = true;
 		if (newType instanceof RefType) {
 		    for (Iterator j = resultSet.iterator(); j.hasNext(); ) {
 			RefLikeType incumbentType = (RefLikeTypej.next();
 			if (incumbentType instanceof RefType) {
 			    if (newType == incumbentType) {
 				// assertion failure.
 				throw new IllegalStateException("ThrowableSet.add(Set): resultSet.contains() failed to screen duplicate RefType "
 								+ newType);
 			    }
 			} else if (incumbentType instanceof AnySubType) {
 			    RefType incumbentBase = ((AnySubTypeincumbentType).getBase();
 			    if (hierarchy.canStoreType(newTypeincumbentBase)) {
 				// No need to add this class.
 				addNewType = false;
 			    }
 			} else { // assertion failure.
 			    throw new IllegalStateException("ThrowableSet.add(Set): incumbent Set element " 
 							    + incumbentType 
 							    + " is neither a RefType nor an AnySubType.");
 			}
 		    }
 		} else if (newType instanceof AnySubType) {
 		    RefType newBase = ((AnySubTypenewType).getBase();
 		    for (Iterator j = resultSet.iterator(); j.hasNext(); ) {
 			RefLikeType incumbentType = (RefLikeTypej.next();
 			if (incumbentType instanceof RefType) {
 			    RefType incumbentBase = (RefTypeincumbentType;
 			    if (hierarchy.canStoreType(incumbentBasenewBase)) {
 				j.remove();
 				changes++;
 			    }
 			} else if (incumbentType instanceof AnySubType) {
 			    RefType incumbentBase = ((AnySubTypeincumbentType).getBase();
 			    if (newBase == incumbentBase) {
 				// assertion failure.
 				throw new IllegalStateException("ThrowableSet.add(Set): resultSet.contains() failed to screen duplicate AnySubType "
 							   + newBase);
 			    } else if (hierarchy.canStoreType(incumbentBasenewBase)) {
 				j.remove();
 				changes++;
 			    } else if (hierarchy.canStoreType(newBaseincumbentBase)) {
 				// No need to add this class.
 				addNewType = false;
 			    }
 			} else { // assertion failure.
 			    throw new IllegalStateException("ThrowableSet.add(Set): old Set element "
 						       + incumbentType
 						       + " is neither a RefType nor an AnySubType.");
 			}
 		    }
 		} else { // assertion failure.
 		    throw new IllegalArgumentException("ThrowableSet.add(Set): new Set element " 
 						       + newType
 						       + " is neither a RefType nor an AnySubType.");
 		}
 		if (addNewType) {
 		    changes++;
 		    resultSet.add(newType);
 		}
 	    }
 	}
 			    
 	ThrowableSet result = null;
 	if (changes > 0) {
 	    result = Manager.v().registerSetIfNew(resultSet
 						  this.);
 	} else {
 	    result = this;
 	}
 	return result;
     }


    
Indicates whether this ThrowableSet includes some exception that might be caught by a handler argument of the type catcher.

Parameters:
catcher type of the handler parameter to be tested.
Returns:
true if this set contains an exception type that might be caught by catcher, false if it does not.
 
     public boolean catchableAs(RefType catcher) {
 	if () {
 	    Manager.v().++;
 	}
 
 
 	if (.size() > 0) {
 	    if () {
 		Manager.v().++;
 	    }
 	    for (Iterator i = .iterator(); i.hasNext(); ) {
 		AnySubType exclusion = (AnySubTypei.next();
 		if (h.canStoreType(catcherexclusion.getBase())) {
 		    return false;
 		}
 	    }
 	}
 
 	if (.contains(catcher)) {
 	    if () {
 		if (.size() == 0) {
 		    Manager.v().++;
 		} else {
 		    Manager.v().++;
 		}
 	    }
 	    return true;
 	} else {
 	    if () {
 		if (.size() == 0) {
 		    Manager.v().++;
 		}
 	    }
 	    for (Iterator i = .iterator(); i.hasNext(); ) {
 		RefLikeType thrownType = (RefLikeTypei.next();
 		if (thrownType instanceof RefType) {
 		    if (thrownType == catcher) {
 			// assertion failure.
 			throw new IllegalStateException("ThrowableSet.catchableAs(RefType): exceptions.contains() failed to match contained RefType "
 							   + catcher);
 		    } else if (h.canStoreType(thrownTypecatcher)) {
 			return true;
 		    }
 		} else {
 		    RefType thrownBase = ((AnySubTypethrownType).getBase();
 		    // At runtime, thrownType might be instantiated by any
 		    // of thrownBase's subtypes, so:
 		    if (h.canStoreType(thrownBasecatcher)
 			|| h.canStoreType(catcherthrownBase)) {
 			return true;
 		    }
 		}
 	    }
 	    return false;
 	}
     }


    
Partitions the exceptions in this ThrowableSet into those which would be caught by a handler with the passed catch parameter type and those which would not.

Parameters:
catcher type of the handler parameter to be tested.
Returns:
a pair of ThrowableSets, one containing the types in this ThrowableSet which would be be caught as catcher and the other containing the types in this ThrowableSet which would not be caught as catcher.
 
     public Pair whichCatchableAs(RefType catcher) {
 	if () {
 	    Manager.v().++;
 	}
 
 	Set caughtIncluded = null;
 	Set caughtExcluded = null;
 	Set uncaughtIncluded = null;
 	Set uncaughtExcluded = null;
 
 	if () {
 	    Manager.v().++;
 	}
 
 	for (Iterator i = .iterator(); i.hasNext(); ) {
 	    AnySubType exclusion = (AnySubTypei.next();
 	    RefType exclusionBase = exclusion.getBase();
 	    if (h.canStoreType(catcherexclusionBase)) {
 		// Because the add() operations ban additions to sets
 		// with exclusions, we can be sure no types in this are
 		// caught by catcher.
 		return new Pair(ThrowableSet.Manager.v().this);
 	    } else if (h.canStoreType(exclusionBasecatcher)) {
 		// exclusion wouldn't be in exceptionsExcluded if one
 		// of its supertypes were not in exceptionsIncluded,
 		// so we know the next loop will add either that supertype 
 		// or catcher to caughtIncluded.  Thus:
 		caughtExcluded = addExceptionToSet(exclusioncaughtExcluded);
 	    } else {
 		uncaughtExcluded = addExceptionToSet(exclusionuncaughtExcluded);
 	    }
 	}
 
 	for (Iterator i = .iterator(); i.hasNext(); ) {
 	    RefLikeType inclusion = (RefLikeTypei.next();
 	    if (inclusion instanceof RefType) {
 		if (h.canStoreType(inclusioncatcher)) {
 		    caughtIncluded = addExceptionToSet(inclusioncaughtIncluded);
 		} else {
 		    uncaughtIncluded = addExceptionToSet(inclusionuncaughtIncluded);
 		}
 	    } else {
 		RefType base = ((AnySubTypeinclusion).getBase();
 		if (h.canStoreType(basecatcher)) {
 		    // All subtypes of base will be caught.  Any exclusions
 		    // will already have been copied to caughtExcluded by
 		    // the preceding loop.
 		    caughtIncluded = 
 			addExceptionToSet(inclusioncaughtIncluded);
 		} else if (h.canStoreType(catcherbase)) {
 		    // Some subtypes of base will be caught, and
 		    // we know that not all of those catchable subtypes
 		    // are among exceptionsExcluded, since in that case we
 		    // would already have returned from within the 
 		    // preceding loop.  So, remove AnySubType(catcher)
 		    // from the uncaught types.
 		    uncaughtIncluded 
 			= addExceptionToSet(inclusionuncaughtIncluded);
 		    uncaughtExcluded 
 			= addExceptionToSet(AnySubType.v(catcher), uncaughtExcluded);
 		    caughtIncluded 
 			= addExceptionToSet(AnySubType.v(catcher), caughtIncluded);
 		    // Any already excluded subtypes of inclusion
 		    // which are subtypes of catcher will have been
 		    // added to caughtExcluded by the previous loop.
else {
		    uncaughtIncluded 
addExceptionToSet(inclusionuncaughtIncluded);
	    }
	ThrowableSet caughtSet 
	    = Manager.v().registerSetIfNew(caughtIncludedcaughtExcluded);
	ThrowableSet uncaughtSet 
	    = Manager.v().registerSetIfNew(uncaughtIncludeduncaughtExcluded);
	return new Pair(caughtSetuncaughtSet);
    }


    
The return type for ThrowableSet.whichCatchableAs(soot.RefType), consisting of a pair of ThrowableSets.
    public static class Pair {
Constructs a ThrowableSet.Pair.

Parameters:
caught The set of exceptions to be returned when getCaught() is called on the constructed ThrowableSet.Pair.
uncaught The set of exceptions to be returned when getUncaught() is called on the constructed ThrowableSet.Pair.
	protected Pair(ThrowableSet caughtThrowableSet uncaught) {
	    this. = caught;
	    this. = uncaught;
	}

Returns:
the set of caught exceptions.
	    return ;
	}

Returns:
the set of uncaught exceptions.
	    return ;
	}

Indicates whether two java.lang.Objects are ThrowableSet.Pairs representing the same set of caught and uncaught exception types.

Parameters:
o the Object to compare to this ThrowableSet.Pair.
Returns:
true if o is a ThrowableSet.Pair representing the same set of caught and uncaught types as this ThrowableSet.Pair.
	public boolean equals(Object o) {
	    if (o == this) {
		return true;
	    }
	    if (! (o instanceof Pair)) {
		return false;
	    }
	    Pair tsp = (Pairo;
	    if (   this..equals(tsp.caught)
		&& this..equals(tsp.uncaught)) {
		return true;
	    }
	    return false;
	public int hashCode() {
	    int result = 31;
	    result = 37 * result + .hashCode();
	    result = 37 * result + .hashCode();
	    return result;
    }


    
Utility method for building sets of exceptional types for a ThrowableSet.Pair.

Parameters:
e The exceptional type to add to the set.
set The Set to which to add the types, or null if no Set has yet been allocated.
Returns:
A Set containing the elements in set plus e.
    private Set addExceptionToSet(RefLikeType eSet set) {
	if (set == null) {
	    set = new HashSet();
	set.add(e);
	return set;
    }


    
Returns a string representation of this ThrowableSet.
    public String toString() {
	StringBuffer buffer = new StringBuffer(this.toBriefString());
	buffer.append(":\n  ");
	for (Iterator i = .iterator(); i.hasNext(); ) {
	    buffer.append('+');
	    Object o = i.next();
	    buffer.append(o == null ? "null" : o.toString());
	    // buffer.append(i.next().toString());
	for (Iterator i = .iterator(); i.hasNext(); ) {
	    buffer.append('-');
	    buffer.append(i.next().toString());
	return buffer.toString();
    }


    
Returns a cryptic identifier for this ThrowableSet, used to identify a set when it appears in a collection.
    public String toBriefString() {
	return super.toString();
    }


    
Returns an java.util.Iterator over a java.util.Collection of Throwable types which iterates over its elements in a consistent order (maintaining an ordering that is consistent across different runs makes it easier to compare sets generated by different implementations of the CFG classes).

Parameters:
coll The collection to iterate over.
Returns:
An iterator which presents the elements of coll in order.
    private static Iterator sortedThrowableIterator(Collection coll) {
	if (coll.size() <= 1) {
	    return coll.iterator();
else {
	    Object array[] = coll.toArray();
	    Arrays.sort(arraynew ThrowableComparator());
	    return Arrays.asList(array).iterator();
    }


    
Comparator used to implement sortedThrowableIterator().
    private static class ThrowableComparator implements java.util.Comparator {
	private static RefType baseType(Object o) {
	    if (o instanceof AnySubType) {
		return ((AnySubTypeo).getBase();
	    } else {
		return (RefTypeo// ClassCastException if o is not a RefType.
	    }
	public int compare(Object o1Object o2) {
	    RefType t1 = baseType(o1);
	    RefType t2 = baseType(o2);
	    if (t1.equals(t2)) {
		// There should never be both AnySubType(t) and
		// t in a ThrowableSet, but if it happens, put 
		// AnySubType(t) first:
		if (o1 instanceof AnySubType) {
		    if (o2 instanceof AnySubType) {
			return 0;
		    } else {
			return -1;
		    }
else if (o2 instanceof AnySubType) {
		    return 1;
else {
		    return 0;
	    } else {
		return t1.toString().compareTo(t2.toString());
	    }
	public boolean equal(Object o1Object o2) {
	    return (o1.equals(o2));
    }


    

Produce an abbreviated representation of this ThrowableSet, suitable for human consumption. The abbreviations include:

  • The strings “java.lang.” is stripped from the beginning of exception names.
  • The string “Exception” is stripped from the ends of exception names.
  • Instances of AnySubType are indicated by surrounding the base type name with parentheses, rather than with the string “Any_subtype_of_
  • If this ThrowableSet includes all the elements of VM_ERRORS, they are abbreviated as “vmErrors” rather than listed individually.
  • Returns:
    An abbreviated representation of the contents of this set.
    public String toAbbreviatedString() {
    }


    

Utility method which prints the abbreviations of the elements in a passed java.util.Set of exception types.

Parameters:
s The exceptions to print.
connector The character to insert between exceptions.
Returns:
An abbreviated representation of the exceptions.
    private String toAbbreviatedString(Set schar connector) {
	final String JAVA_LANG = "java.lang.";
	final int JAVA_LANG_LENGTH = JAVA_LANG.length();
	final String EXCEPTION = "Exception";
	final  int EXCEPTION_LENGTH = EXCEPTION.length();
	Collection vmErrorThrowables = ThrowableSet.Manager.v()..;
	boolean containsAllVmErrors = s.containsAll(vmErrorThrowables);
	StringBuffer buf = new StringBuffer();
	if (containsAllVmErrors) {
	    buf.append(connector);
	    buf.append("vmErrors");
	for (Iterator it = sortedThrowableIterator(s); it.hasNext(); ) {
	    RefLikeType reflikeType = (RefLikeTypeit.next();
	    RefType baseType = null;
	    if (reflikeType instanceof RefType) {
		baseType = (RefType)reflikeType;
		if (vmErrorThrowables.contains(baseType) && containsAllVmErrors) {
		    continue;		// Already accounted for vmErrors.
else {
		    buf.append(connector);
	    } else if (reflikeType instanceof AnySubType) {
		buf.append(connector);
		buf.append('(');
		baseType = ((AnySubType)reflikeType).getBase();
	    }
	    String typeName = baseType.toString();
	    if (typeName.startsWith(JAVA_LANG)) {
		typeName = typeName.substring(JAVA_LANG_LENGTH);
	    }
	    if (typeName.length() > EXCEPTION_LENGTH && 
		typeName.endsWith(EXCEPTION)) {
		typeName = typeName.substring(0, typeName.length()-EXCEPTION_LENGTH);
	    }
	    buf.append(typeName);
	    if (reflikeType instanceof AnySubType) {
		buf.append(')');
	    }
	return buf.toString();
    }


    
A package-private method to provide unit tests with access to the soot.RefLikeType objects which represent the Throwable types included in this set.

Returns:
an unmodifiable collection view of the Throwable types in this set.
        return new AbstractCollection() {
	    public Iterator iterator() {
		return new Iterator() {
		    private final Iterator i = .iterator();
		    public boolean hasNext() {
			return .hasNext();
		    }
		    public Object next() {
			return .next();
		    }
		    public void remove() {
		    }
		};
	    }
	    public int size() {
	    }
	};
    }


    
A package-private method to provide unit tests with access to the soot.RefLikeType objects which represent the Throwable types excluded from this set.

Returns:
an unmodifiable collection view of the Throwable types excluded from this set.
        return new AbstractCollection() {
	    public Iterator iterator() {
		return new Iterator() {
		    private final Iterator i = .iterator();
		    public boolean hasNext() {
			return .hasNext();
		    }
		    public Object next() {
			return .next();
		    }
		    public void remove() {
		    }
		};
	    }
	    public int size() {
	    }
	};
    }


    
A package-private method to provide unit tests with access to ThrowableSet's internals.
    Map getMemoizedAdds() {
	if ( == null) {
	    return .;
else {
	    return Collections.unmodifiableMap();
    }
New to GrepCode? Check out our FAQ X