00001 package edu.ksu.cis.bandera.prog;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 import java.util.Hashtable;
00037 import java.util.HashMap;
00038 import java.util.Enumeration;
00039 import java.util.Iterator;
00040 import java.io.*;
00041
00042 import ca.mcgill.sable.soot.*;
00043 import ca.mcgill.sable.soot.jimple.*;
00044 import ca.mcgill.sable.util.*;
00045
00046 import edu.ksu.cis.bandera.jjjc.*;
00047
00048 public class HierarchyQuery {
00049 private static HashMap classHierarchies;
00050
00051 public static void buildAncestors(SootClass theClass) {
00052 if (classHierarchies == null) classHierarchies = new HashMap();
00053 HashMap theMap = new HashMap();
00054 buildMap(theMap, theClass);
00055 classHierarchies.put(theClass, theMap);
00056 }
00057 private static int buildMap(HashMap map, SootClass current) {
00058 if (current.hasSuperClass()) {
00059 int depth = buildMap(map, current.getSuperClass());
00060 map.put(new Integer(depth+1), current);
00061 return depth+1;
00062 } else {
00063 map.put(new Integer(0), current.getManager().getClass("java.lang.Object"));
00064 return 0;
00065 }
00066 }
00067 public static SootClass leastAncestor(SootClass aClass, SootClass bClass) {
00068 try {
00069 HashMap aMap = (HashMap)classHierarchies.get(aClass);
00070 HashMap bMap = (HashMap)classHierarchies.get(bClass);
00071 int maxDepth;
00072
00073 if (aMap.size() > bMap.size()) {
00074 maxDepth = bMap.size();
00075 } else {
00076 maxDepth = aMap.size();
00077 }
00078
00079
00080
00081
00082
00083
00084 for (int i=maxDepth-1; i>0; i--) {
00085 if ( aMap.get(new Integer(i)) == bMap.get(new Integer(i)) )
00086 return (SootClass)aMap.get(new Integer(i));
00087 }
00088 return (SootClass)aMap.get(new Integer(0));
00089 } catch(java.lang.NullPointerException e) {
00090 System.out.println("Called with " + aClass.getName() + " and " +
00091 bClass.getName());
00092 System.out.println("Hierarchy has maps for:");
00093 Iterator chIt = classHierarchies.values().iterator();
00094 while (chIt.hasNext()) {
00095 HashMap thisMap = (HashMap)chIt.next();
00096 System.out.println(" " + thisMap.get(new Integer(thisMap.size()-1)));
00097 }
00098 throw e;
00099 }
00100 }
00101 public static void main(String args[]) {
00102 SootClassManager classManager = new SootClassManager();
00103 CompilationManager.reset();
00104 CompilationManager.setFilename(args[0]);
00105 CompilationManager.setClasspath(".");
00106 CompilationManager.setIncludedPackagesOrTypes(new String[0]);
00107
00108
00109 try { CompilationManager.compile(); }
00110 catch (Exception e) {
00111 System.out.println(e);
00112 System.out.println("Compilation failed");
00113 }
00114
00115 Hashtable storedClasses = CompilationManager.getCompiledClasses();
00116
00117 Enumeration scIter = storedClasses.elements();
00118 while (scIter.hasMoreElements()) {
00119 ((SootClass) scIter.nextElement()).resolveIfNecessary();
00120 }
00121
00122 scIter = storedClasses.elements();
00123 while (scIter.hasMoreElements()) {
00124 buildAncestors((SootClass)scIter.nextElement());
00125 }
00126
00127 SootClass a = null;
00128 SootClass b = null;
00129
00130 scIter = storedClasses.elements();
00131 while (scIter.hasMoreElements()) {
00132 SootClass tmp = (SootClass) scIter.nextElement();
00133 if (tmp.getName().equals(args[1])) {
00134 a = tmp;
00135 }
00136 if (tmp.getName().equals(args[2])) {
00137 b = tmp;
00138 }
00139 }
00140
00141 System.out.println("Least ancestor of " + a.getName() + " and " +
00142 b.getName() + " is " + leastAncestor(a,b).getName());
00143 }
00144 }