8000 Adapt code only when before normalization hooks are present · symfony/symfony@be1071b · GitHub
[go: up one dir, main page]

Skip to content

Commit be1071b

Browse files
committed
Adapt code only when before normalization hooks are present
1 parent e367a9e commit be1071b

File tree

8 files changed

+125
-157
lines changed

8 files changed

+125
-157
lines changed

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

Lines changed: 72 additions & 9 deletions
+
$this->_usedProperties[\'PROPERTY\'] = true;
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Config\Builder;
1313

1414
use Symfony\Component\Config\Definition\ArrayNode;
15+
use Symfony\Component\Config\Definition\BaseNode;
1516
use Symfony\Component\Config\Definition\BooleanNode;
1617
use Symfony\Component\Config\Definition\ConfigurationInterface;
1718
use Symfony\Component\Config\Definition\EnumNode;
@@ -136,8 +137,12 @@ private function handleArrayNode(ArrayNode $node, ClassBuilder $class, string $n
136137
$class->addRequire($childClass);
137138
$this->classes[] = $childClass;
138139

139-
$property = $class->addProperty($node->getName(), $childClass->getFqcn());
140-
$body = '
140+
$hasNormalizationClosures = $this->hasNormalizationClosures($node);
141+
$property = $class->addProperty(
142+
$node->getName(),
143+
$this->getType($childClass->getFqcn(), $hasNormalizationClosures)
144+
);
145+
$body = $hasNormalizationClosures ? '
141146
/**
142147
* @return CLASS|$this
143148
*/
@@ -157,6 +162,17 @@ public function NAME($value = [])
157162
throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME().\');
158163
}
159164
165+
return $this->PROPERTY;
166+
}' : '
167+
public function NAME(array $value = []): CLASS
168+
{
169+
if (null === $this->PROPERTY) {
170
171+
$this->PROPERTY = new CLASS($value);
172+
} elseif (0 < \func_num_args()) {
173+
throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME().\');
174+
}
175+
160176
return $this->PROPERTY;
161177
}';
162178
$class->addUse(InvalidConfigurationException::class);
@@ -237,10 +253,15 @@ public function NAME(string $VAR, $VALUE): self
237253
}
238254
$class->addRequire($childClass);
239255
$this->classes[] = $childClass;
240-
$property = $class->addProperty($node->getName(), $childClass->getFqcn().'[]');
256+
257+
$hasNormalizationClosures = $this->hasNormalizationClosures($node) || $this->hasNormalizationClosures($prototype);
258+
$property = $class->addProperty(
259+
$node->getName(),
260+
$this->getType($childClass->getFqcn().'[]', $hasNormalizationClosures)
261+
);
241262

