git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@1040 379699f6-c40d-0410-875b-85095c16579ebranch_1_1
parent
8db70be1a7
commit
38d78b49bf
@ -0,0 +1,190 @@ |
||||
/* SlotSet Copyright (C) 1998-1999 Jochen Hoenicke. |
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU 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 General Public License |
||||
* along with this program; see the file COPYING. If not, write to |
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
||||
* |
||||
* $Id$ |
||||
*/ |
||||
|
||||
package jode.flow; |
||||
import jode.decompiler.LocalInfo; |
||||
import jode.util.ArrayEnum; |
||||
|
||||
///#ifdef JDK12
|
||||
///import java.util.Collection;
|
||||
///import java.util.AbstractSet;
|
||||
///import java.util.Iterator;
|
||||
///#else
|
||||
import jode.util.Collection; |
||||
import jode.util.AbstractSet; |
||||
import jode.util.Iterator; |
||||
///#endif
|
||||
|
||||
/** |
||||
* This class represents a set of local info, all having different |
||||
* slots. It is used for representing the in sets of flow block. <p> |
||||
* |
||||
* Its add method will automatically merge any localinfo that have |
||||
* the same slot and is in the method. <p> |
||||
*/ |
||||
public final class SlotSet extends AbstractSet implements Cloneable { |
||||
LocalInfo[] locals; |
||||
int count; |
||||
|
||||
/** |
||||
* Creates a new empty variable set |
||||
*/ |
||||
public SlotSet() { |
||||
locals = null; |
||||
count = 0; |
||||
} |
||||
|
||||
/** |
||||
* Creates a new pre initialized variable set |
||||
*/ |
||||
public SlotSet(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 o) { |
||||
LocalInfo li = (LocalInfo) o; |
||||
LocalInfo contained = findSlot(li.getSlot()); |
||||
if (contained != null) { |
||||
li.combineWith(contained); |
||||
return false; |
||||
} else { |
||||
grow(1); |
||||
locals[count++] = li; |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
public final boolean contains(Object o) { |
||||
return containsSlot(((LocalInfo)o).getSlot()); |
||||
} |
||||
|
||||
/** |
||||
* Checks if the variable set contains a local with the given name. |
||||
*/ |
||||
public final boolean containsSlot(int slot) { |
||||
return findSlot(slot) != null; |
||||
} |
||||
|
||||
/** |
||||
* Checks if the variable set contains a local with the given slot. |
||||
*/ |
||||
public LocalInfo findSlot(int slot) { |
||||
for (int i=0; i<count;i++) |
||||
if (locals[i].getSlot() == slot) |
||||
return locals[i]; |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Removes a local info from this variable set. |
||||
*/ |
||||
public boolean remove(Object li) { |
||||
li = ((LocalInfo) li).getLocalInfo(); |
||||
for (int i=0; i<count;i++) { |
||||
if (locals[i].getLocalInfo() == li) { |
||||
locals[i] = locals[--count]; |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
public int size() { |
||||
return count; |
||||
} |
||||
|
||||
public Iterator iterator() { |
||||
return new Iterator() { |
||||
int pos = 0; |
||||
|
||||
public boolean hasNext() { |
||||
return pos < count; |
||||
} |
||||
|
||||
public Object next() { |
||||
return locals[pos++]; |
||||
} |
||||
|
||||
public void remove() { |
||||
if (pos < count) |
||||
System.arraycopy(locals, pos, |
||||
locals, pos-1, count - pos); |
||||
count--; |
||||
pos--; |
||||
} |
||||
}; |
||||
} |
||||
|
||||
/** |
||||
* Removes everything from this variable set. |
||||
*/ |
||||
public void clear() { |
||||
locals = null; |
||||
count = 0; |
||||
} |
||||
|
||||
public Object clone() { |
||||
try { |
||||
SlotSet other = (SlotSet) super.clone(); |
||||
if (count > 0) { |
||||
other.locals = new LocalInfo[count]; |
||||
System.arraycopy(locals, 0, other.locals, 0, count); |
||||
} |
||||
return other; |
||||
} catch (CloneNotSupportedException ex) { |
||||
throw new jode.AssertError("Clone?"); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Merges this SlotSet with another. For all slots occuring |
||||
* in both variable sets, all corresponding LocalInfos are merged. |
||||
* The variable sets are not changed (use union for this). |
||||
* @return The merged variables. |
||||
* @param vs the other variable set. */ |
||||
public void merge(VariableSet vs) { |
||||
for (int i=0; i<count; i++) { |
||||
LocalInfo li = locals[i]; |
||||
int slot = li.getSlot(); |
||||
for (int j=0; j<vs.count; j++) { |
||||
if (li.getSlot() == vs.locals[j].getSlot()) |
||||
li.combineWith(vs.locals[j]); |
||||
} |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue