/** * Returns a <code>ThrowableSet</code> which contains all the exceptions in <code>addedExceptions * </code> in addition to those in this <code>ThrowableSet</code>. * * @param addedExceptions a set of {@link RefLikeType} and {@link AnySubType} objects to be added * to the types included in this <code>ThrowableSet</code>. * @return a set containing all the <code>addedExceptions</code> as well as the exceptions in this * set. */ private ThrowableSet add(Set addedExceptions) { Set resultSet = new HashSet(this.exceptionsIncluded); 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 = (RefLikeType) i.next(); if (!resultSet.contains(newType)) { boolean addNewType = true; if (newType instanceof RefType) { for (Iterator j = resultSet.iterator(); j.hasNext(); ) { RefLikeType incumbentType = (RefLikeType) j.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 = ((AnySubType) incumbentType).getBase(); if (hierarchy.canStoreType(newType, incumbentBase)) { // 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 = ((AnySubType) newType).getBase(); for (Iterator j = resultSet.iterator(); j.hasNext(); ) { RefLikeType incumbentType = (RefLikeType) j.next(); if (incumbentType instanceof RefType) { RefType incumbentBase = (RefType) incumbentType; if (hierarchy.canStoreType(incumbentBase, newBase)) { j.remove(); changes++; } } else if (incumbentType instanceof AnySubType) { RefType incumbentBase = ((AnySubType) incumbentType).getBase(); if (newBase == incumbentBase) { // assertion failure. throw new IllegalStateException( "ThrowableSet.add(Set): resultSet.contains() failed to screen duplicate AnySubType " + newBase); } else if (hierarchy.canStoreType(incumbentBase, newBase)) { j.remove(); changes++; } else if (hierarchy.canStoreType(newBase, incumbentBase)) { // 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.exceptionsExcluded); } else { result = this; } return result; }