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 3f8aa7b

Browse filesBrowse files
committed
feature #21327 [DI] Factorize compiler passes around new AbstractRecursivePass (nicolas-grekas)
This PR was merged into the 3.3-dev branch. Discussion ---------- [DI] Factorize compiler passes around new AbstractRecursivePass | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | - This PR introduces an AbstractRecursivePass that is able to visit the definition tree recursively everywhere a Definition or a Reference can be nested. All existing compiler passes that need recursivity are updated to leverage this new class. This remove a bunch of boilerplate that was previously repeated all over. It also fixes compiler passes that eg missed looking at configurators for no reason (this "fix" is a new feature really). It then applies recursivity to AutowirePass, that does not handle it today, but should. I'm happy that the net result is a loss of 153 lines :) Commits ------- 6acb80f [DI] Factorize compiler passes around new AbstractRecursivePass
2 parents 3697e1e + 6acb80f commit 3f8aa7b
Copy full SHA for 3f8aa7b

11 files changed

+329
-483
lines changed
+76Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\DependencyInjection\Compiler;
13+
14+
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
15+
use Symfony\Component\DependencyInjection\Definition;
16+
use Symfony\Component\DependencyInjection\ContainerBuilder;
17+
18+
/**
19+
* @author Nicolas Grekas <p@tchwork.com>
20+
*/
21+
abstract class AbstractRecursivePass implements CompilerPassInterface
22+
{
23+
protected $container;
24+
protected $currentId;
25+
26+
/**
27+
* {@inheritdoc}
28+
*/
29+
public function process(ContainerBuilder $container)
30+
{
31+
$this->container = $container;
32+
33+
try {
34+
$this->processValue($container->getDefinitions(), true);
35+
} finally {
36+
$this->container = null;
37+
}
38+
}
39+
40+
/**
41+
* Processes a value found in a definition tree.
42+
*
43+
* @param mixed $value
44+
* @param bool $isRoot
45+
*
46+
* @return mixed The processed value
47+
*/
48+
protected function processValue($value, $isRoot = false)
49+
{
50+
if (is_array($value)) {
51+
foreach ($value as $k => $v) {
52+
if ($isRoot) {
53+
$this->currentId = $k;
54+
}
55+
if ($v !== $processedValue = $this->processValue($v, $isRoot)) {
56+
$value[$k] = $processedValue;
57+
}
58+
}
59+
} elseif ($value instanceof ArgumentInterface) {
60+
$value->setValues($this->processValue($value->getValues()));
61+
} elseif ($value instanceof Definition) {
62+
$value->setArguments($this->processValue($value->getArguments()));
63+
$value->setProperties($this->processValue($value->getProperties()));
64+
$value->setMethodCalls($this->processValue($value->getMethodCalls()));
65+
66+
if ($v = $value->getFactory()) {
67+
$value->setFactory($this->processValue($v));
68+
}
69+
if ($v = $value->getConfigurator()) {
70+
$value->setConfigurator($this->processValue($v));
71+
}
72+
}
73+
74+
return $value;
75+
}
76+
}

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php
+47-56Lines changed: 47 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,13 @@
2525
*
2626
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
2727
*/
28-
class AnalyzeServiceReferencesPass implements RepeatablePassInterface
28+
class AnalyzeServiceReferencesPass extends AbstractRecursivePass implements RepeatablePassInterface
2929
{
3030
private $graph;
31-
private $container;
32-
private $currentId;
3331
private $currentDefinition;
3432
private $repeatedPass;
3533
private $onlyConstructorArguments;
34+
private $lazy;
3635

3736
/**
3837
* @param bool $onlyConstructorArguments Sets this Service Reference pass to ignore method calls
@@ -60,68 +59,60 @@ public function process(ContainerBuilder $container)
6059
$this->container = $container;
6160
$this->graph = $container->getCompiler()->getServiceReferenceGraph();
6261
$this->graph->clear();
63-
64-
foreach ($container->getDefinitions() as $id => $definition) {
65-
if ($definition->isSynthetic() || $definition->isAbstract()) {
66-
continue;
67-
}
68-
69-
$this->currentId = $id;
70-
$this->currentDefinition = $definition;
71-
72-
$this->processArguments($definition->getArguments());
73-
if (is_array($definition->getFactory())) {
74-
$this->processArguments($definition->getFactory());
75-
}
76-
77-
if (!$this->onlyConstructorArguments) {
78-
$this->processArguments($definition->getMethodCalls());
79-
$this->processArguments($definition->getProperties());
80-
if ($definition->getConfigurator()) {
81-
$this->processArguments(array($definition->getConfigurator()));
82-
}
83-
}
84-
}
62+
$this->lazy = false;
8563

8664
foreach ($container->getAliases() as $id => $alias) {
8765
$this->graph->connect($id, $alias, (string) $alias, $this->getDefinition((string) $alias), null);
8866
}
67+
68+
parent::process($container);
8969
}
9070

91-
/**
92-
* Processes service definitions for arguments to find relationships for the service graph.
93-
*
94-
* @param array $arguments An array of Reference or Definition objects relating to service definitions
95-
* @param bool $lazy Whether the references nested in the arguments should be considered lazy or not
96-
*/
97-
private function processArguments(array $arguments, $lazy = false)
71+
protected function processValue($value, $isRoot = false)
9872
{
99-
foreach ($arguments as $argument) {
100-
if (is_array($argument)) {
101-
$this->processArguments($argument, $lazy);
102-
} elseif ($argument instanceof ArgumentInterface) {
103-
$this->processArguments($argument->getValues(), true);
104-
} elseif ($argument instanceof Reference) {
105-
$targetDefinition = $this->getDefinition((string) $argument);
106-
107-
$this->graph->connect(
108-
$this->currentId,
109-
$this->currentDefinition,
110-
$this->getDefinitionId((string) $argument),
111-
$targetDefinition,
112-
$argument,
113-
$lazy || ($targetDefinition && $targetDefinition->isLazy())
114-
);
115-
} elseif ($argument instanceof Definition) {
116-
$this->processArguments($argument->getArguments());
117-
$this->processArguments($argument->getMethodCalls());
118-
$this->processArguments($argument->getProperties());
119-
120-
if (is_array($argument->getFactory())) {
121-
$this->processArguments($argument->getFactory());
122-
}
73+
$lazy = $this->lazy;
74+
75+
if ($value instanceof ArgumentInterface) {
76+
$this->lazy = true;
77+
parent::processValue($value);
78+
$this->lazy = $lazy;
79+
80+
return $value;
81+
}
82+
if ($value instanceof Reference) {
83+
$targetDefinition = $this->getDefinition((string) $value);
84+
85+
$this->graph->connect(
86+
$this->currentId,
87+
$this->currentDefinition,
88+
$this->getDefinitionId((string) $value),
89+
$targetDefinition,
90+
$value,
91+
$this->lazy || ($targetDefinition && $targetDefinition->isLazy())
92+
);
93+
94+
return $value;
95+
}
96+
if (!$value instanceof Definition) {
97+
return parent::processValue($value, $isRoot);
98+
}
99+
if ($isRoot) {
100+
if ($value->isSynthetic() || $value->isAbstract()) {
101+
return $value;
123102
}
103+
$this->currentDefinition = $value;
124104
}
105+
$this->lazy = false;
106+
107+
if ($this->onlyConstructorArguments) {
108+
$this->processValue($value->getFactory());
109+
$this->processValue($value->getArguments());
110+
} else {
111+
parent::processValue($value, $isRoot);
112+
}
113+
$this->lazy = $lazy;
114+
115+
return $value;
125116
}
126117

127118
/**

0 commit comments

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