package soot.dava.toolkits.base.AST.transformations; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import soot.Body; import soot.SootClass; import soot.SootMethod; import soot.dava.DavaBody; import soot.dava.internal.AST.ASTMethodNode; import soot.dava.internal.AST.ASTNode; import soot.util.Chain; /* * It has been seen that Dava's output contains the default constructor with just the invocation * to super() * * According to the java specs the default constructor is not needed unless the constructor has been * overloaded. * * The analysis checks whether there is only one constructor in the class being decompiled. * If this is true and the constructor IS THE DEFAULT CONSTRUCTOR i.e. no arguments * and has an empty body (there will always be a call to super * but that is invoked automatically....) we can remove the constructor from the code * also check tht the call to super has no arguments i.e. default super */ public class RemoveEmptyBodyDefaultConstructor{ public static boolean DEBUG=false; 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); } public static void debug(String debug){ if(DEBUG) System.out.println("DEBUG: "+debug); } }