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 629a14e

Browse filesBrowse files
[DI] Allow extensions to create ServiceLocator as services
1 parent e58be70 commit 629a14e
Copy full SHA for 629a14e
Expand file treeCollapse file tree

18 files changed

+120
-134
lines changed

‎src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php
+5-5Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ private function getContainerDefinitionData(Definition $definition, $omitTags =
232232
}
233233

234234
if ($showArguments) {
235-
$data['arguments'] = $this->describeValue($definition->getArguments(), $omitTags, $showArguments);
235+
$data['arguments'] = $this->describeValue($definition instanceof ArgumentInterface ? $definition->getValues() : $definition->getArguments(), $omitTags, $showArguments);
236236
}
237237

238238
$data['file'] = $definition->getFile();
@@ -399,14 +399,14 @@ private function describeValue($value, $omitTags, $showArguments)
399399
);
400400
}
401401

402-
if ($value instanceof Definition) {
403-
return $this->getContainerDefinitionData($value, $omitTags, $showArguments);
404-
}
405-
406402
if ($value instanceof ArgumentInterface) {
407403
return $this->describeValue($value->getValues(), $omitTags, $showArguments);
408404
}
409405

406+
if ($value instanceof Definition) {
407+
return $this->getContainerDefinitionData($value, $omitTags, $showArguments);
408+
}
409+
410410
return $value;
411411
}
412412
}

‎src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Bundle\FrameworkBundle\Console\Descriptor;
1313

1414
use Symfony\Component\DependencyInjection\Alias;
15+
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
1516
use Symfony\Component\DependencyInjection\ContainerBuilder;
1617
use Symfony\Component\DependencyInjection\Definition;
1718
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
@@ -197,7 +198,7 @@ protected function describeContainerDefinition(Definition $definition, array $op
197198
}
198199

199200
if (isset($options['show_arguments']) && $options['show_arguments']) {
200-
$output .= "\n".'- Arguments: '.($definition->getArguments() ? 'yes' : 'no');
201+
$output .= "\n".'- Arguments: '.(($definition instanceof ArgumentInterface ? $definition->getValues() : $definition->getArguments()) ? 'yes' : 'no');
201202
}
202203

203204
if ($definition->getFile()) {

‎src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php
+4-3Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Symfony\Component\Console\Helper\Table;
1515
use Symfony\Component\Console\Style\SymfonyStyle;
1616
use Symfony\Component\DependencyInjection\Alias;
17+
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
1718
use Symfony\Component\DependencyInjection\Argument\ClosureProxyArgument;
1819
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
1920
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
@@ -326,19 +327,19 @@ protected function describeContainerDefinition(Definition $definition, array $op
326327

327328
$showArguments = isset($options['show_arguments']) && $options['show_arguments'];
328329
$argumentsInformation = array();
329-
if ($showArguments && ($arguments = $definition->getArguments())) {
330+
if ($showArguments && $arguments = $definition instanceof ArgumentInterface ? $definition->getValues() : $definition->getArguments()) {
330331
foreach ($arguments as $argument) {
331332
if ($argument instanceof Reference) {
332333
$argumentsInformation[] = sprintf('Service(%s)', (string) $argument);
333-
} elseif ($argument instanceof Definition) {
334-
$argumentsInformation[] = 'Inlined Service';
335334
} elseif ($argument instanceof IteratorArgument) {
336335
$argumentsInformation[] = sprintf('Iterator (%d element(s))', count($argument->getValues()));
337336
} elseif ($argument instanceof ServiceLocatorArgument) {
338337
$argumentsInformation[] = sprintf('ServiceLocator (%d service(s))', count($argument->getValues()));
339338
} elseif ($argument instanceof ClosureProxyArgument) {
340339
list($reference, $method) = $argument->getValues();
341340
$argumentsInformation[] = sprintf('ClosureProxy(Service(%s)::%s())', $reference, $method);
341+
} elseif ($argument instanceof Definition) {
342+
$argumentsInformation[] = 'Inlined Service';
342343
} else {
343344
$argumentsInformation[] = is_array($argument) ? sprintf('Array (%d element(s))', count($argument)) : $argument;
344345
}

‎src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php
+4-3Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Bundle\FrameworkBundle\Console\Descriptor;
1313

1414
use Symfony\Component\DependencyInjection\Alias;
15+
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
1516
use Symfony\Component\DependencyInjection\Argument\ClosureProxyArgument;
1617
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
1718
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
@@ -396,7 +397,7 @@ private function getContainerDefinitionDocument(Definition $definition, $id = nu
396397
}
397398

398399
if ($showArguments) {
399-
foreach ($this->getArgumentNodes($definition->getArguments(), $dom) as $node) {
400+
foreach ($this->getArgumentNodes($definition instanceof ArgumentInterface ? $definition->getValues() : $definition->getArguments(), $dom) as $node) {
400401
$serviceXML->appendChild($node);
401402
}
402403
}
@@ -440,8 +441,6 @@ private function getArgumentNodes(array $arguments, \DOMDocument $dom)
440441
if ($argument instanceof Reference) {
441442
$argumentXML->setAttribute('type', 'service');
442443
$argumentXML->setAttribute('id', (string) $argument);
443-
} elseif ($argument instanceof Definition) {
444-
$argumentXML->appendChild($dom->importNode($this->getContainerDefinitionDocument($argument, null, false, true)->childNodes->item(0), true));
445444
} elseif ($argument instanceof IteratorArgument) {
446445
$argumentXML->setAttribute('type', 'iterator');
447446

@@ -459,6 +458,8 @@ private function getArgumentNodes(array $arguments, \DOMDocument $dom)
459458
$argumentXML->setAttribute('type', 'closure-proxy');
460459
$argumentXML->setAttribute('id', (string) $reference);
461460
$argumentXML->setAttribute('method', $method);
461+
} elseif ($argument instanceof Definition) {
462+
$argumentXML->appendChild($dom->importNode($this->getContainerDefinitionDocument($argument, null, false, true)->childNodes->item(0), true));
462463
} elseif (is_array($argument)) {
463464
$argumentXML->setAttribute('type', 'collection');
464465

‎src/Symfony/Component/DependencyInjection/Argument/ServiceLocatorArgument.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Argument/ServiceLocatorArgument.php
+6-2Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111

1212
namespace Symfony\Component\DependencyInjection\Argument;
1313

14-
use Symfony\Component\DependencyInjection\Reference;
14+
use Symfony\Component\DependencyInjection\Definition;
1515
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
16+
use Symfony\Component\DependencyInjection\Reference;
17+
use Symfony\Component\DependencyInjection\ServiceLocator;
1618

1719
/**
1820
* Represents a service locator able to lazy load a given range of services.
@@ -21,7 +23,7 @@
2123
*
2224
* @experimental in version 3.3
2325
*/
24-
class ServiceLocatorArgument implements ArgumentInterface
26+
class ServiceLocatorArgument extends Definition implements ArgumentInterface
2527
{
2628
private $values;
2729

@@ -31,6 +33,8 @@ class ServiceLocatorArgument implements ArgumentInterface
3133
public function __construct(array $values)
3234
{
3335
$this->setValues($values);
36+
37+
parent::__construct(ServiceLocator::class);
3438
}
3539

3640
public function getValues()

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php
+4-1Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,11 @@ protected function processValue($value, $isRoot = false)
7373
$lazy = $this->lazy;
7474

7575
if ($value instanceof ArgumentInterface) {
76+
if ($isRoot && $value instanceof Definition) {
77+
$this->currentDefinition = $value;
78+
}
7679
$this->lazy = true;
77-
parent::processValue($value);
80+
parent::processValue($value->getValues());
7881
$this->lazy = $lazy;
7982

8083
return $value;

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php
+38-88Lines changed: 38 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\DependencyInjection\ContainerBuilder;
1616
use Symfony\Component\DependencyInjection\Definition;
1717
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
18+
use Symfony\Component\DependencyInjection\LazyProxy\InheritanceProxyHelper;
1819
use Symfony\Component\DependencyInjection\Reference;
1920

2021
/**
@@ -248,13 +249,7 @@ private function autowireMethod(\ReflectionMethod $reflectionMethod, array $argu
248249
continue;
249250
}
250251

251-
if (method_exists($parameter, 'getType')) {
252-
if ($typeName = $parameter->getType()) {
253-
$typeName = $typeName->isBuiltin() ? null : ($typeName instanceof \ReflectionNamedType ? $typeName->getName() : $typeName->__toString());
254-
}
255-
} elseif (preg_match('/^(?:[^ ]++ ){4}([a-zA-Z_\x7F-\xFF][^ ]++)/', $parameter, $typeName)) {
256-
$typeName = 'callable' === $typeName[1] || 'array' === $typeName[1] ? null : $typeName[1];
257-
}
252+
$typeName = InheritanceProxyHelper::getTypeHint($reflectionMethod, $parameter, true);
258253

259254
if (!$typeName) {
260255
// no default value? Then fail
@@ -274,52 +269,17 @@ private function autowireMethod(\ReflectionMethod $reflectionMethod, array $argu
274269
continue;
275270
}
276271

277-
if ($this->container->has($typeName) && !$this->container->findDefinition($typeName)->isAbstract()) {
278-
$arguments[$index] = new Reference($typeName);
279-
$didAutowire = true;
280-
281-
continue;
282-
}
283-
284-
if (null === $this->types) {
285-
$this->populateAvailableTypes();
286-
}
287-
288-
if (isset($this->types[$typeName])) {
289-
$value = new Reference($this->types[$typeName]);
272+
if ($value = $this->getAutowiredReference($typeName)) {
290273
$didAutowire = true;
291274
$this->usedTypes[$typeName] = $this->currentId;
292-
} elseif ($typeHint = $this->container->getReflectionClass($typeName, true)) {
293-
try {
294-
$value = $this->createAutowiredDefinition($typeHint);
295-
$didAutowire = true;
296-
$this->usedTypes[$typeName] = $this->currentId;
297-
} catch (RuntimeException $e) {
298-
if ($parameter->allowsNull()) {
299-
$value = null;
300-
} elseif ($parameter->isDefaultValueAvailable()) {
301-
$value = $parameter->getDefaultValue();
302-
} else {
303-
// The exception code is set to 1 if the exception must be thrown even if it's an optional setter
304-
if (1 === $e->getCode() || self::MODE_REQUIRED === $mode) {
305-
throw $e;
306-
}
307-
308-
return array();
309-
}
310-
}
311-
} else {
312-
// Typehint against a non-existing class
313-
314-
if (!$parameter->isDefaultValueAvailable()) {
315-
if (self::MODE_REQUIRED === $mode) {
316-
throw new RuntimeException(sprintf('Cannot autowire argument $%s of method %s::%s() for service "%s": Class %s does not exist.', $parameter->name, $reflectionMethod->class, $reflectionMethod->name, $this->currentId, $typeName));
317-
}
318-
319-
return array();
320-
}
321-
275+
} elseif ($parameter->allowsNull()) {
276+
$value = null;
277+
} elseif ($parameter->isDefaultValueAvailable()) {
322278
$value = $parameter->getDefaultValue();
279+
} elseif (self::MODE_REQUIRED === $mode) {
280+
throw new RuntimeException(sprintf('Unable to autowire argument of type "%s" for the service "%s". No matching services were found and it cannot be auto-registered.', $typeName, $this->currentId));
281+
} else {
282+
return array();
323283
}
324284

325285
$arguments[$index] = $value;
@@ -352,42 +312,39 @@ private function autowireOverridenGetters(array $overridenGetters, array $autowi
352312
|| 0 !== $reflectionMethod->getNumberOfParameters()
353313
|| $reflectionMethod->isFinal()
354314
|| $reflectionMethod->returnsReference()
355-
|| !$returnType = $reflectionMethod->getReturnType()
315+
|| !($typeName = InheritanceProxyHelper::getTypeHint($reflectionMethod, null, true))
316+
|| !($typeRef = $this->getAutowiredReference($typeName))
356317
) {
357318
continue;
358319
}
359-
$typeName = $returnType instanceof \ReflectionNamedType ? $returnType->getName() : $returnType->__toString();
360320

361-
if ($this->container->has($typeName) && !$this->container->findDefinition($typeName)->isAbstract()) {
362-
$overridenGetters[$lcMethod] = new Reference($typeName);
363-
continue;
364-
}
321+
$overridenGetters[$lcMethod] = $typeRef;
322+
$this->usedTypes[$typeName] = $this->currentId;
323+
}
365324

366-
if (null === $this->types) {
367-
$this->populateAvailableTypes();
368-
}
325+
return $overridenGetters;
326+
}
369327

370-
if (isset($this->types[$typeName])) {
371-
$value = new Reference($this->types[$typeName]);
372-
} elseif ($returnType = $this->container->getReflectionClass($typeName, true)) {
373-
try {
374-
$value = $this->createAutowiredDefinition($returnType);
375-
} catch (RuntimeException $e) {
376-
if (1 === $e->getCode()) {
377-
throw $e;
378-
}
328+
/**
329+
* @return Reference|null A reference to the service matching the given type, if any
330+
*/
331+
private function getAutowiredReference($typeName, $autoRegister = true)
332+
{
333+
if ($this->container->has($typeName) && !$this->container->findDefinition($typeName)->isAbstract()) {
334+
return new Reference($typeName);
335+
}
379336

380-
continue;
381-
}
382-
} else {
383-
continue;
384-
}
337+
if (null === $this->types) {
338+
$this->populateAvailableTypes();
339+
}
385340

386-
$overridenGetters[$lcMethod] = $value;
387-
$this->usedTypes[$typeName] = $this->currentId;
341+
if (isset($this->types[$typeName])) {
342+
return new Reference($this->types[$typeName]);
388343
}
389344

390-
return $overridenGetters;
345+
if ($autoRegister && $class = $this->container->getReflectionClass($typeName, true)) {
346+
return $this->createAutowiredDefinition($class);
347+
}
391348
}
392349

393350
/**
@@ -473,7 +430,7 @@ private function set($type, $id)
473430
*
474431
* @param \ReflectionClass $typeHint
475432
*
476-
* @return Reference A reference to the registered definition
433+
* @return Reference|null A reference to the registered definition
477434
*
478435
* @throws RuntimeException
479436
*/
@@ -483,12 +440,11 @@ private function createAutowiredDefinition(\ReflectionClass $typeHint)
483440
$classOrInterface = $typeHint->isInterface() ? 'interface' : 'class';
484441
$matchingServices = implode(', ', $this->ambiguousServiceTypes[$typeHint->name]);
485442

486-
throw new RuntimeException(sprintf('Unable to autowire argument of type "%s" for the service "%s". Multiple services exist for this %s (%s).', $typeHint->name, $this->currentId, $classOrInterface, $matchingServices), 1);
443+
throw new RuntimeException(sprintf('Unable to autowire argument of type "%s" for the service "%s". Multiple services exist for this %s (%s).', $typeHint->name, $this->currentId, $classOrInterface, $matchingServices));
487444
}
488445

489446
if (!$typeHint->isInstantiable()) {
490-
$classOrInterface = $typeHint->isInterface() ? 'interface' : 'class';
491-
throw new RuntimeException(sprintf('Unable to autowire argument of type "%s" for the service "%s". No services were found matching this %s and it cannot be auto-registered.', $typeHint->name, $this->currentId, $classOrInterface));
447+
return;
492448
}
493449

494450
$currentId = $this->currentId;
@@ -500,14 +456,8 @@ private function createAutowiredDefinition(\ReflectionClass $typeHint)
500456

501457
$this->populateAvailableType($argumentId, $argumentDefinition);
502458

503-
try {
504-
$this->processValue($argumentDefinition, true);
505-
$this->currentId = $currentId;
506-
} catch (RuntimeException $e) {
507-
$classOrInterface = $typeHint->isInterface() ? 'interface' : 'class';
508-
$message = sprintf('Unable to autowire argument of type "%s" for the service "%s". No services were found matching this %s and it cannot be auto-registered.', $typeHint->name, $this->currentId, $classOrInterface);
509-
throw new RuntimeException($message, 0, $e);
510-
}
459+
$this->processValue($argumentDefinition, true);
460+
$this->currentId = $currentId;
511461

512462
return new Reference($argumentId);
513463
}

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ public function process(ContainerBuilder $container)
5353
*/
5454
private function processValue($value, $rootLevel = 0, $level = 0)
5555
{
56-
if ($value instanceof Definition) {
56+
if ($value instanceof ArgumentInterface) {
57+
$value->setValues($this->processValue($value->getValues(), $rootLevel, 1 + $level));
58+
} elseif ($value instanceof Definition) {
5759
if ($value->isSynthetic() || $value->isAbstract()) {
5860
return $value;
5961
}
@@ -87,8 +89,6 @@ private function processValue($value, $rootLevel = 0, $level = 0)
8789
if (false !== $i) {
8890
$value = array_values($value);
8991
}
90-
} elseif ($value instanceof ArgumentInterface) {
91-
$value->setValues($this->processValue($value->getValues(), $rootLevel, 1 + $level));
9292
} elseif ($value instanceof Reference) {
9393
$id = (string) $value;
9494

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Compiler/ResolveReferencesToAliasesPass.php
+5-1Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111

1212
namespace Symfony\Component\DependencyInjection\Compiler;
1313

14-
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
1514
use Symfony\Component\DependencyInjection\Alias;
15+
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
1616
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
1717
use Symfony\Component\DependencyInjection\Reference;
1818
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -39,6 +39,10 @@ public function process(ContainerBuilder $container)
3939
if ($definition->isSynthetic() || $definition->isAbstract()) {
4040
continue;
4141
}
42+
if ($definition instanceof ArgumentInterface) {
43+
$definition->setValues($this->processArguments($definition->getValues()));
44+
continue;
45+
}
4246

4347
$definition->setArguments($this->processArguments($definition->getArguments()));
4448
$definition->setMethodCalls($this->processArguments($definition->getMethodCalls()));

0 commit comments

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