001: /* Soot - a J*va Optimization Framework
002: * Copyright (C) 2003 Jerome Miecznikowski
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the
016: * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
017: * Boston, MA 02111-1307, USA.
018: */
019:
020: package soot.dava.toolkits.base.AST;
021:
022: import soot.*;
023: import java.util.*;
024: import soot.util.*;
025: import soot.jimple.*;
026: import soot.dava.internal.AST.*;
027:
028: public class TryContentsFinder extends ASTAnalysis {
029: public TryContentsFinder(Singletons.Global g) {
030: }
031:
032: public static TryContentsFinder v() {
033: return G.v().soot_dava_toolkits_base_AST_TryContentsFinder();
034: }
035:
036: private IterableSet curExceptionSet = new IterableSet();
037: private final HashMap<Object, IterableSet> node2ExceptionSet = new HashMap<Object, IterableSet>();
038:
039: public int getAnalysisDepth() {
040: return ANALYSE_VALUES;
041: }
042:
043: public IterableSet remove_CurExceptionSet() {
044: IterableSet s = curExceptionSet;
045:
046: set_CurExceptionSet(new IterableSet());
047:
048: return s;
049: }
050:
051: public void set_CurExceptionSet(IterableSet curExceptionSet) {
052: this .curExceptionSet = curExceptionSet;
053: }
054:
055: public void analyseThrowStmt(ThrowStmt s) {
056: Value op = (s).getOp();
057:
058: if (op instanceof Local)
059: add_ThrownType(((Local) op).getType());
060: else if (op instanceof FieldRef)
061: add_ThrownType(((FieldRef) op).getType());
062: }
063:
064: private void add_ThrownType(Type t) {
065: if (t instanceof RefType)
066: curExceptionSet.add(((RefType) t).getSootClass());
067: }
068:
069: public void analyseInvokeExpr(InvokeExpr ie) {
070: curExceptionSet.addAll(ie.getMethod().getExceptions());
071: }
072:
073: public void analyseInstanceInvokeExpr(InstanceInvokeExpr iie) {
074: analyseInvokeExpr(iie);
075: }
076:
077: public void analyseASTNode(ASTNode n) {
078: if (n instanceof ASTTryNode) {
079:
080: ASTTryNode tryNode = (ASTTryNode) n;
081:
082: ArrayList<Object> toRemove = new ArrayList<Object>();
083: IterableSet tryExceptionSet = node2ExceptionSet.get(tryNode
084: .get_TryBodyContainer());
085: if (tryExceptionSet == null) {
086: tryExceptionSet = new IterableSet();
087: node2ExceptionSet.put(tryNode.get_TryBodyContainer(),
088: tryExceptionSet);
089: }
090:
091: List<Object> catchBodies = tryNode.get_CatchList();
092: List<Object> subBodies = tryNode.get_SubBodies();
093:
094: Iterator<Object> cit = catchBodies.iterator();
095: while (cit.hasNext()) {
096: Object catchBody = cit.next();
097: SootClass exception = (SootClass) tryNode
098: .get_ExceptionMap().get(catchBody);
099:
100: if ((catches_Exception(tryExceptionSet, exception) == false)
101: && (catches_RuntimeException(exception) == false))
102: toRemove.add(catchBody);
103: }
104:
105: Iterator<Object> trit = toRemove.iterator();
106: while (trit.hasNext()) {
107: Object catchBody = trit.next();
108:
109: subBodies.remove(catchBody);
110: catchBodies.remove(catchBody);
111: }
112:
113: IterableSet passingSet = (IterableSet) tryExceptionSet
114: .clone();
115: cit = catchBodies.iterator();
116: while (cit.hasNext())
117: passingSet.remove(tryNode.get_ExceptionMap().get(
118: cit.next()));
119:
120: cit = catchBodies.iterator();
121: while (cit.hasNext())
122: passingSet.addAll(get_ExceptionSet(cit.next()));
123:
124: node2ExceptionSet.put(n, passingSet);
125: }
126:
127: else {
128: Iterator<Object> sbit = n.get_SubBodies().iterator();
129: while (sbit.hasNext()) {
130: Iterator it = ((List) sbit.next()).iterator();
131: while (it.hasNext())
132: add_ExceptionSet(n, get_ExceptionSet(it.next()));
133: }
134: }
135:
136: remove_CurExceptionSet();
137: }
138:
139: public IterableSet get_ExceptionSet(Object node) {
140: IterableSet fullSet = node2ExceptionSet.get(node);
141: if (fullSet == null) {
142: fullSet = new IterableSet();
143: node2ExceptionSet.put(node, fullSet);
144: }
145:
146: return fullSet;
147: }
148:
149: public void add_ExceptionSet(Object node, IterableSet s) {
150: IterableSet fullSet = node2ExceptionSet.get(node);
151: if (fullSet == null) {
152: fullSet = new IterableSet();
153: node2ExceptionSet.put(node, fullSet);
154: }
155:
156: fullSet.addAll(s);
157: }
158:
159: private boolean catches_Exception(IterableSet tryExceptionSet,
160: SootClass c) {
161: Iterator it = tryExceptionSet.iterator();
162: while (it.hasNext()) {
163: SootClass thrownException = (SootClass) it.next();
164:
165: while (true) {
166: if (thrownException == c)
167: return true;
168:
169: if (thrownException.hasSuperclass() == false)
170: break;
171:
172: thrownException = thrownException.getSuperclass();
173: }
174: }
175:
176: return false;
177: }
178:
179: private boolean catches_RuntimeException(SootClass c) {
180: if ((c == Scene.v().getSootClass("java.lang.Throwable"))
181: || (c == Scene.v().getSootClass("java.lang.Exception")))
182: return true;
183:
184: SootClass caughtException = c, runtimeException = Scene.v()
185: .getSootClass("java.lang.RuntimeException");
186:
187: while (true) {
188: if (caughtException == runtimeException)
189: return true;
190:
191: if (caughtException.hasSuperclass() == false)
192: return false;
193:
194: caughtException = caughtException.getSuperclass();
195: }
196: }
197: }
|