comparison vendor/symfony/dependency-injection/Compiler/ResolveInvalidReferencesPass.php @ 14:1fec387a4317

Update Drupal core to 8.5.2 via Composer
author Chris Cannam
date Mon, 23 Apr 2018 09:46:53 +0100
parents 4c8ae668cc8c
children 129ea1e6d783
comparison
equal deleted inserted replaced
13:5fb285c0d0e3 14:1fec387a4317
9 * file that was distributed with this source code. 9 * file that was distributed with this source code.
10 */ 10 */
11 11
12 namespace Symfony\Component\DependencyInjection\Compiler; 12 namespace Symfony\Component\DependencyInjection\Compiler;
13 13
14 use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
15 use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
14 use Symfony\Component\DependencyInjection\ContainerInterface; 16 use Symfony\Component\DependencyInjection\ContainerInterface;
17 use Symfony\Component\DependencyInjection\Definition;
15 use Symfony\Component\DependencyInjection\Reference; 18 use Symfony\Component\DependencyInjection\Reference;
16 use Symfony\Component\DependencyInjection\ContainerBuilder; 19 use Symfony\Component\DependencyInjection\ContainerBuilder;
17 use Symfony\Component\DependencyInjection\Exception\RuntimeException; 20 use Symfony\Component\DependencyInjection\Exception\RuntimeException;
18 21
19 /** 22 /**
23 * @author Johannes M. Schmitt <schmittjoh@gmail.com> 26 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
24 */ 27 */
25 class ResolveInvalidReferencesPass implements CompilerPassInterface 28 class ResolveInvalidReferencesPass implements CompilerPassInterface
26 { 29 {
27 private $container; 30 private $container;
31 private $signalingException;
28 32
29 /** 33 /**
30 * Process the ContainerBuilder to resolve invalid references. 34 * Process the ContainerBuilder to resolve invalid references.
31 *
32 * @param ContainerBuilder $container
33 */ 35 */
34 public function process(ContainerBuilder $container) 36 public function process(ContainerBuilder $container)
35 { 37 {
36 $this->container = $container; 38 $this->container = $container;
37 foreach ($container->getDefinitions() as $definition) { 39 $this->signalingException = new RuntimeException('Invalid reference.');
38 if ($definition->isSynthetic() || $definition->isAbstract()) {
39 continue;
40 }
41 40
42 $definition->setArguments( 41 try {
43 $this->processArguments($definition->getArguments()) 42 $this->processValue($container->getDefinitions(), 1);
44 ); 43 } finally {
45 44 $this->container = $this->signalingException = null;
46 $calls = array();
47 foreach ($definition->getMethodCalls() as $call) {
48 try {
49 $calls[] = array($call[0], $this->processArguments($call[1], true));
50 } catch (RuntimeException $e) {
51 // this call is simply removed
52 }
53 }
54 $definition->setMethodCalls($calls);
55
56 $properties = array();
57 foreach ($definition->getProperties() as $name => $value) {
58 try {
59 $value = $this->processArguments(array($value), true);
60 $properties[$name] = reset($value);
61 } catch (RuntimeException $e) {
62 // ignore property
63 }
64 }
65 $definition->setProperties($properties);
66 } 45 }
67 } 46 }
68 47
69 /** 48 /**
70 * Processes arguments to determine invalid references. 49 * Processes arguments to determine invalid references.
71 * 50 *
72 * @param array $arguments An array of Reference objects 51 * @throws RuntimeException When an invalid reference is found
73 * @param bool $inMethodCall
74 * @param bool $inCollection
75 *
76 * @return array
77 *
78 * @throws RuntimeException When the config is invalid
79 */ 52 */
80 private function processArguments(array $arguments, $inMethodCall = false, $inCollection = false) 53 private function processValue($value, $rootLevel = 0, $level = 0)
81 { 54 {
82 $isNumeric = array_keys($arguments) === range(0, count($arguments) - 1); 55 if ($value instanceof ServiceClosureArgument) {
56 $value->setValues($this->processValue($value->getValues(), 1, 1));
57 } elseif ($value instanceof ArgumentInterface) {
58 $value->setValues($this->processValue($value->getValues(), $rootLevel, 1 + $level));
59 } elseif ($value instanceof Definition) {
60 if ($value->isSynthetic() || $value->isAbstract()) {
61 return $value;
62 }
63 $value->setArguments($this->processValue($value->getArguments(), 0));
64 $value->setProperties($this->processValue($value->getProperties(), 1));
65 $value->setMethodCalls($this->processValue($value->getMethodCalls(), 2));
66 } elseif (is_array($value)) {
67 $i = 0;
83 68
84 foreach ($arguments as $k => $argument) { 69 foreach ($value as $k => $v) {
85 if (is_array($argument)) { 70 try {
86 $arguments[$k] = $this->processArguments($argument, $inMethodCall, true); 71 if (false !== $i && $k !== $i++) {
87 } elseif ($argument instanceof Reference) { 72 $i = false;
88 $id = (string) $argument; 73 }
74 if ($v !== $processedValue = $this->processValue($v, $rootLevel, 1 + $level)) {
75 $value[$k] = $processedValue;
76 }
77 } catch (RuntimeException $e) {
78 if ($rootLevel < $level || ($rootLevel && !$level)) {
79 unset($value[$k]);
80 } elseif ($rootLevel) {
81 throw $e;
82 } else {
83 $value[$k] = null;
84 }
85 }
86 }
89 87
90 $invalidBehavior = $argument->getInvalidBehavior(); 88 // Ensure numerically indexed arguments have sequential numeric keys.
91 $exists = $this->container->has($id); 89 if (false !== $i) {
90 $value = array_values($value);
91 }
92 } elseif ($value instanceof Reference) {
93 if ($this->container->has($value)) {
94 return $value;
95 }
96 $invalidBehavior = $value->getInvalidBehavior();
92 97
93 // resolve invalid behavior 98 // resolve invalid behavior
94 if (!$exists && ContainerInterface::NULL_ON_INVALID_REFERENCE === $invalidBehavior) { 99 if (ContainerInterface::NULL_ON_INVALID_REFERENCE === $invalidBehavior) {
95 $arguments[$k] = null; 100 $value = null;
96 } elseif (!$exists && ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $invalidBehavior) { 101 } elseif (ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $invalidBehavior) {
97 if ($inCollection) { 102 if (0 < $level || $rootLevel) {
98 unset($arguments[$k]); 103 throw $this->signalingException;
99 continue;
100 }
101 if ($inMethodCall) {
102 throw new RuntimeException('Method shouldn\'t be called.');
103 }
104
105 $arguments[$k] = null;
106 } 104 }
105 $value = null;
107 } 106 }
108 } 107 }
109 108
110 // Ensure numerically indexed arguments have sequential numeric keys. 109 return $value;
111 if ($isNumeric) {
112 $arguments = array_values($arguments);
113 }
114
115 return $arguments;
116 } 110 }
117 } 111 }