Blame | Letzte Änderung | Log anzeigen | RSS feed
#!/usr/bin/env php<?phpforeach ([__DIR__ . '/../../../autoload.php', __DIR__ . '/../vendor/autoload.php'] as $file) {if (file_exists($file)) {require $file;break;}}ini_set('xdebug.max_nesting_level', 3000);// Disable Xdebug var_dump() output truncationini_set('xdebug.var_display_max_children', -1);ini_set('xdebug.var_display_max_data', -1);ini_set('xdebug.var_display_max_depth', -1);list($operations, $files, $attributes) = parseArgs($argv);/* Dump nodes by default */if (empty($operations)) {$operations[] = 'dump';}if (empty($files)) {showHelp("Must specify at least one file.");}$lexer = new PhpParser\Lexer\Emulative(['usedAttributes' => ['startLine', 'endLine', 'startFilePos', 'endFilePos', 'comments']]);$parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::PREFER_PHP7,$lexer);$dumper = new PhpParser\NodeDumper(['dumpComments' => true,'dumpPositions' => $attributes['with-positions'],]);$prettyPrinter = new PhpParser\PrettyPrinter\Standard;$traverser = new PhpParser\NodeTraverser();$traverser->addVisitor(new PhpParser\NodeVisitor\NameResolver);foreach ($files as $file) {if (strpos($file, '<?php') === 0) {$code = $file;fwrite(STDERR, "====> Code $code\n");} else {if (!file_exists($file)) {fwrite(STDERR, "File $file does not exist.\n");exit(1);}$code = file_get_contents($file);fwrite(STDERR, "====> File $file:\n");}if ($attributes['with-recovery']) {$errorHandler = new PhpParser\ErrorHandler\Collecting;$stmts = $parser->parse($code, $errorHandler);foreach ($errorHandler->getErrors() as $error) {$message = formatErrorMessage($error, $code, $attributes['with-column-info']);fwrite(STDERR, $message . "\n");}if (null === $stmts) {continue;}} else {try {$stmts = $parser->parse($code);} catch (PhpParser\Error $error) {$message = formatErrorMessage($error, $code, $attributes['with-column-info']);fwrite(STDERR, $message . "\n");exit(1);}}foreach ($operations as $operation) {if ('dump' === $operation) {fwrite(STDERR, "==> Node dump:\n");echo $dumper->dump($stmts, $code), "\n";} elseif ('pretty-print' === $operation) {fwrite(STDERR, "==> Pretty print:\n");echo $prettyPrinter->prettyPrintFile($stmts), "\n";} elseif ('json-dump' === $operation) {fwrite(STDERR, "==> JSON dump:\n");echo json_encode($stmts, JSON_PRETTY_PRINT), "\n";} elseif ('var-dump' === $operation) {fwrite(STDERR, "==> var_dump():\n");var_dump($stmts);} elseif ('resolve-names' === $operation) {fwrite(STDERR, "==> Resolved names.\n");$stmts = $traverser->traverse($stmts);}}}function formatErrorMessage(PhpParser\Error $e, $code, $withColumnInfo) {if ($withColumnInfo && $e->hasColumnInfo()) {return $e->getMessageWithColumnInfo($code);} else {return $e->getMessage();}}function showHelp($error = '') {if ($error) {fwrite(STDERR, $error . "\n\n");}fwrite($error ? STDERR : STDOUT, <<<OUTPUTUsage: php-parse [operations] file1.php [file2.php ...]or: php-parse [operations] "<?php code"Turn PHP source code into an abstract syntax tree.Operations is a list of the following options (--dump by default):-d, --dump Dump nodes using NodeDumper-p, --pretty-print Pretty print file using PrettyPrinter\Standard-j, --json-dump Print json_encode() result--var-dump var_dump() nodes (for exact structure)-N, --resolve-names Resolve names using NodeVisitor\NameResolver-c, --with-column-info Show column-numbers for errors (if available)-P, --with-positions Show positions in node dumps-r, --with-recovery Use parsing with error recovery-h, --help Display this pageExample:php-parse -d -p -N -d file.phpDumps nodes, pretty prints them, then resolves names and dumps them again.OUTPUT);exit($error ? 1 : 0);}function parseArgs($args) {$operations = [];$files = [];$attributes = ['with-column-info' => false,'with-positions' => false,'with-recovery' => false,];array_shift($args);$parseOptions = true;foreach ($args as $arg) {if (!$parseOptions) {$files[] = $arg;continue;}switch ($arg) {case '--dump':case '-d':$operations[] = 'dump';break;case '--pretty-print':case '-p':$operations[] = 'pretty-print';break;case '--json-dump':case '-j':$operations[] = 'json-dump';break;case '--var-dump':$operations[] = 'var-dump';break;case '--resolve-names':case '-N';$operations[] = 'resolve-names';break;case '--with-column-info':case '-c';$attributes['with-column-info'] = true;break;case '--with-positions':case '-P':$attributes['with-positions'] = true;break;case '--with-recovery':case '-r':$attributes['with-recovery'] = true;break;case '--help':case '-h';showHelp();break;case '--':$parseOptions = false;break;default:if ($arg[0] === '-') {showHelp("Invalid operation $arg.");} else {$files[] = $arg;}}}return [$operations, $files, $attributes];}