Skip to content

Instantly share code, notes, and snippets.

@nikic
Created April 24, 2019 18:02
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nikic/a2bfa3e2f604f66115c3e4b8963a6c72 to your computer and use it in GitHub Desktop.
Save nikic/a2bfa3e2f604f66115c3e4b8963a6c72 to your computer and use it in GitHub Desktop.
Analysis of nested ternaries
<?php error_reporting(E_ALL);
use PhpParser\Node\Expr;
require __DIR__ . '/../PHP-Parser/vendor/autoload.php';
$lexer = new PhpParser\Lexer\Emulative([
'usedAttributes' => [
'comments', 'startLine', 'endLine',
'startFilePos', 'endFilePos',
]
]);
$parser = new PhpParser\Parser\Php7($lexer);
$visitor = new class extends PhpParser\NodeVisitorAbstract {
public $path = null;
public $code = null;
public function enterNode(PhpParser\Node $node) {
if (!$node instanceof Expr\Ternary) {
return;
}
$cond = $node->cond;
if (!$cond instanceof Expr\Ternary) {
return;
}
if ($node->if === null && $cond->if === null) {
return;
}
echo $this->path . ":" . $node->getStartLine() . "\n";
// Inaccurate...
$endPos = $cond->getEndFilePos();
if ($this->code[$endPos+1] === ')') {
echo "With parens\n\n";
} else {
echo "WITHOUT parens\n\n";
}
}
};
$traverser = new PhpParser\NodeTraverser;
$traverser->addVisitor($visitor);
$it = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator(__DIR__ . '/sources'),
RecursiveIteratorIterator::LEAVES_ONLY
);
$i = 0;
foreach ($it as $f) {
$path = $f->getPathName();
if (!preg_match('/\.php$/', $path)) {
continue;
}
if (++$i % 1000 == 0) {
echo $i . "\n";
}
$code = file_get_contents($path);
try {
$stmts = $parser->parse($code);
} catch (PhpParser\Error $e) {
echo $path . "\n";
echo "Parse error: " . $e->getMessage() . "\n";
continue;
}
$visitor->path = $path;
$visitor->code = $code;
$traverser->traverse($stmts);
}
<?php error_reporting(E_ALL);
function getTopPackages($min, $max) {
$perPage = 15;
$page = intdiv($min, $perPage);
$id = $page * $perPage;
while (true) {
$page++;
$url = 'https://packagist.org/explore/popular.json?page=' . $page;
$json = json_decode(file_get_contents($url), true);
foreach ($json['packages'] as $package) {
yield $id => $package['name'];
$id++;
if ($id >= $max) {
return;
}
}
}
}
if ($argc < 3) {
echo "Usage: download.php min-package max-package\n";
return;
}
$minPackage = $argv[1];
$maxPackage = $argv[2];
foreach (getTopPackages($minPackage, $maxPackage) as $i => $packageName) {
echo "[$i] $packageName\n";
$packageName = strtolower($packageName);
$url = 'https://repo.packagist.org/p/' . $packageName . '.json';
$json = json_decode(file_get_contents($url), true);
$versions = $json['packages'][$packageName];
if (isset($versions['dev-master'])) {
$version = 'dev-master';
} else {
// Pick last version.
$keys = array_keys($versions);
$version = $keys[count($keys) - 1];
}
$package = $versions[$version];
if ($package['dist'] === null) {
echo "Skipping due to missing dist\n";
continue;
}
$dist = $package['dist']['url'];
$zipball = __DIR__ . '/zipballs/' . $packageName . '.zip';
if (!file_exists($zipball)) {
echo "Downloading $version...\n";
$dir = dirname($zipball);
if (!is_dir($dir)) {
mkdir($dir, 0777, true);
}
exec("wget $dist -O $zipball", $execOutput, $execRetval);
if ($execRetval !== 0) {
echo "wget failed: $execOutput\n";
break;
}
}
}
#!/bin/bash
GLOBIGNORE=".:.."
for zip in zipballs/*/*.zip; do
target=${zip/zipballs/sources}
target=${target/.zip/}
echo $target
if [ -d $target ]; then
continue
fi
echo "Extracting..."
mkdir -p $target
unzip $zip -d $target
subdir=($target/*)
mv $subdir/* $target
rmdir $subdir
done
@TomasVotruba
Copy link

@thg2k ❤️ Thanks

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