/* VariableSet Copyright (C) 1998-2002 Jochen Hoenicke. * * This program 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, or (at your option) * any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; see the file COPYING.LESSER. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id$ */ package net.sf.jode.flow; import net.sf.jode.decompiler.LocalInfo; import net.sf.jode.util.ArrayEnum; ///#def COLLECTIONS java.util import java.util.Collection; import java.util.AbstractSet; import java.util.Iterator; ///#enddef /** * This class represents a set of Variables, which are mainly used in * the in/out sets of StructuredBlock. The type of the Variables is * LocalInfo.

* * It defines some Helper-Function, like intersecting, merging, union * and difference.

* * Note that a variable set can contain LocalInfos that use the same * slot, but are different. */ public final class VariableSet extends AbstractSet implements Cloneable { LocalInfo[] locals; int count; /** * Creates a new empty variable set */ public VariableSet() { locals = null; count = 0; } /** * Creates a new pre initialized variable set */ public VariableSet(LocalInfo[] locals) { count = locals.length; this.locals = locals; } public final void grow(int size) { if (locals != null) { size += count; if (size > locals.length) { int nextSize = locals.length * 2; // GlobalOptions.err.println("wanted: "+size+" next: "+nextSize); LocalInfo[] newLocals = new LocalInfo[nextSize > size ? nextSize : size]; System.arraycopy(locals, 0, newLocals, 0, count); locals = newLocals; } } else if (size > 0) locals = new LocalInfo[size]; } /** * Adds a local info to this variable set. */ public boolean add(Object li) { if (contains(li)) return false; grow(1); locals[count++] = (LocalInfo) li; return true; } /** * Checks if the variable set contains the given local info. */ public boolean contains(Object li) { li = ((LocalInfo) li).getLocalInfo(); for (int i=0; i 0) { other.locals = new LocalInfo[count]; System.arraycopy(locals, 0, other.locals, 0, count); } return other; } catch (CloneNotSupportedException ex) { throw new InternalError("Clone?"); } } /** * Intersects the current VariableSet with another and returns the * intersection. The existing VariableSet are not changed. * @param vs the other variable set. */ public VariableSet intersect(VariableSet vs) { VariableSet intersection = new VariableSet(); intersection.grow(Math.min(count, vs.count)); big_loop: for (int i=0; i