/* 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. */ /* * Maintained by Nomair A. Naeem */ /* * Change log: * November 22nd 2005: Moved this class from structuredAnalysis * package to traversals package. Since this is a traversal not an analysis * */ package soot.dava.toolkits.base.AST.traversals; import java.util.*; import soot.Unit; import soot.jimple.*; import soot.dava.internal.AST.*; import soot.dava.internal.javaRep.*; import soot.dava.toolkits.base.AST.analysis.*; /* * This traversal class is responsible to gather information * regarding the different nodes and statements in the AST. * The class produces a HashMap between the node/statement given as * key and the parent of this construct (value) * * November 23rd, 2005. (Nomair) It is used for instance in the CopyPropagation algorithm * to be able to remove a particular copy * stmt for instance from its parent. */ public class ASTParentNodeFinder extends DepthFirstAdapter{ HashMap<Unit, ASTNode> parentOf; Stack<ASTNode> parentStack; public ASTParentNodeFinder(){ parentOf = new HashMap<Unit, ASTNode>(); parentStack = new Stack<ASTNode>(); } public ASTParentNodeFinder(boolean verbose){ super(verbose); parentOf = new HashMap<Unit, ASTNode>(); parentStack = new Stack<ASTNode>(); } public void inASTMethodNode(ASTMethodNode node){ parentOf.put(node,null); parentStack.push(node); } public void outASTMethodNode(ASTMethodNode node){ parentStack.pop(); } public void inASTSynchronizedBlockNode(ASTSynchronizedBlockNode node){ parentOf.put(node,parentStack.peek()); parentStack.push(node); } public void outASTSynchronizedBlockNode(ASTSynchronizedBlockNode node){ parentStack.pop(); } public void inASTLabeledBlockNode (ASTLabeledBlockNode node){ parentOf.put(node,parentStack.peek()); parentStack.push(node); } public void outASTLabeledBlockNode (ASTLabeledBlockNode node){ parentStack.pop(); } public void inASTUnconditionalLoopNode (ASTUnconditionalLoopNode node){ parentOf.put(node,parentStack.peek()); parentStack.push(node); } public void outASTUnconditionalLoopNode (ASTUnconditionalLoopNode node){ parentStack.pop(); } public void inASTSwitchNode(ASTSwitchNode node){ parentOf.put(node,parentStack.peek()); parentStack.push(node); } public void outASTSwitchNode(ASTSwitchNode node){ parentStack.pop(); } public void inASTIfNode(ASTIfNode node){ parentOf.put(node,parentStack.peek()); parentStack.push(node); } public void outASTIfNode(ASTIfNode node){ parentStack.pop(); } public void inASTIfElseNode(ASTIfElseNode node){ parentOf.put(node,parentStack.peek()); parentStack.push(node); } public void outASTIfElseNode(ASTIfElseNode node){ parentStack.pop(); } public void inASTWhileNode(ASTWhileNode node){ parentOf.put(node,parentStack.peek()); parentStack.push(node); } public void outASTWhileNode(ASTWhileNode node){ parentStack.pop(); } public void inASTForLoopNode(ASTForLoopNode node){ parentOf.put(node,parentStack.peek()); parentStack.push(node); } public void outASTForLoopNode(ASTForLoopNode node){ parentStack.pop(); } public void inASTDoWhileNode(ASTDoWhileNode node){ parentOf.put(node,parentStack.peek()); parentStack.push(node); } public void outASTDoWhileNode(ASTDoWhileNode node){ parentStack.pop(); } public void inASTTryNode(ASTTryNode node){ parentOf.put(node,parentStack.peek()); parentStack.push(node); } public void outASTTryNode(ASTTryNode node){ parentStack.pop(); } public void inASTStatementSequenceNode(ASTStatementSequenceNode node){ parentOf.put(node,parentStack.peek()); parentStack.push(node); } public void outASTStatementSequenceNode(ASTStatementSequenceNode node){ parentStack.pop(); } public void inDefinitionStmt(DefinitionStmt s){ parentOf.put(s,parentStack.peek()); } public void inReturnStmt(ReturnStmt s){ parentOf.put(s,parentStack.peek()); } public void inInvokeStmt(InvokeStmt s){ parentOf.put(s,parentStack.peek()); } public void inThrowStmt(ThrowStmt s){ parentOf.put(s,parentStack.peek()); } public void inDVariableDeclarationStmt(DVariableDeclarationStmt s){ parentOf.put(s,parentStack.peek()); } public void inStmt(Stmt s){ parentOf.put(s,parentStack.peek()); } /* * This is the method which should be invoked by classes needing parent information. * When the method is invoked with a statement or node as input it returns the parent * of that object. The parent can safely be casted to ASTNode as long as the parent * returned is non null */ public Object getParentOf(Object statementOrNode){ return parentOf.get(statementOrNode); } }