Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit962834b

Browse files
committed
Allow scalar configuration in PHP Configuration
1 parent3fb7af0 commit962834b

File tree

29 files changed

+482
-90
lines changed

29 files changed

+482
-90
lines changed

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

Lines changed: 145 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
namespaceSymfony\Component\Config\Builder;
1313

1414
useSymfony\Component\Config\Definition\ArrayNode;
15+
useSymfony\Component\Config\Definition\BaseNode;
1516
useSymfony\Component\Config\Definition\BooleanNode;
17+
useSymfony\Component\Config\Definition\Builder\ExprBuilder;
1618
useSymfony\Component\Config\Definition\ConfigurationInterface;
1719
useSymfony\Component\Config\Definition\EnumNode;
1820
useSymfony\Component\Config\Definition\Exception\InvalidConfigurationException;
@@ -131,8 +133,11 @@ private function handleArrayNode(ArrayNode $node, ClassBuilder $class, string $n
131133
$this->classes[] =$childClass;
132134

133135
$property =$class->addProperty($node->getName(),$childClass->getFqcn());
134-
$body ='
135-
public function NAME(array $value = []): CLASS
136+
$nodeTypes =$this->getParameterTypes($node);
137+
138+
if (['array'] ===$nodeTypes) {
139+
$body ='
140+
public function NAME(PARAM_TYPE $value = []): RETURN_TYPEHINT
136141
{
137142
if (null === $this->PROPERTY) {
138143
$this->PROPERTY = new CLASS($value);
@@ -142,8 +147,33 @@ public function NAME(array $value = []): CLASS
142147
143148
return $this->PROPERTY;
144149
}';
150+
}else {
151+
$body ='
152+
public function NAME(PARAM_TYPE $value = []): RETURN_TYPEHINT
153+
{
154+
if (null === $this->PROPERTY) {
155+
if (\is_array($value)) {
156+
$this->PROPERTY = new CLASS($value);
157+
} else {
158+
$this->PROPERTY = $value;
159+
}
160+
} elseif (!$this->PROPERTY instanceof CLASS) {
161+
throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized with a scalar value. You cannot call NAME() anymore.\');
162+
} elseif ([] !== $value) {
163+
throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME().\');
164+
}
165+
166+
return $this->PROPERTY;
167+
}';
168+
}
169+
145170
$class->addUse(InvalidConfigurationException::class);
146-
$class->addMethod($node->getName(),$body, ['PROPERTY' =>$property->getName(),'CLASS' =>$childClass->getFqcn()]);
171+
$class->addMethod($node->getName(),$body, [
172+
'PROPERTY' =>$property->getName(),
173+
'CLASS' =>$childClass->getFqcn(),
174+
'RETURN_TYPEHINT' => ['array'] ===$nodeTypes ?$childClass->getFqcn() :'self|'.$childClass->getFqcn(),
175+
'PARAM_TYPE' =>\in_array('mixed',$nodeTypes,true) ?'mixed' :implode('|',$nodeTypes),
176+
]);
147177

148178
$this->buildNode($node,$childClass,$this->getSubNamespace($childClass));
149179
}
@@ -174,39 +204,53 @@ private function handlePrototypedArrayNode(PrototypedArrayNode $node, ClassBuild
174204
$prototype =$node->getPrototype();
175205
$methodName =$name;
176206

177-
$parameterType =$this->getParameterType($prototype);
178-
if (null !==$parameterType ||$prototypeinstanceof ScalarNode) {
207+
$nodeTypes =$this->getParameterTypes($node);
208+
$prototypeTypes =$this->getParameterTypes($prototype);
209+
210+
$isObject =$prototypeinstanceof ArrayNode && (!$prototypeinstanceof PrototypedArrayNode || !$prototype->getPrototype()instanceof ScalarNode);
211+
if (!$isObject) {
179212
$class->addUse(ParamConfigurator::class);
180213
$property =$class->addProperty($node->getName());
181214
if (null ===$key =$node->getKeyAttribute()) {
182215
// This is an array of values; don't use singular name
216+
$nodeTypesWithoutArray =array_filter($nodeTypes,staticfn ($type) =>'array' !==$type);
183217
$body ='
184218
/**
185-
* @param ParamConfigurator|list<ParamConfigurator|TYPE> $value
219+
* @param ParamConfigurator|list<ParamConfigurator|PROTOTYPE_TYPE>EXTRA_TYPE $value
186220
*
187221
* @return $this
188222
*/
189-
public function NAME(ParamConfigurator|array $value): static
223+
public function NAME(PARAM_TYPE $value): static
190224
{
191225
$this->PROPERTY = $value;
192226
193227
return $this;
194228
}';
195229

196-
$class->addMethod($node->getName(),$body, ['PROPERTY' =>$property->getName(),'TYPE' =>'' ===$parameterType ?'mixed' :$parameterType]);
230+
$class->addMethod($node->getName(),$body, [
231+
'PROPERTY' =>$property->getName(),
232+
'PROTOTYPE_TYPE' =>implode('|',$prototypeTypes),
233+
'EXTRA_TYPE' =>$nodeTypesWithoutArray ?'|'.implode('|',$nodeTypesWithoutArray) :'',
234+
'PARAM_TYPE' =>\in_array('mixed',$nodeTypes,true) ?'mixed' :'ParamConfigurator|'.implode('|',$nodeTypes),
235+
]);
197236
}else {
198237
$body ='
199238
/**
200239
* @return $this
201240
*/
202-
public function NAME(string $VAR,TYPE $VALUE): static
241+
public function NAME(string $VAR,PARAM_TYPE $VALUE): static
203242
{
204243
$this->PROPERTY[$VAR] = $VALUE;
205244
206245
return $this;
207246
}';
208247

209-
$class->addMethod($methodName,$body, ['PROPERTY' =>$property->getName(),'TYPE' =>'' ===$parameterType ?'mixed' :'ParamConfigurator|'.$parameterType,'VAR' =>'' ===$key ?'key' :$key,'VALUE' =>'value' ===$key ?'data' :'value']);
248+
$class->addMethod($methodName,$body, [
249+
'PROPERTY' =>$property->getName(),
250+
'VAR' =>'' ===$key ?'key' :$key,
251+
'VALUE' =>'value' ===$key ?'data' :'value',
252+
'PARAM_TYPE' =>\in_array('mixed',$prototypeTypes,true) ?'mixed' :'ParamConfigurator|'.implode('|',$prototypeTypes),
253+
]);
210254
}
211255

212256
return;
@@ -216,20 +260,41 @@ public function NAME(string $VAR, TYPE $VALUE): static
216260
if ($prototypeinstanceof ArrayNode) {
217261
$childClass->setAllowExtraKeys($prototype->shouldIgnoreExtraKeys());
218262
}
263+
219264
$class->addRequire($childClass);
220265
$this->classes[] =$childClass;
221266
$property =$class->addProperty($node->getName(),$childClass->getFqcn().'[]');
222267

223268
if (null ===$key =$node->getKeyAttribute()) {
224-
$body ='
225-
public function NAME(array $value = []): CLASS
269+
if (['array'] ===$nodeTypes) {
270+
$body ='
271+
public function NAME(PARAM_TYPE $value = []): RETURN_TYPEHINT
226272
{
227273
return $this->PROPERTY[] = new CLASS($value);
228274
}';
229-
$class->addMethod($methodName,$body, ['PROPERTY' =>$property->getName(),'CLASS' =>$childClass->getFqcn()]);
275+
}else {
276+
$body ='
277+
public function NAME(PARAM_TYPE $value = []): RETURN_TYPEHINT
278+
{
279+
if (\is_array($value)) {
280+
return $this->PROPERTY[] = new CLASS($value);
281+
}
282+
283+
$this->PROPERTY[] = $value;
284+
return $this;
285+
}';
286+
}
287+
288+
$class->addMethod($methodName,$body, [
289+
'PROPERTY' =>$property->getName(),
290+
'CLASS' =>$childClass->getFqcn(),
291+
'RETURN_TYPEHINT' => ['array'] ===$nodeTypes ?$childClass->getFqcn() :'self|'.$childClass->getFqcn(),
292+
'PARAM_TYPE' =>\in_array('mixed',$nodeTypes,true) ?'mixed' :implode('|',$nodeTypes),
293+
]);
230294
}else {
231-
$body ='
232-
public function NAME(string $VAR, array $VALUE = []): CLASS
295+
if (['array'] ===$nodeTypes) {
296+
$body ='
297+
public function NAME(string $VAR, PARAM_TYPE $VALUE = []): CLASS
233298
{
234299
if (!isset($this->PROPERTY[$VAR])) {
235300
return $this->PROPERTY[$VAR] = new CLASS($value);
@@ -240,8 +305,39 @@ public function NAME(string $VAR, array $VALUE = []): CLASS
240305
241306
throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME().\');
242307
}';
308+
}else {
309+
$body ='
310+
public function NAME(string $VAR, PARAM_TYPE $VALUE = []): RETURN_TYPEHINT
311+
{
312+
if (!isset($this->PROPERTY[$VAR])) {
313+
if (\is_array($VALUE)) {
314+
return $this->PROPERTY[$VAR] = new CLASS($value);
315+
} else {
316+
$this->PROPERTY[$VAR] = $VALUE;
317+
318+
return $this;
319+
}
320+
}
321+
if (!$this->PROPERTY[$VAR] instanceof CLASS) {
322+
throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized with a scalar value. You cannot call NAME() anymore.\');
323+
}
324+
if ([] === $VALUE) {
325+
return $this->PROPERTY[$VAR];
326+
}
327+
328+
throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME().\');
329+
}';
330+
}
331+
243332
$class->addUse(InvalidConfigurationException::class);
244-
$class->addMethod($methodName,$body, ['PROPERTY' =>$property->getName(),'CLASS' =>$childClass->getFqcn(),'VAR' =>'' ===$key ?'key' :$key,'VALUE' =>'value' ===$key ?'data' :'value']);
333+
$class->addMethod($methodName,$body, [
334+
'PROPERTY' =>$property->getName(),
335+
'CLASS' =>$childClass->getFqcn(),
336+
'RETURN_TYPEHINT' => ['array'] ===$nodeTypes ?$childClass->getFqcn() :'self|'.$childClass->getFqcn(),
337+
'VAR' =>'' ===$key ?'key' :$key,
338+
'VALUE' =>'value' ===$key ?'data' :'value',
339+
'PARAM_TYPE' =>\in_array('mixed',$nodeTypes,true) ?'mixed' :implode('|',$nodeTypes),
340+
]);
245341
}
246342

247343
$this->buildNode($prototype,$childClass,$namespace.'\\'.$childClass->getName());
@@ -267,35 +363,35 @@ public function NAME($value): static
267363
$class->addMethod($node->getName(),$body, ['PROPERTY' =>$property->getName(),'COMMENT' =>$comment]);
268364
}
269365

270-
privatefunctiongetParameterType(NodeInterface$node):?string
366+
privatefunctiongetParameterTypes(NodeInterface$node):array
271367
{
272-
if ($nodeinstanceof BooleanNode) {
273-
return'bool';
274-
}
275-
276-
if ($nodeinstanceof IntegerNode) {
277-
return'int';
278-
}
279-
280-
if ($nodeinstanceof FloatNode) {
281-
return'float';
282-
}
283-
284-
if ($nodeinstanceof EnumNode) {
285-
return'';
286-
}
368+
$paramTypes = [];
369+
if ($nodeinstanceof BaseNode) {
370+
$types =$node->getNormalizedTypes();
371+
if (\in_array(ExprBuilder::TYPE_ANY,$types,true)) {
372+
$paramTypes[] ='mixed';
373+
}
287374

288-
if ($nodeinstanceof PrototypedArrayNode &&$node->getPrototype()instanceof ScalarNode) {
289-
// This is just an array of variables
290-
return'array';
375+
if (\in_array(ExprBuilder::TYPE_STRING,$types,true)) {
376+
$paramTypes[] ='string';
377+
}
291378
}
292379

293-
if ($nodeinstanceof VariableNode) {
294-
// mixed
295-
return'';
380+
if ($nodeinstanceof BooleanNode) {
381+
$paramTypes[] ='bool';
382+
}elseif ($nodeinstanceof IntegerNode) {
383+
$paramTypes[] ='int';
384+
}elseif ($nodeinstanceof FloatNode) {
385+
$paramTypes[] ='float';
386+
}elseif ($nodeinstanceof EnumNode) {
387+
$paramTypes[] ='mixed';
388+
}elseif ($nodeinstanceof ArrayNode) {
389+
$paramTypes[] ='array';
390+
}elseif ($nodeinstanceof VariableNode) {
391+
$paramTypes[] ='mixed';
296392
}
297393

298-
returnnull;
394+
returnarray_unique($paramTypes);
299395
}
300396

301397
privatefunctiongetComment(VariableNode$node):string
@@ -318,11 +414,8 @@ private function getComment(VariableNode $node): string
318414
returnvar_export($a,true);
319415
},$node->getValues())))."\n";
320416
}else {
321-
$parameterType =$this->getParameterType($node);
322-
if (null ===$parameterType ||'' ===$parameterType) {
323-
$parameterType ='mixed';
324-
}
325-
$comment .=' * @param ParamConfigurator|'.$parameterType.' $value'."\n";
417+
$parameterTypes =$this->getParameterTypes($node);
418+
$comment .=' * @param ParamConfigurator|'.implode('|',$parameterTypes).' $value'."\n";
326419
}
327420

328421
if ($node->isDeprecated()) {
@@ -361,16 +454,20 @@ private function buildToArray(ClassBuilder $class): void
361454
$code ='$this->PROPERTY';
362455
if (null !==$p->getType()) {
363456
if ($p->isArray()) {
364-
$code ='array_map(function ($v) { return $v->toArray(); }, $this->PROPERTY)';
457+
$code ='array_map(function ($v) { return $v instanceof CLASS ? $v->toArray() : $v; }, $this->PROPERTY)';
365458
}else {
366-
$code ='$this->PROPERTY->toArray()';
459+
$code ='$this->PROPERTY instanceof CLASS ? $this->PROPERTY->toArray() : $this->PROPERTY';
367460
}
368461
}
369462

370463
$body .=strtr('
371464
if (null !== $this->PROPERTY) {
372465
$output[\'ORG_NAME\'] ='.$code.';
373-
}', ['PROPERTY' =>$p->getName(),'ORG_NAME' =>$p->getOriginalName()]);
466+
}', [
467+
'PROPERTY' =>$p->getName(),
468+
'ORG_NAME' =>$p->getOriginalName(),
469+
'CLASS' =>$p->getType(),
470+
]);
374471
}
375472

