Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 68fa5a5

Browse files
committed
feature #44171 [Config] Add comment on array methods (jderusse)
This PR was merged into the 6.1 branch. Discussion ---------- [Config] Add comment on array methods | Q | A | ------------- | --- | Branch? | 6.1 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | - | License | MIT | Doc PR | - This PR adds comment section (including `@deprecated`, default, and examples) in the Generated PHP config for array's method headers. Commits ------- 7d58b18 Add comment on array methods
2 parents 7248e16 + 7d58b18 commit 68fa5a5

File tree

8 files changed

+208
-24
lines changed

8 files changed

+208
-24
lines changed

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

Lines changed: 40 additions & 21 deletions
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;
@@ -123,14 +124,18 @@ private function buildNode(NodeInterface $node, ClassBuilder $class, string $nam
123124

124125
private function handleArrayNode(ArrayNode $node, ClassBuilder $class, string $namespace): void
125126
{
127+
if ('' !== $comment = $this->getComment($node)) {
128+
$comment = "/**\n$comment*/\n";
129+
}
130+
126131
$childClass = new ClassBuilder($namespace, $node->getName());
127132
$childClass->setAllowExtraKeys($node->shouldIgnoreExtraKeys());
128133
$class->addRequire($childClass);
129134
$this->classes[] = $childClass;
130135

131136
$property = $class->addProperty($node->getName(), $childClass->getFqcn());
132137
$body = '
133-
public function NAME(array $value = []): CLASS
138+
COMMENTpublic function NAME(array $value = []): CLASS
134139
{
135140
if (null === $this->PROPERTY) {
136141
$this->PROPERTY = new CLASS($value);
@@ -141,7 +146,7 @@ public function NAME(array $value = []): CLASS
141146
return $this->PROPERTY;
142147
}';
143148
$class->addUse(InvalidConfigurationException::class);
144-
$class->addMethod($node->getName(), $body, ['PROPERTY' => $property->getName(), 'CLASS' => $childClass->getFqcn()]);
149+
$class->addMethod($node->getName(), $body, ['COMMENT' => $comment, 'PROPERTY' => $property->getName(), 'CLASS' => $childClass->getFqcn()]);
145150

146151
$this->buildNode($node, $childClass, $this->getSubNamespace($childClass));
147152
}
@@ -218,16 +223,20 @@ public function NAME(string $VAR, TYPE $VALUE): static
218223
$this->classes[] = $childClass;
219224
$property = $class->addProperty($node->getName(), $childClass->getFqcn().'[]');
220225

226+
if ('' !== $comment = $this->getComment($node)) {
227+
$comment = "/**\n$comment*/\n";
228+
}
229+
221230
if (null === $key = $node->getKeyAttribute()) {
222231
$body = '
223-
public function NAME(array $value = []): CLASS
232+
COMMENTpublic function NAME(array $value = []): CLASS
224233
{
225234
return $this->PROPERTY[] = new CLASS($value);
226235
}';
227-
$class->addMethod($methodName, $body, ['PROPERTY' => $property->getName(), 'CLASS' => $childClass->getFqcn()]);
236+
$class->addMethod($methodName, $body, ['COMMENT' => $comment, 'PROPERTY' => $property->getName(), 'CLASS' => $childClass->getFqcn()]);
228237
} else {
229238
$body = '
230-
public function NAME(string $VAR, array $VALUE = []): CLASS
239+
COMMENTpublic function NAME(string $VAR, array $VALUE = []): CLASS
231240
{
232241
if (!isset($this->PROPERTY[$VAR])) {
233242
return $this->PROPERTY[$VAR] = new CLASS($value);
@@ -239,7 +248,7 @@ public function NAME(string $VAR, array $VALUE = []): CLASS
239248
throw new InvalidConfigurationException(\'The node created by "NAME()" has already been initialized. You cannot pass values the second time you call NAME().\');
240249
}';
241250
$class->addUse(InvalidConfigurationException::class);
242-
$class->addMethod($methodName, $body, ['PROPERTY' => $property->getName(), 'CLASS' => $childClass->getFqcn(), 'VAR' => '' === $key ? 'key' : $key, 'VALUE' => 'value' === $key ? 'data' : 'value']);
251+
$class->addMethod($methodName, $body, ['COMMENT' => $comment, 'PROPERTY' => $property->getName(), 'CLASS' => $childClass->getFqcn(), 'VAR' => '' === $key ? 'key' : $key, 'VALUE' => 'value' === $key ? 'data' : 'value']);
243252
}
244253

245254
$this->buildNode($prototype, $childClass, $namespace.'\\'.$childClass->getName());
@@ -296,31 +305,41 @@ private function getParameterType(NodeInterface $node): ?string
296305
return null;
297306
}
298307

299-
private function getComment(VariableNode $node): string
308+
private function getComment(BaseNode $node): string
300309
{
301310
$comment = '';
302311
if ('' !== $info = (string) $node->getInfo()) {
303312
$comment .= ' * '.$info."\n";
304313
}
305314

306-
foreach ((array) ($node->getExample() ?? []) as $example) {
307-
$comment .= ' * @example '.$example."\n";
308-
}
315+
if (!$node instanceof ArrayNode) {
316+
foreach ((array) ($node->getExample() ?? []) as $example) {
317+
$comment .= ' * @example '.$example."\n";
318+
}
309319

310-
if ('' !== $default = $node->getDefaultValue()) {
311-
$comment .= ' * @default '.(null === $default ? 'null' : var_export($default, true))."\n";
312-
}
320+
if ('' !== $default = $node->getDefaultValue()) {
321+
$comment .= ' * @default '.(null === $default ? 'null' : var_export($default, true))."\n";
322+
}
313323

314-
if ($node instanceof EnumNode) {
315-
$comment .= sprintf(' * @param ParamConfigurator|%s $value', implode('|', array_map(function ($a) {
316-
return var_export($a, true);
317-
}, $node->getValues())))."\n";
324+
if ($node instanceof EnumNode) {
325+
$comment .= sprintf(' * @param ParamConfigurator|%s $value', implode('|', array_map(function ($a) {
326+
return var_export($a, true);
327+
}, $node->getValues())))."\n";
328+
} else {
329+
$parameterType = $this->getParameterType($node);
330+
if (null === $parameterType || '' === $parameterType) {
331+
$parameterType = 'mixed';
332+
}
333+
$comment .= ' * @param ParamConfigurator|'.$parameterType.' $value'."\n";
334+
}
318335
} else {
319-
$parameterType = $this->getParameterType($node);
320-
if (null === $parameterType || '' === $parameterType) {
321-
$parameterType = 'mixed';
336+
foreach ((array) ($node->getExample() ?? []) as $example) {
337+
$comment .= ' * @example '.json_encode($example)."\n";
338+
}
339+
340+
if ($node->hasDefaultValue() && [] != $default = $node->getDefaultValue()) {
341+
$comment .= ' * @default '.json_encode($default)."\n";
322342
}
323-
$comment .= ' * @param ParamConfigurator|'.$parameterType.' $value'."\n";
324343
}
325344

326345
if ($node->isDeprecated()) {

src/Symfony/Component/Config/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CHANGELOG
55
---
66

77
* Allow using environment variables in `EnumNode`
8+
* Add Node's information in generated Config
89

910
6.0
1011
---

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,22 @@ public function getConfigTreeBuilder(): TreeBuilder
2525
->useAttributeAsKey('source_class')
2626
->prototype('scalar')->end()
2727
->end()
28+
->arrayNode('books')
29+
->children()
30+
->arrayNode('page')
31+
->example('page 1')
32+
->defaultValue(['number' => 1, 'content' => ''])
33+
->prototype('array')
34+
->children()
35+
->integerNode('number')->end()
36+
->scalarNode('content')->end()
37+
->end()
38+
->end()
39+
->end()
40+
->end()
41+
->info('looks for translation in old fashion way')
42+
->setDeprecated('symfony/config', '6.0')
43+
->end()
2844
->end()
2945
->end()
3046
->arrayNode('messenger')
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
namespace Symfony\Config\AddToList\Translator\Books;
4+
5+
6+
use Symfony\Component\Config\Loader\ParamConfigurator;
7+
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
8+
9+
10+
/**
11+
* This class is automatically generated to help creating config.
12+
*/
13+
class PageConfig
14+
{
15+
private $number;
16+
private $content;
17+
18+
/**
19+
* @default null
20+
* @param ParamConfigurator|int $value
21+
* @return $this
22+
*/
23+
public function number($value): static
24+
{
25+
$this->number = $value;
26+
27+
return $this;
28+
}
29+
30+
/**
31+
* @default null
32+
* @param ParamConfigurator|mixed $value
33+
* @return $this
34+
*/
35+
public function content($value): static
36+
{
37+
$this->content = $value;
38+
39+
return $this;
40+
}
41+
42+
public function __construct(array $value = [])
43+
{
44+
45+
if (isset($value['number'])) {
46+
$this->number = $value['number'];
47+
unset($value['number']);
48+
}
49+
50+
if (isset($value['content'])) {
51+
$this->content = $value['content'];
52+
unset($value['content']);
53+
}
54+
55+
if ([] !== $value) {
56+
throw new InvalidConfigurationException(sprintf('The following keys are not supported by "%s": ', __CLASS__).implode(', ', array_keys($value)));
57+
}
58+
}
59+
60+
public function toArray(): array
61+
{
62+
$output = [];
63+
if (null !== $this->number) {
64+
$output['number'] = $this->number;
65+
}
66+
if (null !== $this->content) {
67+
$output['content'] = $this->content;
68+
}
69+
70+
return $output;
71+
}
72+
73+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
namespace Symfony\Config\AddToList\Translator;
4+
5+
require_once __DIR__.\DIRECTORY_SEPARATOR.'Books'.\DIRECTORY_SEPARATOR.'PageConfig.php';
6+
7+
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
8+
9+
10+
/**
11+
* This class is automatically generated to help creating config.
12+
*/
13+
class BooksConfig
14+
{
15+
private $page;
16+
17+
/**
18+
* @example "page 1"
19+
* @default {"number":1,"content":""}
20+
*/
21+
public function page(array $value = []): \Symfony\Config\AddToList\Translator\Books\PageConfig
22+
{
23+
return $this->page[] = new \Symfony\Config\AddToList\Translator\Books\PageConfig($value);
24+
}
25+
26+
public function __construct(array $value = [])
27+
{
28+
29+
if (isset($value['page'])) {
30+
$this->page = array_map(function ($v) { return new \Symfony\Config\AddToList\Translator\Books\PageConfig($v); }, $value['page']);
31+
unset($value['page']);
32+
}
33+
34+
if ([] !== $value) {
35+
throw new InvalidConfigurationException(sprintf('The following keys are not supported by "%s": ', __CLASS__).implode(', ', array_keys($value)));
36+
}
37+
}
38+
39+
public function toArray(): array
40+
{
41+
$output = [];
42+
if (null !== $this->page) {
43+
$output['page'] = array_map(function ($v) { return $v->toArray(); }, $this->page);
44+
}
45+
46+
return $output;
47+
}
48+
49+
}

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Symfony\Config\AddToList;
44

5+
require_once __DIR__.\DIRECTORY_SEPARATOR.'Translator'.\DIRECTORY_SEPARATOR.'BooksConfig.php';
56

67
use Symfony\Component\Config\Loader\ParamConfigurator;
78
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
@@ -14,6 +15,7 @@ class TranslatorConfig
1415
{
1516
private $fallbacks;
1617
private $sources;
18+
private $books;
1719

1820
/**
1921
* @param ParamConfigurator|list<ParamConfigurator|mixed> $value
@@ -37,6 +39,21 @@ public function source(string $source_class, mixed $value): static
3739
return $this;
3840
}
3941

42+
/**
43+
* looks for translation in old fashion way
44+
* @deprecated The child node "books" at path "translator" is deprecated.
45+
*/
46+
public function books(array $value = []): \Symfony\Config\AddToList\Translator\BooksConfig
47+
{
48+
if (null === $this->books) {
49+
$this->books = new \Symfony\Config\AddToList\Translator\BooksConfig($value);
50+
} elseif ([] !== $value) {
51+
throw new InvalidConfigurationException('The node created by "books()" has already been initialized. You cannot pass values the second time you call books().');
52+
}
53+
54+
return $this->books;
55+
}
56+
4057
public function __construct(array $value = [])
4158
{
4259

@@ -50,6 +67,11 @@ public function __construct(array $value = [])
5067
unset($value['sources']);
5168
}
5269

70+
if (isset($value['books'])) {
71+
$this->books = new \Symfony\Config\AddToList\Translator\BooksConfig($value['books']);
72+
unset($value['books']);
73+
}
74+
5375
if ([] !== $value) {
5476
throw new InvalidConfigurationException(sprintf('The following keys are not supported by "%s": ', __CLASS__).implode(', ', array_keys($value)));
5577
}
@@ -64,6 +86,9 @@ public function toArray(): array
6486
if (null !== $this->sources) {
6587
$output['sources'] = $this->sources;
6688
}
89+
if (null !== $this->books) {
90+
$output['books'] = $this->books->toArray();
91+
}
6792

6893
return $output;
6994
}

src/Symfony/Component/Config/Tests/Builder/Fixtures/Placeholders.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public function getConfigTreeBuilder(): TreeBuilder
1515
->children()
1616
->booleanNode('enabled')->defaultFalse()->end()
1717
->floatNode('favorite_float')->end()
18-
->arrayNode('good_integers')
18+
->arrayNode('good_integers')
1919
->integerPrototype()->end()
2020
->end()
2121
->end()

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,9 @@ public function testConfig(string $name, string $alias)
7373
$expectedCode = $basePath.$name;
7474

7575
// to regenerate snapshot files, uncomment these lines
76-
// (new Filesystem())->remove($expectedCode);
77-
// $configBuilder = $this->generateConfigBuilder('Symfony\\Component\\Config\\Tests\\Builder\\Fixtures\\'.$name, $expectedCode);
76+
//(new Filesystem())->remove($expectedCode);
77+
//$this->generateConfigBuilder('Symfony\\Component\\Config\\Tests\\Builder\\Fixtures\\'.$name, $expectedCode);
78+
//$this->markTestIncomplete('Re-comment the line above and relaunch the tests');
7879

7980
$outputDir = sys_get_temp_dir().\DIRECTORY_SEPARATOR.uniqid('sf_config_builder', true);
8081
$configBuilder = $this->generateConfigBuilder('Symfony\\Component\\Config\\Tests\\Builder\\Fixtures\\'.$name, $outputDir);

0 commit comments

Comments
 (0)