use of soot.dava.internal.AST.ASTNode in project soot by Sable.
the class DavaStaticBlockCleaner method inline.
/*
* Method called with a sootMethod to decide whether this method should be inlined or not
* returns null if it shouldnt be inlined
*
* A method can be inlined if it belongs to the same class and also if its static....(why???)
*/
public ASTMethodNode inline(SootMethod maybeInline) {
if (sootClass != null) {
// 1, method should belong to the same class as the clinit method
if (sootClass.declaresMethod(maybeInline.getSubSignature())) {
if (Modifier.isStatic(maybeInline.getModifiers())) {
// retireve the active body
if (!maybeInline.hasActiveBody())
throw new RuntimeException("method " + maybeInline.getName() + " has no active body!");
Body bod = maybeInline.getActiveBody();
Chain units = ((DavaBody) bod).getUnits();
if (units.size() != 1) {
throw new RuntimeException("DavaBody AST doesn't have single root.");
}
ASTNode ASTtemp = (ASTNode) units.getFirst();
if (!(ASTtemp instanceof ASTMethodNode))
throw new RuntimeException("Starting node of DavaBody AST is not an ASTMethodNode");
// restricting to methods which do not have any variables declared
ASTMethodNode toReturn = (ASTMethodNode) ASTtemp;
ASTStatementSequenceNode declarations = toReturn.getDeclarations();
if (declarations.getStatements().size() == 0) {
// System.out.println("No declarations in the method. we can inline this method");
return toReturn;
}
}
}
}
// meaning dont inline
return null;
}
use of soot.dava.internal.AST.ASTNode in project soot by Sable.
the class RemoveEmptyBodyDefaultConstructor method checkAndRemoveDefault.
public static void checkAndRemoveDefault(SootClass s) {
debug("\n\nRemoveEmptyBodyDefaultConstructor----" + s.getName());
List methods = s.getMethods();
Iterator it = methods.iterator();
List<SootMethod> constructors = new ArrayList<SootMethod>();
while (it.hasNext()) {
SootMethod method = (SootMethod) it.next();
debug("method name is" + method.getName());
if (method.getName().indexOf("<init>") > -1) {
// constructor add to constructor list
constructors.add(method);
}
}
if (constructors.size() != 1) {
// cant do anything since there are more than one constructors
debug("class has more than one constructors cant do anything");
return;
}
// only one constructor check its default (no arguments)
SootMethod constructor = constructors.get(0);
if (constructor.getParameterCount() != 0) {
// can only deal with default constructors
debug("constructor is not the default constructor");
return;
}
debug("Check that the body is empty....and call to super contains no arguments and delete");
if (!constructor.hasActiveBody()) {
debug("No active body found for the default constructor");
return;
}
Body body = constructor.getActiveBody();
Chain units = ((DavaBody) body).getUnits();
if (units.size() != 1) {
debug(" DavaBody AST does not have single root");
return;
}
ASTNode AST = (ASTNode) units.getFirst();
if (!(AST instanceof ASTMethodNode))
throw new RuntimeException("Starting node of DavaBody AST is not an ASTMethodNode");
ASTMethodNode methodNode = (ASTMethodNode) AST;
debug("got methodnode check body is empty and super has nothing in it");
List<Object> subBodies = methodNode.get_SubBodies();
if (subBodies.size() != 1) {
debug("Method node does not have one subBody!!!");
return;
}
List methodBody = (List) subBodies.get(0);
if (methodBody.size() != 0) {
debug("Method body size is greater than 1 so cant do nothing");
return;
}
debug("Method body is empty...check super call is empty");
if (((DavaBody) body).get_ConstructorExpr().getArgCount() != 0) {
debug("call to super not empty");
return;
}
debug("REMOVE METHOD");
s.removeMethod(constructor);
}
use of soot.dava.internal.AST.ASTNode in project soot by Sable.
the class MethodCallFinder method replaceSubBody.
public boolean replaceSubBody(InvokeStmt s, List<ASTStatementSequenceNode> newChangedBodyPart, ASTParentNodeFinder finder) {
// get the stmt seq node of invoke stmt
Object stmtSeqNode = finder.getParentOf(s);
// find the parent node of the stmt seq node
Object ParentOfStmtSeq = finder.getParentOf(stmtSeqNode);
if (ParentOfStmtSeq == null) {
throw new RuntimeException("MethodCall FInder: parent of stmt seq node not found");
}
ASTNode node = (ASTNode) ParentOfStmtSeq;
if (node instanceof ASTMethodNode) {
// get the subBody to replace
List<Object> subBodyToReplace = getSubBodyFromSingleSubBodyNode(node);
List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
((ASTMethodNode) node).replaceBody(newBody);
return true;
} else if (node instanceof ASTSynchronizedBlockNode) {
// get the subBody to replace
List<Object> subBodyToReplace = getSubBodyFromSingleSubBodyNode(node);
List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
((ASTSynchronizedBlockNode) node).replaceBody(newBody);
return true;
} else if (node instanceof ASTLabeledBlockNode) {
// get the subBody to replace
List<Object> subBodyToReplace = getSubBodyFromSingleSubBodyNode(node);
List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
((ASTLabeledBlockNode) node).replaceBody(newBody);
return true;
} else if (node instanceof ASTUnconditionalLoopNode) {
// get the subBody to replace
List<Object> subBodyToReplace = getSubBodyFromSingleSubBodyNode(node);
List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
((ASTUnconditionalLoopNode) node).replaceBody(newBody);
return true;
} else if (node instanceof ASTIfNode) {
// get the subBody to replace
List<Object> subBodyToReplace = getSubBodyFromSingleSubBodyNode(node);
List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
((ASTIfNode) node).replaceBody(newBody);
return true;
} else if (node instanceof ASTWhileNode) {
// get the subBody to replace
List<Object> subBodyToReplace = getSubBodyFromSingleSubBodyNode(node);
List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
((ASTWhileNode) node).replaceBody(newBody);
return true;
} else if (node instanceof ASTDoWhileNode) {
// get the subBody to replace
List<Object> subBodyToReplace = getSubBodyFromSingleSubBodyNode(node);
List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
((ASTDoWhileNode) node).replaceBody(newBody);
return true;
} else if (node instanceof ASTForLoopNode) {
// get the subBody to replace
List<Object> subBodyToReplace = getSubBodyFromSingleSubBodyNode(node);
List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
((ASTForLoopNode) node).replaceBody(newBody);
return true;
} else if (node instanceof ASTIfElseNode) {
List<Object> subBodies = node.get_SubBodies();
if (subBodies.size() != 2)
throw new RuntimeException("Found an ifelse ASTNode which does not have two bodies");
List<Object> ifBody = (List<Object>) subBodies.get(0);
List<Object> elseBody = (List<Object>) subBodies.get(1);
// find out which of these bodies has the stmt seq node with the
// invoke stmt
int subBodyNumber = -1;
Iterator<Object> it = ifBody.iterator();
while (it.hasNext()) {
Object temp = it.next();
if (temp == stmtSeqNode) {
subBodyNumber = 0;
break;
}
}
if (subBodyNumber != 0) {
it = elseBody.iterator();
while (it.hasNext()) {
Object temp = it.next();
if (temp == stmtSeqNode) {
subBodyNumber = 1;
break;
}
}
}
List<Object> subBodyToReplace = null;
if (subBodyNumber == 0)
subBodyToReplace = ifBody;
else if (subBodyNumber == 1)
subBodyToReplace = elseBody;
else
throw new RuntimeException("Could not find the related ASTNode in the method");
List<Object> newBody = createNewSubBody(subBodyToReplace, newChangedBodyPart, stmtSeqNode);
if (subBodyNumber == 0) {
((ASTIfElseNode) node).replaceBody(newBody, elseBody);
return true;
} else if (subBodyNumber == 1) {
((ASTIfElseNode) node).replaceBody(ifBody, newBody);
return true;
}
} else if (node instanceof ASTTryNode) {
// NOTE THAT method INLINING Is currently only done in the tryBody
// and not the catchBody
// THe only reason for this being that mostly method calls are made
// in the try and not the catch
// get try body
List<Object> tryBody = ((ASTTryNode) node).get_TryBody();
Iterator<Object> it = tryBody.iterator();
// find whether stmtSeqNode is in the tryBody
boolean inTryBody = false;
while (it.hasNext()) {
ASTNode temp = (ASTNode) it.next();
if (temp == stmtSeqNode) {
inTryBody = true;
break;
}
}
if (!inTryBody) {
// return without making any changes
return false;
}
List<Object> newBody = createNewSubBody(tryBody, newChangedBodyPart, stmtSeqNode);
((ASTTryNode) node).replaceTryBody(newBody);
return true;
} else if (node instanceof ASTSwitchNode) {
List<Object> indexList = ((ASTSwitchNode) node).getIndexList();
Map<Object, List<Object>> index2BodyList = ((ASTSwitchNode) node).getIndex2BodyList();
Iterator<Object> it = indexList.iterator();
while (it.hasNext()) {
// going through all the cases of the switch
// statement
Object currentIndex = it.next();
List<Object> body = index2BodyList.get(currentIndex);
if (body != null) {
// this body is a list of ASTNodes
// see if it contains stmtSeqNode
boolean found = false;
Iterator<Object> itBody = body.iterator();
while (itBody.hasNext()) {
ASTNode temp = (ASTNode) itBody.next();
if (temp == stmtSeqNode) {
found = true;
break;
}
}
if (found) {
// this is the body which has the stmt seq node
List<Object> newBody = createNewSubBody(body, newChangedBodyPart, stmtSeqNode);
// put this body in the Map
index2BodyList.put(currentIndex, newBody);
// replace in actual switchNode
((ASTSwitchNode) node).replaceIndex2BodyList(index2BodyList);
return true;
}
}
// if body not null
}
// going through all cases
}
return false;
}
use of soot.dava.internal.AST.ASTNode in project soot by Sable.
the class ReachingDefs method newInitialFlow.
/*
* Initial flow into catch statements is empty meaning no definition reaches
*/
@Override
public DavaFlowSet<Stmt> newInitialFlow() {
DavaFlowSet<Stmt> initial = new DavaFlowSet<Stmt>();
// find all definitions in the program
AllDefinitionsFinder defFinder = new AllDefinitionsFinder();
((ASTNode) toAnalyze).apply(defFinder);
List<DefinitionStmt> allDefs = defFinder.getAllDefs();
// DefinitionStmts
for (DefinitionStmt def : allDefs) initial.add(def);
// initial is not the universal set of all definitions
return initial;
}
use of soot.dava.internal.AST.ASTNode in project soot by Sable.
the class DavaBody method analyzeAST.
/*
* Method is invoked by the packmanager just before it is actually about to generate
* decompiled code. Works as a separate stage from the DavaBody() constructor.
* All AST transformations should be implemented from within this method.
*
* Method is also invoked from the InterProceduralAnlaysis method once those have been invoked
*/
public void analyzeAST() {
ASTNode AST = (ASTNode) this.getUnits().getFirst();
debug("analyzeAST", "Applying AST analyzes for method" + this.getMethod().toString());
/*
* Nomair A. Naeem
* tranformations on the AST
* Any AST Transformations added should be added to the applyASTAnalyses method
* unless we are want to delay the analysis till for example THE LAST THING DONE
*/
applyASTAnalyses(AST);
/*
* Nomair A. Naeem
* apply structural flow analyses now
*
*/
debug("analyzeAST", "Applying structure analysis" + this.getMethod().toString());
applyStructuralAnalyses(AST);
debug("analyzeAST", "Applying structure analysis DONE" + this.getMethod().toString());
/*
* Renamer
* March 28th Nomair A. Naeem. Since there is a chance
* that the analyze method gets involved multiple times
* we dont want renaming done more than once.
*
* hence removing the call of the renamer from here
* Also looking ahead i have a feeling that we will be going interprocedural
* for the renamer hence i am placing the renamer code
* inside the interprocedural class
*/
/*
In the end check
1, if there are labels which can be safely removed
2, int temp; temp=0 to be converted to int temp=0;
*/
// AST.apply(new ExtraLabelNamesRemover());
// System.out.println("\nEND analyzing method"+this.getMethod().toString());
}
Aggregations