1 19 20 21 package ca.mcgill.sable.soot.callgraph; 22 import org.eclipse.ui.*; 23 import org.eclipse.jface.action.*; 24 import org.eclipse.jface.viewers.*; 25 import ca.mcgill.sable.graph.*; 26 import ca.mcgill.sable.graph.model.*; 27 import org.eclipse.core.runtime.*; 28 import java.util.*; 29 import java.lang.reflect.*; 30 import soot.jimple.toolkits.annotation.callgraph.*; 31 import soot.*; 32 import soot.tagkit.*; 33 import ca.mcgill.sable.soot.interaction.*; 34 import ca.mcgill.sable.soot.*; 35 import org.eclipse.swt.widgets.*; 36 import org.eclipse.ui.plugin.*; 37 import soot.toolkits.graph.interaction.*; 38 import org.eclipse.core.resources.*; 39 import org.eclipse.jdt.core.*; 40 import org.eclipse.ui.texteditor.*; 41 import org.eclipse.ui.part.*; 42 43 public class CallGraphGenerator { 44 45 private CallGraphInfo info; 46 private Graph graph; 47 private InteractionController controller; 48 private ArrayList centerList; 49 50 51 public CallGraphGenerator() { 52 } 53 54 public void run(){ 55 56 IWorkbench workbench = SootPlugin.getDefault().getWorkbench(); 57 IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); 58 IWorkbenchPage page = window.getActivePage();; 59 60 try{ 61 if (graph == null){ 62 setGraph(new Graph()); 63 graph.setName("CallGraph"); 64 } 65 else{ 66 graph.removeAllChildren(); 67 } 68 IEditorPart part = page.openEditor(graph, "ca.mcgill.sable.graph.GraphEditor", true); 69 ((GraphEditor)part).setPartFactory(new CallGraphPartFactory()); 70 addActions((GraphEditor)part); 71 ((GraphEditor)part).setMenuProvider(new CGMenuProvider(((GraphEditor)part).getGraphEditorGraphicalViewer(), ((GraphEditor)part).getGraphEditorActionRegistry(), part)); 72 73 buildModel(); 74 } 75 catch (PartInitException e3){ 76 e3.printStackTrace(); 77 } 78 catch (Exception e2){ 79 e2.printStackTrace(); 80 } 81 } 82 83 public void addActions(GraphEditor part){ 84 ShowCodeAction showCode = new ShowCodeAction((IWorkbenchPart)part); 85 part.getGraphEditorActionRegistry().registerAction(showCode); 86 part.getGraphEditorSelectionActions().add(showCode.getId()); 87 88 ExpandAction expand = new ExpandAction((IWorkbenchPart)part); 89 part.getGraphEditorActionRegistry().registerAction(expand); 90 part.getGraphEditorSelectionActions().add(expand.getId()); 91 92 CollapseAction collapse = new CollapseAction((IWorkbenchPart)part); 93 part.getGraphEditorActionRegistry().registerAction(collapse); 94 part.getGraphEditorSelectionActions().add(collapse.getId()); 95 96 } 97 98 public void buildModel(){ 99 CallGraphNode cgn = new CallGraphNode(); 100 getGraph().addChild(cgn); 101 cgn.setGenerator(this); 102 cgn.setData(getInfo().getCenter()); 103 104 cgn.setExpand(false); 105 makeCons(getInfo(), cgn); 106 107 } 108 109 private CallGraphNode getNodeForMethod(SootMethod meth){ 110 CallGraphNode node = null; 111 Iterator it = getGraph().getChildren().iterator(); 112 while (it.hasNext()){ 113 CallGraphNode next = (CallGraphNode)it.next(); 114 if (next.getData().equals(meth)){ 115 node = next; 116 } 117 } 118 if (node == null){ 119 node = new CallGraphNode(); 120 getGraph().addChild(node); 121 node.setData(meth); 122 } 123 return node; 124 } 125 126 private void makeCons(CallGraphInfo info, CallGraphNode center){ 127 Iterator it1 = info.getInputs().iterator(); 128 while (it1.hasNext()){ 129 MethInfo mInfo = (MethInfo)it1.next(); 130 SootMethod sm = mInfo.method(); 131 CallGraphNode inNode = getNodeForMethod(sm); 132 inNode.setGenerator(this); 133 Edge inEdge = new Edge(inNode, center); 134 inEdge.setLabel(mInfo.edgeKind().name()); 135 } 136 137 Iterator it2 = info.getOutputs().iterator(); 138 while (it2.hasNext()){ 139 MethInfo mInfo = (MethInfo)it2.next(); 140 SootMethod sm = mInfo.method(); 141 CallGraphNode outNode = getNodeForMethod(sm); 142 outNode.setGenerator(this); 143 Edge inEdge = new Edge(center, outNode); 144 inEdge.setLabel(mInfo.edgeKind().name()); 145 } 146 } 147 148 public void collapseGraph(CallGraphNode node){ 149 ArrayList inputsToRemove = new ArrayList(); 152 ArrayList outputsToRemove = new ArrayList(); 153 ArrayList nodesToRemove = new ArrayList(); 154 155 if (node.getInputs() != null){ 156 Iterator inIt = node.getInputs().iterator(); 157 while (inIt.hasNext()){ 158 Edge next = (Edge)inIt.next(); 159 CallGraphNode src = (CallGraphNode)next.getSrc(); 160 if (src.isLeaf()){ 161 inputsToRemove.add(next); 162 nodesToRemove.add(src); 163 } 164 } 165 } 166 167 if (node.getOutputs() != null){ 168 Iterator outIt = node.getOutputs().iterator(); 169 while (outIt.hasNext()){ 170 Edge next = (Edge)outIt.next(); 171 CallGraphNode tgt = (CallGraphNode)next.getTgt(); 172 if (tgt.isLeaf()){ 173 outputsToRemove.add(next); 174 nodesToRemove.add(tgt); 175 } 176 } 177 } 178 179 Iterator inRIt = inputsToRemove.iterator(); 180 while (inRIt.hasNext()){ 181 Edge temp = (Edge)inRIt.next(); 182 node.removeInput(temp); 183 } 184 185 Iterator outRIt = outputsToRemove.iterator(); 186 while (outRIt.hasNext()){ 187 Edge temp = (Edge)outRIt.next(); 188 node.removeInput(temp); 189 } 190 191 Iterator nodeRIt = nodesToRemove.iterator(); 192 while (nodeRIt.hasNext()){ 193 CallGraphNode temp = (CallGraphNode)nodeRIt.next(); 194 temp.removeAllInputs(); 195 temp.removeAllOutputs(); 196 getGraph().removeChild(temp); 197 } 198 199 node.setExpand(true); 200 } 201 202 public void expandGraph(CallGraphNode node){ 203 getController().setEvent(new InteractionEvent(IInteractionConstants.CALL_GRAPH_NEXT_METHOD, node.getData())); 204 getController().handleEvent(); 205 206 } 207 208 public void showInCode(CallGraphNode node){ 209 SootMethod meth = (SootMethod)node.getData(); 210 String sootClassName = meth.getDeclaringClass().getName(); 211 sootClassName = sootClassName.replaceAll("\\.", System.getProperty("file.separator")); 212 sootClassName = sootClassName + ".java"; 213 String sootMethName = meth.getName(); 214 215 IProject [] progs = SootPlugin.getWorkspace().getRoot().getProjects(); 216 IResource fileToOpen = null; 217 for (int i = 0; i < progs.length; i++){ 218 IProject project = progs[i]; 219 220 IJavaProject jProj = JavaCore.create(project); 221 try { 222 223 IPackageFragmentRoot [] roots = jProj.getAllPackageFragmentRoots(); 224 for (int j = 0; j < roots.length; j++){ 225 if (!(roots[j].getResource() instanceof IContainer)) continue; 226 fileToOpen = ((IContainer)roots[j].getResource()).findMember(sootClassName); 227 if (fileToOpen == null) continue; 228 else break; 229 } 230 } 231 catch(Exception e){ 232 } 233 234 if (fileToOpen != null) break; 235 } 236 237 238 239 IWorkbench workbench = SootPlugin.getDefault().getWorkbench(); 240 IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); 241 IWorkbenchPage page = window.getActivePage();; 242 243 try{ 244 IEditorPart part = page.openEditor(new FileEditorInput((IFile)fileToOpen), org.eclipse.jdt.ui.JavaUI.ID_CU_EDITOR); 245 SourceLnPosTag methTag = (SourceLnPosTag)meth.getTag("SourceLnPosTag"); 246 if (methTag != null){ 247 248 int selOffset = ((AbstractTextEditor)part).getDocumentProvider().getDocument(part.getEditorInput()).getLineOffset(methTag.startLn()-1); 249 250 ((AbstractTextEditor)SootPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor()).selectAndReveal(selOffset, 0); 251 } 252 253 } 254 catch (PartInitException e3){ 255 e3.printStackTrace(); 256 } 257 258 catch (Exception e2){ 259 e2.printStackTrace(); 260 } 261 } 262 263 public void addToGraph(Object info){ 264 CallGraphInfo cgInfo = (CallGraphInfo)info; 265 266 SootMethod center = cgInfo.getCenter(); 267 268 CallGraphNode centerNode = getNodeForMethod(cgInfo.getCenter()); 270 centerNode.setExpand(false); 272 makeCons(cgInfo, centerNode); 274 } 275 276 279 public Graph getGraph() { 280 return graph; 281 } 282 283 286 public void setGraph(Graph graph) { 287 this.graph = graph; 288 } 289 290 293 public CallGraphInfo getInfo() { 294 return info; 295 } 296 297 300 public void setInfo(CallGraphInfo info) { 301 this.info = info; 302 } 303 304 307 public InteractionController getController() { 308 return controller; 309 } 310 311 314 public void setController(InteractionController controller) { 315 this.controller = controller; 316 } 317 318 public void addToCenterList(Object obj){ 319 if (getCenterList() == null){ 320 setCenterList(new ArrayList()); 321 } 322 getCenterList().add(obj); 323 } 324 325 328 public ArrayList getCenterList() { 329 return centerList; 330 } 331 332 335 public void setCenterList(ArrayList list) { 336 centerList = list; 337 } 338 339 } 340 | Popular Tags |