Last active
May 10, 2021 13:34
-
-
Save drupol/11a0e396722a80a72e674d2cb6f22659 to your computer and use it in GitHub Desktop.
Simple example of nikic/php-parser importer in loophp/phptree
This file contains 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 | |
declare(strict_types=1); | |
include __DIR__ . '/vendor/autoload.php'; | |
use drupol\launcher\Launcher; | |
use loophp\phptree\Exporter\Image; | |
use PhpParser\ParserFactory; | |
use loophp\phptree\Importer\NikicPhpParserImporter; | |
$code = file_get_contents(__DIR__ . '/src/Cart.php'); | |
$parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7); | |
$tree = (new NikicPhpParserImporter())->import($parser->parse($code)); | |
$exporter = new Image(); | |
$imagePath = $exporter->setFormat('png')->export($tree); | |
Launcher::open($imagePath); |
Hello there! Your work is great!
I encountered a practical problem when using your work,
that is, the location of functions and variables cannot be automatically located.
Is it possible to generate structured information with specific lineNum variables? Such as json?
This can greatly improve the usability of your work! Thx by the way!
Hello !
Something like this?
<?php
declare(strict_types=1);
include __DIR__ . '/vendor/autoload.php';
use loophp\launcher\Launcher;
use loophp\phptree\Exporter\Image;
use loophp\phptree\Importer\ImporterInterface;
use PhpParser\ParserFactory;
use loophp\phptree\Node\AttributeNode;
use loophp\phptree\Node\AttributeNodeInterface;
use PhpParser\Node;
use loophp\phptree\Node\NodeInterface;
final class NikicPhpParserWithLineNumbers implements ImporterInterface {
/**
* @param Node[] $data
*
* @throws Exception
*/
public function import($data): NodeInterface
{
return $this->parseNode($this->createNode(['label' => 'root']), ...$data);
}
private function createNode(array $attributes): AttributeNodeInterface
{
if (array_key_exists('astNode', $attributes)) {
$attributes['label'] = sprintf(
'%s at line %s',
$attributes['astNode']->getType(),
$attributes['astNode']->getLine()
);
}
return new AttributeNode($attributes);
}
/**
* @return array<int, Node>
*/
private function getAllNodeChildren(Node $astNode): array
{
/** @var array<int, array<int, Node>> $astNodes */
$astNodes = array_map(
static function (string $subNodeName) use ($astNode): array {
$subNodes = $astNode->{$subNodeName};
if (!is_array($subNodes)) {
$subNodes = [$subNodes];
}
return array_filter(
$subNodes,
'is_object'
);
},
$astNode->getSubNodeNames()
);
return array_merge(...$astNodes);
}
/**
* @param Node ...$astNodes
*/
private function parseNode(AttributeNodeInterface $parent, Node ...$astNodes): NodeInterface
{
return array_reduce(
$astNodes,
function (AttributeNodeInterface $carry, Node $astNode): NodeInterface {
return $carry
->add(
$this->parseNode(
$this->createNode([
'label' => $astNode->getType(),
'astNode' => $astNode,
]),
...$this->getAllNodeChildren($astNode)
)
);
},
$parent
);
}
}
$code = file_get_contents(__DIR__ . '/src/Exporter/FancyExporter.php');
$parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7);
$tree = (new NikicPhpParserWithLineNumbers())->import($parser->parse($code));
$exporter = new Image();
$filename = tempnam(sys_get_temp_dir(), 'graph-');
file_put_contents($filename, $exporter->setFormat('svg')->export($tree));
Launcher::open($filename);
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Result: