/** * Utility method which prints the abbreviations of the elements in a passed {@link Set} of * exception types. * * @param s The exceptions to print. * @param connector The character to insert between exceptions. * @return An abbreviated representation of the exceptions. */ private String toAbbreviatedString(Set s, char 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().VM_ERRORS.exceptionsIncluded; 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 = (RefLikeType) it.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(); }
/** * Partitions the exceptions in this <code>ThrowableSet</code> into those which would be caught by * a handler with the passed <code>catch</code> parameter type and those which would not. * * @param catcher type of the handler parameter to be tested. * @return a pair of <code>ThrowableSet</code>s, one containing the types in this <code> * ThrowableSet</code> which would be be caught as <code>catcher</code> and the other * containing the types in this <code>ThrowableSet</code> which would not be caught as <code> * catcher</code>. */ public Pair whichCatchableAs(RefType catcher) { if (INSTRUMENTING) { Manager.v().removesOfAnySubType++; } FastHierarchy h = Scene.v().getOrMakeFastHierarchy(); Set caughtIncluded = null; Set caughtExcluded = null; Set uncaughtIncluded = null; Set uncaughtExcluded = null; if (INSTRUMENTING) { Manager.v().removesFromSearch++; } for (Iterator i = exceptionsExcluded.iterator(); i.hasNext(); ) { AnySubType exclusion = (AnySubType) i.next(); RefType exclusionBase = exclusion.getBase(); if (h.canStoreType(catcher, exclusionBase)) { // 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().EMPTY, this); } else if (h.canStoreType(exclusionBase, catcher)) { // 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(exclusion, caughtExcluded); } else { uncaughtExcluded = addExceptionToSet(exclusion, uncaughtExcluded); } } for (Iterator i = exceptionsIncluded.iterator(); i.hasNext(); ) { RefLikeType inclusion = (RefLikeType) i.next(); if (inclusion instanceof RefType) { if (h.canStoreType(inclusion, catcher)) { caughtIncluded = addExceptionToSet(inclusion, caughtIncluded); } else { uncaughtIncluded = addExceptionToSet(inclusion, uncaughtIncluded); } } else { RefType base = ((AnySubType) inclusion).getBase(); if (h.canStoreType(base, catcher)) { // All subtypes of base will be caught. Any exclusions // will already have been copied to caughtExcluded by // the preceding loop. caughtIncluded = addExceptionToSet(inclusion, caughtIncluded); } else if (h.canStoreType(catcher, base)) { // 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(inclusion, uncaughtIncluded); 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(inclusion, uncaughtIncluded); } } } ThrowableSet caughtSet = Manager.v().registerSetIfNew(caughtIncluded, caughtExcluded); ThrowableSet uncaughtSet = Manager.v().registerSetIfNew(uncaughtIncluded, uncaughtExcluded); return new Pair(caughtSet, uncaughtSet); }