0

For an assignment, I have to find nodes in a java class that meet a certain requirement(being useless). I figured out how to find the required nodes and add them to a separate list but the assignment requires that I list the method names that these nodes belong to in the original java class. Does javaparser offer a way to do this?

My Code:

public class UselessControlFlowDetector extends VoidVisitorAdapter <Void> {

    public static List<Node> ucfNodes = new ArrayList<Node>();

    @Override
    public void visit(MethodDeclaration md, Void arg) {
        super.visit(md, arg);
        String methodName = md.getName().asString();
        int begin = md.getRange().get().begin.line;
        int end =md.getRange().get().end.line;
        int length = end-begin;
        System.out.println(methodName+"|"+length);
        List<IfStmt> nodeListIf = md.findAll(IfStmt.class);
        System.out.println(nodeListIf.toString());
    }

    public static  void findUselessNodes(CompilationUnit cu) {
        //NODE LISTS
        List<IfStmt> nodeListIf = cu.findAll(IfStmt.class);
        List<ForStmt> nodeListFor = cu.findAll(ForStmt.class);
        List<SwitchStmt> nodeListSwitch = cu.findAll(SwitchStmt.class);
        List<WhileStmt> nodeListWhile = cu.findAll(WhileStmt.class);
        List<DoStmt> nodeListDo = cu.findAll(DoStmt.class);
        List<Node> nodeListTotal = new ArrayList<Node>();
        nodeListTotal.addAll(nodeListIf);
        nodeListTotal.addAll(nodeListFor);
        nodeListTotal.addAll(nodeListSwitch);
        nodeListTotal.addAll(nodeListWhile);
        nodeListTotal.addAll(nodeListDo);

        for(int i = 0; i < nodeListTotal.size(); i++) {
            //System.out.println("STARTOFNODE##########");
            //System.out.println(nodeListTotal.get(i).toString());
            //System.out.println("\n" + "Node has " + (nodeListTotal.get(i).getChildNodes().size() - 1) + " child nodes!");
            for(int j = 1; j < nodeListTotal.get(i).getChildNodes().size(); j++) {
                //System.out.println("----------");
                //System.out.println("Child Node " + j);
                if(nodeListTotal.get(i).getChildNodes().get(j).toString().equals("{\r\n" + 
                        "}")) {
                    //System.out.println("Node is empty! Useless control flow found!");
                    System.out.println(nodeListTotal.get(i).getRange().get().begin.line);
                    System.out.println(nodeListTotal.get(i).getRange().get().end.line);
                    //System.out.println(nodeListTotal.get(i).getParentNode());
                    ucfNodes.add(nodeListTotal.get(i));
                }else {
                    //System.out.println(nodeListTotal.get(i).getChildNodes().get(j));
                }
                //System.out.println("----------");
            }
            //System.out.println("ENDOFNODE##########");
        }

        System.out.println("\n" + "Useless nodes found: " + ucfNodes.size());
        for(int i = 0; i < ucfNodes.size(); i++) {
            System.out.println("----------");
            System.out.println("Useless Node #" + (i+1));
            System.out.println(ucfNodes.get(i));
            System.out.println("----------");
            for(int j = 1; j < ucfNodes.get(i).getChildNodes().size(); j++) {
                if(ucfNodes.get(i).getChildNodes().get(j).toString().equals("{\r\n" + 
                        "}")) {
                    System.out.println("Child Node " + j + " is empty!");
                    System.out.println("----------");
                }
            }
        }
    }

    public static class Driver {
        private static final String FILE_PATH = "src/main/java/main/Calculator.java";

        public static void run(){
            try {
                CompilationUnit cu = JavaParser.parse(new FileInputStream(FILE_PATH));
                findUselessNodes(cu);
                VoidVisitor<?> methodVisitor = new MethodAnalyser();
                methodVisitor.visit(cu, null);
            }catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Driver.run();
    }

}
pkovacs92
  • 1
  • 2
  • Did you try searching up the [`getParentNode()`](https://www.javadoc.io/static/com.github.javaparser/javaparser-core/3.15.15/com/github/javaparser/ast/Node.html#getParentNode--) chain for the [`CallableDeclaration`](https://www.javadoc.io/static/com.github.javaparser/javaparser-core/3.15.15/com/github/javaparser/ast/body/CallableDeclaration.html) (method or constructor)? – Andreas Mar 10 '20 at 01:44
  • You need to find which ancestors of each node satisfies: `instanceof BodyDeclaration` and `isMethodDeclaration()`. – sprinter Mar 10 '20 at 03:43
  • I'm sorry, can you give me an example how to pull this off? I tried if(parentNode instanceof CallableDeclaration) but it doesnt seem to work, it gives me an error saying that is incompatible with Node. – pkovacs92 Mar 10 '20 at 17:02

1 Answers1

0

This is a little late answer
There are many ways to get a method name.

Here is one of the ways to get the method name in your visit() method

@Override
public void visit(MethodDeclaration md, Void arg) {
    BreadthFirstIterator bfi = new BreadthFirstIterator(md);
    while (bfi.hasNext()) {
        Node node = bfi.next();
        if (node instanceof Modifier) {
            System.out.println("Method name: " + bfi.next().toString());
            break;
        }
    }
}

There will be more efficient and simple ways.

Dharman
  • 30,962
  • 25
  • 85
  • 135
wazz
  • 11
  • 5