KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jode > flow > VariableSet


1 /* VariableSet 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: VariableSet.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 Variables, which are mainly used in
30  * the in/out sets of StructuredBlock. The type of the Variables is
31  * LocalInfo. <p>
32  *
33  * It defines some Helper-Function, like intersecting, merging, union
34  * and difference. <p>
35  *
36  * Note that a variable set can contain LocalInfos that use the same
37  * slot, but are different.
38  */

39 public final class VariableSet extends AbstractSet JavaDoc implements Cloneable JavaDoc {
40     LocalInfo[] locals;
41     int count;
42
43     /**
44      * Creates a new empty variable set
45      */

46     public VariableSet() {
47         locals = null;
48         count = 0;
49     }
50
51     /**
52      * Creates a new pre initialized variable set
53      */

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

77     public boolean add(Object JavaDoc li) {
78     if (contains(li))
79         return false;
80         grow(1);
81         locals[count++] = (LocalInfo) li;
82     return true;
83     }
84
85     /**
86      * Checks if the variable set contains the given local info.
87      */

88     public boolean contains(Object JavaDoc li) {
89         li = ((LocalInfo) li).getLocalInfo();
90         for (int i=0; i<count;i++)
91             if (locals[i].getLocalInfo() == li)
92                 return true;
93         return false;
94     }
95
96     /**
97      * Checks if the variable set contains a local with the given name.
98      */

99     public final boolean containsSlot(int slot) {
100     return findSlot(slot) != null;
101     }
102
103     /**
104      * Checks if the variable set contains a local with the given name.
105      */

106     public LocalInfo findLocal(String JavaDoc name) {
107         for (int i=0; i<count;i++)
108             if (locals[i].getName().equals(name))
109                 return locals[i];
110         return null;
111     }
112
113     /**
114      * Checks if the variable set contains a local with the given slot.
115      */

116     public LocalInfo findSlot(int slot) {
117         for (int i=0; i<count;i++)
118             if (locals[i].getSlot() == slot)
119                 return locals[i];
120         return null;
121     }
122
123     /**
124      * Removes a local info from this variable set.
125      */

126     public boolean remove(Object JavaDoc li) {
127         li = ((LocalInfo) li).getLocalInfo();
128         for (int i=0; i<count;i++) {
129             if (locals[i].getLocalInfo() == li) {
130                 locals[i] = locals[--count];
131         locals[count] = null;
132         return true;
133         }
134     }
135     return false;
136     }
137
138     public int size() {
139     return count;
140     }
141
142     public Iterator JavaDoc iterator() {
143     return new Iterator JavaDoc() {
144         int pos = 0;
145
146         public boolean hasNext() {
147         return pos < count;
148         }
149         
150         public Object JavaDoc next() {
151         return locals[pos++];
152         }
153       
154         public void remove() {
155         if (pos < count)
156             System.arraycopy(locals, pos,
157                      locals, pos-1, count - pos);
158         count--;
159         pos--;
160         locals[count] = null;
161         }
162     };
163     }
164     
165     /**
166      * Removes everything from this variable set.
167      */

168     public void clear() {
169         locals = null;
170         count = 0;
171     }
172
173     public Object JavaDoc clone() {
174         try {
175             VariableSet other = (VariableSet) super.clone();
176             if (count > 0) {
177                 other.locals = new LocalInfo[count];
178                 System.arraycopy(locals, 0, other.locals, 0, count);
179             }
180             return other;
181         } catch (CloneNotSupportedException JavaDoc ex) {
182             throw new jode.AssertError("Clone?");
183         }
184     }
185
186     /**
187      * Intersects the current VariableSet with another and returns the
188      * intersection. The existing VariableSet are not changed.
189      * @param vs the other variable set.
190      */

191     public VariableSet intersect(VariableSet vs) {
192         VariableSet intersection = new VariableSet();
193         intersection.grow(Math.min(count, vs.count));
194     big_loop:
195         for (int i=0; i<count; i++) {
196             LocalInfo li = locals[i];
197             int slot = li.getSlot();
198         if (vs.containsSlot(slot)
199         && !intersection.containsSlot(slot))
200         intersection.locals[intersection.count++] = li.getLocalInfo();
201         }
202         return intersection;
203     }
204
205     /**
206      * Add the variables in gen to the current set, unless there are
207      * variables in kill using the same slot.
208      * @param gen The gen set.
209      * @param kill The kill set.
210      */

211     public void mergeGenKill(Collection JavaDoc gen, SlotSet kill) {
212         grow(gen.size());
213     big_loop:
214         for (Iterator JavaDoc i = gen.iterator(); i.hasNext(); ) {
215             LocalInfo li2 = (LocalInfo) i.next();
216         if (!kill.containsSlot(li2.getSlot()))
217         add(li2.getLocalInfo());
218         }
219     }
220 }
221
222
Popular Tags