001: package soot.dava.toolkits.base.AST.transformations;
002:
003: import java.util.ArrayList;
004: import java.util.Iterator;
005: import java.util.List;
006: import java.util.Map;
007:
008: import soot.Local;
009: import soot.SootClass;
010: import soot.Type;
011: import soot.dava.internal.AST.ASTNode;
012: import soot.dava.internal.AST.ASTStatementSequenceNode;
013: import soot.dava.internal.AST.ASTSwitchNode;
014: import soot.dava.internal.AST.ASTTryNode;
015: import soot.dava.internal.asg.AugmentedStmt;
016: import soot.dava.toolkits.base.AST.analysis.DepthFirstAdapter;
017: import soot.dava.toolkits.base.AST.structuredAnalysis.UnreachableCodeFinder;
018: import soot.jimple.Stmt;
019:
020: public class UnreachableCodeEliminator extends DepthFirstAdapter {
021: public boolean DUBUG = true;
022: ASTNode AST;
023: UnreachableCodeFinder codeFinder;
024:
025: public UnreachableCodeEliminator(ASTNode AST) {
026: super ();
027: this .AST = AST;
028: setup();
029: }
030:
031: public UnreachableCodeEliminator(boolean verbose, ASTNode AST) {
032: super (verbose);
033: this .AST = AST;
034: setup();
035: }
036:
037: private void setup() {
038: codeFinder = new UnreachableCodeFinder(AST);
039: //parentOf = new ASTParentNodeFinder();
040: //AST.apply(parentOf);
041: }
042:
043: public void inASTStatementSequenceNode(ASTStatementSequenceNode node) {
044: List<Object> toRemove = new ArrayList<Object>();
045: List<Object> stmts = node.getStatements();
046: Iterator<Object> it = stmts.iterator();
047: while (it.hasNext()) {
048: AugmentedStmt as = (AugmentedStmt) it.next();
049: Stmt s = as.get_Stmt();
050: //System.out.println("HERE!!!"+s.toString());
051: if (!codeFinder.isConstructReachable(s)) {
052: toRemove.add(as);
053: //if(DEBUG) System.out.println("Statement "+s.toString()+ " is NOT REACHABLE REMOVE IT");
054: }
055: }
056: it = toRemove.iterator();
057: while (it.hasNext()) {
058: stmts.remove(it.next());
059: }
060: }
061:
062: public void normalRetrieving(ASTNode node) {
063: if (node instanceof ASTSwitchNode) {
064: dealWithSwitchNode((ASTSwitchNode) node);
065: return;
066: }
067:
068: //from the Node get the subBodes
069: List<ASTNode> toReturn = new ArrayList<ASTNode>();
070: Iterator<Object> sbit = node.get_SubBodies().iterator();
071: while (sbit.hasNext()) {
072: Object subBody = sbit.next();
073: Iterator<ASTNode> it = ((List<ASTNode>) subBody).iterator();
074:
075: //go over the ASTNodes in this subBody and apply
076: while (it.hasNext()) {
077: ASTNode temp = it.next();
078: if (!codeFinder.isConstructReachable(temp)) {
079: //System.out.println("-------------------------A child of node of type "+node.getClass()+" whose type is "+temp.getClass()+" is unreachable");
080: toReturn.add(temp);
081: } else {
082: //only apply on reachable nodes
083: temp.apply(this );
084: }
085: }
086:
087: it = toReturn.iterator();
088: while (it.hasNext()) {
089: //System.out.println("Removed");
090: ((List) subBody).remove(it.next());
091: }
092: }//end of going over subBodies
093: }
094:
095: //TODO
096: public void caseASTTryNode(ASTTryNode node) {
097: //get try body
098: List<Object> tryBody = node.get_TryBody();
099: Iterator<Object> it = tryBody.iterator();
100:
101: //go over the ASTNodes in this tryBody and apply
102: List<Object> toReturn = new ArrayList<Object>();
103: while (it.hasNext()) {
104: ASTNode temp = (ASTNode) it.next();
105: if (!codeFinder.isConstructReachable(temp)) {
106: toReturn.add(temp);
107: } else {
108: //only apply on reachable nodes
109: temp.apply(this );
110: }
111: }
112:
113: it = toReturn.iterator();
114: while (it.hasNext()) {
115: tryBody.remove(it.next());
116: }
117:
118: Map<Object, Object> exceptionMap = node.get_ExceptionMap();
119: Map<Object, Object> paramMap = node.get_ParamMap();
120: //get catch list and apply on the following
121: // a, type of exception caught
122: // b, local of exception
123: // c, catchBody
124: List<Object> catchList = node.get_CatchList();
125: Iterator<Object> itBody = null;
126: it = catchList.iterator();
127: while (it.hasNext()) {
128: ASTTryNode.container catchBody = (ASTTryNode.container) it
129: .next();
130:
131: SootClass sootClass = ((SootClass) exceptionMap
132: .get(catchBody));
133: Type type = sootClass.getType();
134:
135: //apply on type of exception
136: caseType(type);
137:
138: //apply on local of exception
139: Local local = (Local) paramMap.get(catchBody);
140: /*
141: * March 18th, 2006, Since these are always locals we dont have access to ValueBox
142: */
143: decideCaseExprOrRef(local);
144:
145: //apply on catchBody
146: List<Object> body = (List<Object>) catchBody.o;
147: toReturn = new ArrayList<Object>();
148: itBody = body.iterator();
149: while (itBody.hasNext()) {
150: ASTNode temp = (ASTNode) itBody.next();
151: if (!codeFinder.isConstructReachable(temp)) {
152: toReturn.add(temp);
153: } else {
154: //only apply on reachable nodes
155: temp.apply(this );
156: }
157: }
158:
159: itBody = toReturn.iterator();
160: while (itBody.hasNext()) {
161: body.remove(itBody.next());
162: }
163: }
164: }
165:
166: private void dealWithSwitchNode(ASTSwitchNode node) {
167: //System.out.println("dealing with SwitchNode");
168: //do a depthfirst on elements of the switchNode
169:
170: List<Object> indexList = node.getIndexList();
171: Map<Object, List<Object>> index2BodyList = node
172: .getIndex2BodyList();
173:
174: Iterator<Object> it = indexList.iterator();
175: while (it.hasNext()) {//going through all the cases of the switch statement
176: Object currentIndex = it.next();
177: List body = index2BodyList.get(currentIndex);
178:
179: if (body == null)
180: continue;
181:
182: //this body is a list of ASTNodes
183:
184: List<ASTNode> toReturn = new ArrayList<ASTNode>();
185: Iterator itBody = body.iterator();
186: //go over the ASTNodes and apply
187: while (itBody.hasNext()) {
188: ASTNode temp = (ASTNode) itBody.next();
189: //System.out.println("Checking whether child of type "+temp.getClass()+" is reachable");
190: if (!codeFinder.isConstructReachable(temp)) {
191: //System.out.println(">>>>>>>>>>>>>>>>>-------------------------A child of node of type "+node.getClass()+" whose type is "+temp.getClass()+" is unreachable");
192: toReturn.add(temp);
193: } else {
194: //System.out.println("child of type "+temp.getClass()+" is reachable");
195: //only apply on reachable nodes
196: temp.apply(this );
197: }
198: }
199:
200: Iterator<ASTNode> newit = toReturn.iterator();
201: while (newit.hasNext()) {
202: //System.out.println("Removed");
203: body.remove(newit.next());
204: }
205:
206: }
207: }
208: }
|