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

jojo1981 / json-ast-builder / 17578743546

09 Sep 2025 09:50AM UTC coverage: 35.019%. First build
17578743546

push

github

web-flow
Merge pull request #2 from jojo1981/feature/upgrade-php-versions

Fix: Make compatible with PHP versions: ^8.0|^8.1|^8.2|^8.3|^8.4

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

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/PlantUmlDataGeneratorVisitor.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 count;
30
use function end;
31
use function strlen;
32
use function substr;
33

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

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

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

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

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

54
    /** @var string[] */
55
    private array $keys = [];
56

57
    /** @var string[] */
58
    private array $states = [];
59

60
    /**
61
     * @return string
62
     */
63
    public function getResult(): string
64
    {
NEW
65
        return PlantUmlHelper::generateDocument($this->objects, $this->links);
×
66
    }
67

68
    /**
69
     * @param JsonNode $jsonNode
70
     * @return mixed
71
     */
72
    public function visitJsonNode(JsonNode $jsonNode): mixed
73
    {
NEW
74
        return $jsonNode->getElement()->accept($this);
×
75
    }
76

77
    /**
78
     * @param ElementNode $elementNode
79
     * @return mixed
80
     */
81
    public function visitElementNode(ElementNode $elementNode): mixed
82
    {
83
        return $elementNode->getValue()->accept($this);
×
84
    }
85

86
    /**
87
     * @param ValueNode $valueNode
88
     * @return mixed
89
     */
90
    public function visitValueNode(ValueNode $valueNode): mixed
91
    {
92
        return $valueNode->getType()->accept($this);
×
93
    }
94

95
    /**
96
     * @param ObjectNode $objectNode
97
     * @return string
98
     */
99
    public function visitObjectNode(ObjectNode $objectNode): string
100
    {
NEW
101
        $lastState = !empty($this->states) ? end($this->states) : null;
×
102
        $this->states[] = 'OBJECT';
×
103
        $this->level++;
×
104
        $this->incrementNodeCount('ObjectNode');
×
105
        $name = $this->getInstanceName('ObjectNode');
×
106
        $this->parents[] = $name;
×
107

108
        $objectName = 'ObjectNode';
×
109
        if (!empty($this->keys)) {
×
NEW
110
            $objectName = end($this->keys);
×
111
        }
112

113
        $text = 'object "**' . $objectName . '**" as ' . $name;
×
NEW
114
        if (count($objectNode->getMembers()) > 0) {
×
115
            $text .= ' {' . PHP_EOL;
×
116
            foreach ($objectNode->getMembers() as $memberNode) {
×
117
                [$key, $value] = $memberNode->accept($this);
×
118
                $text .= '  **' . $key . '**: ' . $value . PHP_EOL;
×
119
            }
120
            $text .= '}';
×
121
        }
122
        $text .= PHP_EOL;
×
123
        $this->objects[] = $text;
×
NEW
124
        array_pop($this->parents);
×
NEW
125
        $this->createParentChildLink($lastState, $name);
×
126

NEW
127
        return 'object';
×
128
    }
129

130
    /**
131
     * @param string $nodeName
132
     * @return void
133
     */
134
    private function incrementNodeCount(string $nodeName): void
135
    {
NEW
136
        if (!array_key_exists($nodeName, $this->nodeCounts)) {
×
NEW
137
            $this->nodeCounts[$nodeName] = 0;
×
138
        }
139

NEW
140
        $this->nodeCounts[$nodeName]++;
×
141
    }
142

143
    /**
144
     * @param string $nodeName
145
     * @return string
146
     */
147
    private function getInstanceName(string $nodeName): string
148
    {
NEW
149
        if (0 === $this->level) {
×
NEW
150
            return $nodeName;
×
151
        }
152

NEW
153
        $name = $nodeName; // . $this->level;
×
NEW
154
        if (array_key_exists($nodeName, $this->nodeCounts)) {
×
NEW
155
            $name .= $this->nodeCounts[$nodeName];
×
156
        }
157

NEW
158
        return $name;
×
159
    }
160

161
    /**
162
     * @param bool|string|null $lastState
163
     * @param string $name
164
     * @return void
165
     */
166
    private function createParentChildLink(bool|string|null $lastState, string $name): void
