001: /* Soot - a J*va Optimization Framework
002: * Copyright (C) 2005 Nomair A. Naeem
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: /*
021: * Maintained by Nomair A. Naeem
022: */
023:
024: /*
025: * Change log: * November 22nd 2005: Moved this class from structuredAnalysis
026: * package to traversals package. Since this is a traversal not an analysis
027: *
028: */
029:
030: package soot.dava.toolkits.base.AST.traversals;
031:
032: import java.util.*;
033:
034: import soot.Unit;
035: import soot.jimple.*;
036: import soot.dava.internal.AST.*;
037: import soot.dava.internal.javaRep.*;
038: import soot.dava.toolkits.base.AST.analysis.*;
039:
040: /*
041: * This traversal class is responsible to gather information
042: * regarding the different nodes and statements in the AST.
043: * The class produces a HashMap between the node/statement given as
044: * key and the parent of this construct (value)
045: *
046: * November 23rd, 2005. (Nomair) It is used for instance in the CopyPropagation algorithm
047: * to be able to remove a particular copy
048: * stmt for instance from its parent.
049: */
050:
051: public class ASTParentNodeFinder extends DepthFirstAdapter {
052:
053: HashMap<Unit, ASTNode> parentOf;
054: Stack<ASTNode> parentStack;
055:
056: public ASTParentNodeFinder() {
057: parentOf = new HashMap<Unit, ASTNode>();
058: parentStack = new Stack<ASTNode>();
059: }
060:
061: public ASTParentNodeFinder(boolean verbose) {
062: super (verbose);
063: parentOf = new HashMap<Unit, ASTNode>();
064: parentStack = new Stack<ASTNode>();
065: }
066:
067: public void inASTMethodNode(ASTMethodNode node) {
068: parentOf.put(node, null);
069: parentStack.push(node);
070: }
071:
072: public void outASTMethodNode(ASTMethodNode node) {
073: parentStack.pop();
074: }
075:
076: public void inASTSynchronizedBlockNode(ASTSynchronizedBlockNode node) {
077: parentOf.put(node, parentStack.peek());
078: parentStack.push(node);
079: }
080:
081: public void outASTSynchronizedBlockNode(
082: ASTSynchronizedBlockNode node) {
083: parentStack.pop();
084: }
085:
086: public void inASTLabeledBlockNode(ASTLabeledBlockNode node) {
087: parentOf.put(node, parentStack.peek());
088: parentStack.push(node);
089: }
090:
091: public void outASTLabeledBlockNode(ASTLabeledBlockNode node) {
092: parentStack.pop();
093: }
094:
095: public void inASTUnconditionalLoopNode(ASTUnconditionalLoopNode node) {
096: parentOf.put(node, parentStack.peek());
097: parentStack.push(node);
098: }
099:
100: public void outASTUnconditionalLoopNode(
101: ASTUnconditionalLoopNode node) {
102: parentStack.pop();
103: }
104:
105: public void inASTSwitchNode(ASTSwitchNode node) {
106: parentOf.put(node, parentStack.peek());
107: parentStack.push(node);
108: }
109:
110: public void outASTSwitchNode(ASTSwitchNode node) {
111: parentStack.pop();
112: }
113:
114: public void inASTIfNode(ASTIfNode node) {
115: parentOf.put(node, parentStack.peek());
116: parentStack.push(node);
117: }
118:
119: public void outASTIfNode(ASTIfNode node) {
120: parentStack.pop();
121: }
122:
123: public void inASTIfElseNode(ASTIfElseNode node) {
124: parentOf.put(node, parentStack.peek());
125: parentStack.push(node);
126: }
127:
128: public void outASTIfElseNode(ASTIfElseNode node) {
129: parentStack.pop();
130: }
131:
132: public void inASTWhileNode(ASTWhileNode node) {
133: parentOf.put(node, parentStack.peek());
134: parentStack.push(node);
135: }
136:
137: public void outASTWhileNode(ASTWhileNode node) {
138: parentStack.pop();
139: }
140:
141: public void inASTForLoopNode(ASTForLoopNode node) {
142: parentOf.put(node, parentStack.peek());
143: parentStack.push(node);
144: }
145:
146: public void outASTForLoopNode(ASTForLoopNode node) {
147: parentStack.pop();
148: }
149:
150: public void inASTDoWhileNode(ASTDoWhileNode node) {
151: parentOf.put(node, parentStack.peek());
152: parentStack.push(node);
153: }
154:
155: public void outASTDoWhileNode(ASTDoWhileNode node) {
156: parentStack.pop();
157: }
158:
159: public void inASTTryNode(ASTTryNode node) {
160: parentOf.put(node, parentStack.peek());
161: parentStack.push(node);
162: }
163:
164: public void outASTTryNode(ASTTryNode node) {
165: parentStack.pop();
166: }
167:
168: public void inASTStatementSequenceNode(ASTStatementSequenceNode node) {
169: parentOf.put(node, parentStack.peek());
170: parentStack.push(node);
171: }
172:
173: public void outASTStatementSequenceNode(
174: ASTStatementSequenceNode node) {
175: parentStack.pop();
176: }
177:
178: public void inDefinitionStmt(DefinitionStmt s) {
179: parentOf.put(s, parentStack.peek());
180: }
181:
182: public void inReturnStmt(ReturnStmt s) {
183: parentOf.put(s, parentStack.peek());
184: }
185:
186: public void inInvokeStmt(InvokeStmt s) {
187: parentOf.put(s, parentStack.peek());
188: }
189:
190: public void inThrowStmt(ThrowStmt s) {
191: parentOf.put(s, parentStack.peek());
192: }
193:
194: public void inDVariableDeclarationStmt(DVariableDeclarationStmt s) {
195: parentOf.put(s, parentStack.peek());
196: }
197:
198: public void inStmt(Stmt s) {
199: parentOf.put(s, parentStack.peek());
200: }
201:
202: /*
203: * This is the method which should be invoked by classes needing parent information.
204: * When the method is invoked with a statement or node as input it returns the parent
205: * of that object. The parent can safely be casted to ASTNode as long as the parent
206: * returned is non null
207: */
208: public Object getParentOf(Object statementOrNode) {
209: return parentOf.get(statementOrNode);
210: }
211: }
|