Skip to content

Instantly share code, notes, and snippets.

@dg
Created May 27, 2020 18:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dg/03ca374593329fe5f17a15f1c87ad8fb to your computer and use it in GitHub Desktop.
Save dg/03ca374593329fe5f17a15f1c87ad8fb to your computer and use it in GitHub Desktop.
Typehints for PHP 7.4
<?php
declare(strict_types=1);
require '/nette.phar';
class TypeHints
{
public $ignoredTypes = ['mixed', 'resource'];
public function update($file)
{
$s = file_get_contents($file);
$s = str_replace("\r\n", "\n", $s);
$s = preg_replace_callback('#((?>\n[ \t]*\/\*\*.+\*\/))?(\s+)((?:var |public |protected |private |static )+)(\$\w++)(\s*=\s*([^\s;]++))?+()#sU',
function ($m) {
list(, $doc, $inter, $keywords, $name, $trailing, $default) = $m;
$hint = '';
$this->processProperty($doc, $default, $hint);
if (trim($doc, "/* \t\n") === '') {
$doc = '';
}
return $doc . $inter . $keywords . ($hint ? $hint . ' ' : '') . $name . $trailing;
}, $s);
$s = str_replace("\n", "\r\n", $s);
file_put_contents($file, $s);
}
private function processProperty(string &$doc, string $default, string &$propHint): void
{
$propHint = '';
if ($doc) {
$doc = preg_replace_callback(
'#\n[ \t]*/?\*+ *@var +(\S+)( +[^*]*)?()#',
function (array $m) use (&$propHint) {
list($line, $type, $info) = $m;
$nnType = str_ireplace(['?', '|null'], '', $type);
$nullable = $type !== $nnType ? '?' : '';
if (in_array($nnType, $this->ignoredTypes, true)) {
} elseif ($nnType === 'static') {
$propHint = $nullable . 'self';
} elseif (preg_match('#^[\w\\\\]+\[\]\z#', $nnType)) {
$propHint = $nullable . 'array';
} elseif (preg_match('#^[\w\\\\]+\z#', $nnType)) {
$propHint = $nullable . $nnType;
if (!trim($info)) {
return '';
}
}
return $line;
},
$doc
);
return;
}
$ch = substr($default, 0, 1);
if ($ch === '[') {
$propHint = 'array';
} elseif ($ch === '"' || $ch === "'") {
$propHint = 'string';
} elseif ($default === 'true' || $default === false) {
$propHint = 'bool';
} elseif (is_numeric($default)) {
$propHint = 'int';
}
}
}
$updater = new TypeHints;
foreach (Nette\Utils\Finder::findFiles('*.php')->from(__DIR__) as $file) {
echo $file, "\n";
$updater->update((string) $file);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment