8000 [DI] Factorize compiler passes around new AbstractRecursivePass · symfony/symfony@dbdfab6 · GitHub
[go: up one dir, main page]

Skip to content

Commit dbdfab6

Browse files
[DI] Factorize compiler passes around new AbstractRecursivePass
1 parent f8b02ed commit dbdfab6

11 files changed

+330
-483
lines changed
Lines 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+
* Process 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

Lines 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