-
-
Save hakre/f6089a4d070075637cba to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Indents of Lines | |
* | |
*/ | |
class LinesIndents { | |
/** | |
* local store of lines object | |
* | |
* @var Lines | |
*/ | |
private $lines; | |
private $metrics; | |
public function __construct(Lines $lines) { | |
$this->lines = $lines; | |
} | |
public function getLinesByType($type) { | |
$lines = $this->lines->getFilteredLines(); | |
return array_filter($lines, function($line) use($type){ | |
$lineType = LineIndent::type($line); | |
return $type===$lineType; | |
}); | |
} | |
public function getTypePerLine() { | |
$lines = $this->lines->getFilteredLines(); | |
return array_map('LineIndent::type', $lines); | |
} | |
/** | |
* | |
* Enter description here ... | |
* | |
* @return int , 0 means nothing could be sensed, 1 space, 2 space, 4 space | |
*/ | |
private function senseIndentStep() { | |
$lines = $this->lines->getFilteredLines(); | |
$indents = array_map('LineIndent::indent', $lines); | |
// sense through all space only lines | |
$counts = array(); | |
foreach($indents as $indent) { | |
if ('' !== trim($indent, ' ') ) | |
continue; | |
$len = strlen($indent); | |
if (!isset($counts[$len])) | |
$counts[$len] = 0; | |
$counts[$len]++; | |
} | |
ksort($counts); | |
// 0 is not interesting | |
if (isset($counts[0])) | |
unset($counts[0]) | |
; | |
// if there are too less lines to metric over, leave it | |
$metricLines = array_sum($counts); | |
if ($metricLines < 24 ) { | |
return 0; | |
} | |
// same for ratio over all lines of the file, 33% should be | |
// convered by metrics. | |
$ratio = (int) ($metricLines / (count($lines)) * 100); | |
if ($ratio < 33) { | |
return 0; | |
} | |
$mods = array(1, 2, 4); | |
$bridges = array(); | |
// build longest bridge | |
foreach($mods as $step) { | |
$current = 0; | |
$bridges[$step] = array(); | |
$bridge = &$bridges[$step]; | |
while($current+=$step) { | |
if (isset($counts[$current])) { | |
$bridge[$current] = $counts[$current]; | |
} else { | |
break; | |
} | |
} | |
} | |
unset($bridge); // remove reference | |
$bridgesLengths = array_filter(array_map('count', $bridges)); | |
arsort($bridgesLengths); | |
$bridgesWeights = array_filter(array_map('array_sum', $bridges)); | |
arsort($bridgesWeights); | |
$lenPref = key($bridgesLengths); | |
$weightPref = key($bridgesWeights); | |
if ($lenPref === $weightPref) | |
return $lenPref | |
; | |
return 0; | |
} | |
public function gatherMetrics() { | |
$lineTypes = $this->getTypePerLine(); | |
$typeCount = array_count_values($lineTypes); | |
$typeCount = $typeCount + array_fill(0, 4, 0); | |
ksort($typeCount); | |
$metrics->typeCount = $typeCount; | |
$metrics->indentedLineCount = count(array_filter($lineTypes)); | |
$metrics->hasMixedLines = (bool) $typeCount[3]; | |
$metrics->hasDifferentIndentTypes = (bool) $typeCount[1] && (bool) $typeCount[2]; | |
if($typeCount[1]===$typeCount[2]) { | |
$preferred = 0; | |
} elseif($typeCount[1]>$typeCount[2]) { | |
$preferred = 1; | |
} else { | |
$preferred = 2; | |
} | |
$metrics->preferredType = $preferred; | |
$metrics->indentStep = $this->senseIndentStep(); | |
return $this->metrics = $metrics; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment