diff --git a/src/main/java/soot/toolkits/exceptions/ThrowableSet.java b/src/main/java/soot/toolkits/exceptions/ThrowableSet.java
index 7e4c44ebd58..4e71b7b404d 100644
--- a/src/main/java/soot/toolkits/exceptions/ThrowableSet.java
+++ b/src/main/java/soot/toolkits/exceptions/ThrowableSet.java
@@ -87,11 +87,15 @@
* with a given name.
*
*/
-
public class ThrowableSet {
private static final boolean INSTRUMENTING = false;
- private final SootClass JAVA_LANG_OBJECT_CLASS = Scene.v().getObjectType().getSootClass();
+
+ // This pattern allows for the field to be static but to delay it's
+ // initialization until it's first use.
+ private static final class LazyInit {
+ static final SootClass JAVA_LANG_OBJECT_CLASS = Scene.v().getObjectType().getSootClass();
+ }
/**
* Set of exception types included within the set.
@@ -121,24 +125,23 @@ public class ThrowableSet {
* @param exclude
* The set of {@link AnySubType} objects representing the types to be excluded from the set.
*/
- protected ThrowableSet(Set include, Set exclude) {
+ private ThrowableSet(Set include, Set exclude) {
exceptionsIncluded = getImmutable(include);
exceptionsExcluded = getImmutable(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
+ // 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.
}
private static Set getImmutable(Set in) {
- if ((null == in) || in.isEmpty()) {
+ if (in == null || in.isEmpty()) {
return Collections.emptySet();
- }
- if (1 == in.size()) {
+ } else if (in.size() == 1) {
return Collections.singleton(in.iterator().next());
+ } else {
+ return Collections.unmodifiableSet(in);
}
- return Collections.unmodifiableSet(in);
}
/**
@@ -201,9 +204,9 @@ private void addToMemoizedAdds(Object key, ThrowableSet value) {
*
* @return a set containing e
as well as the exceptions in this set.
*
- * @throws {@link
- * ThrowableSet.IllegalStateException} if this ThrowableSet
is the result of a
- * {@link #whichCatchableAs(RefType)} operation and, thus, unable to represent the addition of e
.
+ * @throws IllegalStateException
+ * if this ThrowableSet
is the result of a {@link #whichCatchableAs(RefType)} operation and, thus,
+ * unable to represent the addition of e
.
*/
public ThrowableSet add(RefType e) throws ThrowableSet.AlreadyHasExclusionsException {
if (INSTRUMENTING) {
@@ -275,7 +278,7 @@ public ThrowableSet add(RefType e) throws ThrowableSet.AlreadyHasExclusionsExcep
private boolean hasNoHierarchy(RefType type) {
final SootClass sootClass = type.getSootClass();
- return !(sootClass.hasSuperclass() || JAVA_LANG_OBJECT_CLASS == sootClass);
+ return !(sootClass.hasSuperclass() || LazyInit.JAVA_LANG_OBJECT_CLASS == sootClass);
}
/**
@@ -535,14 +538,7 @@ private ThrowableSet add(Set addedExceptions) {
}
}
}
-
- ThrowableSet result = null;
- if (changes > 0) {
- result = Manager.v().registerSetIfNew(resultSet, this.exceptionsExcluded);
- } else {
- result = this;
- }
- return result;
+ return (changes > 0) ? Manager.v().registerSetIfNew(resultSet, this.exceptionsExcluded) : this;
}
/**
@@ -570,14 +566,7 @@ private ThrowableSet remove(Set removedExceptions) {
}
}
}
-
- ThrowableSet result = null;
- if (changes > 0) {
- result = Manager.v().registerSetIfNew(resultSet, this.exceptionsExcluded);
- } else {
- result = this;
- }
- return result;
+ return (changes > 0) ? Manager.v().registerSetIfNew(resultSet, this.exceptionsExcluded) : this;
}
/**
@@ -646,7 +635,7 @@ public boolean catchableAs(RefType catcher) {
if (exceptionsIncluded.contains(catcher)) {
if (INSTRUMENTING) {
- if (exceptionsExcluded.size() == 0) {
+ if (exceptionsExcluded.isEmpty()) {
Manager.v().catchableAsFromMap++;
} else {
Manager.v().catchableAsFromSearch++;
@@ -655,7 +644,7 @@ public boolean catchableAs(RefType catcher) {
return true;
} else {
if (INSTRUMENTING) {
- if (exceptionsExcluded.size() == 0) {
+ if (exceptionsExcluded.isEmpty()) {
Manager.v().catchableAsFromSearch++;
}
}
@@ -671,13 +660,11 @@ public boolean catchableAs(RefType catcher) {
} else {
RefType thrownBase = ((AnySubType) thrownType).getBase();
if (catcherHasNoHierarchy) {
- if (thrownBase.equals(catcher) || thrownBase.getClassName().equals("java.lang.Throwable")) {
+ if (thrownBase.equals(catcher) || "java.lang.Throwable".equals(thrownBase.getClassName())) {
return true;
}
- }
- // At runtime, thrownType might be instantiated by any
- // of thrownBase's subtypes, so:
- else if (h.canStoreType(thrownBase, catcher) || h.canStoreType(catcher, thrownBase)) {
+ } else if (h.canStoreType(thrownBase, catcher) || h.canStoreType(catcher, thrownBase)) {
+ // At runtime, thrownType might be instantiated by any of thrownBase's subtypes
return true;
}
}
@@ -760,7 +747,7 @@ public Pair whichCatchableAs(RefType catcher) {
if (base.equals(catcher)) {
caughtIncluded = addExceptionToSet(inclusion, caughtIncluded);
} else {
- if (base.getClassName().equals("java.lang.Throwable")) {
+ if ("java.lang.Throwable".equals(base.getClassName())) {
caughtIncluded = addExceptionToSet(catcher, caughtIncluded);
}
uncaughtIncluded = addExceptionToSet(inclusion, uncaughtIncluded);
@@ -818,7 +805,7 @@ private Set addExceptionToSet(T e, Set set) {
*/
@Override
public String toString() {
- StringBuffer buffer = new StringBuffer(this.toBriefString());
+ StringBuilder buffer = new StringBuilder(this.toBriefString());
buffer.append(":\n ");
for (RefLikeType ei : exceptionsIncluded) {
buffer.append('+');
@@ -882,7 +869,7 @@ private String toAbbreviatedString(Set extends RefLikeType> s, char connector)
Collection vmErrorThrowables = ThrowableSet.Manager.v().VM_ERRORS.exceptionsIncluded;
boolean containsAllVmErrors = s.containsAll(vmErrorThrowables);
- StringBuffer buf = new StringBuffer();
+ StringBuilder buf = new StringBuilder();
if (containsAllVmErrors) {
buf.append(connector);
@@ -1161,7 +1148,8 @@ public static Manager v() {
* @return a ThrowableSet
representing the set of exceptions corresponding to include
-
* exclude
.
*/
- protected ThrowableSet registerSetIfNew(Set include, Set exclude) {
+ private ThrowableSet registerSetIfNew(Set include, Set exclude) {
+ //NOTE: This method must be private in accordance with the comment in the ThrowableSet constructor.
if (INSTRUMENTING) {
registrationCalls++;
}
@@ -1181,9 +1169,7 @@ protected ThrowableSet registerSetIfNew(Set include, SetThrowableSet.Pair.
@@ -1270,10 +1257,7 @@ public boolean equals(Object o) {
return false;
}
Pair tsp = (Pair) o;
- if (this.caught.equals(tsp.caught) && this.uncaught.equals(tsp.uncaught)) {
- return true;
- }
- return false;
+ return this.caught.equals(tsp.caught) && this.uncaught.equals(tsp.uncaught);
}
@Override
@@ -1287,7 +1271,6 @@ public int hashCode() {
/**
* Comparator used to implement sortedThrowableIterator().
- *
*/
private static class ThrowableComparator implements java.util.Comparator {
@@ -1322,6 +1305,5 @@ public int compare(T o1, T o2) {
return t1.toString().compareTo(t2.toString());
}
}
-
}
}
diff --git a/src/main/java/soot/toolkits/graph/ExceptionalUnitGraph.java b/src/main/java/soot/toolkits/graph/ExceptionalUnitGraph.java
index 32ebac07cf4..63d2729c50f 100644
--- a/src/main/java/soot/toolkits/graph/ExceptionalUnitGraph.java
+++ b/src/main/java/soot/toolkits/graph/ExceptionalUnitGraph.java
@@ -255,47 +255,50 @@ protected void initialize(ThrowAnalysis throwAnalysis, boolean omitExceptingUnit
* extending ExceptionalUnitGraph
. If a Unit
throws one or more exceptions which are
* caught within the method, it will be mapped to a Collection
of ExceptionDest
s
* describing the sets of exceptions that the Unit
might throw to each {@link Trap}. But if all of a
- * Unit
's exceptions escape the method, it will be mapped to null
Unit's exceptions escape the method, it will be mapped to null
, rather than to a
* Collection
containing a single ExceptionDest
with a null
trap. (The
* special case for Unit
s with no caught exceptions allows buildExceptionDests()
to
* ignore completely Unit
s which are outside the scope of all Trap
s.)
*
*/
protected Map> buildExceptionDests(ThrowAnalysis throwAnalysis) {
- Chain units = body.getUnits();
- Map unitToUncaughtThrowables = new LinkedHashMap(units.size());
Map> result = null;
- // Record the caught exceptions.
- for (Trap trap : body.getTraps()) {
- RefType catcher = trap.getException().getType();
- for (Iterator unitIt = 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);
- }
+ final Chain traps = body.getTraps();
+ if (!traps.isEmpty()) {
+ final ThrowableSet EMPTY = ThrowableSet.Manager.v().EMPTY;
+ final Chain units = body.getUnits();
+ final Map unitToUncaughtThrowables = new LinkedHashMap(units.size());
+
+ // Record the caught exceptions.
+ for (Trap trap : traps) {
+ RefType catcher = trap.getException().getType();
+ for (Iterator it = units.iterator(trap.getBeginUnit(), units.getPredOf(trap.getEndUnit())); it.hasNext();) {
+ Unit unit = it.next();
+ ThrowableSet thrownSet = unitToUncaughtThrowables.get(unit);
+ if (thrownSet == null) {
+ thrownSet = throwAnalysis.mightThrow(unit);
+ }
- ThrowableSet.Pair catchableAs = thrownSet.whichCatchableAs(catcher);
- if (!catchableAs.getCaught().equals(ThrowableSet.Manager.v().EMPTY)) {
- result = addDestToMap(result, unit, trap, catchableAs.getCaught());
- unitToUncaughtThrowables.put(unit, catchableAs.getUncaught());
- } else {
- assert thrownSet.equals(catchableAs.getUncaught()) : "ExceptionalUnitGraph.buildExceptionDests(): "
- + "catchableAs.caught == EMPTY, but catchableAs.uncaught != thrownSet" + System.getProperty("line.separator")
- + body.getMethod().getSubSignature() + " Unit: " + unit.toString() + System.getProperty("line.separator")
- + " catchableAs.getUncaught() == " + catchableAs.getUncaught().toString()
- + System.getProperty("line.separator") + " thrownSet == " + thrownSet.toString();
+ ThrowableSet.Pair catchableAs = thrownSet.whichCatchableAs(catcher);
+ if (!EMPTY.equals(catchableAs.getCaught())) {
+ result = addDestToMap(result, unit, trap, catchableAs.getCaught());
+ unitToUncaughtThrowables.put(unit, catchableAs.getUncaught());
+ } else {
+ assert thrownSet.equals(catchableAs.getUncaught()) : "ExceptionalUnitGraph.buildExceptionDests(): "
+ + "catchableAs.caught == EMPTY, but catchableAs.uncaught != thrownSet" + System.getProperty("line.separator")
+ + body.getMethod().getSubSignature() + " Unit: " + unit.toString() + System.getProperty("line.separator")
+ + " catchableAs.getUncaught() == " + catchableAs.getUncaught().toString()
+ + System.getProperty("line.separator") + " thrownSet == " + thrownSet.toString();
+ }
}
}
- }
- for (Map.Entry entry : unitToUncaughtThrowables.entrySet()) {
- Unit unit = entry.getKey();
- ThrowableSet escaping = entry.getValue();
- if (escaping != ThrowableSet.Manager.v().EMPTY) {
- result = addDestToMap(result, unit, null, escaping);
+ for (Map.Entry entry : unitToUncaughtThrowables.entrySet()) {
+ ThrowableSet escaping = entry.getValue();
+ if (escaping != EMPTY) {
+ result = addDestToMap(result, entry.getKey(), null, escaping);
+ }
}
}
return result == null ? Collections.emptyMap() : result;
@@ -322,8 +325,8 @@ protected Map> buildExceptionDests(ThrowAnalysis
* @return a Map
which whose contents are equivalent to the input map
, plus the information that
* u
throws caught
to t
.
*/
- private Map> addDestToMap(Map> map, Unit u, Trap t,
- ThrowableSet caught) {
+ protected Map> addDestToMap(Map> map, Unit u,
+ Trap t, ThrowableSet caught) {
Collection dests = (map == null ? null : map.get(u));
if (dests == null) {
if (t == null) {
@@ -546,7 +549,7 @@ public int hashCode() {
/**
*
* Utility method for checking if a {@link 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
+ * a method directly or which might invoke static initializers indirectly (by creating a new object or by referring to a
* static field; see sections 2.17.4, 2.17.5, and 5.5 of the Java Virtual Machine Specification).
*
*
@@ -667,8 +670,6 @@ public Collection getExceptionDests(final Unit u) {
Collection result = unitToExceptionDests.get(u);
if (result == null) {
ExceptionDest e = new ExceptionDest(null, null) {
- private ThrowableSet throwables;
-
@Override
public ThrowableSet getThrowables() {
if (null == throwables) {
@@ -677,14 +678,14 @@ public ThrowableSet getThrowables() {
return throwables;
}
};
- return Collections.singletonList(e);
+ result = Collections.singletonList(e);
}
return result;
}
public static class ExceptionDest implements ExceptionalGraph.ExceptionDest {
- private Trap trap;
- private ThrowableSet throwables;
+ private final Trap trap;
+ ThrowableSet throwables;
protected ExceptionDest(Trap trap, ThrowableSet throwables) {
this.trap = trap;
@@ -712,7 +713,7 @@ public Unit getHandlerNode() {
@Override
public String toString() {
- StringBuffer buf = new StringBuffer();
+ StringBuilder buf = new StringBuilder();
buf.append(getThrowables());
buf.append(" -> ");
if (trap == null) {