Skip to content

Commit fbe967e

Browse files
committed
Add a new Importer nikic/php-ast.
1 parent 37b4c70 commit fbe967e

File tree

3 files changed

+117
-0
lines changed

3 files changed

+117
-0
lines changed

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ Exporters and importers:
3434
* **Graph**: Export a tree into a Graph using the [graphp/graphp](https://github.com/graphp/graph) library.
3535
* **GraphViz**: Export a tree into a script in [GraphViz](http://www.graphviz.org/) format.
3636
* **Text**: Export a tree into a simple string, easy for storing in a database.
37+
* **nikic/php-ast**: Import a tree from an AST generated by the PHP extension [AST](https://github.com/nikic/php-ast).
38+
* **nikic/php-parser**: Import a tree from an AST generated by [nikic/php-parser](https://github.com/nikic/php-parser).
39+
* **microsoft/tolerant-php-parser**: Import a tree from an AST generated by [microsoft/tolerant-php-parser](https://github.com/microsoft/tolerant-php-parser).
3740

3841
Modifier:
3942
* **Reverse**: To reverse a tree, all the children are mirrored.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace spec\loophp\phptree\Importer;
6+
7+
use loophp\phptree\Importer\NikicPhpAst;
8+
use loophp\phptree\Node\AttributeNodeInterface;
9+
use PhpSpec\ObjectBehavior;
10+
11+
class NikicPhpAstSpec extends ObjectBehavior
12+
{
13+
public function it_can_import(): void
14+
{
15+
$file = __DIR__ . '/../../../../src/Node/Node.php';
16+
$ast = \ast\parse_file($file, 50);
17+
18+
$this
19+
->import($ast)
20+
->shouldImplement(AttributeNodeInterface::class);
21+
22+
$this
23+
->import($ast)
24+
->count()
25+
->shouldReturn(542);
26+
27+
$file = __DIR__ . '/../../../../tests/sample.php';
28+
$ast = \ast\parse_file($file, 50);
29+
30+
$this
31+
->import($ast)
32+
->count()
33+
->shouldReturn(84);
34+
}
35+
36+
public function it_is_initializable(): void
37+
{
38+
$this->shouldHaveType(NikicPhpAst::class);
39+
}
40+
}

src/Importer/NikicPhpAst.php

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace loophp\phptree\Importer;
6+
7+
use ast\Node;
8+
use Exception;
9+
use loophp\phptree\Node\AttributeNode;
10+
use loophp\phptree\Node\AttributeNodeInterface;
11+
use loophp\phptree\Node\NodeInterface;
12+
13+
use function ast\get_metadata;
14+
15+
/**
16+
* Class NikicPhpAst.
17+
*/
18+
final class NikicPhpAst implements ImporterInterface
19+
{
20+
/**
21+
* @var array<int, \ast\Metadata>
22+
*/
23+
private $metadata;
24+
25+
/**
26+
* @param Node $data
27+
*
28+
* @throws Exception
29+
*
30+
* @return \loophp\phptree\Node\NodeInterface
31+
*/
32+
public function import($data): NodeInterface
33+
{
34+
$this->metadata = get_metadata();
35+
36+
return $this->parseNode($this->createNode(['label' => 'root']), $data);
37+
}
38+
39+
/**
40+
* @param array $attributes
41+
*
42+
* @return \loophp\phptree\Node\AttributeNodeInterface
43+
*/
44+
private function createNode(array $attributes): AttributeNodeInterface
45+
{
46+
return new AttributeNode($attributes);
47+
}
48+
49+
/**
50+
* @param \loophp\phptree\Node\AttributeNodeInterface $parent
51+
* @param Node ...$astNodes
52+
*
53+
* @return \loophp\phptree\Node\NodeInterface
54+
*/
55+
private function parseNode(AttributeNodeInterface $parent, Node ...$astNodes): NodeInterface
56+
{
57+
return array_reduce(
58+
$astNodes,
59+
function (AttributeNodeInterface $carry, Node $astNode): NodeInterface {
60+
return $carry
61+
->add(
62+
$this->parseNode(
63+
$this->createNode([
64+
'label' => $this->metadata[$astNode->kind]->name,
65+
'astNode' => $astNode,
66+
]),
67+
...array_values(array_filter($astNode->children, 'is_object'))
68+
)
69+
);
70+
},
71+
$parent
72+
);
73+
}
74+
}

0 commit comments

Comments
 (0)