Skip to content

Commit f2dbc7f

Browse files
lacatoirenicolas-grekas
authored andcommitted
[Config] Fix ArrayShapeGenerator required keys with deep merging
1 parent 4275b53 commit f2dbc7f

File tree

3 files changed

+25
-3
lines changed

3 files changed

+25
-3
lines changed

Definition/ArrayNode.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,14 @@ public function setPerformDeepMerging(bool $boolean): void
126126
$this->performDeepMerging = $boolean;
127127
}
128128

129+
/**
130+
* Whether deep merging should occur.
131+
*/
132+
public function shouldPerformDeepMerging(): bool
133+
{
134+
return $this->performDeepMerging;
135+
}
136+
129137
/**
130138
* Whether extra keys should just be ignored without an exception.
131139
*

Definition/ArrayShapeGenerator.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ private static function doGeneratePhpDoc(NodeInterface $node, int $nestingLevel
6060
$arrayShape = \sprintf("array{%s\n", self::generateInlinePhpDocForNode($node));
6161

6262
foreach ($children as $child) {
63-
$arrayShape .= str_repeat(' ', $nestingLevel).self::dumpNodeKey($child).': ';
63+
$arrayShape .= str_repeat(' ', $nestingLevel).self::dumpNodeKey($child, $node).': ';
6464

6565
if ($child instanceof PrototypedArrayNode) {
6666
$isHashmap = (bool) $child->getKeyAttribute();
@@ -82,7 +82,7 @@ private static function doGeneratePhpDoc(NodeInterface $node, int $nestingLevel
8282
return implode('|', [...self::getNormalizedTypes($node, ['array', 'any']), $arrayShape]);
8383
}
8484

85-
private static function dumpNodeKey(NodeInterface $node): string
85+
private static function dumpNodeKey(NodeInterface $node, ?ArrayNode $parent = null): string
8686
{
8787
$name = $node->getName();
8888
$quoted = str_starts_with($name, '@')
@@ -93,7 +93,9 @@ private static function dumpNodeKey(NodeInterface $node): string
9393
$name = "'".addslashes($name)."'";
9494
}
9595

96-
return $name.($node->isRequired() ? '' : '?');
96+
$optional = !$node->isRequired() || ($parent instanceof ArrayNode && $parent->shouldPerformDeepMerging());
97+
98+
return $name.($optional ? '?' : '');
9799
}
98100

99101
private static function handleNumericNode(NumericNode $node): string

Tests/Definition/ArrayShapeGeneratorTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,18 @@ public function testPhpDocHandlesRequiredNode()
105105
$root = new ArrayNode('root');
106106
$root->addChild($child);
107107

108+
$this->assertStringContainsString('node?: bool', ArrayShapeGenerator::generate($root));
109+
}
110+
111+
public function testPhpDocHandlesRequiredNodeWithNoDeepMerging()
112+
{
113+
$child = new BooleanNode('node');
114+
$child->setRequired(true);
115+
116+
$root = new ArrayNode('root');
117+
$root->setPerformDeepMerging(false);
118+
$root->addChild($child);
119+
108120
$expected = 'node: bool';
109121

110122
$this->assertStringContainsString($expected, ArrayShapeGenerator::generate($root));

0 commit comments

Comments
 (0)