/** * Calculate cyclomatic complexity number * * We can calculate ccn in two ways (we choose the second): * * 1. Cyclomatic complexity (CC) = E - N + 2P * Where: * P = number of disconnected parts of the flow graph (e.g. a calling program and a subroutine) * E = number of edges (transfers of control) * N = number of nodes (sequential group of statements containing only one transfer of control) * * 2. CC = Number of each decision point * * @param string $filename * @return Result */ public function calculate($filename) { $info = new Result(); $tokens = $this->tokenizer->tokenize($filename); $ccn = 0; foreach ($tokens as $token) { switch ($token->getType()) { case T_IF: case T_ELSEIF: case T_FOREACH: case T_FOR: case T_WHILE: case T_DO: case T_BOOLEAN_AND: case T_LOGICAL_AND: case T_BOOLEAN_OR: case T_LOGICAL_OR: case T_CASE: case T_DEFAULT: case T_CATCH: case T_CONTINUE: $ccn++; break; } } $info->setCyclomaticComplexityNumber(max(1, $ccn)); return $info; }
/** * Calculates Maintainability Index * * @param \Hal\Metrics\Complexity\Text\Halstead\Result $rHalstead * @param \Hal\Metrics\Complexity\Text\Length\Result $rLoc * @param \Hal\Metrics\Complexity\Component\McCabe\Result $rMcCabe * @return Result */ public function calculate(\Hal\Metrics\Complexity\Text\Halstead\Result $rHalstead, \Hal\Metrics\Complexity\Text\Length\Result $rLoc, \Hal\Metrics\Complexity\Component\McCabe\Result $rMcCabe) { $result = new Result(); $result->setMaintainabilityIndexWithoutComment(max((171 - 5.2 * \log($rHalstead->getVolume()) - 0.23 * $rMcCabe->getCyclomaticComplexityNumber() - 16.2 * \log($rLoc->getLogicalLoc())) * 100 / 171, 0)); // comment weight if ($rLoc->getLoc() > 0) { $CM = $rLoc->getCommentLoc() / $rLoc->getLoc(); $result->setCommentWeight(50 * sin(sqrt(2.4 * $CM))); } return $result; }
/** * Calculate cyclomatic complexity number * * We can calculate ccn in two ways (we choose the second): * * 1. Cyclomatic complexity (CC) = E - N + 2P * Where: * P = number of disconnected parts of the flow graph (e.g. a calling program and a subroutine) * E = number of edges (transfers of control) * N = number of nodes (sequential group of statements containing only one transfer of control) * * 2. CC = Number of each decision point * * @param string $filename * @return Result */ public function calculate($filename) { $info = new Result(); $tokens = $this->tokenizer->tokenize($filename); $ccn = 1; // default path foreach ($tokens as $token) { switch ($token->getType()) { case T_IF: case T_ELSEIF: case T_FOREACH: case T_FOR: case T_WHILE: case T_DO: case T_BOOLEAN_AND: case T_LOGICAL_AND: case T_BOOLEAN_OR: case T_LOGICAL_OR: case T_SPACESHIP: case T_CASE: case T_DEFAULT: case T_CATCH: case T_CONTINUE: $ccn++; break; case T_STRING: if ('?' == $token->getValue()) { $ccn = $ccn + 2; } break; case T_COALESCE: $ccn = $ccn + 2; break; } } $info->setCyclomaticComplexityNumber(max(1, $ccn)); return $info; }
/** * get the cyclomatic complexity number * * @return int */ public function getCyclomaticComplexityNumber() { return !is_null($this->mcCabe) ? $this->mcCabe->getCyclomaticComplexityNumber() : 0; }
public function testMcCaybeResultCanBeConvertedToArray() { $result = new \Hal\Metrics\Complexity\Component\McCabe\Result(); $array = $result->asArray(); $this->assertArrayHasKey('cyclomaticComplexity', $array); }