376473
$extraKeys =$class->shouldAllowExtraKeys() ?' + $this->_extraKeys' :'';
@@ -420,8 +517,7 @@ private function buildConstructor(ClassBuilder $class): void
420517

421518
$class->addMethod('__construct','
422519
public function __construct(array $value = [])
423-
{
424-
'.$body.'
520+
{'.$body.'
425521
}');
426522
}
427523

‎src/Symfony/Component/Config/Definition/BaseNode.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ abstract class BaseNode implements NodeInterface
3232
protected$name;
3333
protected$parent;
3434
protected$normalizationClosures = [];
35+
protected$normalizedTypes = [];
3536
protected$finalValidationClosures = [];
3637
protected$allowOverwrite =true;
3738
protected$required =false;
@@ -212,6 +213,24 @@ public function setNormalizationClosures(array $closures)
212213
$this->normalizationClosures =$closures;
213214
}
214215

216+
/**
217+
* Sets the list of type supported by normalization.
218+
* see ExprBuilder::TYPE_* constants.
219+
*/
220+
publicfunctionsetNormalizedTypes(array$types)
221+
{
222+
$this->normalizedTypes =$types;
223+
}
224+
225+
/**
226+
* Gets the list of type supported by normalization.
227+
* see ExprBuilder::TYPE_* constants.
228+
*/
229+
publicfunctiongetNormalizedTypes():array
230+
{
231+
return$this->normalizedTypes;
232+
}
233+
215234
/**
216235
* Sets the closures used for final validation.
217236
*

‎src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,7 @@ protected function createNode(): NodeInterface
420420

421421
if (null !==$this->normalization) {
422422
$node->setNormalizationClosures($this->normalization->before);
423+
$node->setNormalizedTypes($this->normalization->declaredTypes);
423424
$node->setXmlRemappings($this->normalization->remappings);
424425
}
425426

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp