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 8408dcc

Browse filesBrowse files
committed
[DI] [CompilerPass] [AutoWire] : fix order service definition problem
1 parent a0e654d commit 8408dcc
Copy full SHA for 8408dcc

File tree

2 files changed

+127
-2
lines changed
Filter options

2 files changed

+127
-2
lines changed

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php
+39-2Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class AutowirePass implements CompilerPassInterface
2929
private $types;
3030
private $notGuessableTypes = array();
3131
private $usedTypes = array();
32+
private $secondPassDefinitions = array();
3233

3334
/**
3435
* {@inheritdoc}
@@ -46,6 +47,10 @@ public function process(ContainerBuilder $container)
4647
}
4748
}
4849

50+
foreach ($this->secondPassDefinitions as $id => $definition) {
51+
$this->completeDefinition($id, $definition);
52+
}
53+
4954
foreach ($this->usedTypes as $type => $id) {
5055
if (isset($this->usedTypes[$type]) && isset($this->notGuessableTypes[$type])) {
5156
$classOrInterface = class_exists($type) ? 'class' : 'interface';
@@ -67,6 +72,7 @@ public function process(ContainerBuilder $container)
6772
$this->types = null;
6873
$this->notGuessableTypes = array();
6974
$this->usedTypes = array();
75+
$this->secondPassDefinitions = array();
7076

7177
if (isset($e)) {
7278
throw $e;
@@ -94,7 +100,8 @@ private function completeDefinition($id, Definition $definition)
94100
}
95101

96102
$arguments = $definition->getArguments();
97-
foreach ($constructor->getParameters() as $index => $parameter) {
103+
$parameters = $this->getPriorityToInstantiableParameters($constructor->getParameters());
104+
foreach ($parameters as $index => $parameter) {
98105
if (array_key_exists($index, $arguments) && '' !== $arguments[$index]) {
99106
continue;
100107
}
@@ -131,7 +138,12 @@ private function completeDefinition($id, Definition $definition)
131138
} elseif ($parameter->isDefaultValueAvailable()) {
132139
$value = $parameter->getDefaultValue();
133140
} else {
134-
throw $e;
141+
if (isset($this->secondPassDefinitions[$id])) {
142+
throw $e;
143+
}
144+
$this->secondPassDefinitions[$id] = $definition;
145+
146+
return;
135147
}
136148
}
137149
}
@@ -299,4 +311,29 @@ private function getReflectionClass($id, Definition $definition)
299311

300312
return $this->reflectionClasses[$id] = $reflector;
301313
}
314+
315+
/**
316+
* Priority for Instantiable parameters.
317+
*
318+
* @param array $parameters
319+
* @return array
320+
*/
321+
private function getPriorityToInstantiableParameters(array $parameters)
322+
{
323+
$result = array();
324+
325+
foreach ($parameters as $index => $parameter) {
326+
try {
327+
if (($typeHint = $parameter->getClass()) && $typeHint->isInstantiable()) {
328+
$result = array($index => $parameter) + $result;
329+
} else {
330+
$result = $result + array($index => $parameter);
331+
}
332+
} catch (\Exception $e) {
333+
$result = $result + array($index => $parameter);
334+
}
335+
}
336+
337+
return $result;
338+
}
302339
}

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowirePassTest.php
+88Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,75 @@ public function provideAutodiscoveredAutowiringOrder()
486486
array('CannotBeAutowiredReverseOrder'),
487487
);
488488
}
489+
490+
public function testAutoDiscoverWithAnyOrderParameters()
491+
{
492+
$container = new ContainerBuilder();
493+
$container->register('a', __NAMESPACE__.'\\'.'Jordan')
494+
->setAutowired(true);
495+
496+
$pass = new AutowirePass();
497+
$pass->process($container);
498+
499+
$this->assertTrue($container->hasDefinition('a'));
500+
501+
$this->assertEquals(
502+
array(
503+
new Reference('autowired.symfony\component\dependencyinjection\tests\compiler\i'),
504+
new Reference('autowired.symfony\component\dependencyinjection\tests\compiler\i'),
505+
new Reference('autowired.symfony\component\dependencyinjection\tests\compiler\d'),
506+
new Reference('autowired.symfony\component\dependencyinjection\tests\compiler\j'),
507+
new Reference('autowired.symfony\component\dependencyinjection\tests\compiler\d'),
508+
new Reference('autowired.symfony\component\dependencyinjection\tests\compiler\j'),
509+
),
510+
$container->getDefinition('a')->getArguments()
511+
);
512+
}
513+
514+
public function testAutoDiscoverWithAnyOrderServices()
515+
{
516+
$container = new ContainerBuilder();
517+
$container->register('montreal', __NAMESPACE__.'\\'.'Montreal')
518+
->setAutowired(true);
519+
$container->register('paris', __NAMESPACE__.'\\'.'Paris')
520+
->setAutowired(true);
521+
522+
$pass = new AutowirePass();
523+
$pass->process($container);
524+
525+
$this->assertTrue($container->hasDefinition('montreal'));
526+
$this->assertTrue($container->hasDefinition('paris'));
527+
528+
$this->assertEquals(
529+
array(
530+
new Reference('autowired.symfony\component\dependencyinjection\tests\compiler\j'),
531+
new Reference('autowired.symfony\component\dependencyinjection\tests\compiler\d'),
532+
new Reference('autowired.symfony\component\dependencyinjection\tests\compiler\d'),
533+
),
534+
$container->getDefinition('montreal')->getArguments()
535+
);
536+
537+
$this->assertEquals(
538+
array(
539+
new Reference('autowired.symfony\component\dependencyinjection\tests\compiler\j'),
540+
),
541+
$container->getDefinition('paris')->getArguments()
542+
);
543+
}
544+
}
545+
546+
class Montreal
547+
{
548+
public function __construct(JInterface $j, DInterface $d, D $d2)
549+
{
550+
}
551+
}
552+
553+
class Paris
554+
{
555+
public function __construct(J $j)
556+
{
557+
}
489558
}
490559

491560
class Foo
@@ -522,6 +591,10 @@ interface EInterface extends DInterface
522591
{
523592
}
524593

594+
interface JInterface
595+
{
596+
}
597+
525598
interface IInterface
526599
{
527600
}
@@ -548,6 +621,21 @@ public function __construct(B $b, DInterface $d)
548621
}
549622
}
550623

624+
class D implements DInterface
625+
{
626+
}
627+
628+
class J implements JInterface
629+
{
630+
}
631+
632+
class Jordan
633+
{
634+
public function __construct(IInterface $i, I $i2, DInterface $d, JInterface $j, D $d2, J $j2)
635+
{
636+
}
637+
}
638+
551639
interface CollisionInterface
552640
{
553641
}

0 commit comments

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