ComplexityVisitor extends PHPVisitorCheck { public static int complexity(Tree tree) { return complexityTrees(tree).size(); }  @Override void visitCaseClause(CaseClauseTree tree); @Override void visitWhileStatement(WhileStatementTree tree); @Override void visitDoWhileStatement(DoWhileStatementTree tree); @Override void visitIfStatement(IfStatementTree tree); @Override void visitForStatement(ForStatementTree tree); @Override void visitForEachStatement(ForEachStatementTree tree); @Override void visitConditionalExpression(ConditionalExpressionTree tree); @Override void visitBinaryExpression(BinaryExpressionTree tree); @Override void visitMethodDeclaration(MethodDeclarationTree tree); @Override void visitFunctionDeclaration(FunctionDeclarationTree tree); @Override void visitFunctionExpression(FunctionExpressionTree tree); @Override void visitArrowFunctionExpression(ArrowFunctionExpressionTree tree); static int complexity(Tree tree); static List<Tree> complexityTrees(Tree tree); static List<Tree> complexityNodesWithoutNestedFunctions(Tree tree);  }
@Test public void declarations() throws Exception { assertOneComplexityToken("function f() {}", "function"); assertOneComplexityToken("$f = function() {};", "function"); assertOneComplexityToken("$f = fn() => 0;", "fn"); assertThat(complexity("class A {}")).isEqualTo(0); assertOneComplexityToken("class A { public function f() {} }", "function"); assertThat(complexity("function f() { f(); return; }")).isEqualTo(1); assertThat(complexity("function f() { return; f(); }")).isEqualTo(1); assertThat(complexity("class A { abstract function f(); }")).isEqualTo(1); assertThat(expressionComplexity("function() { return $a && $b; };")).isEqualTo(2); assertThat(expressionComplexity("fn() => $a && $b;")).isEqualTo(2); }
@Test public void statements() throws Exception { assertThat(complexity("$a = 0;")).isEqualTo(0); assertOneComplexityToken("if ($a) {}", "if"); assertOneComplexityToken("if ($a) {} else {}", "if"); assertThat(complexity("if ($a) {} else if($b) {} else {}")).isEqualTo(2); assertOneComplexityToken("if ($a): endif;", "if"); assertOneComplexityToken("for (;;) {}", "for"); assertOneComplexityToken("foreach ($a as $b) {}", "foreach"); assertOneComplexityToken("while ($a) {}", "while"); assertOneComplexityToken("do {} while($a);", "do"); assertThat(complexity("switch ($a) {}")).isEqualTo(0); assertOneComplexityToken("switch ($a) {case 1:}", "case"); assertThat(complexity("switch ($a) {default:}")).isEqualTo(0); assertThat(complexity("try {}")).isEqualTo(0); assertThat(complexity("try {} catch(E $s) {}")).isEqualTo(0); assertThat(complexity("return 1;")).isEqualTo(0); assertThat(complexity("throw e;")).isEqualTo(0); assertThat(complexity("goto x;")).isEqualTo(0); }
@Test public void expressions() throws Exception { assertThat(complexity("$a;")).isEqualTo(0); assertThat(complexity("$a + $b;")).isEqualTo(0); assertThat(complexity("$f();")).isEqualTo(0); assertOneComplexityToken("$a || $b;", "||"); assertOneComplexityToken("$a && $b;", "&&"); assertOneComplexityToken("$a or $b;", "or"); assertOneComplexityToken("$a and $b;", "and"); assertOneComplexityToken("$a ? $b : $c;", "?"); }