242263
if (null === $key = $node->getKeyAttribute()) {
243-
$body = '
264+
$body = $hasNormalizationClosures ? '
244265
/**
245266
* @return CLASS|$this
246267
*/
@@ -253,11 +274,17 @@ public function NAME($value = [])
253274
return $this;
254275
}
255276
277+
return $this->PROPERTY[] = new CLASS($value);
278+
}' : '
279+
public function NAME(array $value = []): CLASS
280+
{
281+
$this->_usedProperties[\'PROPERTY\'] = true;
282+
256283
return $this->PROPERTY[] = new CLASS($value);
257284
}';
258285
$class->addMethod($methodName, $body, ['PROPERTY' => $property->getName(), 'CLASS' => $childClass->getFqcn()]);
259286
} else {
260-
$body = '
287+
$body = $hasNormalizationClosures ? '
261288
/**
262289
* @return CLASS|$this
263290
*/
@@ -277,6 +304,17 @@ public function NAME(string $VAR, $VALUE = [])
277304
throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME().\');
278305
}
279306
307+
return $this->PROPERTY[$VAR];
308+
}' : '
309+
public function NAME(string $VAR, array $VALUE = []): CLASS
310+
{
311+
if (!isset($this->PROPERTY[$VAR])) {
312+
$this->_usedProperties[\'PROPERTY\'] = true;
313+
$this->PROPERTY[$VAR] = new CLASS($VALUE);
314+
} elseif (1 < \func_num_args()) {
315+
throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME().\');
316+
}
317+
280318
return $this->PROPERTY[$VAR];
281319
}';
282320
$class->addUse(InvalidConfigurationException::class);
@@ -401,9 +439,15 @@ private function buildToArray(ClassBuilder $class): void
401439
$code = '$this->PROPERTY';
402440
if (null !== $p->getType()) {
403441
if ($p->isArray()) {
404-
$code = 'array_map(function ($v) { return $v instanceof CLASS ? $v->toArray() : $v; }, $this->PROPERTY)';
442+
$code = $p->areScalarsAllowed()
443+
? 'array_map(function ($v) { return $v instanceof CLASS ? $v->toArray() : $v; }, $this->PROPERTY)'
444+
: 'array_map(function ($v) { return $v->toArray(); }, $this->PROPERTY)'
445+
;
405446
} else {
406-
$code = '$this->PROPERTY instanceof CLASS ? $this->PROPERTY->toArray() : $this->PROPERTY';
447+
$code = $p->areScalarsAllowed()
448+
? '$this->PROPERTY instanceof CLASS ? $this->PROPERTY->toArray() : $this->PROPERTY'
449+
: '$this->PROPERTY->toArray()'
450+
;
407451
}
408452
}
409453

@@ -431,9 +475,15 @@ private function buildConstructor(ClassBuilder $class): void
431475
$code = '$value[\'ORG_NAME\']';
432476
if (null !== $p->getType()) {
433477
if ($p->isArray()) {
434-
$code = 'array_map(function ($v) { return \is_array($v) ? new '.$p->getType().'($v) : $v; }, $value[\'ORG_NAME\'])';
478+
$code = $p->areScalarsAllowed()
479+
? 'array_map(function ($v) { return \is_array($v) ? new '.$p->getType().'($v) : $v; }, $value[\'ORG_NAME\'])'
480+
: 'array_map(function ($v) { return new '.$p->getType().'($v); }, $value[\'ORG_NAME\'])'
481+
;
435482
} else {
436-
$code = '\is_array($value[\'ORG_NAME\']) ? new '.$p->getType().'($value[\'ORG_NAME\']) : $value[\'ORG_NAME\']';
483+
$code = $p->areScalarsAllowed()
484+
? '\is_array($value[\'ORG_NAME\']) ? new '.$p->getType().'($value[\'ORG_NAME\']) : $value[\'ORG_NAME\']'
485+
: 'new '.$p->getType().'($value[\'ORG_NAME\'])'
486+
;
437487
}
438488
}
439489

@@ -492,4 +542,17 @@ private function getSubNamespace(ClassBuilder $rootClass): string
492542
{
493543
return sprintf('%s\\%s', $rootClass->getNamespace(), substr($rootClass->getName(), 0, -6));
494544
}
545+
546+
private function hasNormalizationClosures(BaseNode $node): bool
547+
{
548+
$r = new \ReflectionProperty($node, 'normalizationClosures');
549+
$r->setAccessible(true);
550+
551+
return [] !== $r->getValue($node);
552+
}
553+
554+
private function getType(string $classType, bool $hasNormalizationClosures): string
555+
{
556+
return $classType.($hasNormalizationClosures ? '|scalar' : '');
557+
}
495558
}

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class Property
2323
private $name;
2424
private $originalName;
2525
private $array = false;
26+
private $scalarsAllowed = false;
2627
private $type = null;
2728
private $content;
2829

@@ -47,6 +48,11 @@ public function setType(string $type): void
4748
$this->array = false;
4849
$this->type = $type;
4950

