MicrosoftFancyExporter   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 115
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 55
c 1
b 0
f 0
dl 0
loc 115
ccs 0
cts 80
cp 0
rs 10
wmc 15

6 Methods

Rating   Name   Duplication   Size   Complexity  
A export() 0 13 1
A __construct() 0 3 1
A removeOriginalNode() 0 3 1
A filterObsoleteNode() 0 7 1
B applyLabel() 0 37 6
A applyShape() 0 25 5
1
<?php
2
3
declare(strict_types=1);
4
5
namespace loophp\PhptreeAstGenerator\Exporter;
6
7
use Closure;
8
use loophp\phptree\Exporter\ExporterInterface;
9
use loophp\phptree\Modifier\Apply;
10
use loophp\phptree\Modifier\Filter;
11
use loophp\phptree\Node\AttributeNodeInterface;
12
use loophp\phptree\Node\NodeInterface;
13
use Microsoft\PhpParser\Node;
14
15
use function get_class;
16
use function in_array;
17
18
class MicrosoftFancyExporter implements ExporterInterface
19
{
20
    /**
21
     * @var \loophp\phptree\Exporter\ExporterInterface
22
     */
23
    private $exporter;
24
25
    /**
26
     * MicrosoftFancyGenerator constructor.
27
     *
28
     * @param \loophp\phptree\Exporter\ExporterInterface $exporter
29
     */
30
    public function __construct(ExporterInterface $exporter)
31
    {
32
        $this->exporter = $exporter;
33
    }
34
35
    /**
36
     * {@inheritdoc}
37
     */
38
    public function export(NodeInterface $node)
39
    {
40
        $applyShapeModifier = new Apply(Closure::fromCallable([$this, 'applyShape']));
41
        $applyLabelModifier = new Apply(Closure::fromCallable([$this, 'applyLabel']));
42
        $filterModifier = new Filter(Closure::fromCallable([$this, 'filterObsoleteNode']));
43
        $removeOriginalNode = new Apply(Closure::fromCallable([$this, 'removeOriginalNode']));
44
45
        $node = $applyLabelModifier->modify($node);
46
        $node = $applyShapeModifier->modify($node);
47
        $node = $filterModifier->modify($node);
48
        $node = $removeOriginalNode->modify($node);
49
50
        return $this->exporter->export($node);
51
    }
52
53
    private function applyLabel(AttributeNodeInterface $node): void
54
    {
55
        $astNode = $node->getAttribute('astNode');
56
57
        if (null === $astNode) {
58
            return;
59
        }
60
61
        $astTokens = iterator_to_array($astNode->getChildNodesAndTokens());
62
63
        switch (true) {
64
            case $astNode instanceof Node\ClassBaseClause:
65
            case $astNode instanceof Node\QualifiedName:
66
                $node->setAttribute(
67
                    'label',
68
                    sprintf('%s', (string) $astNode)
69
                );
70
71
                break;
72
            case $astNode instanceof Node\Statement\NamespaceDefinition:
73
                $node->setAttribute(
74
                    'label',
75
                    sprintf('Namespace %s', addslashes($node[0]->getAttribute('label')))
76
                );
77
                unset($node[0]);
78
79
                break;
80
            case $astNode instanceof Node\Statement\ClassDeclaration:
81
                $node->setAttribute(
82
                    'label',
83
                    sprintf(
84
                        'Class %s',
85
                        $astTokens['name']->getText((string) $astNode->getRoot())
86
                    )
87
                );
88
89
                break;
90
        }
91
    }
92
93
    private function applyShape(AttributeNodeInterface $node): void
94
    {
95
        $astNode = $node->getAttribute('astNode');
96
97
        if (null === $astNode) {
98
            return;
99
        }
100
101
        switch (true) {
102
            default:
103
                $node->setAttribute('shape', 'rect');
104
105
                break;
106
            case $astNode instanceof Node\Statement\NamespaceDefinition:
107
                $node->setAttribute('shape', 'house');
108
109
                break;
110
            case $astNode instanceof Node\Statement\ClassDeclaration:
111
                $node->setAttribute('shape', 'invhouse');
112
113
                break;
114
            case $astNode instanceof Node\MethodDeclaration:
115
                $node->setAttribute('shape', 'folder');
116
117
                break;
118
        }
119
    }
120
121
    private function filterObsoleteNode(AttributeNodeInterface $node): bool
122
    {
123
        $removeTypes = [
124
            Node\Statement\NamespaceUseDeclaration::class,
125
        ];
126
127
        return in_array(get_class($node->getAttribute('astNode')), $removeTypes, true);
128
    }
129
130
    private function removeOriginalNode(AttributeNodeInterface $node): void
131
    {
132
        $node->setAttribute('astNode', '');
133
    }
134
}
135