protected function calculateStatistics()
{
$classStack = $functionStack = [];
if ($this->cacheTokens) {
$tokens = \PHP_Token_Stream_CachingFactory::get($this->getPath());
} else {
$tokens = new \PHP_Token_Stream($this->getPath());
}
$this->processClasses($tokens);
$this->processTraits($tokens);
$this->processFunctions($tokens);
$this->linesOfCode = $tokens->getLinesOfCode();
unset($tokens);
for ($lineNumber = 1; $lineNumber <= $this->linesOfCode['loc']; $lineNumber++) {
if (isset($this->startLines[$lineNumber])) {
// Start line of a class.
if (isset($this->startLines[$lineNumber]['className'])) {
if (isset($currentClass)) {
$classStack[] =& $currentClass;
}
$currentClass =& $this->startLines[$lineNumber];
} elseif (isset($this->startLines[$lineNumber]['traitName'])) {
$currentTrait =& $this->startLines[$lineNumber];
} elseif (isset($this->startLines[$lineNumber]['methodName'])) {
$currentMethod =& $this->startLines[$lineNumber];
} elseif (isset($this->startLines[$lineNumber]['functionName'])) {
if (isset($currentFunction)) {
$functionStack[] =& $currentFunction;
}
$currentFunction =& $this->startLines[$lineNumber];
}
}
if (isset($this->coverageData[$lineNumber])) {
if (isset($currentClass)) {
$currentClass['executableLines']++;
}
if (isset($currentTrait)) {
$currentTrait['executableLines']++;
}
if (isset($currentMethod)) {
$currentMethod['executableLines']++;
}
if (isset($currentFunction)) {
$currentFunction['executableLines']++;
}
$this->numExecutableLines++;
if (count($this->coverageData[$lineNumber]) > 0) {
if (isset($currentClass)) {
$currentClass['executedLines']++;
}
if (isset($currentTrait)) {
$currentTrait['executedLines']++;
}
if (isset($currentMethod)) {
$currentMethod['executedLines']++;
}
if (isset($currentFunction)) {
$currentFunction['executedLines']++;
}
$this->numExecutedLines++;
}
}
if (isset($this->endLines[$lineNumber])) {
// End line of a class.
if (isset($this->endLines[$lineNumber]['className'])) {
unset($currentClass);
if ($classStack) {
end($classStack);
$key = key($classStack);
$currentClass =& $classStack[$key];
unset($classStack[$key]);
}
} elseif (isset($this->endLines[$lineNumber]['traitName'])) {
unset($currentTrait);
} elseif (isset($this->endLines[$lineNumber]['methodName'])) {
unset($currentMethod);
} elseif (isset($this->endLines[$lineNumber]['functionName'])) {
unset($currentFunction);
if ($functionStack) {
end($functionStack);
$key = key($functionStack);
$currentFunction =& $functionStack[$key];
unset($functionStack[$key]);
}
}
}
}
foreach ($this->traits as &$trait) {
foreach ($trait['methods'] as &$method) {
if ($method['executableLines'] > 0) {
$method['coverage'] = $method['executedLines'] / $method['executableLines'] * 100;
} else {
$method['coverage'] = 100;
}
$method['crap'] = $this->crap($method['ccn'], $method['coverage']);
$trait['ccn'] += $method['ccn'];
}
if ($trait['executableLines'] > 0) {
$trait['coverage'] = $trait['executedLines'] / $trait['executableLines'] * 100;
if ($trait['coverage'] == 100) {
$this->numTestedClasses++;
}
} else {
$trait['coverage'] = 100;
}
$trait['crap'] = $this->crap($trait['ccn'], $trait['coverage']);
}
foreach ($this->classes as &$class) {
foreach ($class['methods'] as &$method) {
if ($method['executableLines'] > 0) {
$method['coverage'] = $method['executedLines'] / $method['executableLines'] * 100;
} else {
$method['coverage'] = 100;
}
$method['crap'] = $this->crap($method['ccn'], $method['coverage']);
$class['ccn'] += $method['ccn'];
}
if ($class['executableLines'] > 0) {
$class['coverage'] = $class['executedLines'] / $class['executableLines'] * 100;
if ($class['coverage'] == 100) {
$this->numTestedClasses++;
}
} else {
$class['coverage'] = 100;
}
$class['crap'] = $this->crap($class['ccn'], $class['coverage']);
}
}