javaif-statementjavaparser

Google javaparser IfStmt not counting consequent <else-if>


I am using Google javaparser to parse the java file, when I try to count the "If" statement, it seems like I can not get the number of "else-if" statement.

For example, I want to parse the following code:

    if(i>1){
      i++;
    }else if(i>2){
      i++;
    }else if(i>3){
      i++;
    }else{
      i++;
    }

I want to get the Cyclomatic complexity so that I need to count the number of "if" and "else-if". When I use Visitor pattern, I can only visit the "IfStmt" defined in the API, the code looks like:

    private static class IfStmtVisitor extends VoidVisitorAdapter<Void> {
    int i = 0;

    @Override
    public void visit(IfStmt n, Void arg) {
        //visit a if statement, add 1
        i++;
        if (n.getElseStmt() != null) {
            i++;
        }
    }

    public int getNumber() {
        return i;
    }
}

There is no way to get "else-if" but the Visitor pattern with "IfStmt" treats the whole code block as one "if" Statement.So, I expect the number to be 4, but it is 2.

Anyone have some idea?


Solution

  • A if-statement only contains one "then Statement" and one "else Statement". The else Statement can be a hidden if statement. So there is a recursivity. To track your needed complexity the following recursive method may help:

    private static class IfStmtVisitor extends VoidVisitorAdapter<Void> {
        int i = 0;
    
        @Override
        public void visit(IfStmt n, Void arg) 
        {
            cyclomaticCount(n);
        }
    
        private void cyclomaticCount(IfStmt n)
        {
            // one for the if-then
            i++;
            Statement elseStmt = n.getElseStmt();
            if (elseStmt != null)
            {
                if (  IfStmt.class.isAssignableFrom(elseStmt.getClass())) 
                {
                    cyclomaticCount((IfStmt) elseStmt);
                }
                else
                {
                    // another for the else
                    i++;
                }
            }
        }
    
        public int getNumber() {
            return i;
        }
    }
    

    Hope that helps.