Skip to content

Commit 00b545f

Browse files
committed
[DependencyInjection] Keep map indexes in ServiceLocatorTagPass::register
1 parent f960d64 commit 00b545f

File tree

2 files changed

+44
-29
lines changed

2 files changed

+44
-29
lines changed

src/Symfony/Component/DependencyInjection/Compiler/ServiceLocatorTagPass.php

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,27 @@ protected function processValue(mixed $value, bool $isRoot = false): mixed
6464
throw new InvalidArgumentException(\sprintf('Invalid definition for service "%s": an array of references is expected as first argument when the "container.service_locator" tag is set.', $this->currentId));
6565
}
6666

67-
$value->setArgument(0, self::map($services));
67+
$i = 0;
68+
69+
foreach ($services as $k => $v) {
70+
if ($v instanceof ServiceClosureArgument) {
71+
continue;
72+
}
73+
74+
if ($i === $k) {
75+
if ($v instanceof Reference) {
76+
unset($services[$k]);
77+
$k = (string) $v;
78+
}
79+
++$i;
80+
} elseif (\is_int($k)) {
81+
$i = null;
82+
}
83+
84+
$services[$k] = new ServiceClosureArgument($v);
85+
}
86+
87+
$value->setArgument(0, $services);
6888

6989
$id = '.service_locator.'.ContainerBuilder::hash($value);
7090

@@ -83,8 +103,12 @@ protected function processValue(mixed $value, bool $isRoot = false): mixed
83103

84104
public static function register(ContainerBuilder $container, array $map, ?string $callerId = null): Reference
85105
{
106+
foreach ($map as $k => $v) {
107+
$map[$k] = new ServiceClosureArgument($v);
108+
}
109+
86110
$locator = (new Definition(ServiceLocator::class))
87-
->addArgument(self::map($map))
111+
->addArgument($map)
88112
->addTag('container.service_locator');
89113

90114
if (null !== $callerId && $container->hasDefinition($callerId)) {
@@ -109,29 +133,4 @@ public static function register(ContainerBuilder $container, array $map, ?string
109133

110134
return new Reference($id);
111135
}
112-
113-
public static function map(array $services): array
114-
{
115-
$i = 0;
116-
117-
foreach ($services as $k => $v) {
118-
if ($v instanceof ServiceClosureArgument) {
119-
continue;
120-
}
121-
122-
if ($i === $k) {
123-
if ($v instanceof Reference) {
124-
unset($services[$k]);
125-
$k = (string) $v;
126-
}
127-
++$i;
128-
} elseif (\is_int($k)) {
129-
$i = null;
130-
}
131-
132-
$services[$k] = new ServiceClosureArgument($v);
133-
}
134-
135-
return $services;
136-
}
137136
}

src/Symfony/Component/DependencyInjection/Tests/Compiler/ServiceLocatorTagPassTest.php

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,15 +201,31 @@ public function testIndexedByServiceIdWithDecoration()
201201
static::assertInstanceOf(DecoratedService::class, $locator->get(Service::class));
202202
}
203203

204-
public function testDefinitionOrderIsTheSame()
204+
public function testServicesKeysAreKept()
205205
{
206206
$container = new ContainerBuilder();
207207
$container->register('service-1');
208208
$container->register('service-2');
209209

210210
$locator = ServiceLocatorTagPass::register($container, [
211-
new Reference('service-2'),
212211
new Reference('service-1'),
212+
'service-2' => new Reference('service-2'),
213+
]);
214+
$locator = $container->getDefinition($locator);
215+
$factories = $locator->getArguments()[0];
216+
217+
static::assertSame([0, 'service-2'], array_keys($factories));
218+
}
219+
220+
public function testDefinitionOrderIsTheSame()
221+
{
222+
$container = new ContainerBuilder();
223+
$container->register('service-1');
224+
$container->register('service-2');
225+
226+
$locator = ServiceLocatorTagPass::register($container, [
227+
'service-2' => new Reference('service-2'),
228+
'service-1' => new Reference('service-1'),
213229
]);
214230
$locator = $container->getDefinition($locator);
215231
$factories = $locator->getArguments()[0];

0 commit comments

Comments
 (0)