1 cananian 1.1.2.1 // CompleteClazNumbering.java, created Sun Mar 10 21:01:51 2002 by cananian
 2 cananian 1.1.2.1 // Copyright (C) 2000 C. Scott Ananian <cananian@alumni.princeton.edu>
 3 cananian 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details.
 4 cananian 1.1.2.1 package harpoon.Backend.RuntimeTiny;
 5 cananian 1.1.2.1 
 6 cananian 1.1.2.1 import harpoon.Analysis.ClassHierarchy;
 7 cananian 1.1.2.1 import harpoon.ClassFile.HClass;
 8 cananian 1.1.2.1 import harpoon.Util.HClassUtil;
 9 cananian 1.1.2.1 
10 cananian 1.1.2.1 import java.util.Collections;
11 cananian 1.1.2.1 import java.util.HashMap;
12 cananian 1.1.2.1 import java.util.Iterator;
13 cananian 1.1.2.1 import java.util.Map;
14 cananian 1.1.2.1 
15 cananian 1.1.2.1 /**
16 cananian 1.1.2.1  * <code>CompleteClazNumbering</code> extends PreOrderClazNumbering
17 cananian 1.1.2.1  * to create a numbering valid for all classes in the given classhierarchy.
18 cananian 1.1.2.1  * Single-inheritance instantiated classes are placed first, in the order
19 cananian 1.1.2.1  * given by <code>PreOrderClazNumbering</code>, and multiple-inheritance
20 cananian 1.1.2.1  * instantiated classes are placed next.  Lastly, we'll number all
21 cananian 1.1.2.1  * non-instantiated classes.  This was we can use the lowest part of
22 cananian 1.1.2.1  * the numbering to implement 'instanceOf' using the 
23 cananian 1.1.2.1  * <code>PreOrderClazNumbering</code>, use a slightly-larger part of
24 cananian 1.1.2.1  * the numbering to compactly encode the classes which can actually
25 cananian 1.1.2.1  * tag an instantiated object, and still have a numbering which is
26 cananian 1.1.2.1  * valid for all classes in the hierarchy (and thus is good for
27 cananian 1.1.2.1  * sorting and such).
28 cananian 1.1.2.1  * 
29 cananian 1.1.2.1  * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
30 cananian 1.3      * @version $Id: CompleteClazNumbering.java,v 1.3 2004/02/08 03:21:01 cananian Exp $
31 cananian 1.1.2.1  */
32 cananian 1.1.2.1 public class CompleteClazNumbering extends ClazNumbering {
33 cananian 1.1.2.1     private final Map<HClass,Integer> map = new HashMap<HClass,Integer>();
34 cananian 1.1.2.1     private final int min, max;
35 cananian 1.1.2.1     
36 cananian 1.1.2.1     /** Creates a <code>CompleteClazNumbering</code>. */
37 cananian 1.1.2.1     public CompleteClazNumbering(ClassHierarchy ch, PreOrderClazNumbering pocn)
38 cananian 1.1.2.1     {
39 cananian 1.1.2.1         this.min = pocn.minNumber();
40 cananian 1.1.2.1         int n = pocn.maxNumber()+1;
41 cananian 1.1.2.1         // start with the instantiated classes.
42 cananian 1.3             for (HClass hc : ch.instantiatedClasses()) {
43 cananian 1.1.2.1             assert !hc.isInterface();
44 cananian 1.1.2.1             if (HClassUtil.baseClass(hc).isInterface())
45 cananian 1.1.2.1                 map.put(hc, new Integer(n++));
46 cananian 1.1.2.1             else
47 cananian 1.1.2.1                 map.put(hc, new Integer(pocn.clazNumber(hc)));
48 cananian 1.1.2.1         }
49 cananian 1.1.2.1         assert map.size()==n-min;
50 cananian 1.1.2.1         // now do all the rest.
51 cananian 1.3             for (HClass hc : ch.classes()) {
52 cananian 1.1.2.1             if (!map.containsKey(hc))
53 cananian 1.1.2.1                 map.put(hc, new Integer(n++));
54 cananian 1.1.2.1         }
55 cananian 1.1.2.1         assert map.size()==n-min;
56 cananian 1.1.2.1         this.max = n-1;
57 cananian 1.1.2.1         assert this.min==Collections.min(map.values()).intValue();
58 cananian 1.1.2.1         assert this.max==Collections.max(map.values()).intValue();
59 cananian 1.1.2.1     }
60 cananian 1.1.2.1     public CompleteClazNumbering(ClassHierarchy ch) {
61 cananian 1.1.2.1         this(ch, new PreOrderClazNumbering(ch));
62 cananian 1.1.2.1     }
63 cananian 1.1.2.1     public int clazNumber(HClass hc) {
64 cananian 1.1.2.1         assert map.containsKey(hc);
65 cananian 1.1.2.1         return map.get(hc).intValue();
66 cananian 1.1.2.1     }
67 cananian 1.1.2.1     public int minNumber() {
68 cananian 1.1.2.1         return min;
69 cananian 1.1.2.1     }
70 cananian 1.1.2.1     public int maxNumber() {
71 cananian 1.1.2.1         return max;
72 cananian 1.1.2.1     }
73 cananian 1.2     }