1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- <?php
- declare(strict_types=1);
- /**
- * This file is part of Hyperf.
- *
- * @link https://www.hyperf.io
- * @document https://hyperf.wiki
- * @contact group@hyperf.io
- * @license https://github.com/hyperf/hyperf/blob/master/LICENSE
- */
- namespace Hyperf\Di\Aop;
- use Hyperf\Support\Composer;
- use PhpParser\Node\Stmt\ClassLike;
- use PhpParser\Node\Stmt\Namespace_;
- use PhpParser\NodeTraverser;
- use PhpParser\Parser;
- use PhpParser\ParserFactory;
- use PhpParser\PrettyPrinter\Standard;
- use PhpParser\PrettyPrinterAbstract;
- class Ast
- {
- private Parser $astParser;
- private PrettyPrinterAbstract $printer;
- public function __construct()
- {
- $parserFactory = new ParserFactory();
- $this->astParser = $parserFactory->create(ParserFactory::ONLY_PHP7);
- $this->printer = new Standard();
- }
- public function parse(string $code): ?array
- {
- return $this->astParser->parse($code);
- }
- public function proxy(string $className)
- {
- $code = $this->getCodeByClassName($className);
- $stmts = $this->astParser->parse($code);
- $traverser = new NodeTraverser();
- $visitorMetadata = new VisitorMetadata($className);
- // User could modify or replace the node visitors by Hyperf\Di\Aop\AstVisitorRegistry.
- $queue = clone AstVisitorRegistry::getQueue();
- foreach ($queue as $string) {
- $visitor = new $string($visitorMetadata);
- $traverser->addVisitor($visitor);
- }
- $modifiedStmts = $traverser->traverse($stmts);
- return $this->printer->prettyPrintFile($modifiedStmts);
- }
- public function parseClassByStmts(array $stmts): string
- {
- $namespace = $className = '';
- foreach ($stmts as $stmt) {
- if ($stmt instanceof Namespace_ && $stmt->name) {
- $namespace = $stmt->name->toString();
- foreach ($stmt->stmts as $node) {
- if (($node instanceof ClassLike) && $node->name) {
- $className = $node->name->toString();
- break;
- }
- }
- }
- }
- return ($namespace && $className) ? $namespace . '\\' . $className : '';
- }
- private function getCodeByClassName(string $className): string
- {
- $file = Composer::getLoader()->findFile($className);
- if (! $file) {
- return '';
- }
- return file_get_contents($file);
- }
- }
|