Skip to content

Instantly share code, notes, and snippets.

@SqueeG
Forked from Chipcius/hacklang-php-juggler.php
Last active August 29, 2015 14:07
Show Gist options
  • Select an option

  • Save SqueeG/3c67bd3f2996f11db407 to your computer and use it in GitHub Desktop.

Select an option

Save SqueeG/3c67bd3f2996f11db407 to your computer and use it in GitHub Desktop.
#!/usr/bin/php
<?php
if(!array_key_exists(1, $argv) || $argv[1] === '--help' || $argv[1] === '-h')
{
printLine("Hacklang php translation tool");
printLine("Version 1");
printLine('usage: ./headerModifyer.php <directory> [options]');
printLine('');
printLine('Available options:');
printLine(' php (defult) Makes headers <?php');
printLine(' hack Makes headers <?hh');
printLine(' hack decl Makes headers <?hh //decl');
printLine(' hack partial Makes headers <?hh //partial');
printLine(' hack strict Makes headers <?hh //strict');
printLine('');
exit;
}
$fileCount = 0;
$dir = realpath($argv[1]);
if($dir === false)
throw new Exception('Invalid directory');
if(array_key_exists(2, $argv) && ($argv[2] === 'hack' ||$argv[2] === 'hhvm'))
{
$output = recursiveDirectoryIterator($dir, 'makeHacklang');
}
else
{
//Use the hacklang stuff to normalize the files first :D
$output = recursiveDirectoryIterator($dir, 'makeHacklang');
$fileCount = 0;
$output = recursiveDirectoryIterator($dir, 'makePHP');
}
print('Updated '. $fileCount . ' files'. PHP_EOL);
function recursiveDirectoryIterator ($directory, $function)
{
if(!file_exists($directory))
return;
if(!function_exists($function))
throw new Exception('The function '. $function . ' does not excist');
if(!is_dir($directory))
{
$handle = new SplFileInfo($directory);
call_user_func($function, $handle);
return;
}
$iterator = new DirectoryIterator ( $directory );
foreach ( $iterator as $handle )
{
if ($handle->isFile() && $handle->getExtension() === 'php')
{
call_user_func($function, $handle);
}
elseif (!$handle->isDot () && !$handle->isFile())
{
switch ($handle->getFilename()) {
case 'views':
case '.':
case 'i18n':
case 'vendor':
continue 2;//one for the swith and one for the foreach loop
break;
default:
break;
}
//print($directory.DIRECTORY_SEPARATOR.$handle->__toString().PHP_EOL);
recursiveDirectoryIterator(
$directory.DIRECTORY_SEPARATOR.$handle->__toString(),
$function
);
}
}
}
function makeHacklang(SplFileInfo $fileHandle)
{
global $argv;
static $count = 0;
$thisFile = realpath(__FILE__);
$fullPath = $fileHandle->getPathname();
if($fullPath === $thisFile)
return;
$hhvm_level = '';
if(array_key_exists(3, $argv))
{
switch ($argv[3])
{
case 'decl':
$hhvm_level = ' //decl';
break;
case 'partial':
$hhvm_level = ' //partial';
break;
case 'strict':
$hhvm_level = ' //strict';
break;
}
}
$fileContent = file_get_contents($fullPath);
$search = [
'<?php defi',
'<?php',
'<?hh //partial',
'<?hh //decl',
'<?hh //strict',
];
$replace = [
'<?hh'.$hhvm_level. PHP_EOL . 'defi',
'<?hh'.$hhvm_level,
'<?hh'.$hhvm_level,
'<?hh'.$hhvm_level,
'<?hh'.$hhvm_level,
];
$newContent = str_replace($search, $replace, $fileContent);
//$newContent = str_replace('<?hh'.PHP_EOL, '<?hh'.$hhvm_level . PHP_EOL,$newContent);
$newContent = splitTranlateHacklang($newContent, $fullPath);
if($fileContent === $newContent)
return;
//print(++$count . PHP_EOL);
//print('Updated: ' .$fullPath . PHP_EOL);
$GLOBALS["fileCount"]++;
$stuff = file_put_contents($fullPath, $newContent);
if($stuff === false)
throw new Exception('Could not write to file');
}
function makePHP(SplFileInfo $fileHandle)
{
static $count = 0;
$thisFile = realpath(__FILE__);
$fullPath = $fileHandle->getPathname();
if($fullPath === $thisFile)
return;
$fileContent = file_get_contents($fullPath);
$newContent = str_replace('<?hh', '<?php', $fileContent);
$newContent = splitTranlatePHP($newContent, $fullPath);
if($fileContent === $newContent)
return;
//print(++$count . PHP_EOL);
//print('Updated: ' .$fullPath . PHP_EOL);
$GLOBALS["fileCount"]++;
$stuff = file_put_contents($fullPath, $newContent);
if($stuff === false)
throw new Exception('Could not write to file');
}
function printLine($text = ''){
print($text. PHP_EOL);
}
function splitTranlatePHP($fileContents, $filename)
{
$lines = explode(PHP_EOL, $fileContents);
$invalidHints = [
'mixed' => true,
'int' => true,
'string' => true,
'bool' => true,
'float' => true,
];
foreach ($lines as $index => $line)
{
$hasKeywordFunction = strpos($line, ' function ') !== false;
$hasKeywordPublic = strpos($line, 'public') !== false;
$hasKeywordProtected = strpos($line, 'protected') !== false;
$hasKeywordPrivate = strpos($line, 'private') !== false;
$hasDollar = strpos($line, '$') !== false;
$hadAccessModifyer = $hasKeywordPublic || $hasKeywordPrivate || $hasKeywordProtected;
if($hasKeywordFunction && $hadAccessModifyer)
{
$lines[$index] = $line = str_replace('):', ')//:', $line);
$argumentsStart = strpos($line, '(');
$argumentsEnd = strpos($line, ')');
$arguments = substr($line, $argumentsStart+1, $argumentsEnd-$argumentsStart-1);
$argumentArray = explode(',', $arguments);
$newArgumentsArray = [];
foreach ($argumentArray as $key => $argument)
{
$argument = trim($argument);
if(strlen($argument) === 0)
continue;
$argument = str_replace('& ', ' &', $argument);
$dollarPos = strpos($argument, '$');
if($dollarPos === 0)
{
$newArgumentsArray[$key] = $argument;
continue;
}
if($dollarPos > 0 && $argument[$dollarPos-1] === '&')
$dollarPos--;
if($dollarPos === 0)
{
$newArgumentsArray[$key] = $argument;
continue;
}
$typeHint = trim(substr($argument,0,$dollarPos));
if(substr($typeHint, 0,2) === '/*')
$typeHint = substr($typeHint, 2);
if(substr($typeHint, -2) === '*/')
$typeHint = substr($typeHint, 0, strlen($typeHint) -2);
if(array_key_exists($typeHint, $invalidHints))
{
$newArgumentsArray[$key] = '/*' . $typeHint . '*/ ' . substr($argument, $dollarPos);
continue;
}
if(strpos($typeHint, '?') !== false)
{
$newArgumentsArray[$key] = '/*' . $typeHint . '*/ ' . substr($argument, $dollarPos);
continue;
}
if($typeHint === '&')
{
print('WARNING! passing value by reference'.PHP_EOL);
print($line.PHP_EOL);
print($filename.PHP_EOL);
$newArgumentsArray[$key] = $argument;
continue;
}
$newArgumentsArray[$key] = $argument;
}
$newArguments = implode(', ', $newArgumentsArray);
$line = str_replace($arguments, $newArguments, $line);
//Donno if the is needed :/
$lines[$index] = $line;
}
elseif(!$hasKeywordFunction && $hadAccessModifyer && $hasDollar)
{
$lineEdit = $line;
$startPos = 0;
$reconstructedLine = '';
$preVariable = substr($line, 0 , strpos($line,'$'));
$postIncludingVariable = substr($line, strpos($line,'$'));
$firstSpaceAfterVariable = strpos($postIncludingVariable, ' ');
$firstTabAfterVariable = strpos($postIncludingVariable, "\t");
$firstSemicolonAfterVariable = strpos($postIncludingVariable, "\t");
$endOfVariable = PHP_INT_MAX;
if($firstSpaceAfterVariable !== false && $firstSpaceAfterVariable < $endOfVariable)
$endOfVariable = $firstSpaceAfterVariable;
if($firstTabAfterVariable !== false && $firstTabAfterVariable < $endOfVariable)
$endOfVariable = $firstTabAfterVariable;
if($firstSemicolonAfterVariable !== false && $firstSemicolonAfterVariable < $endOfVariable)
$endOfVariable = $firstSemicolonAfterVariable;
$variable = substr($postIncludingVariable, 0, $endOfVariable);
$oldAssignations = substr($postIncludingVariable, $endOfVariable);
$newAccessor = '';
if(strpos($preVariable, 'public') !== false)
{
$startPos = strpos($line, 'public');
$newAccessor .= 'public';
}
elseif(strpos($preVariable, 'protected') !== false)
{
$startPos = strpos($line, 'protected');
$newAccessor .= 'protected';
}
elseif(strpos($preVariable, 'private') !== false)
{
$startPos = strpos($line, 'private');
$newAccessor .= 'private';
}
else
continue;
if(strpos($preVariable, 'static') !== false)
{
$pos = strpos($line, 'static');
if($pos < $startPos)
$startPos = $pos;
$newAccessor .= ' ' . 'static';
}
$type = str_replace(['public','protected','private','static',], '', $preVariable);
$type = trim($type);
if(strlen($type) > 0)
{
if(substr($type, 0,2) !== '/*')
$type = '/*'. $type;
if(substr($type, -2) !== '*/')
$type .= '*/';
$type .= ' ';
}
$oldPreSpacing = substr($line, 0, $startPos);
$reconstructedLine = $oldPreSpacing . $newAccessor . ' '. $type . $variable . $oldAssignations;
if(trim($reconstructedLine) != trim($line))
{
$line = $reconstructedLine;
$lines[$index] = $line;
}
}
}
return implode(PHP_EOL, $lines);
}
function splitTranlateHacklang($fileContents, $filename)
{
$lines = explode(PHP_EOL, $fileContents);
foreach ($lines as $index => $line)
{
$hasKeywordFunction = strpos($line, ' function ') !== false;
$hasKeywordPublic = strpos($line, 'public') !== false;
$hasKeywordProtected = strpos($line, 'protected') !== false;
$hasKeywordPrivate = strpos($line, 'private') !== false;
$hasDollar = strpos($line, '$') !== false;
$hadAccessModifyer = $hasKeywordPublic || $hasKeywordPrivate || $hasKeywordProtected;
if($hasKeywordFunction && $hadAccessModifyer)
{
$lines[$index] = $line = str_replace(')//:' ,'):', $line);
$argumentsStart = strpos($line, '(');
$argumentsEnd = strpos($line, ')');
//print(PHP_EOL);
//print(PHP_EOL);
$arguments = substr($line, $argumentsStart+1, $argumentsEnd-$argumentsStart-1);
$argumentArray = explode(',', $arguments);
$newArgumentsArray = [];
foreach ($argumentArray as $key => $argument)
{
$argument = trim($argument);
if(strlen($argument) === 0)
continue;
$argument = str_replace('& ', ' &', $argument);
$dollarPos = strpos($argument, '$');
if($dollarPos === 0)
{
$newArgumentsArray[$key] = $argument;
continue;
}
if($dollarPos > 0 && $argument[$dollarPos-1] === '&')
$dollarPos--;
if($dollarPos === 0)
{
$newArgumentsArray[$key] = $argument;
continue;
}
$typeHint = trim(substr($argument,0,$dollarPos));
if(substr($typeHint, 0,2) === '/*')
$typeHint = substr($typeHint, 2);
if(substr($typeHint, -2) === '*/')
$typeHint = substr($typeHint, 0, strlen($typeHint) -2);
if($typeHint === 'array' || $typeHint === 'stdClass')
{
$newArgumentsArray[$key] = $argument;
continue;
}
if($typeHint === '&')
{
print('WARNING! passing value by reference'.PHP_EOL);
print($line.PHP_EOL);
print($filename.PHP_EOL);
$newArgumentsArray[$key] = $argument;
continue;
}
$newArgumentsArray[$key] = '' . $typeHint . ' ' . substr($argument, $dollarPos);
}
$newArguments = implode(', ', $newArgumentsArray);
$line = str_replace($arguments, $newArguments, $line);
//Donno if the is needed :/
$lines[$index] = $line;
}
elseif(!$hasKeywordFunction && $hadAccessModifyer && $hasDollar)
{
$lineEdit = $line;
$startPos = 0;
$reconstructedLine = '';
$preVariable = substr($line, 0 , strpos($line,'$'));
$postIncludingVariable = substr($line, strpos($line,'$'));
$firstSpaceAfterVariable = strpos($postIncludingVariable, ' ');
$firstTabAfterVariable = strpos($postIncludingVariable, "\t");
$firstSemicolonAfterVariable = strpos($postIncludingVariable, "\t");
$endOfVariable = PHP_INT_MAX;
if($firstSpaceAfterVariable !== false && $firstSpaceAfterVariable < $endOfVariable)
$endOfVariable = $firstSpaceAfterVariable;
if($firstTabAfterVariable !== false && $firstTabAfterVariable < $endOfVariable)
$endOfVariable = $firstTabAfterVariable;
if($firstSemicolonAfterVariable !== false && $firstSemicolonAfterVariable < $endOfVariable)
$endOfVariable = $firstSemicolonAfterVariable;
$variable = substr($postIncludingVariable, 0, $endOfVariable);
$oldAssignations = substr($postIncludingVariable, $endOfVariable);
$newAccessor = '';
if(strpos($preVariable, 'public') !== false)
{
$startPos = strpos($line, 'public');
$newAccessor .= 'public';
}
elseif(strpos($preVariable, 'protected') !== false)
{
$startPos = strpos($line, 'protected');
$newAccessor .= 'protected';
}
elseif(strpos($preVariable, 'private') !== false)
{
$startPos = strpos($line, 'private');
$newAccessor .= 'private';
}
else
continue;
if(strpos($preVariable, 'static') !== false)
{
$pos = strpos($line, 'static');
if($pos < $startPos)
$startPos = $pos;
$newAccessor .= ' ' . 'static';
}
$type = str_replace(['public','protected','private','static',], '', $preVariable);
$type = trim($type);
if(strlen($type) > 0)
{
if(substr($type, 0,2) === '/*')
$type = substr($type, 2);
if(substr($type, -2) === '*/')
$type = substr($type,0, strlen($type) -2);
$type .= ' ';
}
$oldPreSpacing = substr($line, 0, $startPos);
$reconstructedLine = $oldPreSpacing . $newAccessor . ' '. $type . $variable . $oldAssignations;
if(trim($reconstructedLine) != trim($line))
{
$line = $reconstructedLine;
$lines[$index] = $line;
}
}
}
return implode(PHP_EOL, $lines);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment