Skip to content

Instantly share code, notes, and snippets.

@jwpage
Created April 7, 2014 02:10
Show Gist options
  • Save jwpage/10013903 to your computer and use it in GitHub Desktop.
Save jwpage/10013903 to your computer and use it in GitHub Desktop.
Namespacer proof-of-concept
{
"require": {
"nikic/php-parser": "1.0.0-beta1"
}
}
<?php
use PhpParser\NodeTraverser;
require __DIR__.'/vendor/autoload.php';
class NamespacerVisitor extends PhpParser\NodeVisitorAbstract
{
public $classes = [];
public $uses = [];
public $namespace = null;
public function beforeTraverse(array $nodes) {}
public function leaveNode(PhpParser\Node $node) {
if ($node instanceof PhpParser\Node\Stmt\Namespace_) {
$this->namespace = $node->name->__toString();
}
if ($node instanceof PhpParser\Node\Stmt\UseUse) {
$this->uses[$node->alias] = $node->name;
}
if ($node instanceof PhpParser\Node\Name) {
$this->classes[] = $node->__toString();
}
}
public function enterNode(PhpParser\Node $node) {}
public function afterTraverse(array $nodes) {}
}
$traverser = new NodeTraverser;
$parser = new PhpParser\Parser(new PhpParser\Lexer);
$visitor = new NamespacerVisitor();
$traverser->addVisitor($visitor);
$code = file_get_contents($argv[1]);
try {
$stmts = $parser->parse($code);
$traverser->traverse($stmts);
} catch (PHPParser\Error $e) {
echo 'Parse Error: ', $e->getMessage();
}
$real = [];
foreach ($visitor->classes as $class) {
// If it's a function, skip it.
if (function_exists($class)) {
continue;
}
// If it's the name of the namespace, skip it.
if ($visitor->namespace == $class) {
continue;
}
// If it's defined as a "use" alias, skip it.
if (isset($visitor->uses[$class])) {
continue;
}
// If it's already defined in the list of `use` stmts, skip it.
if (array_search($class, $visitor->uses)) {
continue;
}
$real[] = $class;
}
$real = array_unique($real);
sort($real);
foreach ($real as $class) {
echo "use $class;\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment