/* 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;
}
}