1 salcianu 1.1.2.1 // GenType.java, created Tue Mar  7 18:32:52 2000 by salcianu
  2 cananian 1.1.2.3 // Copyright (C) 2000 Alexandru SALCIANU <salcianu@retezat.lcs.mit.edu>
  3 salcianu 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 salcianu 1.1.2.1 package harpoon.Analysis.MetaMethods;
  5 salcianu 1.1.2.1 
  6 salcianu 1.1.2.1 import harpoon.ClassFile.HClass;
  7 salcianu 1.1.2.1 import harpoon.Analysis.ClassHierarchy;
  8 salcianu 1.1.2.1 import harpoon.Analysis.PointerAnalysis.PAWorkList;
  9 salcianu 1.1.2.1 
 10 salcianu 1.1.2.1 import harpoon.Util.Util;
 11 salcianu 1.1.2.1 
 12 salcianu 1.1.2.1 /**
 13 salcianu 1.1.2.1  * <code>GenType</code> models a type. Although we can always record
 14 salcianu 1.1.2.1  the possible types of a variable as a set of <code>HClass</code>es,
 15 salcianu 1.1.2.1  this is inneficient in most of the cases. <code>GenType</code> tries
 16 salcianu 1.1.2.1  to cope with this by representing both monomorphic types (which
 17 salcianu 1.1.2.1  correspond to a single <code>HCode</code>) and polymorphic types
 18 salcianu 1.1.2.1  (which correspond to a set of <code>HClass</code>es, a type cone
 19 salcianu 1.1.2.1  rooted in a specific <code>HClass</code>)
 20 salcianu 1.1.2.1  * 
 21 cananian 1.1.2.3  * @author  Alexandru SALCIANU <salcianu@retezat.lcs.mit.edu>
 22 salcianu 1.5      * @version $Id: GenType.java,v 1.5 2002/05/02 22:11:39 salcianu Exp $
 23 salcianu 1.1.2.1  */
 24 cananian 1.1.2.2 public class GenType implements java.io.Serializable {
 25 salcianu 1.1.2.1 
 26 salcianu 1.1.2.1     /** Monomorphic type. This is an exact type, just the point 
 27 salcianu 1.1.2.1         <code>hclass</code> into the type space. */
 28 salcianu 1.1.2.1     public static final int MONO = 1;
 29 salcianu 1.1.2.1     /** Polymorphic type. This is a cone into the type space, rooted in
 30 salcianu 1.1.2.1         <code>hclass</code> and containing <code>hclass</code> and all its
 31 salcianu 1.1.2.1         subtypes (subclasses). */
 32 salcianu 1.1.2.1     public static final int POLY = 2;
 33 salcianu 1.1.2.1 
 34 salcianu 1.1.2.1     HClass hclass = null;
 35 salcianu 1.1.2.1     int    kind   = POLY;
 36 salcianu 1.1.2.1 
 37 salcianu 1.5         /** Creates a <code>GenType</code>. <code>kind</code> should be
 38 salcianu 1.5          <code>MONO</code> or <code>POLY</code>. */
 39 salcianu 1.1.2.1     public GenType(HClass hclass, int kind) {
 40 salcianu 1.5             assert (kind == MONO) || (kind == POLY) : 
 41 salcianu 1.5                 "kind should be GenType.MONO or GenType.POLY";
 42 salcianu 1.1.2.1         this.hclass = hclass;
 43 salcianu 1.1.2.1         this.kind   = kind;
 44 salcianu 1.1.2.1     }
 45 salcianu 1.1.2.1 
 46 salcianu 1.1.2.1     /** Creates a polymorphic type, having <code>hclass</code> as superclass.
 47 salcianu 1.1.2.1      */
 48 salcianu 1.1.2.1     public GenType(HClass hclass){
 49 salcianu 1.1.2.1         this(hclass,POLY);
 50 salcianu 1.1.2.1     }
 51 salcianu 1.1.2.1 
 52 salcianu 1.1.2.1     /** Checks whether this is a polymorphic type. */
 53 salcianu 1.1.2.1     public boolean isPOLY(){
 54 salcianu 1.1.2.1         return kind == POLY;
 55 salcianu 1.1.2.1     }
 56 salcianu 1.1.2.1 
 57 salcianu 1.1.2.1     /** Returns the underlying <code>HClass</code>. 
 58 salcianu 1.1.2.1         If <code>this</code> general type represents a monomorphic type,
 59 salcianu 1.1.2.1         the result is exactly that type. Otherwise, for polymorphic types,
 60 salcianu 1.1.2.1         the result is the root of the type cone. */
 61 salcianu 1.1.2.1     public HClass getHClass(){
 62 salcianu 1.1.2.1         return hclass;
 63 salcianu 1.1.2.1     }
 64 salcianu 1.1.2.1 
 65 salcianu 1.1.2.1     /** Checks the equality of <code>this</code> object with object
 66 salcianu 1.1.2.1         <code>o</code>. */
 67 salcianu 1.1.2.1     public boolean equals(Object o){
 68 salcianu 1.1.2.1         GenType gt2 = (GenType) o;
 69 salcianu 1.1.2.1         return (kind == gt2.kind) && hclass.equals(gt2.hclass);
 70 salcianu 1.1.2.1     }
 71 salcianu 1.1.2.1 
 72 cananian 1.1.2.2     private transient int hash = 0;
 73 salcianu 1.1.2.1     /** Computes the hash code of <code>this</code> object. */
 74 salcianu 1.1.2.1     public int hashCode(){
 75 cananian 1.1.2.2         if(hash == 0)
 76 cananian 1.1.2.2             hash = hclass.hashCode() + kind;
 77 salcianu 1.1.2.1         return hash;
 78 salcianu 1.1.2.1     }
 79 salcianu 1.1.2.1 
 80 salcianu 1.1.2.1     /** Checks whether <code>this</code> general type is included into the
 81 salcianu 1.1.2.1         set of types abstracted by the general type <code>gt2</code>. */
 82 salcianu 1.1.2.1     public boolean included(GenType gt2, ClassHierarchy ch){
 83 salcianu 1.1.2.1         if(gt2 == null) return false;
 84 salcianu 1.1.2.1         if(equals(gt2)) return true;
 85 salcianu 1.1.2.1 
 86 salcianu 1.1.2.1         // if the other type is monomorphic then either this type is
 87 salcianu 1.1.2.1         // monomorphic and different (equals returned false) and so this type
 88 salcianu 1.1.2.1         // is not included in it, or this is polymorphic and again gt2 cannot
 89 salcianu 1.1.2.1         // include this.
 90 salcianu 1.1.2.1         if(!gt2.isPOLY()) return false;
 91 salcianu 1.1.2.1 
 92 salcianu 1.1.2.1         // now, gt2 is known to be polymorphic, we have to check if hclass is
 93 salcianu 1.1.2.1         // included in the gt2 type cone <=> hclass is a subclass of gt2.hclass
 94 salcianu 1.1.2.1         // generate all the ancestors of hclass and see if gt2.hclass is among
 95 salcianu 1.1.2.1         // them.
 96 salcianu 1.1.2.1 
 97 salcianu 1.1.2.1         PAWorkList W = new PAWorkList();
 98 salcianu 1.1.2.1         W.add(hclass);
 99 salcianu 1.1.2.1         while(!W.isEmpty()){
100 salcianu 1.1.2.1             HClass c = (HClass) W.remove();
101 salcianu 1.1.2.1 
102 salcianu 1.1.2.1             HClass parent = c.getSuperclass();
103 salcianu 1.1.2.1             if(parent != null){
104 salcianu 1.1.2.1                 if(parent.equals(gt2.hclass)) return true;
105 salcianu 1.1.2.1                 W.add(parent);
106 salcianu 1.1.2.1             }
107 salcianu 1.1.2.1             
108 salcianu 1.1.2.1             HClass[] interfs = c.getInterfaces();
109 salcianu 1.1.2.1             for(int i = 0; i < interfs.length ; i++){
110 salcianu 1.1.2.1                 if(interfs[i].equals(gt2.hclass)) return true;
111 salcianu 1.1.2.1                 W.add(interfs[i]);
112 salcianu 1.1.2.1             }
113 salcianu 1.1.2.1         }
114 salcianu 1.1.2.1         return false;
115 salcianu 1.1.2.1     }
116 salcianu 1.1.2.1 
117 salcianu 1.1.2.1     /** Pretty printer for debug purposes. */
118 salcianu 1.1.2.1     public String toString(){
119 salcianu 1.1.2.1         return "<" + hclass.toString() + "," + (isPOLY()?"P":"M") + ">"; 
120 salcianu 1.1.2.1     }
121 salcianu 1.1.2.1 
122 cananian 1.2     }