• 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/JsonStringGeneratorVisitor.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 function array_merge;
27
use function count;
28
use function str_repeat;
29

30
/**
31
 * @package Jojo1981\JsonAstBuilder\Visitor
32
 */
33
final class JsonStringGeneratorVisitor implements VisitorInterface
34
{
35
    /** @var array */
36
    private array $options;
37

38
    /** @var string */
39
    private string $result = '';
40

41
    /** @var int */
42
    private int $level = 0;
43

44
    /** @var string */
45
    private string $indent;
46

47
    public function __construct(array $options = [])
48
    {
49
        $defaults = [
×
50
            'useTabs' => false,
×
51
            'pretty' => true,
×
52
            'indentSize' => 2,
×
53
            'spacesBeforeColon' => 0,
×
54
            'spacesAfterColon' => 1,
×
55
            'lineSeparator' => PHP_EOL
×
56
        ];
×
NEW
57
        $this->options = array_merge($defaults, $options);
×
NEW
58
        $this->indent = str_repeat($this->options['useTabs'] ? "\t" : ' ', $this->options['indentSize']);
×
59
    }
60

61
    /**
62
     * @return string
63
     */
64
    public function getResult(): string
65
    {
66
        return $this->result;
×
67
    }
68

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

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

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

96
    /**
97
     * @param ObjectNode $objectNode
98
     * @return mixed
99
     */
100
    public function visitObjectNode(ObjectNode $objectNode): mixed
101
    {
102
        $this->addText('{');
×
103

NEW
104
        $memberCount = count($objectNode->getMembers());
×
105
        if ($memberCount > 0) {
×
106
            $this->level++;
×
107
            $this->addNewline();
×
108
            $this->addIndent();
×
109
            for ($i = 0; $i < $memberCount; $i++) {
×
110
                $member = $objectNode->getMembers()[$i];
×
111
                $member->accept($this);
×
112
                if ($i < $memberCount - 1) {
×
113
                    $this->addText(',');
×
114
                    $this->addNewline();
×
115
                    $this->addIndent();
×
116
                }
117
            }
118
            $this->level--;
×
119
            $this->addNewline();
×
120
            $this->addIndent();
×
121
        }
122

123
        $this->addText('}');
×
124

NEW
125
        return null;
×
126
    }
127

128
    /**
129
     * @param string $text
130
     * @return void
131
     */
132
    private function addText(string $text): void
133
    {
NEW
134
        $this->result .= $text;
×
135
    }
136

137
    /**
138
     * @return void
139
     */
140
    private function addNewline(): void
141
    {
NEW
142
        if ($this->options['pretty']) {
×
NEW
143
            $this->result .= $this->options['lineSeparator'];
×
144
        }
145
    }
146

147
    /**
148
     * @return void
149
     */
150
    private function addIndent(): void
151
    {
NEW
152
        if ($this->options['pretty']) {
×
NEW
153
            $this->result .= str_repeat($this->indent, $this->level);
×
154
        }
155
    }
156

157
    /**
158
     * @param ArrayNode $arrayNode
159
     * @return mixed
160
     */
161
    public function visitArrayNode(ArrayNode $arrayNode): mixed
162
    {
163
        $this->addText('[');
×
164

NEW
165
        $elementCount = count($arrayNode->getElements());
×
166
        if ($elementCount > 0) {
×
167
            $this->level++;
×
168
            $this->addNewline();
×
169
            $this->addIndent();
×
170
            for ($i = 0; $i < $elementCount; $i++) {
×
171
                $element = $arrayNode->getElements()[$i];
×
172
                $element->accept($this);
×
173
                if ($i < $elementCount - 1) {
×
174
                    $this->addText(',');
×
175
                    $this->addNewline();
×
176
                    $this->addIndent();
×
177
                }
178
            }
179

180
            $this->level--;
×
181
            $this->addNewline();
×
182
            $this->addIndent();
×
183
        }
184
        $this->addText(']');
×
185

NEW
186
        return null;
×
187
    }
188

189
    /**
190
     * @param StringNode $stringNode
191
     * @return mixed
192
     */
193
    public function visitStringNode(StringNode $stringNode): mixed
194
    {
195
        $this->addText('"' . $stringNode->getValue() . '"');
×
196

NEW
197
        return null;
×
198
    }
199

200
    /**
201
     * @param KeyNode $keyNode
202
     * @return mixed
203
     */
204
    public function visitKeyNode(KeyNode $keyNode): mixed
205
    {
206
        $this->addText('"' . $keyNode->getValue() . '"');
×
207

NEW
208
        return null;
×
209
    }
210

211
    /**
212
     * @param NumberNode $numberNode
213
     * @return mixed
214
     */
215
    public function visitNumberNode(NumberNode $numberNode): mixed
216
    {
217
        $this->addText((string) $numberNode->getValue());
×
218

NEW
219
        return null;
×
220
    }
221

222
    /**
223
     * @param IntegerNode $integerNode
224
     * @return mixed
225
     */
226
    public function visitIntegerNode(IntegerNode $integerNode): mixed
227
    {
228
        $this->addText((string) $integerNode->getValue());
×
229

NEW
230
        return null;
×
231
    }
232

233
    /**
234
     * @param BooleanNode $booleanNode
235
     * @return mixed
236
     */
237
    public function visitBooleanNode(BooleanNode $booleanNode): mixed
238
    {
239
        $this->addText($booleanNode->getValue() ? 'true' : 'false');
×
240

NEW
241
        return null;
×
242
    }
243

244
    /**
245
     * @param NullNode $nullNode
246
     * @return mixed
247
     */
248
    public function visitNullNode(NullNode $nullNode): mixed
249
    {
250
        $this->addText('null');
×
251

NEW
252
        return null;
×
253
    }
254

255
    /**
256
     * @param MemberNode $memberNode
257
     * @return mixed
258
     */
259
    public function visitMemberNode(MemberNode $memberNode): mixed
260
    {
261
        $memberNode->getKey()->accept($this);
×
NEW
262
        $spaceBefore = str_repeat(' ', $this->options['spacesBeforeColon']);
×
NEW
263
        $spaceAfter = str_repeat(' ', $this->options['spacesAfterColon']);
×
264
        $this->addText($spaceBefore . ':' . $spaceAfter);
×
265
        $memberNode->getValue()->accept($this);
×
266

NEW
267
        return null;
×
268
    }
269
}
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