• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

jojo1981 / json-ast-builder / 17578687754

09 Sep 2025 09:48AM UTC coverage: 35.019%. Remained the same
17578687754

push

github

jojo1981
Fix: Make compatible with PHP versions: ^8.0|^8.1|^8.2|^8.3|^8.4. Closes #1
https://github.com/jojo1981/json-ast-builder/issues/1

161 of 407 new or added lines in 17 files covered. (39.56%)

290 existing lines in 25 files now uncovered.

374 of 1068 relevant lines covered (35.02%)

3.47 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/Visitor/PlantUmlAstNodesGeneratorVisitor.php
1
<?php
2
/*
3
 * This file is part of the jojo1981/json-ast-builder package
4
 *
5
 * Copyright (c) 2019 Joost Nijhuis <jnijhuis81@gmail.com>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed in the root of the source code
9
 */
10
declare(strict_types=1);
11

12
namespace Jojo1981\JsonAstBuilder\Visitor;
13

14
use Jojo1981\JsonAstBuilder\Ast\ArrayNode;
15
use Jojo1981\JsonAstBuilder\Ast\BooleanNode;
16
use Jojo1981\JsonAstBuilder\Ast\ElementNode;
17
use Jojo1981\JsonAstBuilder\Ast\IntegerNode;
18
use Jojo1981\JsonAstBuilder\Ast\JsonNode;
19
use Jojo1981\JsonAstBuilder\Ast\KeyNode;
20
use Jojo1981\JsonAstBuilder\Ast\MemberNode;
21
use Jojo1981\JsonAstBuilder\Ast\NullNode;
22
use Jojo1981\JsonAstBuilder\Ast\NumberNode;
23
use Jojo1981\JsonAstBuilder\Ast\ObjectNode;
24
use Jojo1981\JsonAstBuilder\Ast\StringNode;
25
use Jojo1981\JsonAstBuilder\Ast\ValueNode;
26
use Jojo1981\JsonAstBuilder\Helper\PlantUmlHelper;
27
use function array_key_exists;
28
use function array_pop;
29
use function end;
30
use function explode;
31
use function get_class;
32

33
/**
34
 * @package Jojo1981\JsonAstBuilder\Visitor
35
 */
36
final class PlantUmlAstNodesGeneratorVisitor implements VisitorInterface
37
{
38
    /** @var string[] */
39
    private array $objects = [];
40

41
    /** @var string[] */
42
    private array $links = [];
43

44
    /** @var int */
45
    private int $level = 0;
46

47
    /** @var int[] */
48
    private array $nodeCounts = [];
49

50
    /** @var string[] */
51
    private array $parents = [];
52

53
    /** @var int */
54
    private int $maxLevel = 20;
55

56
    /**
57
     * @return string
58
     */
59
    public function getResult(): string
60
    {
NEW
61
        return PlantUmlHelper::generateDocument($this->objects, $this->links);
×
62
    }
63

64
    public function visitJsonNode(JsonNode $jsonNode): mixed
65
    {
UNCOV
66
        $this->addObjectForNode('JsonNode', '  element: ElementNode');
×
UNCOV
67
        $this->pushParent('JsonNode');
×
UNCOV
68
        $jsonNode->getElement()->accept($this);
×
UNCOV
69
        $this->popParent();
×
70

NEW
71
        return null;
×
72
    }
73

74
    /**
75
     * @param string $nodeName
76
     * @param string|null $body
77
     * @return void
78
     */
79
    private function addObjectForNode(string $nodeName, ?string $body = null): void
80
    {
NEW
81
        $this->incrementNodeCount($nodeName);
×
NEW
82
        $instanceName = $this->getInstanceName($nodeName);
×
83

NEW
84
        $text = 'object "' . $nodeName . '" as ' . $instanceName;
×
NEW
85
        if (null !== $body) {
×
NEW
86
            $text .= ' {' . PHP_EOL;
×
NEW
87
            $text .= $body . PHP_EOL;
×
NEW
88
            $text .= '}' . PHP_EOL;
×
89
        }
NEW
90
        if ($this->level < $this->maxLevel) {
×
NEW
91
            $this->objects[] = $text;
×
92
        }
93

NEW
94
        $this->linkWithParent($instanceName);
×
95
    }
96

97
    /**
98
     * @param string $nodeName
99
     * @return void
100
     */
101
    private function incrementNodeCount(string $nodeName): void
102
    {
NEW
103
        if (!array_key_exists($nodeName, $this->nodeCounts)) {
×
NEW
104
            $this->nodeCounts[$nodeName] = 0;
×
105
        }
106

NEW
107
        $this->nodeCounts[$nodeName]++;
×
108
    }
109

110
    /**
111
     * @param string $nodeName
112
     * @return string
113
     */
114
    private function getInstanceName(string $nodeName): string
115
    {
NEW
116
        if (0 === $this->level) {
×
NEW
117
            return $nodeName;
×
118
        }
119

NEW
120
        $name = $nodeName . $this->level;
×
NEW
121
        if (array_key_exists($nodeName, $this->nodeCounts)) {
×
NEW
122
            $name .= $this->nodeCounts[$nodeName];
×
123
        }
124

NEW
125
        return $name;
×
126
    }
127

128
    /**
129
     * @param string $name
130
     * @return void
131
     */
132
    private function linkWithParent(string $name): void
133
    {
NEW
134
        if (!empty($this->parents) && $this->level < $this->maxLevel) {
×
NEW
135
            $this->links[] = end($this->parents) . ' --* ' . $name;
×
136
        }
137
    }
138

139
    /**
140
     * @param string $nodeName
141
     * @return void
142
     */
143
    private function pushParent(string $nodeName): void
144
    {
NEW
145
        $this->parents[] = $this->getInstanceName($nodeName);
×
NEW
146
        $this->level++;
×
147
    }
148

149
    /**
150
     * @return void
151
     */
152
    private function popParent(): void
153
    {
NEW
154
        $this->level--;
×
NEW
155
        array_pop($this->parents);
×
156
    }
157

158
    public function visitElementNode(ElementNode $elementNode): mixed
159
    {
NEW
160
        $this->addObjectForNode('ElementNode', '  value: ValueNode');
×
161
        $this->pushParent('ElementNode');
×
162
        $elementNode->getValue()->accept($this);
×
163
        $this->popParent();
×
164

NEW
165
        return null;
×
166

167
    }
168

169
    public function visitValueNode(ValueNode $valueNode): mixed
170
    {
NEW
171
        $parts = explode('\\', get_class($valueNode->getType()));
×
NEW
172
        $this->addObjectForNode('ValueNode', '  type: ' . end($parts));
×
UNCOV
173
        $this->pushParent('ValueNode');
×
UNCOV
174
        $valueNode->getType()->accept($this);
×
UNCOV
175
        $this->popParent();
×
176

NEW
177
        return null;
×
178
    }
179

180
    public function visitObjectNode(ObjectNode $objectNode): mixed
181
    {
UNCOV
182
        $this->addObjectForNode('ObjectNode', '  members: MemberNode[]');
×
183
        $this->pushParent('ObjectNode');
×
184
        foreach ($objectNode->getMembers() as $memberNode) {
×
UNCOV
185
            $memberNode->accept($this);
×
186
        }
187
        $this->popParent();
×
188

NEW
189
        return null;
×
190
    }
191

192
    /**
193
     * @param MemberNode $memberNode
194
     * @return mixed
195
     */
196
    public function visitMemberNode(MemberNode $memberNode): mixed
197
    {
198
        $this->addObjectForNode('MemberNode', '  key: KeyNode' . PHP_EOL . '  value: ElementNode');
×
UNCOV
199
        $this->pushParent('MemberNode');
×
UNCOV
200
        $memberNode->getKey()->accept($this);
×
201
        $memberNode->getValue()->accept($this);
×
202
        $this->popParent();
×
203

NEW
204
        return null;
×
205
    }
206

207
    /**
208
     * @param KeyNode $keyNode
209
     * @return mixed
210
     */
211
    public function visitKeyNode(KeyNode $keyNode): mixed
212
    {
UNCOV
213
        $this->addObjectForNode('KeyNode', '  value: ' . $keyNode->getValue());
×
214

NEW
215
        return null;
×
216
    }
217

218
    public function visitArrayNode(ArrayNode $arrayNode): mixed
219
    {
220
        $this->addObjectForNode('ArrayNode', '  elements: ElementNode[]');
×
UNCOV
221
        $this->pushParent('ArrayNode');
×
UNCOV
222
        foreach ($arrayNode->getElements() as $elementNode) {
×
UNCOV
223
            $elementNode->accept($this);
×
224
        }
UNCOV
225
        $this->popParent();
×
226

NEW
227
        return null;
×
228
    }
229

230
    public function visitStringNode(StringNode $stringNode): mixed
231
    {
232
        $this->addObjectForNode('StringNode', '  value: ' . $stringNode->getValue());
×
233

NEW
234
        return null;
×
235
    }
236

237
    public function visitNumberNode(NumberNode $numberNode): mixed
238
    {
UNCOV
239
        $this->addObjectForNode('NumberNode', '  value: ' . $numberNode->getValue());
×
240

NEW
241
        return null;
×
242
    }
243

244
    /**
245
     * @param IntegerNode $integerNode
246
     * @return mixed
247
     */
248
    public function visitIntegerNode(IntegerNode $integerNode): mixed
249
    {
UNCOV
250
        $this->addObjectForNode('IntegerNode', '  value: ' . $integerNode->getValue());
×
251

NEW
252
        return null;
×
253
    }
254

255
    /**
256
     * @param BooleanNode $booleanNode
257
     * @return mixed
258
     */
259
    public function visitBooleanNode(BooleanNode $booleanNode): mixed
260
    {
UNCOV
261
        $this->addObjectForNode('BooleanNode', '  value: ' . ($booleanNode->getValue() ? 'true' : 'false'));
×
262

NEW
263
        return null;
×
264
    }
265

266
    /**
267
     * @param NullNode $nullNode
268
     * @return mixed
269
     */
270
    public function visitNullNode(NullNode $nullNode): mixed
271
    {
272
        $this->addObjectForNode('NullNode');
×
273

NEW
274
        return null;
×
275
    }
276
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc