14
14
use Symfony \Component \Config \Definition \ArrayNode ;
15
15
use Symfony \Component \Config \Definition \BaseNode ;
16
16
use Symfony \Component \Config \Definition \BooleanNode ;
17
- use Symfony \Component \Config \Definition \Builder \ExprBuilder ;
18
17
use Symfony \Component \Config \Definition \ConfigurationInterface ;
19
18
use Symfony \Component \Config \Definition \EnumNode ;
20
19
use Symfony \Component \Config \Definition \Exception \InvalidConfigurationException ;
@@ -127,24 +126,18 @@ private function handleArrayNode(ArrayNode $node, ClassBuilder $class, string $n
127
126
$ class ->addRequire ($ childClass );
128
127
$ this ->classes [] = $ childClass ;
129
128
130
- $ hasNormalizationClosures = $ this ->hasNormalizationClosures ($ node );
131
129
$ comment = $ this ->getComment ($ node );
132
- if ($ hasNormalizationClosures ) {
133
- $ comment = sprintf (" * @template TValue \n * @param TValue \$value \n%s " , $ comment );
134
- $ comment .= sprintf (' * @return %s|$this ' ."\n" , $ childClass ->getFqcn ());
135
- $ comment .= sprintf (' * @psalm-return (TValue is array ? %s : static) ' ."\n " , $ childClass ->getFqcn ());
136
- }
137
- if ('' !== $ comment ) {
138
- $ comment = "/** \n$ comment*/ \n" ;
139
- }
130
+ $ comment = sprintf (" * @template TValue \n * @param TValue \$value \n%s " , $ comment );
131
+ $ comment .= sprintf (' * @return %s|$this ' ."\n" , $ childClass ->getFqcn ());
132
+ $ comment .= sprintf (' * @psalm-return (TValue is array ? %s : static) ' ."\n " , $ childClass ->getFqcn ());
133
+ $ comment = "/** \n$ comment*/ \n" ;
140
134
141
135
$ property = $ class ->addProperty (
142
136
$ node ->getName (),
143
- $ this -> getType ( $ childClass ->getFqcn (), $ hasNormalizationClosures )
137
+ $ childClass ->getFqcn (). ' |scalar '
144
138
);
145
- $ nodeTypes = $ this ->getParameterTypes ($ node );
146
- $ body = $ hasNormalizationClosures ? '
147
- COMMENTpublic function NAME(PARAM_TYPE $value = []): CLASS|static
139
+ $ body = '
140
+ COMMENTpublic function NAME(mixed $value = []): CLASS|static
148
141
{
149
142
if (!\is_array($value)) {
150
143
$this->_usedProperties[ \'PROPERTY \'] = true;
@@ -160,26 +153,10 @@ private function handleArrayNode(ArrayNode $node, ClassBuilder $class, string $n
160
153
throw new InvalidConfigurationException( \'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME(). \');
161
154
}
162
155
163
- return $this->PROPERTY;
164
- } ' : '
165
93C6
code>
- COMMENTpublic function NAME(array $value = []): CLASS
166
- {
167
- if (null === $this->PROPERTY) {
168
- $this->_usedProperties[ \'PROPERTY \'] = true;
169
- $this->PROPERTY = new CLASS($value);
170
- } elseif (0 < \func_num_args()) {
171
- throw new InvalidConfigurationException( \'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME(). \');
172
- }
173
-
174
156
return $this->PROPERTY;
175
157
} ' ;
176
158
$ class ->addUse (InvalidConfigurationException::class);
177
- $ class ->addMethod ($ node ->getName (), $ body , [
178
- 'COMMENT ' => $ comment ,
179
- 'PROPERTY ' => $ property ->getName (),
180
- 'CLASS ' => $ childClass ->getFqcn (),
181
- 'PARAM_TYPE ' => \in_array ('mixed ' , $ nodeTypes , true ) ? 'mixed ' : implode ('| ' , $ nodeTypes ),
182
- ]);
159
+ $ class ->addMethod ($ node ->getName (), $ body , ['COMMENT ' => $ comment , 'PROPERTY ' => $ property ->getName (), 'CLASS ' => $ childClass ->getFqcn ()]);
183
160
184
161
$ this ->buildNode ($ node , $ childClass , $ this ->getSubNamespace ($ childClass ));
185
162
}
@@ -216,21 +193,19 @@ private function handlePrototypedArrayNode(PrototypedArrayNode $node, ClassBuild
216
193
$ methodName = $ name ;
217
194
$ hasNormalizationClosures = $ this ->hasNormalizationClosures ($ node ) || $ this ->hasNormalizationClosures ($ prototype );
218
195
219
- $ nodeParameterTypes = $ this ->getParameterTypes ($ node );
220
- $ prototypeParameterTypes = $ this ->getParameterTypes ($ prototype );
221
- if (!$ prototype instanceof ArrayNode || ($ prototype instanceof PrototypedArrayNode && $ prototype ->getPrototype () instanceof ScalarNode)) {
196
+ $ parameterType = $ this ->getParameterType ($ prototype );
197
+ if (null !== $ parameterType || $ prototype instanceof ScalarNode) {
222
198
$ class ->addUse (ParamConfigurator::class);
223
199
$ property = $ class ->addProperty ($ node ->getName ());
224
200
if (null === $ key = $ node ->getKeyAttribute ()) {
225
201
// This is an array of values; don't use singular name
226
- $ nodeTypesWithoutArray = array_filter ($ nodeParameterTypes , static fn ($ type ) => 'array ' !== $ type );
227
202
$ body = '
228
203
/**
229
- * @param ParamConfigurator|list<ParamConfigurator|PROTOTYPE_TYPE>EXTRA_TYPE $value
204
+ * @param PHPDOC_TYPE $value
230
205
*
231
206
* @return $this
232
207
*/
233
- public function NAME(PARAM_TYPE $value): static
208
+ public function NAME(TYPE $value): static
234
209
{
235
210
$this->_usedProperties[ \'PROPERTY \'] = true;
236
211
$this->PROPERTY = $value;
@@ -240,9 +215,8 @@ public function NAME(PARAM_TYPE $value): static
240
215
241
216
$ class ->addMethod ($ node ->getName (), $ body , [
242
217
'PROPERTY ' => $ property ->getName (),
243
- 'PROTOTYPE_TYPE ' => implode ('| ' , $ prototypeParameterTypes ),
244
- 'EXTRA_TYPE ' => $ nodeTypesWithoutArray ? '| ' .implode ('| ' , $ nodeTypesWithoutArray ) : '' ,
245
- 'PARAM_TYPE ' => \in_array ('mixed ' , $ nodeParameterTypes , true ) ? 'mixed ' : 'ParamConfigurator| ' .implode ('| ' , $ nodeParameterTypes ),
218
+ 'TYPE ' => $ hasNormalizationClosures ? 'mixed ' : 'ParamConfigurator|array ' ,
219
+ 'PHPDOC_TYPE ' => $ hasNormalizationClosures ? 'mixed ' : sprintf ('ParamConfigurator|list<ParamConfigurator|%s> ' , '' === $ parameterType ? 'mixed ' : $ parameterType ),
246
220
]);
247
221
} else {
248
222
$ body = '
@@ -259,7 +233,7 @@ public function NAME(string $VAR, TYPE $VALUE): static
259
233
260
234
$ class ->addMethod ($ methodName , $ body , [
261
235
'PROPERTY ' => $ property ->getName (),
262
- 'TYPE ' => \in_array ( 'mixed ' , $ prototypeParameterTypes , true ) ? ' mixed ' : ' ParamConfigurator| ' . implode ( ' | ' , $ prototypeParameterTypes ) ,
236
+ 'TYPE ' => 'mixed ' ,
263
237
'VAR ' => '' === $ key ? 'key ' : $ key ,
264
238
'VALUE ' => 'value ' === $ key ? 'data ' : 'value ' ,
265
239
]);
@@ -277,22 +251,19 @@ public function NAME(string $VAR, TYPE $VALUE): static
277
251
278
252
$ property = $ class ->addProperty (
279
253
$ node ->getName (),
280
- $ this -> getType ( $ childClass ->getFqcn ().'[] ' , $ hasNormalizationClosures )
254
+ $ childClass ->getFqcn ().'[]|scalar '
281
255
);
282
256
283
257
$ comment = $ this ->getComment ($ node );
284
- if ($ hasNormalizationClosures ) {
285
- $ comment = sprintf (" * @template TValue \n * @param TValue \$value \n%s " , $ comment );
286
- $ comment .= sprintf (' * @return %s|$this ' ."\n" , $ childClass ->getFqcn ());
287
- $ comment .= sprintf (' * @psalm-return (TValue is array ? %s : static) ' ."\n " , $ childClass ->getFqcn ());
288
- }
289
- if ('' !== $ comment ) {
290
- $ comment = "/** \n$ comment*/ \n" ;
291
- }
258
+ $ comment = sprintf (" * @template TValue \n * @param TValue \$value \n%s " , $ comment );
259
+ $ comment .= sprintf (' * @return %s|$this ' ."\n" , $ childClass ->getFqcn ());
260
+ $ comment .= sprintf (' * @psalm-return (TValue is array ? %s : static) ' ."\n " , $ childClass ->getFqcn ());
261
+ $ comment = "/** \n$ comment*/ \n" ;
262
+
292
263
293
264
if (null === $ key = $ node ->getKeyAttribute ()) {
294
- $ body = $ hasNormalizationClosures ? '
295
- COMMENTpublic function NAME(PARAM_TYPE $value = []): CLASS|static
265
+ $ body = '
266
+ COMMENTpublic function NAME(mixed $value = []): CLASS|static
296
267
{
297
268
$this->_usedProperties[ \'PROPERTY \'] = true;
298
269
if (!\is_array($value)) {
@@ -301,23 +272,12 @@ public function NAME(string $VAR, TYPE $VALUE): static
301
272
return $this;
302
273
}
303
274
304
- return $this->PROPERTY[] = new CLASS($value);
305
- } ' : '
306
- COMMENTpublic function NAME(array $value = []): CLASS
307
- {
308
- $this->_usedProperties[ \'PROPERTY \'] = true;
309
-
310
275
return $this->PROPERTY[] = new CLASS($value);
311
276
} ' ;
312
- $ class ->addMethod ($ methodName , $ body , [
313
- 'COMMENT ' => $ comment ,
314
- 'PROPERTY ' => $ property ->getName (),
315
- 'CLASS ' => $ childClass ->getFqcn (),
316
- 'PARAM_TYPE ' => \in_array ('mixed ' , $ nodeParameterTypes , true ) ? 'mixed ' : implode ('| ' , $ nodeParameterTypes ),
317
- ]);
277
+ $ class ->addMethod ($ methodName , $ body , ['COMMENT ' => $ comment , 'PROPERTY ' => $ property ->getName (), 'CLASS ' => $ childClass ->getFqcn ()]);
318
278
} else {
319
- $ body = $ hasNormalizationClosures ? '
320
- COMMENTpublic function NAME(string $VAR, PARAM_TYPE $VALUE = []): CLASS|static
279
+ $ body = '
280
+ COMMENTpublic function NAME(string $VAR, mixed $VALUE = []): CLASS|static
321
281
{
322
282
if (!\is_array($VALUE)) {
323
283
$this->_usedProperties[ \'PROPERTY \'] = true;
@@ -333,17 +293,6 @@ public function NAME(string $VAR, TYPE $VALUE): static
333
293
throw new InvalidConfigurationException( \'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME(). \');
334
294
}
335
295
336
- return $this->PROPERTY[$VAR];
337
- } ' : '
338
- COMMENTpublic function NAME(string $VAR, array $VALUE = []): CLASS
339
- {
340
- if (!isset($this->PROPERTY[$VAR])) {
341
- $this->_usedProperties[ \'PROPERTY \'] = true;
342
- $this->PROPERTY[$VAR] = new CLASS($VALUE);
343
- } elseif (1 < \func_num_args()) {
344
- throw new InvalidConfigurationException( \'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME(). \');
345
- }
346
-
347
296
return $this->PROPERTY[$VAR];
348
297
} ' ;
349
298
$ class ->addUse (InvalidConfigurationException::class);
@@ -352,7 +301,6 @@ public function NAME(string $VAR, TYPE $VALUE): static
352
301
'CLASS ' => $ childClass ->getFqcn (),
353
302
'VAR ' => '' === $ key ? 'key ' : $ key ,
354
303
'VALUE ' => 'value ' === $ key ? 'data ' : 'value ' ,
355
- 'PARAM_TYPE ' => \in_array ('mixed ' , $ prototypeParameterTypes , true ) ? 'mixed ' : implode ('| ' , $ prototypeParameterTypes ),
356
304
]);
357
305
}
358
306
@@ -380,33 +328,35 @@ public function NAME($value): static
380
328
$ class ->addMethod ($ node ->getName (), $ body , ['PROPERTY ' => $ property ->getName (), 'COMMENT ' => $ comment ]);
381
329
}
382
330
383
- private function getParameterTypes (NodeInterface $ node ): array
331
+ private function getParameterType (NodeInterface $ node ): ? string
384
332
{
385
- $ paramTypes = [];
386
- if ($ node instanceof BaseNode) {
387
- $ types = $ node ->getNormalizedTypes ();
388
- if (\in_array (ExprBuilder::TYPE_ANY , $ types , true )) {
389
- $ paramTypes [] = 'mixed ' ;
390
- }
391
- if (\in_array (ExprBuilder::TYPE_STRING , $ types , true )) {
392
- $ paramTypes [] = 'string ' ;
393
- }
394
- }
395
333
if ($ node instanceof BooleanNode) {
396
- $ paramTypes [] = 'bool ' ;
397
- } elseif ($ node instanceof IntegerNode) {
398
- $ paramTypes [] = 'int ' ;
399
- } elseif ($ node instanceof FloatNode) {
400
- $ paramTypes [] = 'float ' ;
401
- } elseif ($ node instanceof EnumNode) {
402
- $ paramTypes [] = 'mixed ' ;
403
- } elseif ($ node instanceof ArrayNode) {
404
- $ paramTypes [] = 'array ' ;
405
- } elseif ($ node instanceof VariableNode) {
406
- $ paramTypes [] = 'mixed ' ;
334
+ return 'bool ' ;
407
335
}
408
336
409
- return array_unique ($ paramTypes );
337
+ if ($ node instanceof IntegerNode) {
338
+ return 'int ' ;
339
+ }
340
+
341
+ if ($ node instanceof FloatNode) {
342
+ return 'float ' ;
343
+ }
344
+
345
+ if ($ node instanceof EnumNode) {
346
+ return '' ;
347
+ }
348
+
349
+ if ($ node instanceof PrototypedArrayNode && $ node ->getPrototype () instanceof ScalarNode) {
350
+ // This is just an array of variables
351
+ return 'array ' ;
352
+ }
353
+
354
+ if ($ node instanceof VariableNode) {
355
+ // mixed
356
+ return '' ;
357
+ }
358
+
359
+ return null ;
410
360
}
411
361
412
362
private function getComment (BaseNode $ node ): string
@@ -428,8 +378,11 @@ private function getComment(BaseNode $node): string
428
378
if ($ node instanceof EnumNode) {
429
379
$ comment .= sprintf (' * @param ParamConfigurator|%s $value ' , implode ('| ' , array_unique (array_map (fn ($ a ) => !$ a instanceof \UnitEnum ? var_export ($ a , true ) : '\\' .ltrim (var_export ($ a , true ), '\\' ), $ node ->getValues ()))))."\n" ;
430
380
} else {
431
- $ parameterTypes = $ this ->getParameterTypes ($ node );
432
- $ comment .= ' * @param ParamConfigurator| ' .implode ('| ' , $ parameterTypes ).' $value ' ."\n" ;
381
+ $ parameterType = $ this ->getParameterType ($ node );
382
+ if (null === $ parameterType || '' === $ parameterType ) {
383
+ $ parameterType = 'mixed ' ;
384
+ }
385
+ $ comment .= ' * @param ParamConfigurator| ' .$ parameterType .' $value ' ."\n" ;
433
386
}
434
387
} else {
435
388
foreach ((array ) ($ node ->getExample () ?? []) as $ example ) {
@@ -589,7 +542,6 @@ private function hasNormalizationClosures(NodeInterface $node): bool
589
542
} catch (\ReflectionException ) {
590
543
return false ;
591
544
}
592
- $ r ->setAccessible (true );
593
545
594
546
return [] !== $ r ->getValue ($ node );
595
547
}
0 commit comments