51+
if ('|scalar' === substr($type, -7)) {
52+
$this->scalarsAllowed = true;
53+
$this->type = $type = substr($type, 0, -7);
54+
}
55+
5056
if ('[]' === substr($type, -2)) {
5157
$this->array = true;
5258
$this->type = substr($type, 0, -2);
@@ -72,4 +78,9 @@ public function isArray(): bool
7278
{
7379
return $this->array;
7480
}
81+
82+
public function areScalarsAllowed(): bool
83+
{
84+
return $this->scalarsAllowed;
85+
}
7586
}

src/Symfony/Component/Config/Tests/Builder/Fixtures/AddToList/Symfony/Config/AddToList/MessengerConfig.php

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,9 @@ class MessengerConfig
1616
private $receiving;
1717
private $_usedProperties = [];
1818

19-
/**
20-
* @return \Symfony\Config\AddToList\Messenger\RoutingConfig|$this
21-
*/
22-
public function routing(string $message_class, $value = [])
19+
public function routing(string $message_class, array $value = []): \Symfony\Config\AddToList\Messenger\RoutingConfig
2320
{
24-
if (!\is_array($value)) {
25-
$this->_usedProperties['routing'] = true;
26-
$this->routing[$message_class] = $value;
27-
28-
return $this;
29-
}
30-
31-
if (!isset($this->routing[$message_class]) || !$this->routing[$message_class] instanceof \Symfony\Config\AddToList\Messenger\RoutingConfig) {
21+
if (!isset($this->routing[$message_class])) {
3222
$this->_usedProperties['routing'] = true;
3323
$this->routing[$message_class] = new \Symfony\Config\AddToList\Messenger\RoutingConfig($value);
3424
} elseif (1 < \func_num_args()) {
@@ -38,17 +28,9 @@ public function routing(string $message_class, $value = [])
3828
return $this->routing[$message_class];
3929
}
4030

41-
/**
42-
* @return \Symfony\Config\AddToList\Messenger\ReceivingConfig|$this
43-
*/
44-
public function receiving($value = [])
31+
public function receiving(array $value = []): \Symfony\Config\AddToList\Messenger\ReceivingConfig
4532
{
4633
$this->_usedProperties['receiving'] = true;
47-
if (!\is_array($value)) {
48-
$this->receiving[] = $value;
49-
50-
return $this;
51-
}
5234

5335
return $this->receiving[] = new \Symfony\Config\AddToList\Messenger\ReceivingConfig($value);
5436
}
@@ -57,13 +39,13 @@ public function __construct(array $value = [])
5739
{
5840
if (array_key_exists('routing', $value)) {
5941
$this->_usedProperties['routing'] = true;
60-
$this->routing = array_map(function ($v) { return \is_array($v) ? new \Symfony\Config\AddToList\Messenger\RoutingConfig($v) : $v; }, $value['routing']);
42+
$this->routing = array_map(function ($v) { return new \Symfony\Config\AddToList\Messenger\RoutingConfig($v); }, $value['routing']);
6143
unset($value['routing']);
6244
}
6345

6446
if (array_key_exists('receiving', $value)) {
6547
$this->_usedProperties['receiving'] = true;
66-
$this->receiving = array_map(function ($v) { return \is_array($v) ? new \Symfony\Config\AddToList\Messenger\ReceivingConfig($v) : $v; }, $value['receiving']);
48+
$this->receiving = array_map(function ($v) { return new \Symfony\Config\AddToList\Messenger\ReceivingConfig($v); }, $value['receiving']);
6749
unset($value['receiving']);
6850
}
6951

@@ -76,10 +58,10 @@ public function toArray(): array
7658
{
7759
$output = [];
7860
if (isset($this->_usedProperties['routing'])) {
79-
$output['routing'] = array_map(function ($v) { return $v instanceof \Symfony\Config\AddToList\Messenger\RoutingConfig ? $v->toArray() : $v; }, $this->routing);
61+
$output['routing'] = array_map(function ($v) { return $v->toArray(); }, $this->routing);
8062
}
8163
if (isset($this->_usedProperties['receiving'])) {
82-
$output['receiving'] = array_map(function ($v) { return $v instanceof \Symfony\Config\AddToList\Messenger\ReceivingConfig ? $v->toArray() : $v; }, $this->receiving);
64+
$output['receiving'] = array_map(function ($v) { return $v->toArray(); }, $this->receiving);
8365
}
8466

8567
return $output;

src/Symfony/Component/Config/Tests/Builder/Fixtures/AddToList/Symfony/Config/AddToListConfig.php

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,9 @@ class AddToListConfig implements \Symfony\Component\Config\Builder\ConfigBuilder
1616
private $messenger;
1717
private $_usedProperties = [];
1818

19-
/**
20-
* @return \Symfony\Config\AddToList\TranslatorConfig|$this
21-
*/
22-
public function translator($value = [])
19+
public function translator(array $value = []): \Symfony\Config\AddToList\TranslatorConfig
2320
{
24-
if (!\is_array($value)) {
25-
$this->_usedProperties['translator'] = true;
26-
$this->translator = $value;
27-
28-
return $this;
29-
}
30-
31-
if (!$this->translator instanceof \Symfony\Config\AddToList\TranslatorConfig) {
21+
if (null === $this->translator) {
3222
$this->_usedProperties['translator'] = true;
3323
$this->translator = new \Symfony\Config\AddToList\TranslatorConfig($value);
3424
} elseif (0 < \func_num_args()) {
@@ -38,19 +28,9 @@ public function translator($value = [])
3828
return $this->translator;
3929
}
4030

41-
/**
42-
* @return \Symfony\Config\AddToList\MessengerConfig|$this
43-
*/
44-
public function messenger($value = [])
31+
public function messenger(array $value = []): \Symfony\Config\AddToList\MessengerConfig
4532
{
46-
if (!\is_array($value)) {
47-
$this->_usedProperties['messenger'] = true;
48-
$this->messenger = $value;
49-
50-
return $this;
51-
}
52-
53-
if (!$this->messenger instanceof \Symfony\Config\AddToList\MessengerConfig) {
33+
if (null === $this->messenger) {
5434
$this->_usedProperties['messenger'] = true;
5535
$this->messenger = new \Symfony\Config\AddToList\MessengerConfig($value);
5636
} elseif (0 < \func_num_args()) {
@@ -69,13 +49,13 @@ public function __construct(array $value = [])
6949
{
7050
if (array_key_exists('translator', $value)) {
7151
$this->_usedProperties['translator'] = true;
72-
$this->translator = \is_array($value['translator']) ? new \Symfony\Config\AddToList\TranslatorConfig($value['translator']) : $value['translator'];
52+
$this->translator = new \Symfony\Config\AddToList\TranslatorConfig($value['translator']);
7353
unset($value['translator']);
7454
}
7555

7656
if (array_key_exists('messenger', $value)) {
7757
$this->_usedProperties['messenger'] = true;
78-
$this->messenger = \is_array($value['messenger']) ? new \Symfony\Config\AddToList\MessengerConfig($value['messenger']) : $value['messenger'];
58+
$this->messenger = new \Symfony\Config\AddToList\MessengerConfig($value['messenger']);
7959
unset($value['messenger']);
8060
}
8161

@@ -88,10 +68,10 @@ public function toArray(): array
8868
{
8969
$output = [];
9070
if (isset($this->_usedProperties['translator'])) {
91-
$output['translator'] = $this->translator instanceof \Symfony\Config\AddToList\TranslatorConfig ? $this->translator->toArray() : $this->translator;
71+
$output['translator'] = $this->translator->toArray();
9272
}
9373
if (isset($this->_usedProperties['messenger'])) {
94-
$output['messenger'] = $this->messenger instanceof \Symfony\Config\AddToList\MessengerConfig ? $this->messenger->toArray() : $this->messenger;
74+
$output['messenger'] = $this->messenger->toArray();
9575
}
9676

9777
return $output;

0 commit comments

Comments
 (0)
0