Passed
Push — master ( 28c5ec...7a4f55 )
by Pol
04:19
created

NikicPhpParserImporter::import()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace loophp\phptree\Importer;
6
7
use Exception;
8
use loophp\phptree\Node\AttributeNode;
9
use loophp\phptree\Node\AttributeNodeInterface;
10
use loophp\phptree\Node\NodeInterface;
11
use PhpParser\Node;
12
use SplObjectStorage;
13
14
use function get_class;
15
use function is_array;
16
17
final class NikicPhpParserImporter implements ImporterInterface
18
{
19
    /**
20
     * @var SplObjectStorage
21
     */
22
    private $nodeMap;
23
24 2
    public function __construct()
25
    {
26 2
        $this->nodeMap = new SplObjectStorage();
27 2
    }
28
29
    /**
30
     * @param Node[] $data
31
     *
32
     * @throws Exception
33
     *
34
     * @return \loophp\phptree\Node\NodeInterface
35
     */
36 1
    public function import($data): NodeInterface
37
    {
38 1
        return (new AttributeNode(['label' => 'root']))
39 1
            ->add(...$this->parseNodes($data));
40
    }
41
42
    /**
43
     * @param \PhpParser\Node $astNode
44
     *
45
     * @return array<int, Node>
46
     */
47 1
    private function getNodeChildren(Node $astNode): array
48
    {
49 1
        $subNodeNames = $astNode->getSubNodeNames();
50
51 1
        $nodes = [];
52
53 1
        foreach ($subNodeNames as $subNodeName) {
54 1
            $subNodes = $astNode->{$subNodeName};
55
56 1
            if (!is_array($subNodes)) {
57 1
                $subNodes = [$subNodes];
58
            }
59
60 1
            foreach ($subNodes as $subNode) {
61 1
                if (false === ($subNode instanceof Node)) {
62 1
                    continue;
63
                }
64
65 1
                $nodes[] = $subNode;
66
            }
67
        }
68
69 1
        return $nodes;
70
    }
71
72
    /**
73
     * @param \PhpParser\Node $astNode
74
     *
75
     * @throws \Exception
76
     *
77
     * @return AttributeNodeInterface
78
     */
79 1
    private function parseNode(Node $astNode): AttributeNodeInterface
80
    {
81
        $attributes = [
82 1
            'label' => sprintf('%s', $astNode->getType()),
83 1
            'type' => $astNode->getType(),
84 1
            'class' => get_class($astNode),
85 1
            'shape' => 'rect',
86 1
            'astNode' => $astNode,
87
        ];
88
89 1
        return (new AttributeNode($attributes))
90 1
            ->add(...$this->parseNodes($this->getNodeChildren($astNode)));
91
    }
92
93
    /**
94
     * @param Node[] $astNodes
95
     *
96
     * @throws \Exception
97
     *
98
     * @return AttributeNodeInterface[]
99
     */
100 1
    private function parseNodes(array $astNodes): array
101
    {
102 1
        $treeNodes = [];
103
104 1
        foreach ($astNodes as $node) {
105 1
            if (false === $this->nodeMap->contains($node)) {
106 1
                $treeNode = $this->parseNode($node);
107 1
                $treeNode->setAttribute('astNode', $node);
108 1
                $this->nodeMap->attach($node, $treeNode);
109
            }
110
111 1
            $treeNodes[] = $this->nodeMap->offsetGet($node);
112
        }
113
114 1
        return $treeNodes;
115
    }
116
}
117