KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > jimple > toolkits > typing > integer > TypeVariable


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 1997-2000 Etienne Gagnon. All rights reserved.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */

19
20 /*
21  * Modified by the Sable Research Group and others 1997-1999.
22  * See the 'credits' file distributed with Soot for the complete list of
23  * contributors. (Soot is distributed at http://www.sable.mcgill.ca/soot)
24  */

25
26
27 package soot.jimple.toolkits.typing.integer;
28
29 import soot.*;
30 import soot.jimple.*;
31 import soot.util.*;
32 import java.util.*;
33 import java.util.*;
34
35 /** Represents a type variable. **/
36 class TypeVariable implements Comparable JavaDoc
37 {
38   private static final boolean DEBUG = false;
39
40   private final int id;
41   private final TypeResolver resolver;
42
43   private TypeVariable rep = this;
44   private int rank = 0;
45
46   private TypeNode approx;
47   private TypeNode inv_approx;
48   
49   private TypeNode type;
50
51   private List parents = Collections.unmodifiableList(new LinkedList());
52   private List children = Collections.unmodifiableList(new LinkedList());
53
54   public TypeVariable(int id, TypeResolver resolver)
55   {
56     this.id = id;
57     this.resolver = resolver;
58   }
59
60   public TypeVariable(int id, TypeResolver resolver, TypeNode type)
61   {
62     this.id = id;
63     this.resolver = resolver;
64     this.type = type;
65     approx = type;
66     inv_approx = type;
67   }
68
69   public int hashCode()
70   {
71     if(rep != this)
72       {
73     return ecr().hashCode();
74       }
75    
76     return id;
77   }
78
79   public boolean equals(Object JavaDoc obj)
80   {
81     if(rep != this)
82       {
83     return ecr().equals(obj);
84       }
85
86     if(obj == null)
87       {
88     return false;
89       }
90
91     if(!obj.getClass().equals(getClass()))
92       {
93     return false;
94       }
95     
96     TypeVariable ecr = ((TypeVariable) obj).ecr();
97
98     if(ecr != this)
99       {
100     return false;
101       }
102     
103     return true;
104   }
105
106   public int compareTo(Object JavaDoc o)
107   {
108     if(rep != this)
109       {
110     return ecr().compareTo(o);
111       }
112
113     return id - ((TypeVariable) o).ecr().id;
114   }
115   
116   private TypeVariable ecr()
117   {
118     if(rep != this)
119       {
120     rep = rep.ecr();
121       }
122
123     return rep;
124   }
125
126   public TypeVariable union(TypeVariable var) throws TypeException
127   {
128     if(rep != this)
129       {
130     return ecr().union(var);
131       }
132
133     TypeVariable y = var.ecr();
134
135     if(this == y)
136       {
137     return this;
138       }
139     
140     if(rank > y.rank)
141       {
142     y.rep = this;
143
144     merge(y);
145     y.clear();
146
147     return this;
148       }
149
150     rep = y;
151     if(rank == y.rank)
152       {
153     y.rank++;
154       }
155
156     y.merge(this);
157     clear();
158
159     return y;
160   }
161
162   private void clear()
163   {
164     inv_approx = null;
165     approx = null;
166     type = null;
167     parents = null;
168     children = null;
169   }
170
171   private void merge(TypeVariable var) throws TypeException
172   {
173     // Merge types
174
if(type == null)
175       {
176     type = var.type;
177       }
178     else if(var.type != null)
179       {
180     error("Type Error(22): Attempt to merge two types.");
181       }
182
183     // Merge parents
184
{
185       Set set = new TreeSet(parents);
186       set.addAll(var.parents);
187       set.remove(this);
188       parents = Collections.unmodifiableList(new LinkedList(set));
189     }
190
191     // Merge children
192
{
193       Set set = new TreeSet(children);
194       set.addAll(var.children);
195       set.remove(this);
196       children = Collections.unmodifiableList(new LinkedList(set));
197     }
198   }
199
200   public int id()
201   {
202     if(rep != this)
203       {
204     return ecr().id();
205       }
206
207     return id;
208   }
209
210   public void addParent(TypeVariable variable)
211   {
212     if(rep != this)
213       {
214     ecr().addParent(variable);
215     return;
216       }
217
218     TypeVariable var = variable.ecr();
219  
220     if(var == this)
221       {
222     return;
223       }
224
225     {
226       Set set = new TreeSet(parents);
227       set.add(var);
228       parents = Collections.unmodifiableList(new LinkedList(set));
229     }
230     
231     {
232       Set set = new TreeSet(var.children);
233       set.add(this);
234       var.children = Collections.unmodifiableList(new LinkedList(set));
235     }
236   }
237
238   public void removeParent(TypeVariable variable)
239   {
240     if(rep != this)
241       {
242     ecr().removeParent(variable);
243     return;
244       }
245
246     TypeVariable var = variable.ecr();
247  
248     {
249       Set set = new TreeSet(parents);
250       set.remove(var);
251       parents = Collections.unmodifiableList(new LinkedList(set));
252     }
253
254     {
255       Set set = new TreeSet(var.children);
256       set.remove(this);
257       var.children = Collections.unmodifiableList(new LinkedList(set));
258     }
259   }
260
261   public void addChild(TypeVariable variable)
262   {
263     if(rep != this)
264       {
265     ecr().addChild(variable);
266     return;
267       }
268
269     TypeVariable var = variable.ecr();
270  
271     if(var == this)
272       {
273     return;
274       }
275
276     {
277       Set set = new TreeSet(children);
278       set.add(var);
279       children = Collections.unmodifiableList(new LinkedList(set));
280     }
281
282     {
283       Set set = new TreeSet(var.parents);
284       set.add(this);
285       var.parents = Collections.unmodifiableList(new LinkedList(set));
286     }
287   }
288
289   public void removeChild(TypeVariable variable)
290   {
291     if(rep != this)
292       {
293     ecr().removeChild(variable);
294     return;
295       }
296
297     TypeVariable var = variable.ecr();
298  
299     {
300       Set set = new TreeSet(children);
301       set.remove(var);
302       children = Collections.unmodifiableList(new LinkedList(set));
303     }
304
305     {
306       Set set = new TreeSet(var.parents);
307       set.remove(this);
308       var.parents = Collections.unmodifiableList(new LinkedList(set));
309     }
310   }
311
312   public List parents()
313   {
314     if(rep != this)
315       {
316     return ecr().parents();
317       }
318     
319     return parents;
320   }
321
322   public List children()
323   {
324     if(rep != this)
325       {
326     return ecr().children();
327       }
328     
329     return children;
330   }
331
332   public TypeNode approx()
333   {
334     if(rep != this)
335       {
336     return ecr().approx();
337       }
338
339     return approx;
340   }
341
342   public TypeNode inv_approx()
343   {
344     if(rep != this)
345       {
346     return ecr().inv_approx();
347       }
348
349     return inv_approx;
350   }
351
352   public TypeNode type()
353   {
354     if(rep != this)
355       {
356     return ecr().type();
357       }
358
359     return type;
360   }
361
362   static void error(String JavaDoc message) throws TypeException
363   {
364     try
365       {
366     throw new TypeException(message);
367       }
368     catch(TypeException e)
369       {
370     if(DEBUG)
371       {
372         e.printStackTrace();
373       }
374     throw e;
375       }
376   }
377
378   /** Computes approximative types. The work list must be
379    * initialized with all constant type variables. */

380   public static void computeApprox(TreeSet workList) throws TypeException
381   {
382     while(workList.size() > 0)
383       {
384     TypeVariable var = (TypeVariable) workList.first();
385     workList.remove(var);
386
387     var.fixApprox(workList);
388       }
389   }
390
391   public static void computeInvApprox(TreeSet workList) throws TypeException
392   {
393     while(workList.size() > 0)
394       {
395     TypeVariable var = (TypeVariable) workList.first();
396     workList.remove(var);
397
398     var.fixInvApprox(workList);
399       }
400   }
401
402   private void fixApprox(TreeSet workList) throws TypeException
403   {
404     if(rep != this)
405       {
406     ecr().fixApprox(workList);
407     return;
408       }
409
410     for(Iterator i = parents.iterator(); i.hasNext();)
411       {
412     TypeVariable parent = ((TypeVariable) i.next()).ecr();
413
414     if(parent.approx == null)
415       {
416         parent.approx = approx;
417         workList.add(parent);
418       }
419     else
420       {
421         TypeNode type = parent.approx.lca_2(approx);
422
423         if(type != parent.approx)
424           {
425         parent.approx = type;
426         workList.add(parent);
427           }
428       }
429       }
430
431     if(type != null)
432       {
433     approx = type;
434       }
435   }
436
437   private void fixInvApprox(TreeSet workList) throws TypeException
438   {
439     if(rep != this)
440       {
441     ecr().fixInvApprox(workList);
442     return;
443       }
444
445     for(Iterator i = children.iterator(); i.hasNext();)
446       {
447     TypeVariable child = ((TypeVariable) i.next()).ecr();
448
449     if(child.inv_approx == null)
450       {
451         child.inv_approx = inv_approx;
452         workList.add(child);
453       }
454     else
455       {
456         TypeNode type = child.inv_approx.gcd_2(inv_approx);
457
458         if(type != child.inv_approx)
459           {
460         child.inv_approx = type;
461         workList.add(child);
462           }
463       }
464       }
465
466     if(type != null)
467       {
468     inv_approx = type;
469       }
470   }
471
472   public String JavaDoc toString()
473   {
474     if(rep != this)
475       {
476     return ecr().toString();
477       }
478     
479     StringBuffer JavaDoc s = new StringBuffer JavaDoc();
480     s.append(",[parents:");
481
482     {
483       boolean comma = false;
484       
485       for(Iterator i = parents.iterator(); i.hasNext(); )
486     {
487       if(comma)
488         {
489           s.append(",");
490         }
491       else
492         {
493           comma = true;
494         }
495       s.append(((TypeVariable) i.next()).id());
496     }
497     }
498     
499     s.append("],[children:");
500
501     {
502       boolean comma = false;
503       
504       for(Iterator i = children.iterator(); i.hasNext(); )
505     {
506       if(comma)
507         {
508           s.append(",");
509         }
510       else
511         {
512           comma = true;
513         }
514       s.append(((TypeVariable) i.next()).id());
515     }
516     }
517     
518     s.append("]");
519     return "[id:" + id + ((type != null) ? (",type:" + type) : "") + ",approx:" + approx + ",inv_approx:" + inv_approx + s + "]";
520   }
521
522   public void fixParents()
523   {
524     if(rep != this)
525       {
526     ecr().fixParents();
527     return;
528       }
529
530     {
531       Set set = new TreeSet(parents);
532       parents = Collections.unmodifiableList(new LinkedList(set));
533     }
534   }
535
536   public void fixChildren()
537   {
538     if(rep != this)
539       {
540     ecr().fixChildren();
541     return;
542       }
543
544     {
545       Set set = new TreeSet(children);
546       children = Collections.unmodifiableList(new LinkedList(set));
547     }
548   }
549
550 }
551
Popular Tags