| Home >> All >> Compil3r >> [ Quad Javadoc ] |
Source code: Compil3r/Quad/CHACallGraph.java
1 // CHACallGraph.java, created Mon Mar 3 18:01:33 2003 by joewhaley 2 // Copyright (C) 2001-3 John Whaley <jwhaley@alum.mit.edu> 3 // Licensed under the terms of the GNU LGPL; see COPYING for details. 4 package Compil3r.Quad; 5 6 import java.util.ArrayList; 7 import java.util.Arrays; 8 import java.util.Collection; 9 import java.util.Collections; 10 import java.util.Iterator; 11 import java.util.LinkedHashSet; 12 import java.util.LinkedList; 13 import java.util.Set; 14 15 import Bootstrap.PrimordialClassLoader; 16 import Clazz.jq_Class; 17 import Clazz.jq_Method; 18 import Clazz.jq_Type; 19 20 /** 21 * A simple call graph implementation based on class-hierarchy analysis with 22 * optional rapid type analysis. 23 * 24 * @author John Whaley <jwhaley@alum.mit.edu> 25 * @version $Id: CHACallGraph.java,v 1.5 2003/07/04 07:31:54 joewhaley Exp $ 26 */ 27 public class CHACallGraph extends CallGraph { 28 29 public static final CHACallGraph INSTANCE = new CHACallGraph(); 30 31 protected final Set classes; 32 33 /** 34 * Construct a call graph assuming only the given types are 35 * used by the program, i.e. rapid type analysis. 36 * 37 * @param classes set of types from which to build the call graph 38 */ 39 public CHACallGraph(Set/*jq_Type*/ classes) { this.classes = classes; } 40 protected CHACallGraph() { this.classes = null; } 41 42 /** 43 * @see Compil3r.Quad.CallGraph#getTargetMethods(java.lang.Object, Compil3r.Quad.ProgramLocation) 44 */ 45 public Collection getTargetMethods(Object context, ProgramLocation callSite) { 46 jq_Method method = (jq_Method) callSite.getTargetMethod(); 47 if (callSite.isSingleTarget()) 48 return Collections.singleton(method); 49 50 Collection result; 51 if (callSite.isInterfaceCall()) { 52 result = new LinkedHashSet(); 53 Collection s = classes!=null?classes:PrimordialClassLoader.loader.getAllTypes(); 54 for (Iterator i=new ArrayList(s).iterator(); i.hasNext(); ) { 55 jq_Type t = (jq_Type) i.next(); 56 if (t instanceof jq_Class) { 57 jq_Class c = (jq_Class) t; 58 c.prepare(); 59 if (c.implementsInterface(method.getDeclaringClass())) { 60 jq_Method m2 = c.getVirtualMethod(method.getNameAndDesc()); 61 if (m2 != null && !m2.isAbstract()) result.add(m2); 62 } 63 } 64 } 65 } else { 66 result = new LinkedList(); 67 LinkedList worklist = new LinkedList(); 68 worklist.add(method.getDeclaringClass()); 69 while (!worklist.isEmpty()) { 70 jq_Class c = (jq_Class) worklist.removeFirst(); 71 c.load(); 72 jq_Method m2 = (jq_Method) c.getDeclaredMember(method.getNameAndDesc()); 73 if (m2 != null) { 74 if (!m2.isAbstract()) { 75 result.add(m2); 76 } 77 if (m2.isFinal() || m2.isPrivate()) { 78 continue; 79 } 80 } 81 for (Iterator i=Arrays.asList(c.getSubClasses()).iterator(); i.hasNext(); ) { 82 jq_Class c2 = (jq_Class) i.next(); 83 if (classes == null || classes.contains(c2)) worklist.add(c2); 84 } 85 } 86 } 87 return result; 88 } 89 90 /* (non-Javadoc) 91 * @see Compil3r.Quad.CallGraph#getRoots() 92 */ 93 public Collection getRoots() { 94 throw new UnsupportedOperationException(); 95 } 96 97 /* (non-Javadoc) 98 * @see Compil3r.Quad.CallGraph#setRoots(java.util.Collection) 99 */ 100 public void setRoots(Collection roots) { 101 throw new UnsupportedOperationException(); 102 } 103 104 }