protected function commandMain()
{
// Load set, change
$chglist = [];
$options = [];
$loaded_sets = [];
$setstack = [$this->args['--set']];
while (!empty($setstack)) {
$setname = array_shift($setstack);
// Prevent infinite-loop
if (isset($loaded_sets[$setname])) {
continue;
}
$loaded_sets[$setname] = true;
// Load
$setfile = $this->setpath . '/' . $setname . '.json';
if (!file_exists($setfile)) {
Logging::error('Unable load setfile {name}', ['name' => $setfile]);
exit(1);
}
if ($this->args['--verbose']) {
Logging::info('Load set {name}', ['name' => basename($setfile)]);
}
$info = json_decode(file_get_contents($setfile));
// Depend
if (isset($info->depend)) {
foreach ($info->depend as $setname) {
$setstack[] = $setname;
}
}
// Options
if (isset($info->options)) {
foreach ($info->options as $key => $value) {
if (!isset($options[$key])) {
$options[$key] = $value;
}
}
}
// Instantiate
if (isset($info->changes)) {
foreach (array_reverse($info->changes) as $chgname) {
$chglist[] = $chgname;
}
}
}
$chglist = array_reverse($chglist);
// FIXME: use a better method making load order correct
if ($this->args['--verbose']) {
Logging::info('Set options ' . print_r($options, true));
}
// Instantiate change
foreach ($chglist as $key => $chgname) {
if ($this->args['--verbose']) {
Logging::info('Load change {name}', ['name' => $chgname]);
}
$chgname = '\\PhpMigration\\Changes\\' . $chgname;
$chglist[$key] = new $chgname();
}
$chgvisitor = new CheckVisitor($chglist);
// Instance parser
if (isset($options['parse_as_version']) && $options['parse_as_version'] == 7) {
$kind = ParserFactory::ONLY_PHP7;
} else {
$kind = ParserFactory::PREFER_PHP7;
}
$parser = (new ParserFactory())->create($kind);
if ($this->args['--verbose']) {
Logging::info('Parser created ' . get_class($parser));
}
// Instance traverser
$traverser_pre = new NodeTraverser();
$traverser_pre->addVisitor(new NameResolver());
$traverser_pre->addVisitor(new ReduceVisitor());
$traverser = new NodeTraverser();
$traverser->addVisitor($chgvisitor);
// Prepare filelist
$filelist = [];
foreach ($this->args['<file>'] as $file) {
if (is_dir($file)) {
$iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($file), 0, \RecursiveIteratorIterator::CATCH_GET_CHILD);
$iterator = new \RegexIterator($iterator, '/\\.php$/');
try {
foreach ($iterator as $file) {
$filelist[] = $file;
}
} catch (Exception $e) {
continue;
}
} else {
$filelist[] = new \SplFileInfo($file);
}
}
// Parse
$chgvisitor->prepare();
foreach ($filelist as $file) {
if ($this->args['--verbose']) {
Logging::info('Parse file {file}', ['file' => $file]);
}
if (!file_exists($file)) {
Logging::warning('No such file or directory "{file}"', ['file' => $file]);
continue;
} elseif (!is_readable($file)) {
Logging::warning('Permission denied "{file}"', ['file' => $file]);
continue;
}
$chgvisitor->setFile($file);
$chgvisitor->setCode(file_get_contents($file));
try {
$stmts = $parser->parse($chgvisitor->getCode());
} catch (PhpParserError $e) {
$chgvisitor->addSpot('PARSE', true, $e->getMessage(), 'NONE', $e->getStartLine());
if ($this->args['--verbose']) {
Logging::warning('Parse error {file}, error message "{exception}"', ['exception' => $e, 'file' => $file]);
}
continue;
}
// Apply traversers
$stmts = $traverser_pre->traverse($stmts);
$traverser->traverse($stmts);
}
$chgvisitor->finish();
// Display
$has_output = false;
foreach ($chgvisitor->getSpots() as $spotlist) {
// Init nums
$nums = ['total' => 0, 'identified' => 0];
$nums['total'] = count($spotlist);
foreach ($spotlist as $key => $spot) {
if ($spot['identified']) {
$nums['identified']++;
} elseif ($this->args['--quite']) {
// Remove uncertain
unset($spotlist[$key]);
}
}
$has_output = true;
if (!$spotlist) {
continue;
}
usort($spotlist, function ($a, $b) {
return $a['line'] - $b['line'];
});
$spot = current($spotlist);
echo "\n";
echo 'File: ' . $spot['file'] . "\n";
echo "--------------------------------------------------------------------------------\n";
echo 'Found ' . $nums['total'] . ' spot(s), ' . $nums['identified'] . " identified\n";
echo "--------------------------------------------------------------------------------\n";
foreach ($spotlist as $spot) {
printf("%5d | %-10s | %1s | %s | %s\n", $spot['line'], $spot['cate'], $spot['identified'] ? '*' : ' ', $spot['version'], $spot['message']);
}
echo "--------------------------------------------------------------------------------\n";
}
// No spot found
if (!$has_output) {
echo "No spot found\n";
}
// Dump tree
if ($this->args['--dump']) {
$nodeDumper = new NodeDumper();
echo $nodeDumper->dump($stmts) . "\n";
}
}