Skip to content

Commit 5fc28ce

Browse files
Merge branch '2.7' into 2.8
* 2.7: [travis] Disable hirak/prestissimo for deps=low/high tests [HttpFoundation] fix phpdoc of UploadedFile Lower complexity of Form:isValid() skipped dns-sensitive tests when DnsMock is not found [FrameworkBundle] Return the invokable service if its name is the class name [ci] Skip dns-sensitive tests when DnsMock is not found Exclude Bridge\PhpUnit from composer.json by default fixed CS Optimize ReplaceAliasByActualDefinitionPass [Process] use __METHOD__ where applicable [Routing] Don't needlessly execute strtr's as they are fairly expensive
2 parents 1472804 + 1414606 commit 5fc28ce

File tree

1 file changed

+65
-74
lines changed

1 file changed

+65
-74
lines changed

Compiler/ReplaceAliasByActualDefinitionPass.php

Lines changed: 65 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ class ReplaceAliasByActualDefinitionPass implements CompilerPassInterface
2525
{
2626
private $compiler;
2727
private $formatter;
28-
private $sourceId;
2928

3029
/**
3130
* Process the Container to replace aliases with service definitions.
@@ -36,118 +35,110 @@ class ReplaceAliasByActualDefinitionPass implements CompilerPassInterface
3635
*/
3736
public function process(ContainerBuilder $container)
3837
{
38+
// Setup
3939
$this->compiler = $container->getCompiler();
4040
$this->formatter = $this->compiler->getLoggingFormatter();
41-
42-
foreach ($container->getAliases() as $id => $alias) {
43-
$aliasId = (string) $alias;
44-
45-
if ('service_container' === $aliasId) {
41+
// First collect all alias targets that need to be replaced
42+
$seenAliasTargets = array();
43+
$replacements = array();
44+
foreach ($container->getAliases() as $definitionId => $target) {
45+
$targetId = (string) $target;
46+
// Special case: leave this target alone
47+
if ('service_container' === $targetId) {
4648
continue;
4749
}
48-
50+
// Check if target needs to be replaces
51+
if (isset($replacements[$targetId])) {
52+
$container->setAlias($definitionId, $replacements[$targetId]);
53+
}
54+
// No neeed to process the same target twice
55+
if (isset($seenAliasTargets[$targetId])) {
56+
continue;
57+
}
58+
// Process new target
59+
$seenAliasTargets[$targetId] = true;
4960
try {
50-
$definition = $container->getDefinition($aliasId);
61+
$definition = $container->getDefinition($targetId);
5162
} catch (InvalidArgumentException $e) {
52-
throw new InvalidArgumentException(sprintf('Unable to replace alias "%s" with actual definition "%s".', $id, $alias), null, $e);
63+
throw new InvalidArgumentException(sprintf('Unable to replace alias "%s" with actual definition "%s".', $definitionId, $targetId), null, $e);
5364
}
54-
5565
if ($definition->isPublic()) {
5666
continue;
5767
}
58-
68+
// Remove private definition and schedule for replacement
5969
$definition->setPublic(true);
60-
$container->setDefinition($id, $definition);
61-
$container->removeDefinition($aliasId);
62-
63-
$this->updateReferences($container, $aliasId, $id);
64-
65-
// we have to restart the process due to concurrent modification of
66-
// the container
67-
$this->process($container);
68-
69-
break;
70+
$container->setDefinition($definitionId, $definition);
71+
$container->removeDefinition($targetId);
72+
$replacements[$targetId] = $definitionId;
7073
}
71-
}
7274

73-
/**
74-
* Updates references to remove aliases.
75-
*
76-
* @param ContainerBuilder $container The container
77-
* @param string $currentId The alias identifier being replaced
78-
* @param string $newId The id of the service the alias points to
79-
*/
80-
private function updateReferences($container, $currentId, $newId)
81-
{
82-
foreach ($container->getAliases() as $id => $alias) {
83-
if ($currentId === (string) $alias) {
84-
$container->setAlias($id, $newId);
85-
}
86-
}
87-
88-
foreach ($container->getDefinitions() as $id => $definition) {
89-
$this->sourceId = $id;
90-
91-
$definition->setArguments(
92-
$this->updateArgumentReferences($definition->getArguments(), $currentId, $newId)
93-
);
94-
95-
$definition->setMethodCalls(
96-
$this->updateArgumentReferences($definition->getMethodCalls(), $currentId, $newId)
97-
);
98-
99-
$definition->setProperties(
100-
$this->updateArgumentReferences($definition->getProperties(), $currentId, $newId)
101-
);
102-
103-
$definition->setFactoryService($this->updateFactoryServiceReference($definition->getFactoryService(false), $currentId, $newId), false);
104-
$definition->setFactory($this->updateFactoryReference($definition->getFactory(), $currentId, $newId));
75+
// Now replace target instances in all definitions
76+
foreach ($container->getDefinitions() as $definitionId => $definition) {
77+
$definition->setArguments($this->updateArgumentReferences($replacements, $definitionId, $definition->getArguments()));
78+
$definition->setMethodCalls($this->updateArgumentReferences($replacements, $definitionId, $definition->getMethodCalls()));
79+
$definition->setProperties($this->updateArgumentReferences($replacements, $definitionId, $definition->getProperties()));
80+
$definition->setFactoryService($this->updateFactoryReferenceId($replacements, $definition->getFactoryService(false)), false);
81+
$definition->setFactory($this->updateFactoryReference($replacements, $definition->getFactory()));
10582
}
10683
}
10784

10885
/**
109-
* Updates argument references.
86+
* Recursively updates references in an array.
11087
*
111-
* @param array $arguments An array of Arguments
112-
* @param string $currentId The alias identifier
113-
* @param string $newId The identifier the alias points to
88+
* @param array $replacements Table of aliases to replace
89+
* @param string $definitionId Identifier of this definition
90+
* @param array $arguments Where to replace the aliases
11491
*
11592
* @return array
11693
*/
117-
private function updateArgumentReferences(array $arguments, $currentId, $newId)
94+
private function updateArgumentReferences(array $replacements, $definitionId, array $arguments)
11895
{
11996
foreach ($arguments as $k => $argument) {
97+
// Handle recursion step
12098
if (is_array($argument)) {
121-
$arguments[$k] = $this->updateArgumentReferences($argument, $currentId, $newId);
122-
} elseif ($argument instanceof Reference) {
123-
if ($currentId === (string) $argument) {
124-
$arguments[$k] = new Reference($newId, $argument->getInvalidBehavior());
125-
$this->compiler->addLogMessage($this->formatter->formatUpdateReference($this, $this->sourceId, $currentId, $newId));
126-
}
99+
$arguments[$k] = $this->updateArgumentReferences($replacements, $definitionId, $argument);
100+
continue;
101+
}
102+
// Skip arguments that don't need replacement
103+
if (!$argument instanceof Reference) {
104+
continue;
105+
}
106+
$referenceId = (string) $argument;
107+
if (!isset($replacements[$referenceId])) {
108+
continue;
127109
}
110+
// Perform the replacement
111+
$newId = $replacements[$referenceId];
112+
$arguments[$k] = new Reference($newId, $argument->getInvalidBehavior());
113+
$this->compiler->addLogMessage($this->formatter->formatUpdateReference($this, $definitionId, $referenceId, $newId));
128114
}
129115

130116
return $arguments;
131117
}
132118

133-
private function updateFactoryServiceReference($factoryService, $currentId, $newId)
119+
/**
120+
* Returns the updated reference for the factory service.
121+
*
122+
* @param array $replacements Table of aliases to replace
123+
* @param string|null $referenceId Factory service reference identifier
124+
*
125+
* @return string|null
126+
*/
127+
private function updateFactoryReferenceId(array $replacements, $referenceId)
134128
{
135-
if (null === $factoryService) {
129+
if (null === $referenceId) {
136130
return;
137131
}
138132

139-
return $currentId === $factoryService ? $newId : $factoryService;
133+
return isset($replacements[$referenceId]) ? $replacements[$referenceId] : $referenceId;
140134
}
141135

142-
private function updateFactoryReference($factory, $currentId, $newId)
136+
private function updateFactoryReference(array $replacements, $factory)
143137
{
144-
if (null === $factory || !is_array($factory) || !$factory[0] instanceof Reference) {
145-
return $factory;
138+
if (is_array($factory) && $factory[0] instanceof Reference && isset($replacements[$referenceId = (string) $factory[0]])) {
139+
$factory[0] = new Reference($replacements[$referenceId], $factory[0]->getInvalidBehavior());
146140
}
147141

148-
if ($currentId === (string) $factory[0]) {
149-
$factory[0] = new Reference($newId, $factory[0]->getInvalidBehavior());
150-
}
151142

152143
return $factory;
153144
}

0 commit comments

Comments
 (0)