1 cananian 1.1.2.1 // CHFinalMap.java, created Fri Oct 20 23:09:43 2000 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.Maps; 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.ClassFile.HConstructor; 9 cananian 1.1.2.1 import harpoon.ClassFile.HField; 10 cananian 1.1.2.1 import harpoon.ClassFile.HMethod; 11 cananian 1.3 import net.cscott.jutil.WorkSet; 12 cananian 1.1.2.1 13 cananian 1.1.2.1 import java.lang.reflect.Modifier; 14 cananian 1.1.2.1 import java.util.HashMap; 15 cananian 1.1.2.1 import java.util.Map; 16 cananian 1.1.2.1 /** 17 cananian 1.1.2.1 * <code>CHFinalMap</code> is a slightly smarter <code>FinalMap</code> 18 cananian 1.1.2.1 * that, given a <code>ClassHierarchy</code> for context, aggressively 19 cananian 1.1.2.1 * makes methods final if the <code>ClassHierarchy</code> doesn't contain 20 cananian 1.1.2.1 * a reachable method which overrides it. 21 cananian 1.1.2.1 * 22 cananian 1.1.2.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 23 cananian 1.3 * @version $Id: CHFinalMap.java,v 1.3 2004/02/08 01:57:37 cananian Exp $ 24 cananian 1.1.2.1 */ 25 cananian 1.1.2.4 public class CHFinalMap extends DefaultFinalMap 26 cananian 1.1.2.4 implements java.io.Serializable { 27 cananian 1.1.2.1 private final ClassHierarchy ch; 28 cananian 1.1.2.1 29 cananian 1.1.2.1 /** Creates a <code>CHFinalMap</code>. */ 30 cananian 1.1.2.1 public CHFinalMap(ClassHierarchy ch) { this.ch = ch; } 31 cananian 1.1.2.1 32 cananian 1.1.2.1 public boolean isFinal(HClass hc) { 33 cananian 1.1.2.1 return super.isFinal(hc) || ch.children(hc).size()==0; 34 cananian 1.1.2.1 } 35 cananian 1.1.2.1 public boolean isFinal(HMethod hm) { 36 cananian 1.1.2.3 // abstract methods are never final, even if no reachable methods 37 cananian 1.1.2.3 // implement it. (this deals with unexecutable method calls) 38 cananian 1.1.2.3 if (Modifier.isAbstract(hm.getModifiers())) return false; 39 cananian 1.1.2.3 // at least as precise as DefaultFinalMap 40 cananian 1.1.2.1 if (super.isFinal(hm)) return true; 41 cananian 1.1.2.1 // call non-virtual methods final. 42 cananian 1.1.2.1 if (hm.isStatic() || 43 cananian 1.1.2.1 Modifier.isPrivate(hm.getModifiers()) || 44 cananian 1.1.2.1 hm instanceof HConstructor) return true; 45 cananian 1.1.2.1 // next bit is time consuming. check cache first. 46 cananian 1.1.2.4 if (cache==null) cache = new HashMap(); 47 cananian 1.1.2.2 if (!cache.containsKey(hm)) { 48 cananian 1.1.2.2 // if no overrides, this is final. 49 cananian 1.1.2.2 cache.put(hm, new Boolean(ch.overrides(hm).size()==0)); 50 cananian 1.1.2.1 } 51 cananian 1.1.2.2 return ((Boolean) cache.get(hm)).booleanValue(); 52 cananian 1.1.2.1 } 53 cananian 1.1.2.4 private transient Map cache = null; 54 cananian 1.2 }