Created
December 26, 2016 20:54
-
-
Save nikic/3229644ada5576622d7d538f6bff2098 to your computer and use it in GitHub Desktop.
Demo for format preserving AST transformation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* This demo replaces all unqualified function calls and namespaced lookups | |
* with fully qualified ones. Apart from this change all formatting should | |
* be preserved. */ | |
use PhpParser\Lexer; | |
use PhpParser\Parser; | |
use PhpParser\NodeTraverser; | |
use PhpParser\NodeVisitor; | |
use PhpParser\NodeVisitorAbstract; | |
use PhpParser\PrettyPrinter; | |
use PhpParser\Error; | |
use PhpParser\Node; | |
$dir = /* directory to operate on */; | |
require __DIR__ . '/vendor/autoload.php'; | |
class NameFullyQualifier extends NodeVisitorAbstract { | |
public function leaveNode(Node $node) { | |
if ($node instanceof Node\Name | |
&& $node->hasAttribute('namespacedName') | |
&& !in_array(strtolower($node), ['true', 'false', 'null']) | |
) { | |
return new Node\Name\FullyQualified($node); | |
} | |
return null; | |
} | |
} | |
$lexer = new Lexer\Emulative([ | |
'usedAttributes' => [ | |
'comments', | |
'startLine', 'endLine', | |
'startTokenPos', 'endTokenPos', | |
], | |
]); | |
$parser = new Parser\Php7($lexer, [ | |
'useIdentifierNodes' => true, | |
'useConsistentVariableNodes' => true, | |
'useExpressionStatements' => true, | |
'useNopStatements' => false, | |
]); | |
$nameResolver = new NodeVisitor\NameResolver(null, [ | |
'replaceNodes' => false | |
]); | |
$traverser = new NodeTraverser(); | |
$traverser->addVisitor(new NodeVisitor\CloningVisitor()); | |
$traverser->addVisitor($nameResolver); | |
$traverser->addVisitor(new NameFullyQualifier()); | |
$printer = new PrettyPrinter\Standard(); | |
$it = new RecursiveIteratorIterator( | |
new RecursiveDirectoryIterator($dir), | |
RecursiveIteratorIterator::LEAVES_ONLY | |
); | |
foreach ($it as $file) { | |
if (!preg_match('/\.php$/', $file)) { | |
continue; | |
} | |
try { | |
$code = file_get_contents($file); | |
$origStmts = $parser->parse($code); | |
$newCode = $printer->printFormatPreserving( | |
$traverser->traverse($origStmts), | |
$origStmts, | |
$lexer->getTokens() | |
); | |
file_put_contents($file, $newCode); | |
} catch (Error $e) { | |
echo "Parser error in $file: {$e->getMessage()}\n"; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment