8000 [DI] Simplify AutowirePass and other master-only cleanups · symfony/symfony@34e5cc7 · GitHub
[go: up one dir, main page]

Skip to content

Commit 34e5cc7

Browse files
[DI] Simplify AutowirePass and other master-only cleanups
1 parent 924c1f0 commit 34e5cc7

13 files changed

+89
-121
lines changed

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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/TextDescriptor.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,15 +330,15 @@ protected function describeContainerDefinition(Definition $definition, array $op
330330
foreach ($arguments as $argument) {
331331
if ($argument instanceof Reference) {
332332
$argumentsInformation[] = sprintf('Service(%s)', (string) $argument);
333-
} elseif ($argument instanceof Definition) {
334-
$argumentsInformation[] = 'Inlined Service';
335333
} elseif ($argument instanceof IteratorArgument) {
336334
$argumentsInformation[] = sprintf('Iterator (%d element(s))', count($argument->getValues()));
337335
} elseif ($argument instanceof ServiceLocatorArgument) {
338336
$argumentsInformation[] = sprintf('ServiceLocator (%d service(s))', count($argument->getValues()));
339337
} elseif ($argument instanceof ClosureProxyArgument) {
340338
list($reference, $method) = $argument->getValues();
341339
$argumentsInformation[] = sprintf('ClosureProxy(Service(%s)::%s())', $reference, $method);
340+
} elseif ($argument instanceof Definition) {
341+
$argumentsInformation[] = 'Inlined Service';
342342
} else {
343343
$argumentsInformation[] = is_array($argument) ? sprintf('Array (%d element(s))', count($argument)) : $argument;
344344
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -440,8 +440,6 @@ private function getArgumentNodes(array $arguments, \DOMDocument $dom)
440440
if ($argument instanceof Reference) {
441441
$argumentXML->setAttribute('type', 'service');
442442
$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));
445443
} elseif ($argument instanceof IteratorArgument) {
446444
$argumentXML->setAttribute('type', 'iterator');
447445

@@ -459,6 +457,8 @@ private function getArgumentNodes(array $arguments, \DOMDocument $dom)
459457
$argumentXML->setAttribute('type', 'closure-proxy');
460458
$argumentXML->setAttribute('id', (string) $reference);
461459
$argumentXML->setAttribute('method', $method);
460+
} elseif ($argument instanceof Definition) {
461+
$argumentXML->appendChild($dom->importNode($this->getContainerDefinitionDocument($argument, null, false, true)->childNodes->item(0), true));
462462
} elseif (is_array($argument)) {
463463
$argumentXML->setAttribute('type', 'collection');
464464

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ protected function processValue($value, $isRoot = false)
7474

7575
if ($value instanceof ArgumentInterface) {
7676
$this->lazy = true;
77-
parent::processValue($value);
77+
parent::processValue($value->getValues());
7878
$this->lazy = $lazy;
7979

8080
return $value;

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

Lines changed: 43 additions & 87 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
/**
@@ -252,13 +253,7 @@ private function autowireMethod(\ReflectionMethod $reflectionMethod, array $argu
252253
continue;
253254
}
254255

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

263258
if (!$typeName) {
264259
// no default value? Then fail
@@ -278,52 +273,23 @@ private function autowireMethod(\ReflectionMethod $reflectionMethod, array $argu
278273
continue;
279274
}
280275

281-
if ($this->container->has($typeName) && !$this->container->findDefinition($typeName)->isAbstract()) {
282-
$arguments[$index] = new Reference($typeName);
283-
$didAutowire = true;
284-
285-
continue;
286-
}
287-
288-
if (null === $this->types) {
289-
$this->populateAvailableTypes();
290-
}
291-
292-
if (isset($this->types[$typeName])) {
293-
$value = new Reference($this->types[$typeName]);
276+
if ($value = $this->getAutowiredReference($typeName)) {
294277
$didAutowire = true;
295278
$this->usedTypes[$typeName] = $this->currentId;
296-
} elseif ($typeHint = $this->container->getReflectionClass($typeName, true)) {
297-
try {
298-
$value = $this->createAutowiredDefinition($typeHint);
299-
$didAutowire = true;
300-
$this->usedTypes[$typeName] = $this->currentId;
301-
} catch (RuntimeException $e) {
302-
if ($parameter->allowsNull()) {
303-
$value = null;
304-
} elseif ($parameter->isDefaultValueAvailable()) {
305-
$value = $parameter->getDefaultValue();
306-
} else {
307-
// The exception code is set to 1 if the exception must be thrown even if it's an optional setter
308-
if (1 === $e->getCode() || self::MODE_REQUIRED === $mode) {
309-
throw $e;
310-
}
311-
312-
return array();
313-
}
314-
}
315-
} else {
316-
// Typehint against a non-existing class
317-
318-
if (!$parameter->isDefaultValueAvailable()) {
319-
if (self::MODE_REQUIRED === $mode) {
320-
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));
321-
}
322-
323-
return array();
279+
} elseif ($parameter->isDefaultValueAvailable()) {
280+
$value = $parameter->getDefaultValue();
281+
} elseif ($parameter->allowsNull()) {
282+
$value = null;
283+
} elseif (self::MODE_REQUIRED === $mode) {
284+
if ($classOrInterface = class_exists($typeName, false) ? 'class' : (interface_exists($typeName, false) ? 'interface' : null)) {
285+
$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.', $typeName, $this->currentId, $classOrInterface);
286+
} else {
287+
$message = 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);
324288
}
325289

326-
$value = $parameter->getDefaultValue();
290+
throw new RuntimeException($message);
291+
} else {
292+
return array();
327293
}
328294

329295
$arguments[$index] = $value;
@@ -356,42 +322,39 @@ private function autowireOverridenGetters(array $overridenGetters, array $autowi
356322
|| 0 !== $reflectionMethod->getNumberOfParameters()
357323
|| $reflectionMethod->isFinal()
358324
|| $reflectionMethod->returnsReference()
359-
|| !$returnType = $reflectionMethod->getReturnType()
325+
|| !($typeName = InheritanceProxyHelper::getTypeHint($reflectionMethod, null, true))
326+
|| !($typeRef = $this->getAutowiredReference($typeName))
360327
) {
361328
continue;
362329
}
363-
$typeName = $returnType instanceof \ReflectionNamedType ? $returnType->getName() : $returnType->__toString();
364330

365-
if ($this->container->has($typeName) && !$this->container->findDefinition($typeName)->isAbstract()) {
366-
$overridenGetters[$lcMethod] = new Reference($typeName);
367-
continue;
368-
}
331+
$overridenGetters[$lcMethod] = $typeRef;
332+
$this->usedTypes[$typeName] = $this->currentId;
333+
}
369334

370-
if (null === $this->types) {
371-
$this->populateAvailableTypes();
372-
}
335+
return $overridenGetters;
336+
}
373337

374-
if (isset($this->types[$typeName])) {
375-
$value = new Reference($this->types[$typeName]);
376-
} elseif ($returnType = $this->container->getReflectionClass($typeName, true)) {
377-
try {
378-
$value = $this->createAutowiredDefinition($returnType);
379-
} catch (RuntimeException $e) {
380-
if (1 === $e->getCode()) {
381-
throw $e;
382-
}
338+
/**
339+
* @return Reference|null A reference to the service matching the given type, if any
340+
*/
341+
private function getAutowiredReference($typeName, $autoRegister = true)
342+
{
343+
if ($this->container->has($typeName) && !$this->container->findDefinition($typeName)->isAbstract()) {
344+
return new Reference($typeName);
345+
}
383346

384-
continue;
385-
}
386-
} else {
387-
continue;
388-
}
347+
if (null === $this->types) {
348+
$this->populateAvailableTypes();
349+
}
389350

390-
$overridenGetters[$lcMethod] = $value;
391-
$this->usedTypes[$typeName] = $this->currentId;
351+
if (isset($this->types[$typeName])) {
352+
return new Reference($this->types[$typeName]);
392353
}
393354

394-
return $overridenGetters;
355+
if ($autoRegister && $class = $this->container->getReflectionClass($typeName, true)) {
356+
return $this->createAutowiredDefinition($class);
357+
}
395358
}
396359

397360
/**
@@ -477,7 +440,7 @@ private function set($type, $id)
477440
*
478441
* @param \ReflectionClass $typeHint
479442
*
480-
* @return Reference A reference to the registered definition
443+
* @return Reference|null A reference to the registered definition
481444
*
482445
* @throws RuntimeException
483446
*/
@@ -487,12 +450,11 @@ private function createAutowiredDefinition(\ReflectionClass $typeHint)
487450
$classOrInterface = $typeHint->isInterface() ? 'interface' : 'class';
488451
$matchingServices = implode(', ', $this->ambiguousServiceTypes[$typeHint->name]);
489452

490-
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);
453+
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));
491454
}
492455

