Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
331 changes: 175 additions & 156 deletions src/main/java/analyzer/visitors/ClassComplexityVisitor.java
Original file line number Diff line number Diff line change
@@ -1,167 +1,186 @@
package analyzer.visitors;

import analyzer.AbstractVoidVisitorAdapter;
import analyzer.ComplexityCounter;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.stmt.*;
import com.github.javaparser.ast.expr.BinaryExpr;
import com.github.javaparser.ast.expr.ConditionalExpr;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.stmt.CatchClause;
import com.github.javaparser.ast.stmt.ContinueStmt;
import com.github.javaparser.ast.stmt.ForStmt;
import com.github.javaparser.ast.stmt.ForeachStmt;
import com.github.javaparser.ast.stmt.IfStmt;
import com.github.javaparser.ast.stmt.Statement;
import com.github.javaparser.ast.stmt.SwitchEntryStmt;
import com.github.javaparser.ast.stmt.ThrowStmt;
import com.github.javaparser.ast.stmt.TryStmt;
import com.github.javaparser.ast.stmt.WhileStmt;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import analyzer.AbstractVoidVisitorAdapter;
import analyzer.ComplexityCounter;

/**
* Created by laurynassakalauskas on 15/10/2016.
*/
public class ClassComplexityVisitor extends AbstractVoidVisitorAdapter<ComplexityCounter> {

protected String methodName;

/**
* Before visiting any method, mark the method name, so we could collect it later.
*
* @param declaration
* @param counter
*/
public void visit(MethodDeclaration declaration, ComplexityCounter counter) {

methodName = declaration.getNameAsString();

super.visit(declaration, counter);
}


/**
* Count foreach statements
*
* @param statement
* @param counter
*/
@Override
public void visit(ForeachStmt statement, ComplexityCounter counter) {
counter.add(methodName, "FOREACH");

super.visit(statement, counter);
}

/**
* Count for statements
*
* @param statement
* @param counter
*/
@Override
public void visit(ForStmt statement, ComplexityCounter counter) {
counter.add(methodName, "FOR");

super.visit(statement, counter);
}

/**
* Count if/else statements
*
* @param statement
* @param counter
*/
@Override
public void visit(IfStmt statement, ComplexityCounter counter) {
counter.add(methodName, "IF");

if(statement.getElseStmt() != null) {
counter.add(methodName, "ELSE");
}


String condition = statement.getCondition().toString();

regexCheck(condition, Pattern.compile("/(\\s|\\w|\\d)&(\\s|\\w|\\d)/xg"), "BITWISE_AND_OPERATOR", counter);
regexCheck(condition, Pattern.compile("/(\\s|\\w|\\d)\\|(\\s|\\w|\\d)/xg"), "BITWISE_OR_OPERATOR", counter);
regexCheck(condition, Pattern.compile("/(\\s|\\w|\\d)&&(\\s|\\w|\\d)/xg"), "AND_OPERATOR", counter);
regexCheck(condition, Pattern.compile("/(\\s|\\w|\\d)\\|\\|(\\s|\\w|\\d)/xg"), "OR_OPERATOR", counter);


super.visit(statement, counter);
}


private void regexCheck(String haystack, Pattern pattern, String type, ComplexityCounter counter) {
Matcher matcher = pattern.matcher(haystack);

while (matcher.find()) {
counter.add(methodName, type);
}
}

/**
* Count switch statements
*
* @param statement
* @param counter
*/
@Override
public void visit(SwitchEntryStmt statement, ComplexityCounter counter) {


for (Statement st :statement.getStatements()) {

counter.add(methodName, "SWITCH");

}

super.visit(statement, counter);
}

/**
* Count throw statements
*
* @param statement
* @param counter
*/
@Override
public void visit(ThrowStmt statement, ComplexityCounter counter) {

counter.add(methodName, "THROW");

super.visit(statement, counter);
}

/**
* Count try statements
*
* @param statement
* @param counter
*/
@Override
public void visit(TryStmt statement, ComplexityCounter counter) {

counter.add(methodName, "TRY");

super.visit(statement, counter);
}

/**
* Count catch statements
*
* @param statement
* @param counter
*/
@Override
public void visit(CatchClause statement, ComplexityCounter counter) {

counter.add(methodName, "CATCH");

super.visit(statement, counter);
}

/**
* Count while statements
*
* @param statement
* @param counter
*/
@Override
public void visit(WhileStmt statement, ComplexityCounter counter) {

counter.add(methodName, "WHILE");

super.visit(statement, counter);
}
protected String methodName;

/**
* Before visiting any method, mark the method name, so we could collect it
* later.
*
* @param declaration
* @param counter
*/
public void visit(MethodDeclaration declaration, ComplexityCounter counter) {

methodName = declaration.getNameAsString();

super.visit(declaration, counter);
}

/**
* Count foreach statements
*
* @param statement
* @param counter
*/
@Override
public void visit(ForeachStmt statement, ComplexityCounter counter) {
counter.add(methodName, "FOREACH");

super.visit(statement, counter);
}

/**
* Count for statements
*
* @param statement
* @param counter
*/
@Override
public void visit(ForStmt statement, ComplexityCounter counter) {
counter.add(methodName, "FOR");

super.visit(statement, counter);
}

/**
* Count if/else statements
*
* @param statement
* @param counter
*/
@Override
public void visit(IfStmt statement, ComplexityCounter counter) {
counter.add(methodName, "IF");

// The else should not count. this block cause double count on elseif block.
// if (statement.getElseStmt() != null) {
// counter.add(methodName, "ELSE");
// }

analyzeCondition(statement.getCondition(), counter);

super.visit(statement, counter);
}

/**
* Count switch statements
*
* @param statement
* @param counter
*/
@Override
public void visit(SwitchEntryStmt statement, ComplexityCounter counter) {

for (@SuppressWarnings("unused") Statement st : statement.getStatements()) {

counter.add(methodName, "SWITCH");

}

super.visit(statement, counter);
}

/**
* Count throw statements
*
* @param statement
* @param counter
*/
@Override
public void visit(ThrowStmt statement, ComplexityCounter counter) {

counter.add(methodName, "THROW");

super.visit(statement, counter);
}


/**
* Count catch statements
*
* @param statement
* @param counter
*/
@Override
public void visit(CatchClause statement, ComplexityCounter counter) {

counter.add(methodName, "CATCH");

super.visit(statement, counter);
}

/**
* Count while statements
*
* @param statement
* @param counter
*/
@Override
public void visit(WhileStmt statement, ComplexityCounter counter) {

counter.add(methodName, "WHILE");

analyzeCondition(statement.getCondition(), counter);

super.visit(statement, counter);
}

/**
* Count continue statements
*
* @param statement
* @param counter
*/
@Override
public void visit(ContinueStmt statement, ComplexityCounter counter) {
counter.add(methodName, "CONTINUE");
super.visit(statement, counter);
}


/**
* Count condition expression
*
* @param expression
* @param counter
*/
@Override
public void visit(ConditionalExpr expression, ComplexityCounter counter) {
counter.add(methodName, "CONDITIONAL");
analyzeCondition(expression.getCondition(), counter);

super.visit(expression, counter);
}

private void analyzeCondition(Expression condition, ComplexityCounter counter) {

if (condition.getMetaModel().getType().equals(BinaryExpr.class)) {

new ConditinalOperatorComplexityVisitor(methodName).visit((BinaryExpr) condition, counter);

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package analyzer.visitors;

import com.github.javaparser.ast.expr.BinaryExpr;
import com.github.javaparser.ast.expr.BinaryExpr.Operator;

import analyzer.AbstractVoidVisitorAdapter;
import analyzer.ComplexityCounter;

public class ConditinalOperatorComplexityVisitor extends AbstractVoidVisitorAdapter<ComplexityCounter> {

private String methodName;

public ConditinalOperatorComplexityVisitor(String methodName) {
super();
this.methodName = methodName;
}

@Override
public void visit(BinaryExpr expr, ComplexityCounter counter) {
Operator operator = expr.getOperator();
switch (operator) {
case BINARY_AND:
counter.add(methodName, "BITWISE_AND_OPERATOR");
break;
case BINARY_OR:
counter.add(methodName, "BITWISE_OR_OPERATOR");
break;
case AND:
counter.add(methodName, "AND_OPERATOR");
break;
case OR:
counter.add(methodName, "OR_OPERATOR");
break;
default:
break;
}
super.visit(expr, counter);
}

}