Skip to content

Commit 93c3cbb

Browse files
committed
Use array instead of stdClass
1 parent d60eada commit 93c3cbb

File tree

3 files changed

+51
-46
lines changed

3 files changed

+51
-46
lines changed

src/Symfony/Component/Config/Builder/JsonSchemaGenerator.php

Lines changed: 42 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,13 @@
2020
use Symfony\Component\Config\Definition\NodeInterface;
2121
use Symfony\Component\Config\Definition\NumericNode;
2222
use Symfony\Component\Config\Definition\PrototypedArrayNode;
23-
use Symfony\Component\Config\Definition\ScalarNode;
2423
use Symfony\Component\Config\Definition\StringNode;
2524
use Symfony\Component\Config\Definition\VariableNode;
2625

2726
/**
2827
* Generates a JSON Schema from a Node definition.
2928
*
30-
* @internal
29+
* @author Jérôme Tamarelle<jerome@tamarelle.net>
3130
*/
3231
final class JsonSchemaGenerator
3332
{
@@ -36,109 +35,107 @@ final class JsonSchemaGenerator
3635
*
3736
* @param array<string, mixed> $meta Additional attributes to include in the schema root
3837
*/
39-
public function generate(NodeInterface $node, array $meta = []): \stdClass
38+
public function generate(NodeInterface $node, array $meta = []): array
4039
{
41-
return (object) [
40+
return [
4241
'$schema' => 'http://json-schema.org/draft-07/schema',
4342
... $meta,
44-
... (array) $this->generateNode($node),
43+
... $this->generateNode($node),
4544
];
4645
}
4746

48-
public function generateNode(NodeInterface $node): \stdClass
47+
public function generateNode(NodeInterface $node): array
4948
{
5049
if ($node instanceof PrototypedArrayNode) {
5150
$prototypeSchema = $this->generateNode($node->getPrototype());
5251

5352
if ($node->getKeyAttribute()) {
54-
$schema = (object) [
53+
$schema = [
5554
'type' => 'object',
5655
'additionalProperties' => $prototypeSchema,
5756
];
5857

5958
if ($node->getMinNumberOfElements()) {
60-
$schema->minProperties = $node->getMinNumberOfElements();
59+
$schema['minProperties'] = $node->getMinNumberOfElements();
6160
}
6261
} else {
63-
$schema = (object) [
62+
$schema = [
6463
'type' => 'array',
6564
'items' => $prototypeSchema
6665
];
6766

6867
if ($node->getMinNumberOfElements()) {
69-
$schema->minItems = $node->getMinNumberOfElements();
68+
$schema['minItems'] = $node->getMinNumberOfElements();
7069
}
7170
}
7271
} elseif ($node instanceof ArrayNode) {
73-
$schema = (object) ['type' => ['object']];
72+
$schema = ['type' => ['object']];
7473
$children = $node->getChildren();
7574
foreach ($children as $child) {
76-
$schema->properties ??= new \stdClass();
77-
$schema->properties->{$child->getName()} = $this->generateNode($child);
75+
$schema['properties'] ??= [];
76+
$schema['properties'][$child->getName()] = $this->generateNode($child);
7877
if ($child->isRequired()) {
79-
$schema->required ??= [];
80-
$schema->required[] = $child->getName();
78+
$schema['required'] ??= [];
79+
$schema['required'][] = $child->getName();
8180
}
8281
}
8382

84-
if (property_exists($schema, 'properties')) {
83+
if (isset($schema['properties'])) {
8584
if ($node->shouldIgnoreExtraKeys()) {
86-
$schema->additionalProperties = true;
85+
$schema['additionalProperties'] = true;
8786
} else {
88-
$schema->additionalProperties = false;
87+
$schema['additionalProperties'] = false;
8988
}
9089
}
9190
} elseif ($node instanceof BooleanNode) {
92-
$schema = (object) ['type' => ['boolean']];
91+
$schema = ['type' => ['boolean']];
9392

9493
if ($node->isNullable()) {
95-
$schema->type[] = 'null';
94+
$schema['type'][] = 'null';
9695
}
9796
} elseif ($node instanceof StringNode) {
98-
$schema = (object) ['type' => ['string']];
97+
$schema = ['type' => ['string']];
9998
} elseif ($node instanceof EnumNode) {
100-
$schema = (object) [
99+
$schema = [
101100
'$anyOf' => [
102-
(object) ['enum' => array_map(static function (mixed $case): string|int|float|bool|null {
101+
['enum' => array_map(static function (mixed $case): string|int|float|bool|null {
103102
if ($case instanceof \UnitEnum) {
104103
return \sprintf('!php/enum %s::%s', $case::class, $case->name);
105104
}
106105

107106
return $case;
108107
}, $node->getValues())],
109-
(object) ['type' => 'null'],
108+
['type' => 'null'],
110109
],
111110
];
112111
} elseif ($node instanceof NumericNode) {
113-
$schema = (object) ['type' => $node instanceof IntegerNode ? ['integer'] : ['number']];
112+
$schema = ['type' => $node instanceof IntegerNode ? ['integer'] : ['number']];
114113

115114
if (null !== $node->getMin()) {
116-
$schema->minimum = $node->getMin();
115+
$schema['minimum'] = $node->getMin();
117116
}
118117

119118
if (null !== $node->getMax()) {
120-
$schema->maximum = $node->getMax();
119+
$schema['maximum'] = $node->getMax();
121120
}
122-
} elseif ($node instanceof ScalarNode) {
123-
$schema = (object) ['type' => ['array', 'object', 'string', 'number', 'boolean', 'null']];
124121
} elseif ($node instanceof VariableNode) {
125-
$schema = (object) ['type' => null];
122+
$schema = ['type' => ['array', 'object', 'string', 'number', 'boolean', 'null']];
126123
} else {
127-
$schema = (object) ['type' => ['null']];
124+
$schema = ['type' => ['null']];
128125
}
129126

130127
if ($node instanceof BaseNode) {
131128
$normalizedTypes = array_diff($node->getNormalizedTypes(), [ExprBuilder::TYPE_ANY, ExprBuilder::TYPE_ARRAY]);
132129

133-
if (isset($schema->type) && $node->hasDefaultValue() && $node->getDefaultValue() === null) {
130+
if (isset($schema['type']) && $node->hasDefaultValue() && $node->getDefaultValue() === null) {
134131
$normalizedTypes[] = 'null';
135132
}
136133

137134
if ($normalizedTypes) {
138-
$schema = (object)[
135+
$schema = [
139136
'$anyOf' => [
140137
$schema,
141-
(object)[
138+
[
142139
'type' => array_values(
143140
array_unique(
144141
array_map(fn($type) => match ($type) {
@@ -156,32 +153,32 @@ public function generateNode(NodeInterface $node): \stdClass
156153
];
157154
}
158155

159-
if (is_array($schema->type ?? null)) {
160-
$schema->type = array_values(array_unique($schema->type));
156+
if (is_array($schema['type'] ?? null)) {
157+
$schema['type'] = array_values(array_unique($schema['type']));
161158
}
162159

163160
if ($node->hasDefaultValue() && !($node instanceof ArrayNode && $node->getDefaultValue() === [])) {
164-
$schema->default = $node->getDefaultValue();
161+
$schema['default'] = $node->getDefaultValue();
165162
}
166163

167164
if ($node->getInfo()) {
168-
$schema->description = $node->getInfo();
165+
$schema['description'] = $node->getInfo();
169166
}
170167

171168
if ($node->getExample()) {
172-
$schema->examples = [$node->getExample()];
169+
$schema['examples'] = [$node->getExample()];
173170
}
174171

175172
if ($node->isDeprecated()) {
176-
$schema->deprecated = true;
177-
$schema->deprecationMessage = $node->getDeprecationMessage($node);
173+
$schema['deprecated'] = true;
174+
$schema['deprecationMessage'] = $node->getDeprecationMessage($node);
178175
}
179176
}
180177

181-
if (empty($schema->type)) {
182-
unset($schema->type);
183-
} elseif (is_array($schema->type) && count($schema->type) === 1) {
184-
$schema->type = $schema->type[0];
178+
if (empty($schema['type'])) {
179+
unset($schema['type']);
180+
} elseif (is_array($schema['type']) && count($schema['type']) === 1) {
181+
$schema['type'] = $schema['type'][0];
185182
}
186183

187184
return $schema;

src/Symfony/Component/Config/Tests/Builder/JsonSchemaGeneratorTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public static function provideNodes(): iterable
6666
],
6767
]];
6868
yield [new ScalarNode('node'), ['type' => ['array', 'object', 'string', 'number', 'boolean', 'null']]];
69-
yield [new VariableNode('node'), new \stdClass()];
69+
yield [new VariableNode('node'), ['type' => ['array', 'object', 'string', 'number', 'boolean', 'null']]];
7070

7171
yield [new IntegerNode('node'), ['type' => 'integer']];
7272
yield [new IntegerNode('node', min: 1), ['type' => 'integer', 'minimum' => 1]];

src/Symfony/Component/Config/Tests/Fixtures/Configuration/ExampleConfiguration.schema.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,14 @@
268268
"default": null
269269
},
270270
"variable": {
271+
"type": [
272+
"array",
273+
"object",
274+
"string",
275+
"number",
276+
"boolean",
277+
"null"
278+
],
271279
"examples": [
272280
[
273281
"foo",

0 commit comments

Comments
 (0)