Skip to content

Instantly share code, notes, and snippets.

@thekid
Created February 27, 2016 18:49
Show Gist options
  • Select an option

  • Save thekid/499e3667a4c7153defdb to your computer and use it in GitHub Desktop.

Select an option

Save thekid/499e3667a4c7153defdb to your computer and use it in GitHub Desktop.
Convert to PHP 7
<?php
use io\collections\FileCollection;
use io\collections\iterate\FilteredIOCollectionIterator;
use io\collections\iterate\ExtensionEqualsFilter;
use util\cmd\Console;
use io\streams\Streams;
use lang\XPClass;
class Convert {
const IMPORTS = "<?=imports; ?>\n";
private static function rewrite($file, $version) {
$tokens= token_get_all(Streams::readAll($file->getInputStream()));
$source= '';
$array= [];
$imports= [];
$namespace= '';
$replace= [self::IMPORTS => ''];
$type= null;
for ($i= 0, $s= sizeof($tokens); $i < $s; $i++) {
$token= $tokens[$i];
// Record whether inside type body or outside
if (null === $type && (T_INTERFACE === $token[0] || T_CLASS === $token[0] || T_TRAIT === $token[0])) {
$type= $tokens[$i + 2][1];
}
// Record namespace
else if (T_NAMESPACE === $token[0]) {
$namespace= '';
while (++$i < $s && ';' !== $tokens[$i][0]) {
$namespace.= $tokens[$i][1];
}
$token= 'namespace'.$namespace.';';
$namespace= trim($namespace).'\\';
}
// Record imports
else if (T_USE === $token[0] && !$type) {
if (empty($imports)) {
$source.= self::IMPORTS;
}
$import= '';
while (++$i < $s && ';' !== $tokens[$i][0]) {
$import.= $tokens[$i][1];
}
$token= 'use'.$import.';';
$imports[trim($import)]= true;
}
// newinstance('a.b.C') => new class() implements|extends C { ... }
else if (T_STRING === $token[0] && 'newinstance' === $token[1] && T_STRING === $tokens[$i + 2][0]) {
$literal= $tokens[$i + 2][1];
$braces= 0;
$args= '';
for ($i+= 6; $i < $s; $i++) {
if ('[' === $tokens[$i]) {
$braces++;
} else if (']' === $tokens[$i]) {
$braces--;
if (0 === $braces) break;
} else {
$args.= is_array($tokens[$i]) ? $tokens[$i][1] : $tokens[$i];
}
}
$token= '(new class('.trim($args).') ';
if ('\\' === $literal{0}) {
$class= new XPClass($literal);
} else if ('self' === $literal) {
$version= '7.0' && $literal= $type; // https://bugs.php.net/bug.php?id=71678
$class= new XPClass($namespace.$type);
} else {
$class= null;
foreach ($imports as $import => $_) {
if (0 === substr_compare($import, $literal, -strlen($literal))) {
$class= new XPClass($import);
break;
}
}
$class || $class= new XPClass($namespace.$literal);
}
if ($class->isInterface()) {
$token.= 'implements '.$literal.' {';
} else if ($class->isTrait()) {
$token.= ' { use '.$literal.'; ';
} else {
$token.= 'extends '.$literal.' {';
}
if ('[' === $tokens[$i + 3]) {
for ($i+= 4; $i < $s; $i++) {
// 'list' => [] vs. 'toString' => function() { ... }
if (']' === $tokens[$i]) {
break;
} else if (',' === $tokens[$i]) {
// Skip
} else if (T_CONSTANT_ENCAPSED_STRING === $tokens[$i][0]) {
if ('#' === $tokens[$i][1]{1}) {
$p= strrpos($tokens[$i][1], ' ');
$member= substr($tokens[$i][1], $p + 1, -1);
$token.= substr($tokens[$i][1], 1, $p - 1)."\n ";
} else {
$member= substr($tokens[$i][1], 1, -1);
}
if (T_FUNCTION === $tokens[$i + 4][0]) {
$token.= 'public function '.$member;
$braces= 0;
for ($i+= 5; $i < $s; $i++) {
if ('{' === $tokens[$i]) {
$braces++;
$token.= '{';
} else if ('}' === $tokens[$i]) {
$braces--;
$token.= '}';
if (0 === $braces) break;
} else {
$token.= is_array($tokens[$i]) ? $tokens[$i][1] : $tokens[$i];
}
}
} else {
$token.= 'public $'.$member.' = ';
$braces= 0;
for ($i+= 4; $i < $s; $i++) {
if ('[' === $tokens[$i]) {
$braces++;
$token.= '[';
} else if (']' === $tokens[$i]) {
$braces--;
if (-1 === $braces) {
$token= trim($token).";\n ";
break 2;
}
$token.= ']';
} else if (',' === $tokens[$i]) {
if (0 === $braces) break;
} else {
$token.= is_array($tokens[$i]) ? $tokens[$i][1] : $tokens[$i];
}
}
$token.= ';';
}
} else {
$token.= is_array($tokens[$i]) ? $tokens[$i][1] : $tokens[$i];
}
}
$token.= '}';
} else if (T_CONSTANT_ENCAPSED_STRING === $tokens[$i + 3][0]) {
$token.= str_replace('\\\\', '\\', substr($tokens[$i + 3][1], 2, -1));
$i+= 3;
} else {
$token.= ' }';
}
}
$source.= is_array($token) ? $token[1] : $token;
}
$source= strtr($source, $replace);
// Console::writeLine($source);
// return;
with ($file->getOutputStream(), function($out) use($source) {
$out->write($source);
});
return true;
}
public static function main($args) {
$sources= new FilteredIOCollectionIterator(
new FileCollection($args[0]),
new ExtensionEqualsFilter(\xp::CLASS_FILE_EXT),
true
);
Console::writeLine($sources);
$version= isset($args[1]) ? $args[1] : '7.0';
Console::write('[');
foreach ($sources as $file) {
Console::write(self::rewrite($file, $version) ? '.' : 'E');
}
Console::write(']');
}
}
@thekid
Copy link
Author

thekid commented Feb 27, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment