Search code examples
javastatic-analysisjavaparser

Is there a way to get all the statements in a method without manually traversing the AST


just wondering if there is a way to get all the statements in a method without manually traversing the AST of a method.

So far I've tried to get all of the statements by manually traversing through the tree which is generally a bad idea and tricky to do as well.

public void visit(MethodDeclaration n, Object arg) {
        int total = 0;
        NodeList<Statement> statements = n.getBody().get().getStatements();
        for(Node node: statements) {
            //System.out.println(node.getClass());
            if(node instanceof ExpressionStmt) {
                if(node.toString().contains("=")) {
                    total++;
                }
            }
        }
        super.visit(n, arg);
        System.out.println(total);
    }

The code above works but It gets only the statements at the same depth level of the tree rather than all of statements of all the depth levels of the AST If anyone could help it would be much appreciated.


Solution

  • You need to use another visitor if you want to get through all of statements of all the depth levels of the AST.

    Based on your example:

    /**
     * Visitor which counts expression statements
     */
    GenericVisitorAdapter<ExpressionStmt, Integer> expressionsCountVisitor = new GenericVisitorAdapter<ExpressionStmt, Integer>() {
    
            /**
             * This is based on your example
             */
            @Override
            public ExpressionStmt visit(ExpressionStmt expressionStmt, Integer count) {
                if(expressionStmt.toString().contains("=")) {
                    count++;
                }
                return super.visit(expressionStmt, count);
            }
    
            /**
             * But better to check for AssignExpr instead of ".contains("=")"
             */
            @Override
            public ExpressionStmt visit(AssignExpr assignExpr, Integer count) {
                // counts each "=" assign expression
                count++;
                return super.visit(assignExpr, count);
            }
    
        };
    
    // And then use this visitor for each MethodDecalration
    
    public void visit(MethodDeclaration methodDeclaration, Object arg) {
        Integer total = 0;
        // traverses down the hierarchy of this method declaration
        methodDeclaration.accept(expressionsCountVisitor, total);
        super.visit(methodDeclaration, arg);
        System.out.println(total);
    }