493456
if (!$typeHint->isInstantiable()) {
494-
$classOrInterface = $typeHint->isInterface() ? 'interface' : 'class';
495-
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));
457+
return;
496458
}
497459

498460
$currentId = $this->currentId;
@@ -504,14 +466,8 @@ private function createAutowiredDefinition(\ReflectionClass $typeHint)
504466

505467
$this->populateAvailableType($argumentId, $argumentDefinition);
506468

507-
try {
508-
$this->processValue($argumentDefinition);
509-
$this->currentId = $currentId;
510-
} catch (RuntimeException $e) {
511-
$classOrInterface = $typeHint->isInterface() ? 'interface' : 'class';
512-
$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);
513-
throw new RuntimeException($message, 0, $e);
514-
}
469+
$this->processValue($argumentDefinition);
470+
$this->currentId = $currentId;
515471

516472
return new Reference($argumentId);
517473
}

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

Lines 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

Lines changed: 1 addition & 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;

src/Symfony/Component/DependencyInjection/ContainerBuilder.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,6 +1127,9 @@ public function resolveServices($value)
11271127
$parameterBag = $this->getParameterBag();
11281128
$services = array();
11291129
foreach ($value->getValues() as $k => $v) {
1130+
if ($v->getInvalidBehavior() === ContainerInterface::IGNORE_ON_INVALID_REFERENCE && !$this->has((string) $v)) {
1131+
continue;
1132+
}
11301133
$services[$k] = function () use ($v, $parameterBag) {
11311134
return $this->resolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($v)));
11321135
};

src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\DependencyInjection\Dumper;
1313

14+
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
1415
use Symfony\Component\DependencyInjection\Argument\ClosureProxyArgument;
1516
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
1617
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
@@ -1289,6 +1290,8 @@ private function exportParameters(array $parameters, $path = '', $indent = 12)
12891290
foreach ($parameters as $key => $value) {
12901291
if (is_array($value)) {
12911292
$value = $this->exportParameters($value, $path.'/'.$key, $indent + 4);
1293+
} elseif ($value instanceof ArgumentInterface) {
1294+
throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain special arguments. "%s" found in "%s".', get_class($value), $path.'/'.$key));
12921295
} elseif ($value instanceof Variable) {
12931296
throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain variable references. Variable "%s" found in "%s".', $value, $path.'/'.$key));
12941297
} elseif ($value instanceof Definition) {
@@ -1461,6 +1464,8 @@ private function getDefinitionsFromArguments(array $arguments)
14611464
foreach ($arguments as $argument) {
14621465
if (is_array($argument)) {
14631466
$definitions = array_merge($definitions, $this->getDefinitionsFromArguments($argument));
1467+
} elseif ($argument instanceof ArgumentInterface) {
1468+
$definitions = array_merge($definitions, $this->getDefinitionsFromArguments($argument->getValues()));
14641469
} elseif ($argument instanceof Definition) {
14651470
$definitions = array_merge(
14661471
$definitions,

0 commit comments

Comments
 (0)
0