167
    {
168
        if (!empty($this->parents)) {
×
NEW
169
            $parent = end($this->parents);
×
170
            $arrow = $lastState === 'ARRAY' ? '--o' : '--*';
×
NEW
171
            $this->links[] = $parent . ' ' . $arrow . ' ' . $name;
×
172
        }
173

174
        $this->level--;
×
175

NEW
176
        array_pop($this->states);
×
177
    }
178

179
    /**
180
     * @param ArrayNode $arrayNode
181
     * @return string
182
     */
183
    public function visitArrayNode(ArrayNode $arrayNode): string
184
    {
NEW
185
        $lastState = !empty($this->states) ? end($this->states) : null;
×
186
        $this->states[] = 'ARRAY';
×
187
        $this->level++;
×
188
        $this->incrementNodeCount('ArrayNode');
×
189
        $name = $this->getInstanceName('ArrayNode');
×
190
        $this->parents[] = $name;
×
191

192
        $objectName = 'ArrayNode';
×
193
        if (!empty($this->keys)) {
×
NEW
194
            $objectName = end($this->keys);
×
195
        }
196

197
        $keys = $this->keys;
×
198
        $this->keys = [];
×
199
        $text = 'object "' . $objectName . '" as ' . $name;
×
NEW
200
        if (count($arrayNode->getElements()) > 0) {
×
201
            $text .= ' {' . PHP_EOL;
×
NEW
202
            $text .= '  element count: ' . count($arrayNode->getElements()) . PHP_EOL;
×
203
            foreach ($arrayNode->getElements() as $index => $elementNode) {
×
204
                //$text .= '  ' . $elementNode->accept($this) . PHP_EOL;
205
                $this->keys[] = 'element ' . ++$index;
×
206
                $elementNode->accept($this);
×
NEW
207
                array_pop($this->keys);
×
208
            }
209
            $text .= '}';
×
210
        }
211
        $text .= PHP_EOL;
×
212
        $this->objects[] = $text;
×
NEW
213
        array_pop($this->parents);
×
214
        $this->keys = $keys;
×
NEW
215
        $this->createParentChildLink($lastState, $name);
×
216

217
        return 'array';
×
218
    }
219

220
    /**
221
     * @param StringNode $stringNode
222
     * @return string
223
     */
224
    public function visitStringNode(StringNode $stringNode): string
225
    {
226
        $result = $stringNode->getValue();
×
NEW
227
        if (strlen($result) > 25) {
×
NEW
228
            $result = substr($result, 0, 25) . '...';
×
229
        }
230

231
        return $result;
×
232
    }
233

234
    /**
235
     * @param KeyNode $keyNode
236
     * @return string
237
     */
238
    public function visitKeyNode(KeyNode $keyNode): string
239
    {
240
        return $keyNode->getValue();
×
241
    }
242

243
    /**
244
     * @param NumberNode $numberNode
245
     * @return float
246
     */
247
    public function visitNumberNode(NumberNode $numberNode): float
248
    {
249
        return $numberNode->getValue();
×
250
    }
251

252
    /**
253
     * @param IntegerNode $integerNode
254
     * @return int
255
     */
256
    public function visitIntegerNode(IntegerNode $integerNode): int
257
    {
258
        return $integerNode->getValue();
×
259
    }
260

261
    /**
262
     * @param BooleanNode $booleanNode
263
     * @return bool
264
     */
265
    public function visitBooleanNode(BooleanNode $booleanNode): bool
266
    {
267
        return $booleanNode->getValue();
×
268
    }
269

270
    /**
271
     * @param NullNode $nullNode
272
     * @return null
273
     */
274
    public function visitNullNode(NullNode $nullNode): mixed
275
    {
276
        return null;
×
277
    }
278

279
    /**
280
     * @param MemberNode $memberNode
281
     * @return array
282
     */
283
    public function visitMemberNode(MemberNode $memberNode): array
284
    {
285
        $key = $memberNode->getKey()->accept($this);
×
286
        $this->keys[] = $key;
×
287
        $value = $memberNode->getValue()->accept($this);
×
NEW
288
        array_pop($this->keys);
×
289

290
        return [$key, $value];
×
291
    }
292
}
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

© 2026 Coveralls, Inc