KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jode > flow > SlotSet


1 /* SlotSet Copyright (C) 1998-2002 Jochen Hoenicke.
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU Lesser General Public License as published by
5  * the Free Software Foundation; either version 2, or (at your option)
6  * any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program; see the file COPYING.LESSER. If not, write to
15  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
16  *
17  * $Id: SlotSet.java.in,v 4.1.2.1 2002/05/28 17:34:09 hoenicke Exp $
18  */

19
20 package jode.flow;
21 import jode.decompiler.LocalInfo;
22 import jode.util.ArrayEnum;
23
24 import java.util.Collection JavaDoc;
25 import java.util.AbstractSet JavaDoc;
26 import java.util.Iterator JavaDoc;
27
28 /**
29  * This class represents a set of local info, all having different
30  * slots. It is used for representing the in sets of flow block. <p>
31  *
32  * Its add method will automatically merge any localinfo that have
33  * the same slot and is in the method. <p>
34  */

35 public final class SlotSet extends AbstractSet JavaDoc implements Cloneable JavaDoc {
36     LocalInfo[] locals;
37     int count;
38
39     /**
40      * Creates a new empty variable set
41      */

42     public SlotSet() {
43         locals = null;
44         count = 0;
45     }
46
47     /**
48      * Creates a new pre initialized variable set
49      */

50     public SlotSet(LocalInfo[] locals) {
51         count = locals.length;
52         this.locals = locals;
53     }
54
55     public final void grow(int size) {
56         if (locals != null) {
57             size += count;
58             if (size > locals.length) {
59                 int nextSize = locals.length * 2;
60 // GlobalOptions.err.println("wanted: "+size+" next: "+nextSize);
61
LocalInfo[] newLocals
62                     = new LocalInfo[nextSize > size ? nextSize : size];
63                 System.arraycopy(locals, 0, newLocals, 0, count);
64                 locals = newLocals;
65             }
66         } else if (size > 0)
67             locals = new LocalInfo[size];
68     }
69
70     /**
71      * Adds a local info to this variable set.
72      */

73     public boolean add(Object JavaDoc o) {
74     LocalInfo li = (LocalInfo) o;
75     LocalInfo contained = findSlot(li.getSlot());
76     if (contained != null) {
77         li.combineWith(contained);
78         return false;
79     } else {
80         grow(1);
81         locals[count++] = li;
82         return true;
83     }
84     }
85
86     public final boolean contains(Object JavaDoc o) {
87     return containsSlot(((LocalInfo)o).getSlot());
88     }
89     
90     /**
91      * Checks if the variable set contains a local with the given name.
92      */

93     public final boolean containsSlot(int slot) {
94     return findSlot(slot) != null;
95     }
96
97     /**
98      * Checks if the variable set contains a local with the given slot.
99      */

100     public LocalInfo findSlot(int slot) {
101         for (int i=0; i<count;i++)
102             if (locals[i].getSlot() == slot)
103                 return locals[i];
104         return null;
105     }
106
107     /**
108      * Removes a slot from this variable set.
109      */

110     public boolean remove(Object JavaDoc li) {
111         int slot = ((LocalInfo) li).getSlot();
112         for (int i=0; i<count;i++) {
113             if (locals[i].getSlot() == slot) {
114                 locals[i] = locals[--count];
115         locals[count] = null;
116         return true;
117         }
118     }
119     return false;
120     }
121
122     public int size() {
123     return count;
124     }
125
126     public Iterator JavaDoc iterator() {
127     return new Iterator JavaDoc() {
128         int pos = 0;
129
130         public boolean hasNext() {
131         return pos < count;
132         }
133         
134         public Object JavaDoc next() {
135         return locals[pos++];
136         }
137       
138         public void remove() {
139         if (pos < count)
140             System.arraycopy(locals, pos,
141                      locals, pos-1, count - pos);
142         count--;
143         pos--;
144         }
145     };
146     }
147     
148     /**
149      * Removes everything from this variable set.
150      */

151     public void clear() {
152         locals = null;
153         count = 0;
154     }
155
156     public Object JavaDoc clone() {
157         try {
158             SlotSet other = (SlotSet) super.clone();
159             if (count > 0) {
160                 other.locals = new LocalInfo[count];
161                 System.arraycopy(locals, 0, other.locals, 0, count);
162             }
163             return other;
164         } catch (CloneNotSupportedException JavaDoc ex) {
165             throw new jode.AssertError("Clone?");
166         }
167     }
168
169     /**
170      * Merges this SlotSet with another. For all slots occuring
171      * in both variable sets, all corresponding LocalInfos are merged.
172      * The sets are not changed (use addAll for this).
173      * @return The merged variables.
174      * @param vs the other variable set. */

175     public void merge(VariableSet vs) {
176         for (int i=0; i<count; i++) {
177             LocalInfo li = locals[i];
178             int slot = li.getSlot();
179         for (int j=0; j<vs.count; j++) {
180         if (li.getSlot() == vs.locals[j].getSlot())
181             li.combineWith(vs.locals[j]);
182         }
183     }
184     }
185
186     /**
187      * Add the slots in kill to the current set, unless there are
188      * already in this set. This differs from addAll, in the fact that it
189      * doesn't combine the locals.
190      *
191      * @param kill The other kill set.
192      */

193     public void mergeKill(SlotSet kill) {
194         grow(kill.size());
195     big_loop:
196         for (Iterator JavaDoc i = kill.iterator(); i.hasNext(); ) {
197             LocalInfo li2 = (LocalInfo) i.next();
198         if (!containsSlot(li2.getSlot()))
199         add(li2.getLocalInfo());
200         }
201     }
202 }
203
Popular Tags