Skip to content

Instantly share code, notes, and snippets.

@hakre
Created November 27, 2012 18:31
Show Gist options
  • Save hakre/f6089a4d070075637cba to your computer and use it in GitHub Desktop.
Save hakre/f6089a4d070075637cba to your computer and use it in GitHub Desktop.
<?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