/* Soot - a J*va Optimization Framework * Copyright (C) 2005 Nomair A. Naeem * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ package soot.dava.toolkits.base.AST.transformations; import soot.*; import java.util.*; import soot.jimple.*; import soot.dava.internal.asg.*; import soot.dava.internal.SET.*; import soot.dava.internal.AST.*; import soot.dava.internal.javaRep.*; public class UselessLabelFinder{ public static boolean DEBUG = false; public UselessLabelFinder( Singletons.Global g ) {} public static UselessLabelFinder v() { return G.v().soot_dava_toolkits_base_AST_transformations_UselessLabelFinder(); } //check whether label on a node is useless public boolean findAndKill(ASTNode node){ if(!(node instanceof ASTLabeledNode)){ if(DEBUG) System.out.println("Returning from findAndKill for node of type "+node.getClass()); return false; } else{ if(DEBUG) System.out.println("FindAndKill continuing for node fo type"+node.getClass()); } String label = ((ASTLabeledNode)node).get_Label().toString(); if(label==null) return false; if(DEBUG) System.out.println("dealing with labeled node"+label); List<Object> subBodies = node.get_SubBodies(); Iterator<Object> it = subBodies.iterator(); while(it.hasNext()){ List subBodyTemp = null; if(node instanceof ASTTryNode){ //an astTryNode ASTTryNode.container subBody = (ASTTryNode.container)it.next(); subBodyTemp = (List)subBody.o; //System.out.println("\ntryNode body"); } else{//not an astTryNode //System.out.println("not try node in findAndkill"); subBodyTemp = (List)it.next(); } if(checkForBreak(subBodyTemp,label)){ //found a break return false; } } // only if all bodies dont contain a break can we remove the label //means break was not found so we can remove ((ASTLabeledNode)node).set_Label(new SETNodeLabel()); if (DEBUG) System.out.println("USELESS LABEL DETECTED"); return true; } /* Returns True if finds a break for this label */ private boolean checkForBreak(List ASTNodeBody,String outerLabel){ // if(DEBUG) // System.out.println("method checkForBreak..... label is "+outerLabel); Iterator it = ASTNodeBody.iterator(); while(it.hasNext()){ ASTNode temp = (ASTNode)it.next(); //check if this is ASTStatementSequenceNode if(temp instanceof ASTStatementSequenceNode){ //if(DEBUG) System.out.println("Stmt seq Node"); ASTStatementSequenceNode stmtSeq = (ASTStatementSequenceNode)temp; List<Object> statements = stmtSeq.getStatements(); Iterator<Object> stmtIt = statements.iterator(); while(stmtIt.hasNext()){ AugmentedStmt as = (AugmentedStmt)stmtIt.next(); Stmt s = as.get_Stmt(); String labelBroken = breaksLabel(s); if(labelBroken != null && outerLabel!=null){//stmt breaks some label if(labelBroken.compareTo(outerLabel)==0){ //we have found a break breaking this label return true; } } } }//if it was a StmtSeq node else{ //otherwise recursion //getSubBodies //if(DEBUG) System.out.println("Not Stmt seq Node"); List<Object> subBodies=temp.get_SubBodies(); Iterator<Object> subIt = subBodies.iterator(); while(subIt.hasNext()){ List subBodyTemp = null; if(temp instanceof ASTTryNode){ ASTTryNode.container subBody = (ASTTryNode.container) subIt.next(); subBodyTemp = (List)subBody.o; //System.out.println("Try body node"); } else{ subBodyTemp = (List)subIt.next(); } if(checkForBreak(subBodyTemp,outerLabel)){ //if this is true there was a break found return true; } } } } return false; } /* If the stmt is a break/continue stmt then this method returns the labels name else returns null */ private String breaksLabel(Stmt stmt){ if(!(stmt instanceof DAbruptStmt)){ //this is not a break stmt return null; } DAbruptStmt abStmt = (DAbruptStmt)stmt; if(abStmt.is_Break() || abStmt.is_Continue()){ SETNodeLabel label = abStmt.getLabel(); return label.toString(); } else return null; } }