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

Appearance settings

Commit b28e597

Browse filesBrowse files
committed
Merge branch '7.2' into 7.3
* 7.2: [DependencyInjection] Fix phpdoc for $configurator in Autoconfigure attribute [TypeInfo] Fix create union with nullable type [DependencyInjection] Defer check for circular references instead of skipping them. [Validator] Synchronize IBAN formats
2 parents 0c7c251 + 0f6fd37 commit b28e597
Copy full SHA for b28e597

File tree

6 files changed

+58
-14
lines changed
Filter options

6 files changed

+58
-14
lines changed

‎src/Symfony/Component/DependencyInjection/Attribute/Autoconfigure.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Attribute/Autoconfigure.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class Autoconfigure
2828
* @param bool|null $shared Whether to declare the service as shared
2929
* @param bool|null $autowire Whether to declare the service as autowired
3030
* @param array<string, mixed>|null $properties The properties to define when creating the service
31-
* @param array<class-string, string>|string|null $configurator A PHP function, reference or an array containing a class/Reference and a method to call after the service is fully initialized
31+
* @param array{string, string}|string|null $configurator A PHP function, reference or an array containing a class/reference and a method to call after the service is fully initialized
3232
* @param string|null $constructor The public static method to use to instantiate the service
3333
*/
3434
public function __construct(

‎src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php
+25-10Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class CheckCircularReferencesPass implements CompilerPassInterface
2828
{
2929
private array $currentPath;
3030
private array $checkedNodes;
31+
private array $checkedLazyNodes;
3132

3233
/**
3334
* Checks the ContainerBuilder object for circular references.
@@ -57,22 +58,36 @@ private function checkOutEdges(array $edges): void
5758
$node = $edge->getDestNode();
5859
$id = $node->getId();
5960

60-
if (empty($this->checkedNodes[$id])) {
61-
// Don't check circular references for lazy edges
62-
if (!$node->getValue() || (!$edge->isLazy() && !$edge->isWeak())) {
63-
$searchKey = array_search($id, $this->currentPath);
64-
$this->currentPath[] = $id;
61+
if (!empty($this->checkedNodes[$id])) {
62+
continue;
63+
}
64+
65+
$isLeaf = !!$node->getValue();
66+
$isConcrete = !$edge->isLazy() && !$edge->isWeak();
67+
68+
// Skip already checked lazy services if they are still lazy. Will not gain any new information.
69+
if (!empty($this->checkedLazyNodes[$id]) && (!$isLeaf || !$isConcrete)) {
70+
continue;
71+
}
6572

66-
if (false !== $searchKey) {
67-
throw new ServiceCircularReferenceException($id, \array_slice($this->currentPath, $searchKey));
68-
}
73+
// Process concrete references, otherwise defer check circular references for lazy edges.
74+
if (!$isLeaf || $isConcrete) {
75+
$searchKey = array_search($id, $this->currentPath);
76+
$this->currentPath[] = $id;
6977

70-
$this->checkOutEdges($node->getOutEdges());
78+
if (false !== $searchKey) {
79+
throw new ServiceCircularReferenceException($id, \array_slice($this->currentPath, $searchKey));
7180
}
7281

82+
$this->checkOutEdges($node->getOutEdges());
83+
7384
$this->checkedNodes[$id] = true;
74-
array_pop($this->currentPath);
85+
unset($this->checkedLazyNodes[$id]);
86+
} else {
87+
$this->checkedLazyNodes[$id] = true;
7588
}
89+
90+
array_pop($this->currentPath);
7691
}
7792
}
7893
}

‎src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckCircularReferencesPassTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckCircularReferencesPassTest.php
+18Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
16+
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
17+
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
1618
use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass;
1719
use Symfony\Component\DependencyInjection\Compiler\CheckCircularReferencesPass;
1820
use Symfony\Component\DependencyInjection\Compiler\Compiler;
21+
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
1922
use Symfony\Component\DependencyInjection\ContainerBuilder;
2023
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
2124
use Symfony\Component\DependencyInjection\Reference;
@@ -126,6 +129,21 @@ public function testProcessIgnoresLazyServices()
126129
$this->addToAssertionCount(1);
127130
}
128131

132+
public function testProcessDefersLazyServices()
133+
{
134+
$container = new ContainerBuilder();
135+
136+
$container->register('a')->addArgument(new ServiceLocatorArgument(new TaggedIteratorArgument('tag', needsIndexes: true)));
137+
$container->register('b')->addArgument(new Reference('c'))->addTag('tag');
138+
$container->register('c')->addArgument(new Reference('b'));
139+
140+
(new ServiceLocatorTagPass())->process($container);
141+
142+
$this->expectException(ServiceCircularReferenceException::class);
143+
144+
$this->process($container);
145+
}
146+
129147
public function testProcessIgnoresIteratorArguments()
130148
{
131149
$container = new ContainerBuilder();

‎src/Symfony/Component/TypeInfo/Tests/TypeFactoryTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/TypeInfo/Tests/TypeFactoryTest.php
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,10 @@ public function testCreateNullable()
199199
new NullableType(new UnionType(new BuiltinType(TypeIdentifier::INT), new BuiltinType(TypeIdentifier::STRING))),
200200
Type::nullable(Type::union(Type::int(), Type::string(), Type::null())),
201201
);
202+
$this->assertEquals(
203+
new NullableType(new UnionType(new BuiltinType(TypeIdentifier::INT), new BuiltinType(TypeIdentifier::STRING))),
204+
Type::union(Type::nullable(Type::int()), Type::string()),
205+
);
202206
}
203207

204208
/**

‎src/Symfony/Component/TypeInfo/TypeFactoryTrait.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/TypeInfo/TypeFactoryTrait.php
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,13 @@ public static function union(Type ...$types): UnionType
270270
$isNullable = fn (Type $type): bool => $type instanceof BuiltinType && TypeIdentifier::NULL === $type->getTypeIdentifier();
271271

272272
foreach ($types as $type) {
273+
if ($type instanceof NullableType) {
274+
$nullableUnion = true;
275+
$unionTypes[] = $type->getWrappedType();
276+
277+
continue;
278+
}
279+
273280
if ($type instanceof UnionType) {
274281
foreach ($type->getTypes() as $unionType) {
275282
if ($isNullable($type)) {

‎src/Symfony/Component/Validator/Constraints/IbanValidator.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Validator/Constraints/IbanValidator.php
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class IbanValidator extends ConstraintValidator
6969
'DK' => 'DK\d{2}\d{4}\d{9}\d{1}', // Denmark
7070
'DO' => 'DO\d{2}[\dA-Z]{4}\d{20}', // Dominican Republic
7171
'DZ' => 'DZ\d{2}\d{22}', // Algeria
72-
'EE' => 'EE\d{2}\d{2}\d{2}\d{11}\d{1}', // Estonia
72+
'EE' => 'EE\d{2}\d{2}\d{14}', // Estonia
7373
'EG' => 'EG\d{2}\d{4}\d{4}\d{17}', // Egypt
7474
'ES' => 'ES\d{2}\d{4}\d{4}\d{1}\d{1}\d{10}', // Spain
7575
'FI' => 'FI\d{2}\d{3}\d{11}', // Finland
@@ -126,7 +126,7 @@ class IbanValidator extends ConstraintValidator
126126
'MZ' => 'MZ\d{2}\d{21}', // Mozambique
127127
'NC' => 'FR\d{2}\d{5}\d{5}[\dA-Z]{11}\d{2}', // France
128128
'NE' => 'NE\d{2}[A-Z]{2}\d{22}', // Niger
129-
'NI' => 'NI\d{2}[A-Z]{4}\d{24}', // Nicaragua
129+
'NI' => 'NI\d{2}[A-Z]{4}\d{20}', // Nicaragua
130130
'NL' => 'NL\d{2}[A-Z]{4}\d{10}', // Netherlands (The)
131131
'NO' => 'NO\d{2}\d{4}\d{6}\d{1}', // Norway
132132
'OM' => 'OM\d{2}\d{3}[\dA-Z]{16}', // Oman
@@ -150,7 +150,7 @@ class IbanValidator extends ConstraintValidator
150150
'SM' => 'SM\d{2}[A-Z]{1}\d{5}\d{5}[\dA-Z]{12}', // San Marino
151151
'SN' => 'SN\d{2}[A-Z]{2}\d{22}', // Senegal
152152
'SO' => 'SO\d{2}\d{4}\d{3}\d{12}', // Somalia
153-
'ST' => 'ST\d{2}\d{4}\d{4}\d{11}\d{2}', // Sao Tome and Principe
153+
'ST' => 'ST\d{2}\d{8}\d{11}\d{2}', // Sao Tome and Principe
154154
'SV' => 'SV\d{2}[A-Z]{4}\d{20}', // El Salvador
155155
'TD' => 'TD\d{2}\d{23}', // Chad
156156
'TF' => 'FR\d{2}\d{5}\d{5}[\dA-Z]{11}\d{2}', // France

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.