Mercurial > hg > cmmr2012-drupal-site
comparison vendor/symfony/dependency-injection/Dumper/PhpDumper.php @ 4:a9cd425dd02b
Update, including to Drupal core 8.6.10
author | Chris Cannam |
---|---|
date | Thu, 28 Feb 2019 13:11:55 +0000 |
parents | 5311817fb629 |
children | 12f9dff5fda9 |
comparison
equal
deleted
inserted
replaced
3:307d7a7fd348 | 4:a9cd425dd02b |
---|---|
12 namespace Symfony\Component\DependencyInjection\Dumper; | 12 namespace Symfony\Component\DependencyInjection\Dumper; |
13 | 13 |
14 use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; | 14 use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; |
15 use Symfony\Component\DependencyInjection\Argument\IteratorArgument; | 15 use Symfony\Component\DependencyInjection\Argument\IteratorArgument; |
16 use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; | 16 use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; |
17 use Symfony\Component\DependencyInjection\Variable; | 17 use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass; |
18 use Symfony\Component\DependencyInjection\Compiler\CheckCircularReferencesPass; | |
19 use Symfony\Component\DependencyInjection\Container; | |
20 use Symfony\Component\DependencyInjection\ContainerBuilder; | |
21 use Symfony\Component\DependencyInjection\ContainerInterface; | |
18 use Symfony\Component\DependencyInjection\Definition; | 22 use Symfony\Component\DependencyInjection\Definition; |
19 use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass; | |
20 use Symfony\Component\DependencyInjection\ContainerBuilder; | |
21 use Symfony\Component\DependencyInjection\Container; | |
22 use Symfony\Component\DependencyInjection\ContainerInterface; | |
23 use Symfony\Component\DependencyInjection\Reference; | |
24 use Symfony\Component\DependencyInjection\TypedReference; | |
25 use Symfony\Component\DependencyInjection\Parameter; | |
26 use Symfony\Component\DependencyInjection\Exception\EnvParameterException; | 23 use Symfony\Component\DependencyInjection\Exception\EnvParameterException; |
27 use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; | 24 use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; |
28 use Symfony\Component\DependencyInjection\Exception\RuntimeException; | 25 use Symfony\Component\DependencyInjection\Exception\RuntimeException; |
29 use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; | 26 use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; |
27 use Symfony\Component\DependencyInjection\ExpressionLanguage; | |
30 use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface as ProxyDumper; | 28 use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface as ProxyDumper; |
31 use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\NullDumper; | 29 use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\NullDumper; |
32 use Symfony\Component\DependencyInjection\ExpressionLanguage; | 30 use Symfony\Component\DependencyInjection\Parameter; |
31 use Symfony\Component\DependencyInjection\Reference; | |
32 use Symfony\Component\DependencyInjection\TypedReference; | |
33 use Symfony\Component\DependencyInjection\Variable; | |
33 use Symfony\Component\ExpressionLanguage\Expression; | 34 use Symfony\Component\ExpressionLanguage\Expression; |
34 use Symfony\Component\HttpKernel\Kernel; | 35 use Symfony\Component\HttpKernel\Kernel; |
35 | 36 |
36 /** | 37 /** |
37 * PhpDumper dumps a service container as a PHP class. | 38 * PhpDumper dumps a service container as a PHP class. |
52 const NON_FIRST_CHARS = 'abcdefghijklmnopqrstuvwxyz0123456789_'; | 53 const NON_FIRST_CHARS = 'abcdefghijklmnopqrstuvwxyz0123456789_'; |
53 | 54 |
54 private $definitionVariables; | 55 private $definitionVariables; |
55 private $referenceVariables; | 56 private $referenceVariables; |
56 private $variableCount; | 57 private $variableCount; |
57 private $reservedVariables = array('instance', 'class'); | 58 private $inlinedDefinitions; |
59 private $serviceCalls; | |
60 private $reservedVariables = ['instance', 'class', 'this']; | |
58 private $expressionLanguage; | 61 private $expressionLanguage; |
59 private $targetDirRegex; | 62 private $targetDirRegex; |
60 private $targetDirMaxMatches; | 63 private $targetDirMaxMatches; |
61 private $docStar; | 64 private $docStar; |
62 private $serviceIdToMethodNameMap; | 65 private $serviceIdToMethodNameMap; |
63 private $usedMethodNames; | 66 private $usedMethodNames; |
64 private $namespace; | 67 private $namespace; |
65 private $asFiles; | 68 private $asFiles; |
66 private $hotPathTag; | 69 private $hotPathTag; |
67 private $inlineRequires; | 70 private $inlineRequires; |
68 private $inlinedRequires = array(); | 71 private $inlinedRequires = []; |
69 private $circularReferences = array(); | 72 private $circularReferences = []; |
70 | 73 |
71 /** | 74 /** |
72 * @var ProxyDumper | 75 * @var ProxyDumper |
73 */ | 76 */ |
74 private $proxyDumper; | 77 private $proxyDumper; |
105 * | 108 * |
106 * @return string|array A PHP class representing the service container or an array of PHP files if the "as_files" option is set | 109 * @return string|array A PHP class representing the service container or an array of PHP files if the "as_files" option is set |
107 * | 110 * |
108 * @throws EnvParameterException When an env var exists but has not been dumped | 111 * @throws EnvParameterException When an env var exists but has not been dumped |
109 */ | 112 */ |
110 public function dump(array $options = array()) | 113 public function dump(array $options = []) |
111 { | 114 { |
112 $this->targetDirRegex = null; | 115 $this->targetDirRegex = null; |
113 $this->inlinedRequires = array(); | 116 $this->inlinedRequires = []; |
114 $options = array_merge(array( | 117 $options = array_merge([ |
115 'class' => 'ProjectServiceContainer', | 118 'class' => 'ProjectServiceContainer', |
116 'base_class' => 'Container', | 119 'base_class' => 'Container', |
117 'namespace' => '', | 120 'namespace' => '', |
118 'as_files' => false, | 121 'as_files' => false, |
119 'debug' => true, | 122 'debug' => true, |
120 'hot_path_tag' => 'container.hot_path', | 123 'hot_path_tag' => 'container.hot_path', |
121 'inline_class_loader_parameter' => 'container.dumper.inline_class_loader', | 124 'inline_class_loader_parameter' => 'container.dumper.inline_class_loader', |
122 'build_time' => time(), | 125 'build_time' => time(), |
123 ), $options); | 126 ], $options); |
124 | 127 |
125 $this->namespace = $options['namespace']; | 128 $this->namespace = $options['namespace']; |
126 $this->asFiles = $options['as_files']; | 129 $this->asFiles = $options['as_files']; |
127 $this->hotPathTag = $options['hot_path_tag']; | 130 $this->hotPathTag = $options['hot_path_tag']; |
128 $this->inlineRequires = $options['inline_class_loader_parameter'] && $this->container->hasParameter($options['inline_class_loader_parameter']) && $this->container->getParameter($options['inline_class_loader_parameter']); | 131 $this->inlineRequires = $options['inline_class_loader_parameter'] && $this->container->hasParameter($options['inline_class_loader_parameter']) && $this->container->getParameter($options['inline_class_loader_parameter']); |
136 $baseClassWithNamespace = $baseClass; | 139 $baseClassWithNamespace = $baseClass; |
137 } | 140 } |
138 | 141 |
139 $this->initializeMethodNamesMap('Container' === $baseClass ? Container::class : $baseClass); | 142 $this->initializeMethodNamesMap('Container' === $baseClass ? Container::class : $baseClass); |
140 | 143 |
141 (new AnalyzeServiceReferencesPass())->process($this->container); | 144 if ($this->getProxyDumper() instanceof NullDumper) { |
142 $this->circularReferences = array(); | 145 (new AnalyzeServiceReferencesPass(true, false))->process($this->container); |
143 $checkedNodes = array(); | 146 try { |
147 (new CheckCircularReferencesPass())->process($this->container); | |
148 } catch (ServiceCircularReferenceException $e) { | |
149 $path = $e->getPath(); | |
150 end($path); | |
151 $path[key($path)] .= '". Try running "composer require symfony/proxy-manager-bridge'; | |
152 | |
153 throw new ServiceCircularReferenceException($e->getServiceId(), $path); | |
154 } | |
155 } | |
156 | |
157 (new AnalyzeServiceReferencesPass(false, !$this->getProxyDumper() instanceof NullDumper))->process($this->container); | |
158 $checkedNodes = []; | |
159 $this->circularReferences = []; | |
144 foreach ($this->container->getCompiler()->getServiceReferenceGraph()->getNodes() as $id => $node) { | 160 foreach ($this->container->getCompiler()->getServiceReferenceGraph()->getNodes() as $id => $node) { |
145 $currentPath = array($id => $id); | 161 if (!$node->getValue() instanceof Definition) { |
146 $this->analyzeCircularReferences($node->getOutEdges(), $checkedNodes, $currentPath); | 162 continue; |
163 } | |
164 if (!isset($checkedNodes[$id])) { | |
165 $this->analyzeCircularReferences($id, $node->getOutEdges(), $checkedNodes); | |
166 } | |
147 } | 167 } |
148 $this->container->getCompiler()->getServiceReferenceGraph()->clear(); | 168 $this->container->getCompiler()->getServiceReferenceGraph()->clear(); |
169 $checkedNodes = []; | |
149 | 170 |
150 $this->docStar = $options['debug'] ? '*' : ''; | 171 $this->docStar = $options['debug'] ? '*' : ''; |
151 | 172 |
152 if (!empty($options['file']) && is_dir($dir = dirname($options['file']))) { | 173 if (!empty($options['file']) && is_dir($dir = \dirname($options['file']))) { |
153 // Build a regexp where the first root dirs are mandatory, | 174 // Build a regexp where the first root dirs are mandatory, |
154 // but every other sub-dir is optional up to the full path in $dir | 175 // but every other sub-dir is optional up to the full path in $dir |
155 // Mandate at least 2 root dirs and not more that 5 optional dirs. | 176 // Mandate at least 2 root dirs and not more that 5 optional dirs. |
156 | 177 |
157 $dir = explode(DIRECTORY_SEPARATOR, realpath($dir)); | 178 $dir = explode(\DIRECTORY_SEPARATOR, realpath($dir)); |
158 $i = count($dir); | 179 $i = \count($dir); |
159 | 180 |
160 if (3 <= $i) { | 181 if (3 <= $i) { |
161 $regex = ''; | 182 $regex = ''; |
162 $lastOptionalDir = $i > 8 ? $i - 5 : 3; | 183 $lastOptionalDir = $i > 8 ? $i - 5 : 3; |
163 $this->targetDirMaxMatches = $i - $lastOptionalDir; | 184 $this->targetDirMaxMatches = $i - $lastOptionalDir; |
164 | 185 |
165 while (--$i >= $lastOptionalDir) { | 186 while (--$i >= $lastOptionalDir) { |
166 $regex = sprintf('(%s%s)?', preg_quote(DIRECTORY_SEPARATOR.$dir[$i], '#'), $regex); | 187 $regex = sprintf('(%s%s)?', preg_quote(\DIRECTORY_SEPARATOR.$dir[$i], '#'), $regex); |
167 } | 188 } |
168 | 189 |
169 do { | 190 do { |
170 $regex = preg_quote(DIRECTORY_SEPARATOR.$dir[$i], '#').$regex; | 191 $regex = preg_quote(\DIRECTORY_SEPARATOR.$dir[$i], '#').$regex; |
171 } while (0 < --$i); | 192 } while (0 < --$i); |
172 | 193 |
173 $this->targetDirRegex = '#'.preg_quote($dir[0], '#').$regex.'#'; | 194 $this->targetDirRegex = '#'.preg_quote($dir[0], '#').$regex.'#'; |
174 } | 195 } |
175 } | 196 } |
188 use Symfony\Component\DependencyInjection\Argument\RewindableGenerator; | 209 use Symfony\Component\DependencyInjection\Argument\RewindableGenerator; |
189 | 210 |
190 // This file has been auto-generated by the Symfony Dependency Injection Component for internal use. | 211 // This file has been auto-generated by the Symfony Dependency Injection Component for internal use. |
191 | 212 |
192 EOF; | 213 EOF; |
193 $files = array(); | 214 $files = []; |
194 | 215 |
195 if ($ids = array_keys($this->container->getRemovedIds())) { | 216 if ($ids = array_keys($this->container->getRemovedIds())) { |
196 sort($ids); | 217 sort($ids); |
197 $c = "<?php\n\nreturn array(\n"; | 218 $c = "<?php\n\nreturn [\n"; |
198 foreach ($ids as $id) { | 219 foreach ($ids as $id) { |
199 $c .= ' '.$this->doExport($id)." => true,\n"; | 220 $c .= ' '.$this->doExport($id)." => true,\n"; |
200 } | 221 } |
201 $files['removed-ids.php'] = $c .= ");\n"; | 222 $files['removed-ids.php'] = $c .= "];\n"; |
202 } | 223 } |
203 | 224 |
204 foreach ($this->generateServiceFiles() as $file => $c) { | 225 foreach ($this->generateServiceFiles() as $file => $c) { |
205 $files[$file] = $fileStart.$c; | 226 $files[$file] = $fileStart.$c; |
206 } | 227 } |
207 foreach ($this->generateProxyClasses() as $file => $c) { | 228 foreach ($this->generateProxyClasses() as $file => $c) { |
208 $files[$file] = "<?php\n".$c; | 229 $files[$file] = "<?php\n".$c; |
209 } | 230 } |
210 $files[$options['class'].'.php'] = $code; | 231 $files[$options['class'].'.php'] = $code; |
211 $hash = ucfirst(strtr(ContainerBuilder::hash($files), '._', 'xx')); | 232 $hash = ucfirst(strtr(ContainerBuilder::hash($files), '._', 'xx')); |
212 $code = array(); | 233 $code = []; |
213 | 234 |
214 foreach ($files as $file => $c) { | 235 foreach ($files as $file => $c) { |
215 $code["Container{$hash}/{$file}"] = $c; | 236 $code["Container{$hash}/{$file}"] = $c; |
216 } | 237 } |
217 array_pop($code); | 238 array_pop($code); |
235 | 256 |
236 if (!\\class_exists({$options['class']}::class, false)) { | 257 if (!\\class_exists({$options['class']}::class, false)) { |
237 \\class_alias(\\Container{$hash}\\{$options['class']}::class, {$options['class']}::class, false); | 258 \\class_alias(\\Container{$hash}\\{$options['class']}::class, {$options['class']}::class, false); |
238 } | 259 } |
239 | 260 |
240 return new \\Container{$hash}\\{$options['class']}(array( | 261 return new \\Container{$hash}\\{$options['class']}([ |
241 'container.build_hash' => '$hash', | 262 'container.build_hash' => '$hash', |
242 'container.build_id' => '$id', | 263 'container.build_id' => '$id', |
243 'container.build_time' => $time, | 264 'container.build_time' => $time, |
244 ), __DIR__.\\DIRECTORY_SEPARATOR.'Container{$hash}'); | 265 ], __DIR__.\\DIRECTORY_SEPARATOR.'Container{$hash}'); |
245 | 266 |
246 EOF; | 267 EOF; |
247 } else { | 268 } else { |
248 foreach ($this->generateProxyClasses() as $c) { | 269 foreach ($this->generateProxyClasses() as $c) { |
249 $code .= $c; | 270 $code .= $c; |
250 } | 271 } |
251 } | 272 } |
252 | 273 |
253 $this->targetDirRegex = null; | 274 $this->targetDirRegex = null; |
254 $this->inlinedRequires = array(); | 275 $this->inlinedRequires = []; |
255 $this->circularReferences = array(); | 276 $this->circularReferences = []; |
256 | 277 |
257 $unusedEnvs = array(); | 278 $unusedEnvs = []; |
258 foreach ($this->container->getEnvCounters() as $env => $use) { | 279 foreach ($this->container->getEnvCounters() as $env => $use) { |
259 if (!$use) { | 280 if (!$use) { |
260 $unusedEnvs[] = $env; | 281 $unusedEnvs[] = $env; |
261 } | 282 } |
262 } | 283 } |
279 } | 300 } |
280 | 301 |
281 return $this->proxyDumper; | 302 return $this->proxyDumper; |
282 } | 303 } |
283 | 304 |
284 /** | 305 private function analyzeCircularReferences($sourceId, array $edges, &$checkedNodes, &$currentPath = []) |
285 * Generates Service local temp variables. | 306 { |
286 * | 307 $checkedNodes[$sourceId] = true; |
287 * @return string | 308 $currentPath[$sourceId] = $sourceId; |
288 */ | 309 |
289 private function addServiceLocalTempVariables($cId, Definition $definition, \SplObjectStorage $inlinedDefinitions, \SplObjectStorage $allInlinedDefinitions) | |
290 { | |
291 $allCalls = $calls = $behavior = array(); | |
292 | |
293 foreach ($allInlinedDefinitions as $def) { | |
294 $arguments = array($def->getArguments(), $def->getFactory(), $def->getProperties(), $def->getMethodCalls(), $def->getConfigurator()); | |
295 $this->getServiceCallsFromArguments($arguments, $allCalls, false, $cId, $behavior, $allInlinedDefinitions[$def]); | |
296 } | |
297 | |
298 $isPreInstance = isset($inlinedDefinitions[$definition]) && isset($this->circularReferences[$cId]) && !$this->getProxyDumper()->isProxyCandidate($definition) && $definition->isShared(); | |
299 foreach ($inlinedDefinitions as $def) { | |
300 $this->getServiceCallsFromArguments(array($def->getArguments(), $def->getFactory()), $calls, $isPreInstance, $cId); | |
301 if ($def !== $definition) { | |
302 $arguments = array($def->getProperties(), $def->getMethodCalls(), $def->getConfigurator()); | |
303 $this->getServiceCallsFromArguments($arguments, $calls, $isPreInstance && !$this->hasReference($cId, $arguments, true), $cId); | |
304 } | |
305 } | |
306 if (!isset($inlinedDefinitions[$definition])) { | |
307 $arguments = array($definition->getProperties(), $definition->getMethodCalls(), $definition->getConfigurator()); | |
308 $this->getServiceCallsFromArguments($arguments, $calls, false, $cId); | |
309 } | |
310 | |
311 $code = ''; | |
312 foreach ($calls as $id => $callCount) { | |
313 if ('service_container' === $id || $id === $cId || isset($this->referenceVariables[$id])) { | |
314 continue; | |
315 } | |
316 if ($callCount <= 1 && $allCalls[$id] <= 1) { | |
317 continue; | |
318 } | |
319 | |
320 $name = $this->getNextVariableName(); | |
321 $this->referenceVariables[$id] = new Variable($name); | |
322 | |
323 $reference = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE === $behavior[$id] ? new Reference($id, $behavior[$id]) : null; | |
324 $code .= sprintf(" \$%s = %s;\n", $name, $this->getServiceCall($id, $reference)); | |
325 } | |
326 | |
327 if ('' !== $code) { | |
328 if ($isPreInstance) { | |
329 $code .= <<<EOTXT | |
330 | |
331 if (isset(\$this->services['$cId'])) { | |
332 return \$this->services['$cId']; | |
333 } | |
334 | |
335 EOTXT; | |
336 } | |
337 | |
338 $code .= "\n"; | |
339 } | |
340 | |
341 return $code; | |
342 } | |
343 | |
344 private function analyzeCircularReferences(array $edges, &$checkedNodes, &$currentPath) | |
345 { | |
346 foreach ($edges as $edge) { | 310 foreach ($edges as $edge) { |
347 $node = $edge->getDestNode(); | 311 $node = $edge->getDestNode(); |
348 $id = $node->getId(); | 312 $id = $node->getId(); |
349 | 313 |
350 if ($node->getValue() && ($edge->isLazy() || $edge->isWeak())) { | 314 if (!$node->getValue() instanceof Definition || $sourceId === $id || $edge->isLazy() || $edge->isWeak()) { |
351 // no-op | 315 // no-op |
352 } elseif (isset($currentPath[$id])) { | 316 } elseif (isset($currentPath[$id])) { |
317 $currentId = $id; | |
353 foreach (array_reverse($currentPath) as $parentId) { | 318 foreach (array_reverse($currentPath) as $parentId) { |
354 $this->circularReferences[$parentId][$id] = $id; | 319 $this->circularReferences[$parentId][$currentId] = $currentId; |
355 $id = $parentId; | 320 if ($parentId === $id) { |
321 break; | |
322 } | |
323 $currentId = $parentId; | |
356 } | 324 } |
357 } elseif (!isset($checkedNodes[$id])) { | 325 } elseif (!isset($checkedNodes[$id])) { |
358 $checkedNodes[$id] = true; | 326 $this->analyzeCircularReferences($id, $node->getOutEdges(), $checkedNodes, $currentPath); |
359 $currentPath[$id] = $id; | 327 } elseif (isset($this->circularReferences[$id])) { |
360 $this->analyzeCircularReferences($node->getOutEdges(), $checkedNodes, $currentPath); | 328 $this->connectCircularReferences($id, $currentPath); |
361 unset($currentPath[$id]); | 329 } |
362 } | 330 } |
363 } | 331 unset($currentPath[$sourceId]); |
332 } | |
333 | |
334 private function connectCircularReferences($sourceId, &$currentPath, &$subPath = []) | |
335 { | |
336 $subPath[$sourceId] = $sourceId; | |
337 $currentPath[$sourceId] = $sourceId; | |
338 | |
339 foreach ($this->circularReferences[$sourceId] as $id) { | |
340 if (isset($currentPath[$id])) { | |
341 $currentId = $id; | |
342 foreach (array_reverse($currentPath) as $parentId) { | |
343 $this->circularReferences[$parentId][$currentId] = $currentId; | |
344 if ($parentId === $id) { | |
345 break; | |
346 } | |
347 $currentId = $parentId; | |
348 } | |
349 } elseif (!isset($subPath[$id]) && isset($this->circularReferences[$id])) { | |
350 $this->connectCircularReferences($id, $currentPath, $subPath); | |
351 } | |
352 } | |
353 unset($currentPath[$sourceId]); | |
354 unset($subPath[$sourceId]); | |
364 } | 355 } |
365 | 356 |
366 private function collectLineage($class, array &$lineage) | 357 private function collectLineage($class, array &$lineage) |
367 { | 358 { |
368 if (isset($lineage[$class])) { | 359 if (isset($lineage[$class])) { |
394 $lineage[$class] = substr($exportedFile, 1, -1); | 385 $lineage[$class] = substr($exportedFile, 1, -1); |
395 } | 386 } |
396 | 387 |
397 private function generateProxyClasses() | 388 private function generateProxyClasses() |
398 { | 389 { |
399 $alreadyGenerated = array(); | 390 $alreadyGenerated = []; |
400 $definitions = $this->container->getDefinitions(); | 391 $definitions = $this->container->getDefinitions(); |
401 $strip = '' === $this->docStar && method_exists('Symfony\Component\HttpKernel\Kernel', 'stripComments'); | 392 $strip = '' === $this->docStar && method_exists('Symfony\Component\HttpKernel\Kernel', 'stripComments'); |
402 $proxyDumper = $this->getProxyDumper(); | 393 $proxyDumper = $this->getProxyDumper(); |
403 ksort($definitions); | 394 ksort($definitions); |
404 foreach ($definitions as $definition) { | 395 foreach ($definitions as $definition) { |
409 continue; | 400 continue; |
410 } | 401 } |
411 $alreadyGenerated[$class] = true; | 402 $alreadyGenerated[$class] = true; |
412 // register class' reflector for resource tracking | 403 // register class' reflector for resource tracking |
413 $this->container->getReflectionClass($class); | 404 $this->container->getReflectionClass($class); |
414 $proxyCode = "\n".$proxyDumper->getProxyCode($definition); | 405 if ("\n" === $proxyCode = "\n".$proxyDumper->getProxyCode($definition)) { |
406 continue; | |
407 } | |
415 if ($strip) { | 408 if ($strip) { |
416 $proxyCode = "<?php\n".$proxyCode; | 409 $proxyCode = "<?php\n".$proxyCode; |
417 $proxyCode = substr(Kernel::stripComments($proxyCode), 5); | 410 $proxyCode = substr(Kernel::stripComments($proxyCode), 5); |
418 } | 411 } |
419 yield sprintf('%s.php', explode(' ', $proxyCode, 3)[1]) => $proxyCode; | 412 yield sprintf('%s.php', explode(' ', $proxyCode, 3)[1]) => $proxyCode; |
423 /** | 416 /** |
424 * Generates the require_once statement for service includes. | 417 * Generates the require_once statement for service includes. |
425 * | 418 * |
426 * @return string | 419 * @return string |
427 */ | 420 */ |
428 private function addServiceInclude($cId, Definition $definition, \SplObjectStorage $inlinedDefinitions) | 421 private function addServiceInclude($cId, Definition $definition) |
429 { | 422 { |
430 $code = ''; | 423 $code = ''; |
431 | 424 |
432 if ($this->inlineRequires && !$this->isHotPath($definition)) { | 425 if ($this->inlineRequires && !$this->isHotPath($definition)) { |
433 $lineage = $calls = $behavior = array(); | 426 $lineage = []; |
434 foreach ($inlinedDefinitions as $def) { | 427 foreach ($this->inlinedDefinitions as $def) { |
435 if (!$def->isDeprecated() && is_string($class = is_array($factory = $def->getFactory()) && is_string($factory[0]) ? $factory[0] : $def->getClass())) { | 428 if (!$def->isDeprecated() && \is_string($class = \is_array($factory = $def->getFactory()) && \is_string($factory[0]) ? $factory[0] : $def->getClass())) { |
436 $this->collectLineage($class, $lineage); | 429 $this->collectLineage($class, $lineage); |
437 } | 430 } |
438 $arguments = array($def->getArguments(), $def->getFactory(), $def->getProperties(), $def->getMethodCalls(), $def->getConfigurator()); | 431 } |
439 $this->getServiceCallsFromArguments($arguments, $calls, false, $cId, $behavior, $inlinedDefinitions[$def]); | 432 |
440 } | 433 foreach ($this->serviceCalls as $id => list($callCount, $behavior)) { |
441 | |
442 foreach ($calls as $id => $callCount) { | |
443 if ('service_container' !== $id && $id !== $cId | 434 if ('service_container' !== $id && $id !== $cId |
444 && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE !== $behavior[$id] | 435 && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE !== $behavior |
445 && $this->container->has($id) | 436 && $this->container->has($id) |
446 && $this->isTrivialInstance($def = $this->container->findDefinition($id)) | 437 && $this->isTrivialInstance($def = $this->container->findDefinition($id)) |
447 && is_string($class = is_array($factory = $def->getFactory()) && is_string($factory[0]) ? $factory[0] : $def->getClass()) | 438 && \is_string($class = \is_array($factory = $def->getFactory()) && \is_string($factory[0]) ? $factory[0] : $def->getClass()) |
448 ) { | 439 ) { |
449 $this->collectLineage($class, $lineage); | 440 $this->collectLineage($class, $lineage); |
450 } | 441 } |
451 } | 442 } |
452 | 443 |
453 foreach (array_diff_key(array_flip($lineage), $this->inlinedRequires) as $file => $class) { | 444 foreach (array_diff_key(array_flip($lineage), $this->inlinedRequires) as $file => $class) { |
454 $code .= sprintf(" include_once %s;\n", $file); | 445 $code .= sprintf(" include_once %s;\n", $file); |
455 } | 446 } |
456 } | 447 } |
457 | 448 |
458 foreach ($inlinedDefinitions as $def) { | 449 foreach ($this->inlinedDefinitions as $def) { |
459 if ($file = $def->getFile()) { | 450 if ($file = $def->getFile()) { |
460 $code .= sprintf(" include_once %s;\n", $this->dumpValue($file)); | 451 $code .= sprintf(" include_once %s;\n", $this->dumpValue($file)); |
461 } | 452 } |
462 } | 453 } |
463 | 454 |
464 if ('' !== $code) { | 455 if ('' !== $code) { |
465 $code .= "\n"; | |
466 } | |
467 | |
468 return $code; | |
469 } | |
470 | |
471 /** | |
472 * Generates the inline definition of a service. | |
473 * | |
474 * @return string | |
475 * | |
476 * @throws RuntimeException When the factory definition is incomplete | |
477 * @throws ServiceCircularReferenceException When a circular reference is detected | |
478 */ | |
479 private function addServiceInlinedDefinitions($id, Definition $definition, \SplObjectStorage $inlinedDefinitions, &$isSimpleInstance) | |
480 { | |
481 $code = ''; | |
482 | |
483 foreach ($inlinedDefinitions as $def) { | |
484 if ($definition === $def) { | |
485 continue; | |
486 } | |
487 if ($inlinedDefinitions[$def] <= 1 && !$def->getMethodCalls() && !$def->getProperties() && !$def->getConfigurator() && false === strpos($this->dumpValue($def->getClass()), '$')) { | |
488 continue; | |
489 } | |
490 if (isset($this->definitionVariables[$def])) { | |
491 $name = $this->definitionVariables[$def]; | |
492 } else { | |
493 $name = $this->getNextVariableName(); | |
494 $this->definitionVariables[$def] = new Variable($name); | |
495 } | |
496 | |
497 // a construct like: | |
498 // $a = new ServiceA(ServiceB $b); $b = new ServiceB(ServiceA $a); | |
499 // this is an indication for a wrong implementation, you can circumvent this problem | |
500 // by setting up your service structure like this: | |
501 // $b = new ServiceB(); | |
502 // $a = new ServiceA(ServiceB $b); | |
503 // $b->setServiceA(ServiceA $a); | |
504 if (isset($inlinedDefinitions[$definition]) && $this->hasReference($id, array($def->getArguments(), $def->getFactory()))) { | |
505 throw new ServiceCircularReferenceException($id, array($id)); | |
506 } | |
507 | |
508 $code .= $this->addNewInstance($def, '$'.$name, ' = ', $id); | |
509 | |
510 if (!$this->hasReference($id, array($def->getProperties(), $def->getMethodCalls(), $def->getConfigurator()), true)) { | |
511 $code .= $this->addServiceProperties($def, $name); | |
512 $code .= $this->addServiceMethodCalls($def, $name); | |
513 $code .= $this->addServiceConfigurator($def, $name); | |
514 } else { | |
515 $isSimpleInstance = false; | |
516 } | |
517 | |
518 $code .= "\n"; | 456 $code .= "\n"; |
519 } | 457 } |
520 | 458 |
521 return $code; | 459 return $code; |
522 } | 460 } |
555 $return = 'return '; | 493 $return = 'return '; |
556 } else { | 494 } else { |
557 $instantiation .= ' = '; | 495 $instantiation .= ' = '; |
558 } | 496 } |
559 | 497 |
560 $code = $this->addNewInstance($definition, $return, $instantiation, $id); | 498 return $this->addNewInstance($definition, $return, $instantiation, $id); |
561 | |
562 if (!$isSimpleInstance) { | |
563 $code .= "\n"; | |
564 } | |
565 | |
566 return $code; | |
567 } | 499 } |
568 | 500 |
569 /** | 501 /** |
570 * Checks if the definition is a trivial instance. | 502 * Checks if the definition is a trivial instance. |
571 * | 503 * |
576 private function isTrivialInstance(Definition $definition) | 508 private function isTrivialInstance(Definition $definition) |
577 { | 509 { |
578 if ($definition->isSynthetic() || $definition->getFile() || $definition->getMethodCalls() || $definition->getProperties() || $definition->getConfigurator()) { | 510 if ($definition->isSynthetic() || $definition->getFile() || $definition->getMethodCalls() || $definition->getProperties() || $definition->getConfigurator()) { |
579 return false; | 511 return false; |
580 } | 512 } |
581 if ($definition->isDeprecated() || $definition->isLazy() || $definition->getFactory() || 3 < count($definition->getArguments())) { | 513 if ($definition->isDeprecated() || $definition->isLazy() || $definition->getFactory() || 3 < \count($definition->getArguments())) { |
582 return false; | 514 return false; |
583 } | 515 } |
584 | 516 |
585 foreach ($definition->getArguments() as $arg) { | 517 foreach ($definition->getArguments() as $arg) { |
586 if (!$arg || $arg instanceof Parameter) { | 518 if (!$arg || $arg instanceof Parameter) { |
587 continue; | 519 continue; |
588 } | 520 } |
589 if (is_array($arg) && 3 >= count($arg)) { | 521 if (\is_array($arg) && 3 >= \count($arg)) { |
590 foreach ($arg as $k => $v) { | 522 foreach ($arg as $k => $v) { |
591 if ($this->dumpValue($k) !== $this->dumpValue($k, false)) { | 523 if ($this->dumpValue($k) !== $this->dumpValue($k, false)) { |
592 return false; | 524 return false; |
593 } | 525 } |
594 if (!$v || $v instanceof Parameter) { | 526 if (!$v || $v instanceof Parameter) { |
606 } elseif (!is_scalar($arg) || $this->dumpValue($arg) !== $this->dumpValue($arg, false)) { | 538 } elseif (!is_scalar($arg) || $this->dumpValue($arg) !== $this->dumpValue($arg, false)) { |
607 return false; | 539 return false; |
608 } | 540 } |
609 } | 541 } |
610 | 542 |
611 if (false !== strpos($this->dumpLiteralClass($this->dumpValue($definition->getClass())), '$')) { | |
612 return false; | |
613 } | |
614 | |
615 return true; | 543 return true; |
616 } | 544 } |
617 | 545 |
618 /** | 546 /** |
619 * Adds method calls to a service definition. | 547 * Adds method calls to a service definition. |
625 */ | 553 */ |
626 private function addServiceMethodCalls(Definition $definition, $variableName = 'instance') | 554 private function addServiceMethodCalls(Definition $definition, $variableName = 'instance') |
627 { | 555 { |
628 $calls = ''; | 556 $calls = ''; |
629 foreach ($definition->getMethodCalls() as $call) { | 557 foreach ($definition->getMethodCalls() as $call) { |
630 $arguments = array(); | 558 $arguments = []; |
631 foreach ($call[1] as $value) { | 559 foreach ($call[1] as $value) { |
632 $arguments[] = $this->dumpValue($value); | 560 $arguments[] = $this->dumpValue($value); |
633 } | 561 } |
634 | 562 |
635 $calls .= $this->wrapServiceConditionals($call[1], sprintf(" \$%s->%s(%s);\n", $variableName, $call[0], implode(', ', $arguments))); | 563 $calls .= $this->wrapServiceConditionals($call[1], sprintf(" \$%s->%s(%s);\n", $variableName, $call[0], implode(', ', $arguments))); |
647 | 575 |
648 return $code; | 576 return $code; |
649 } | 577 } |
650 | 578 |
651 /** | 579 /** |
652 * Generates the inline definition setup. | |
653 * | |
654 * @return string | |
655 * | |
656 * @throws ServiceCircularReferenceException when the container contains a circular reference | |
657 */ | |
658 private function addServiceInlinedDefinitionsSetup($id, Definition $definition, \SplObjectStorage $inlinedDefinitions, $isSimpleInstance) | |
659 { | |
660 $this->referenceVariables[$id] = new Variable('instance'); | |
661 | |
662 $code = ''; | |
663 foreach ($inlinedDefinitions as $def) { | |
664 if ($definition === $def || !$this->hasReference($id, array($def->getProperties(), $def->getMethodCalls(), $def->getConfigurator()), true)) { | |
665 continue; | |
666 } | |
667 | |
668 // if the instance is simple, the return statement has already been generated | |
669 // so, the only possible way to get there is because of a circular reference | |
670 if ($isSimpleInstance) { | |
671 throw new ServiceCircularReferenceException($id, array($id)); | |
672 } | |
673 | |
674 $name = (string) $this->definitionVariables[$def]; | |
675 $code .= $this->addServiceProperties($def, $name); | |
676 $code .= $this->addServiceMethodCalls($def, $name); | |
677 $code .= $this->addServiceConfigurator($def, $name); | |
678 } | |
679 | |
680 if ('' !== $code && ($definition->getProperties() || $definition->getMethodCalls() || $definition->getConfigurator())) { | |
681 $code .= "\n"; | |
682 } | |
683 | |
684 return $code; | |
685 } | |
686 | |
687 /** | |
688 * Adds configurator definition. | 580 * Adds configurator definition. |
689 * | 581 * |
690 * @param Definition $definition | 582 * @param Definition $definition |
691 * @param string $variableName | 583 * @param string $variableName |
692 * | 584 * |
696 { | 588 { |
697 if (!$callable = $definition->getConfigurator()) { | 589 if (!$callable = $definition->getConfigurator()) { |
698 return ''; | 590 return ''; |
699 } | 591 } |
700 | 592 |
701 if (is_array($callable)) { | 593 if (\is_array($callable)) { |
702 if ($callable[0] instanceof Reference | 594 if ($callable[0] instanceof Reference |
703 || ($callable[0] instanceof Definition && $this->definitionVariables->contains($callable[0]))) { | 595 || ($callable[0] instanceof Definition && $this->definitionVariables->contains($callable[0])) |
596 ) { | |
704 return sprintf(" %s->%s(\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); | 597 return sprintf(" %s->%s(\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); |
705 } | 598 } |
706 | 599 |
707 $class = $this->dumpValue($callable[0]); | 600 $class = $this->dumpValue($callable[0]); |
708 // If the class is a string we can optimize call_user_func away | 601 // If the class is a string we can optimize call_user_func away |
712 | 605 |
713 if (0 === strpos($class, 'new ')) { | 606 if (0 === strpos($class, 'new ')) { |
714 return sprintf(" (%s)->%s(\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); | 607 return sprintf(" (%s)->%s(\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); |
715 } | 608 } |
716 | 609 |
717 return sprintf(" \\call_user_func(array(%s, '%s'), \$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); | 610 return sprintf(" \\call_user_func([%s, '%s'], \$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); |
718 } | 611 } |
719 | 612 |
720 return sprintf(" %s(\$%s);\n", $callable, $variableName); | 613 return sprintf(" %s(\$%s);\n", $callable, $variableName); |
721 } | 614 } |
722 | 615 |
730 * @return string | 623 * @return string |
731 */ | 624 */ |
732 private function addService($id, Definition $definition, &$file = null) | 625 private function addService($id, Definition $definition, &$file = null) |
733 { | 626 { |
734 $this->definitionVariables = new \SplObjectStorage(); | 627 $this->definitionVariables = new \SplObjectStorage(); |
735 $this->referenceVariables = array(); | 628 $this->referenceVariables = []; |
736 $this->variableCount = 0; | 629 $this->variableCount = 0; |
737 | 630 $this->referenceVariables[$id] = new Variable('instance'); |
738 $return = array(); | 631 |
632 $return = []; | |
739 | 633 |
740 if ($class = $definition->getClass()) { | 634 if ($class = $definition->getClass()) { |
741 $class = $this->container->resolveEnvPlaceholders($class); | 635 $class = $class instanceof Parameter ? '%'.$class.'%' : $this->container->resolveEnvPlaceholders($class); |
742 $return[] = sprintf(0 === strpos($class, '%') ? '@return object A %1$s instance' : '@return \%s', ltrim($class, '\\')); | 636 $return[] = sprintf(0 === strpos($class, '%') ? '@return object A %1$s instance' : '@return \%s', ltrim($class, '\\')); |
743 } elseif ($definition->getFactory()) { | 637 } elseif ($definition->getFactory()) { |
744 $factory = $definition->getFactory(); | 638 $factory = $definition->getFactory(); |
745 if (is_string($factory)) { | 639 if (\is_string($factory)) { |
746 $return[] = sprintf('@return object An instance returned by %s()', $factory); | 640 $return[] = sprintf('@return object An instance returned by %s()', $factory); |
747 } elseif (is_array($factory) && (is_string($factory[0]) || $factory[0] instanceof Definition || $factory[0] instanceof Reference)) { | 641 } elseif (\is_array($factory) && (\is_string($factory[0]) || $factory[0] instanceof Definition || $factory[0] instanceof Reference)) { |
748 if (is_string($factory[0]) || $factory[0] instanceof Reference) { | 642 $class = $factory[0] instanceof Definition ? $factory[0]->getClass() : (string) $factory[0]; |
749 $return[] = sprintf('@return object An instance returned by %s::%s()', (string) $factory[0], $factory[1]); | 643 $class = $class instanceof Parameter ? '%'.$class.'%' : $this->container->resolveEnvPlaceholders($class); |
750 } elseif ($factory[0] instanceof Definition) { | 644 $return[] = sprintf('@return object An instance returned by %s::%s()', $class, $factory[1]); |
751 $return[] = sprintf('@return object An instance returned by %s::%s()', $factory[0]->getClass(), $factory[1]); | |
752 } | |
753 } | 645 } |
754 } | 646 } |
755 | 647 |
756 if ($definition->isDeprecated()) { | 648 if ($definition->isDeprecated()) { |
757 if ($return && 0 === strpos($return[count($return) - 1], '@return')) { | 649 if ($return && 0 === strpos($return[\count($return) - 1], '@return')) { |
758 $return[] = ''; | 650 $return[] = ''; |
759 } | 651 } |
760 | 652 |
761 $return[] = sprintf('@deprecated %s', $definition->getDeprecationMessage($id)); | 653 $return[] = sprintf('@deprecated %s', $definition->getDeprecationMessage($id)); |
762 } | 654 } |
767 $shared = $definition->isShared() ? ' shared' : ''; | 659 $shared = $definition->isShared() ? ' shared' : ''; |
768 $public = $definition->isPublic() ? 'public' : 'private'; | 660 $public = $definition->isPublic() ? 'public' : 'private'; |
769 $autowired = $definition->isAutowired() ? ' autowired' : ''; | 661 $autowired = $definition->isAutowired() ? ' autowired' : ''; |
770 | 662 |
771 if ($definition->isLazy()) { | 663 if ($definition->isLazy()) { |
664 unset($this->circularReferences[$id]); | |
772 $lazyInitialization = '$lazyLoad = true'; | 665 $lazyInitialization = '$lazyLoad = true'; |
773 } else { | 666 } else { |
774 $lazyInitialization = ''; | 667 $lazyInitialization = ''; |
775 } | 668 } |
776 | 669 |
791 { | 684 { |
792 | 685 |
793 EOF; | 686 EOF; |
794 } | 687 } |
795 | 688 |
689 $this->serviceCalls = []; | |
690 $this->inlinedDefinitions = $this->getDefinitionsFromArguments([$definition], null, $this->serviceCalls); | |
691 | |
692 $code .= $this->addServiceInclude($id, $definition); | |
693 | |
796 if ($this->getProxyDumper()->isProxyCandidate($definition)) { | 694 if ($this->getProxyDumper()->isProxyCandidate($definition)) { |
797 $factoryCode = $asFile ? "\$this->load('%s.php', false)" : '$this->%s(false)'; | 695 $factoryCode = $asFile ? "\$this->load('%s.php', false)" : '$this->%s(false)'; |
798 $code .= $this->getProxyDumper()->getProxyFactoryCode($definition, $id, sprintf($factoryCode, $methodName)); | 696 $code .= $this->getProxyDumper()->getProxyFactoryCode($definition, $id, sprintf($factoryCode, $methodName)); |
799 } | 697 } |
800 | 698 |
801 if ($definition->isDeprecated()) { | 699 if ($definition->isDeprecated()) { |
802 $code .= sprintf(" @trigger_error(%s, E_USER_DEPRECATED);\n\n", $this->export($definition->getDeprecationMessage($id))); | 700 $code .= sprintf(" @trigger_error(%s, E_USER_DEPRECATED);\n\n", $this->export($definition->getDeprecationMessage($id))); |
803 } | 701 } |
804 | 702 |
805 $inlinedDefinitions = $this->getDefinitionsFromArguments(array($definition)); | 703 $code .= $this->addInlineService($id, $definition); |
806 $constructorDefinitions = $this->getDefinitionsFromArguments(array($definition->getArguments(), $definition->getFactory())); | |
807 $otherDefinitions = new \SplObjectStorage(); | |
808 | |
809 foreach ($inlinedDefinitions as $def) { | |
810 if ($def === $definition || isset($constructorDefinitions[$def])) { | |
811 $constructorDefinitions[$def] = $inlinedDefinitions[$def]; | |
812 } else { | |
813 $otherDefinitions[$def] = $inlinedDefinitions[$def]; | |
814 } | |
815 } | |
816 | |
817 $isSimpleInstance = !$definition->getProperties() && !$definition->getMethodCalls() && !$definition->getConfigurator(); | |
818 | |
819 $code .= | |
820 $this->addServiceInclude($id, $definition, $inlinedDefinitions). | |
821 $this->addServiceLocalTempVariables($id, $definition, $constructorDefinitions, $inlinedDefinitions). | |
822 $this->addServiceInlinedDefinitions($id, $definition, $constructorDefinitions, $isSimpleInstance). | |
823 $this->addServiceInstance($id, $definition, $isSimpleInstance). | |
824 $this->addServiceLocalTempVariables($id, $definition, $otherDefinitions, $inlinedDefinitions). | |
825 $this->addServiceInlinedDefinitions($id, $definition, $otherDefinitions, $isSimpleInstance). | |
826 $this->addServiceInlinedDefinitionsSetup($id, $definition, $inlinedDefinitions, $isSimpleInstance). | |
827 $this->addServiceProperties($definition). | |
828 $this->addServiceMethodCalls($definition). | |
829 $this->addServiceConfigurator($definition). | |
830 (!$isSimpleInstance ? "\n return \$instance;\n" : '') | |
831 ; | |
832 | 704 |
833 if ($asFile) { | 705 if ($asFile) { |
834 $code = implode("\n", array_map(function ($line) { return $line ? substr($line, 8) : $line; }, explode("\n", $code))); | 706 $code = implode("\n", array_map(function ($line) { return $line ? substr($line, 8) : $line; }, explode("\n", $code))); |
835 } else { | 707 } else { |
836 $code .= " }\n"; | 708 $code .= " }\n"; |
837 } | 709 } |
838 | 710 |
839 $this->definitionVariables = null; | 711 $this->definitionVariables = $this->inlinedDefinitions = null; |
840 $this->referenceVariables = null; | 712 $this->referenceVariables = $this->serviceCalls = null; |
713 | |
714 return $code; | |
715 } | |
716 | |
717 private function addInlineVariables($id, Definition $definition, array $arguments, $forConstructor) | |
718 { | |
719 $code = ''; | |
720 | |
721 foreach ($arguments as $argument) { | |
722 if (\is_array($argument)) { | |
723 $code .= $this->addInlineVariables($id, $definition, $argument, $forConstructor); | |
724 } elseif ($argument instanceof Reference) { | |
725 $code .= $this->addInlineReference($id, $definition, $this->container->normalizeId($argument), $forConstructor); | |
726 } elseif ($argument instanceof Definition) { | |
727 $code .= $this->addInlineService($id, $definition, $argument, $forConstructor); | |
728 } | |
729 } | |
730 | |
731 return $code; | |
732 } | |
733 | |
734 private function addInlineReference($id, Definition $definition, $targetId, $forConstructor) | |
735 { | |
736 list($callCount, $behavior) = $this->serviceCalls[$targetId]; | |
737 | |
738 while ($this->container->hasAlias($targetId)) { | |
739 $targetId = (string) $this->container->getAlias($targetId); | |
740 } | |
741 | |
742 if ($id === $targetId) { | |
743 return $this->addInlineService($id, $definition, $definition); | |
744 } | |
745 | |
746 if ('service_container' === $targetId || isset($this->referenceVariables[$targetId])) { | |
747 return ''; | |
748 } | |
749 | |
750 $hasSelfRef = isset($this->circularReferences[$id][$targetId]); | |
751 $forConstructor = $forConstructor && !isset($this->definitionVariables[$definition]); | |
752 $code = $hasSelfRef && !$forConstructor ? $this->addInlineService($id, $definition, $definition) : ''; | |
753 | |
754 if (isset($this->referenceVariables[$targetId]) || (2 > $callCount && (!$hasSelfRef || !$forConstructor))) { | |
755 return $code; | |
756 } | |
757 | |
758 $name = $this->getNextVariableName(); | |
759 $this->referenceVariables[$targetId] = new Variable($name); | |
760 | |
761 $reference = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE >= $behavior ? new Reference($targetId, $behavior) : null; | |
762 $code .= sprintf(" \$%s = %s;\n", $name, $this->getServiceCall($targetId, $reference)); | |
763 | |
764 if (!$hasSelfRef || !$forConstructor) { | |
765 return $code; | |
766 } | |
767 | |
768 $code .= sprintf(<<<'EOTXT' | |
769 | |
770 if (isset($this->%s['%s'])) { | |
771 return $this->%1$s['%2$s']; | |
772 } | |
773 | |
774 EOTXT | |
775 , | |
776 'services', | |
777 $id | |
778 ); | |
779 | |
780 return $code; | |
781 } | |
782 | |
783 private function addInlineService($id, Definition $definition, Definition $inlineDef = null, $forConstructor = true) | |
784 { | |
785 $isSimpleInstance = $isRootInstance = null === $inlineDef; | |
786 | |
787 if (isset($this->definitionVariables[$inlineDef = $inlineDef ?: $definition])) { | |
788 return ''; | |
789 } | |
790 | |
791 $arguments = [$inlineDef->getArguments(), $inlineDef->getFactory()]; | |
792 | |
793 $code = $this->addInlineVariables($id, $definition, $arguments, $forConstructor); | |
794 | |
795 if ($arguments = array_filter([$inlineDef->getProperties(), $inlineDef->getMethodCalls(), $inlineDef->getConfigurator()])) { | |
796 $isSimpleInstance = false; | |
797 } elseif ($definition !== $inlineDef && 2 > $this->inlinedDefinitions[$inlineDef]) { | |
798 return $code; | |
799 } | |
800 | |
801 if (isset($this->definitionVariables[$inlineDef])) { | |
802 $isSimpleInstance = false; | |
803 } else { | |
804 $name = $definition === $inlineDef ? 'instance' : $this->getNextVariableName(); | |
805 $this->definitionVariables[$inlineDef] = new Variable($name); | |
806 $code .= '' !== $code ? "\n" : ''; | |
807 | |
808 if ('instance' === $name) { | |
809 $code .= $this->addServiceInstance($id, $definition, $isSimpleInstance); | |
810 } else { | |
811 $code .= $this->addNewInstance($inlineDef, '$'.$name, ' = ', $id); | |
812 } | |
813 | |
814 if ('' !== $inline = $this->addInlineVariables($id, $definition, $arguments, false)) { | |
815 $code .= "\n".$inline."\n"; | |
816 } elseif ($arguments && 'instance' === $name) { | |
817 $code .= "\n"; | |
818 } | |
819 | |
820 $code .= $this->addServiceProperties($inlineDef, $name); | |
821 $code .= $this->addServiceMethodCalls($inlineDef, $name); | |
822 $code .= $this->addServiceConfigurator($inlineDef, $name); | |
823 } | |
824 | |
825 if ($isRootInstance && !$isSimpleInstance) { | |
826 $code .= "\n return \$instance;\n"; | |
827 } | |
841 | 828 |
842 return $code; | 829 return $code; |
843 } | 830 } |
844 | 831 |
845 /** | 832 /** |
881 private function addNewInstance(Definition $definition, $return, $instantiation, $id) | 868 private function addNewInstance(Definition $definition, $return, $instantiation, $id) |
882 { | 869 { |
883 $class = $this->dumpValue($definition->getClass()); | 870 $class = $this->dumpValue($definition->getClass()); |
884 $return = ' '.$return.$instantiation; | 871 $return = ' '.$return.$instantiation; |
885 | 872 |
886 $arguments = array(); | 873 $arguments = []; |
887 foreach ($definition->getArguments() as $value) { | 874 foreach ($definition->getArguments() as $value) { |
888 $arguments[] = $this->dumpValue($value); | 875 $arguments[] = $this->dumpValue($value); |
889 } | 876 } |
890 | 877 |
891 if (null !== $definition->getFactory()) { | 878 if (null !== $definition->getFactory()) { |
892 $callable = $definition->getFactory(); | 879 $callable = $definition->getFactory(); |
893 if (is_array($callable)) { | 880 if (\is_array($callable)) { |
894 if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $callable[1])) { | 881 if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $callable[1])) { |
895 throw new RuntimeException(sprintf('Cannot dump definition because of invalid factory method (%s)', $callable[1] ?: 'n/a')); | 882 throw new RuntimeException(sprintf('Cannot dump definition because of invalid factory method (%s)', $callable[1] ?: 'n/a')); |
896 } | 883 } |
897 | 884 |
898 if ($callable[0] instanceof Reference | 885 if ($callable[0] instanceof Reference |
912 | 899 |
913 if (0 === strpos($class, 'new ')) { | 900 if (0 === strpos($class, 'new ')) { |
914 return $return.sprintf("(%s)->%s(%s);\n", $class, $callable[1], $arguments ? implode(', ', $arguments) : ''); | 901 return $return.sprintf("(%s)->%s(%s);\n", $class, $callable[1], $arguments ? implode(', ', $arguments) : ''); |
915 } | 902 } |
916 | 903 |
917 return $return.sprintf("\\call_user_func(array(%s, '%s')%s);\n", $class, $callable[1], $arguments ? ', '.implode(', ', $arguments) : ''); | 904 return $return.sprintf("\\call_user_func([%s, '%s']%s);\n", $class, $callable[1], $arguments ? ', '.implode(', ', $arguments) : ''); |
918 } | 905 } |
919 | 906 |
920 return $return.sprintf("%s(%s);\n", $this->dumpLiteralClass($this->dumpValue($callable)), $arguments ? implode(', ', $arguments) : ''); | 907 return $return.sprintf("%s(%s);\n", $this->dumpLiteralClass($this->dumpValue($callable)), $arguments ? implode(', ', $arguments) : ''); |
921 } | 908 } |
922 | 909 |
959 * @final since Symfony 3.3 | 946 * @final since Symfony 3.3 |
960 */ | 947 */ |
961 class $class extends $baseClass | 948 class $class extends $baseClass |
962 { | 949 { |
963 private \$parameters; | 950 private \$parameters; |
964 private \$targetDirs = array(); | 951 private \$targetDirs = []; |
965 | 952 |
966 public function __construct() | 953 public function __construct() |
967 { | 954 { |
968 | 955 |
969 EOF; | 956 EOF; |
977 | 964 |
978 EOF; | 965 EOF; |
979 } | 966 } |
980 if ($this->asFiles) { | 967 if ($this->asFiles) { |
981 $code = str_replace('$parameters', "\$buildParameters;\n private \$containerDir;\n private \$parameters", $code); | 968 $code = str_replace('$parameters', "\$buildParameters;\n private \$containerDir;\n private \$parameters", $code); |
982 $code = str_replace('__construct()', '__construct(array $buildParameters = array(), $containerDir = __DIR__)', $code); | 969 $code = str_replace('__construct()', '__construct(array $buildParameters = [], $containerDir = __DIR__)', $code); |
983 $code .= " \$this->buildParameters = \$buildParameters;\n"; | 970 $code .= " \$this->buildParameters = \$buildParameters;\n"; |
984 $code .= " \$this->containerDir = \$containerDir;\n"; | 971 $code .= " \$this->containerDir = \$containerDir;\n"; |
985 } | 972 } |
986 | 973 |
987 if ($this->container->isCompiled()) { | 974 if ($this->container->isCompiled()) { |
999 | 986 |
1000 if ($this->container->getParameterBag()->all()) { | 987 if ($this->container->getParameterBag()->all()) { |
1001 $code .= " \$this->parameters = \$this->getDefaultParameters();\n\n"; | 988 $code .= " \$this->parameters = \$this->getDefaultParameters();\n\n"; |
1002 } | 989 } |
1003 | 990 |
1004 $code .= " \$this->services = array();\n"; | 991 $code .= " \$this->services = [];\n"; |
1005 } else { | 992 } else { |
1006 $arguments = $this->container->getParameterBag()->all() ? 'new ParameterBag($this->getDefaultParameters())' : null; | 993 $arguments = $this->container->getParameterBag()->all() ? 'new ParameterBag($this->getDefaultParameters())' : null; |
1007 $code .= " parent::__construct($arguments);\n"; | 994 $code .= " parent::__construct($arguments);\n"; |
1008 } | 995 } |
1009 | 996 |
1097 if ($this->container->has($normalizedId)) { | 1084 if ($this->container->has($normalizedId)) { |
1098 $code .= ' '.$this->doExport($id).' => '.$this->doExport($normalizedId).",\n"; | 1085 $code .= ' '.$this->doExport($id).' => '.$this->doExport($normalizedId).",\n"; |
1099 } | 1086 } |
1100 } | 1087 } |
1101 | 1088 |
1102 return $code ? " \$this->normalizedIds = array(\n".$code." );\n" : ''; | 1089 return $code ? " \$this->normalizedIds = [\n".$code." ];\n" : ''; |
1103 } | 1090 } |
1104 | 1091 |
1105 /** | 1092 /** |
1106 * Adds the syntheticIds definition. | 1093 * Adds the syntheticIds definition. |
1107 * | 1094 * |
1116 if ($definition->isSynthetic() && 'service_container' !== $id) { | 1103 if ($definition->isSynthetic() && 'service_container' !== $id) { |
1117 $code .= ' '.$this->doExport($id)." => true,\n"; | 1104 $code .= ' '.$this->doExport($id)." => true,\n"; |
1118 } | 1105 } |
1119 } | 1106 } |
1120 | 1107 |
1121 return $code ? " \$this->syntheticIds = array(\n{$code} );\n" : ''; | 1108 return $code ? " \$this->syntheticIds = [\n{$code} ];\n" : ''; |
1122 } | 1109 } |
1123 | 1110 |
1124 /** | 1111 /** |
1125 * Adds the removedIds definition. | 1112 * Adds the removedIds definition. |
1126 * | 1113 * |
1136 } else { | 1123 } else { |
1137 $code = ''; | 1124 $code = ''; |
1138 $ids = array_keys($ids); | 1125 $ids = array_keys($ids); |
1139 sort($ids); | 1126 sort($ids); |
1140 foreach ($ids as $id) { | 1127 foreach ($ids as $id) { |
1128 if (preg_match('/^\d+_[^~]++~[._a-zA-Z\d]{7}$/', $id)) { | |
1129 continue; | |
1130 } | |
1141 $code .= ' '.$this->doExport($id)." => true,\n"; | 1131 $code .= ' '.$this->doExport($id)." => true,\n"; |
1142 } | 1132 } |
1143 | 1133 |
1144 $code = "array(\n{$code} )"; | 1134 $code = "[\n{$code} ]"; |
1145 } | 1135 } |
1146 | 1136 |
1147 return <<<EOF | 1137 return <<<EOF |
1148 | 1138 |
1149 public function getRemovedIds() | 1139 public function getRemovedIds() |
1168 if (!$definition->isSynthetic() && (!$this->asFiles || !$definition->isShared() || $this->isHotPath($definition))) { | 1158 if (!$definition->isSynthetic() && (!$this->asFiles || !$definition->isShared() || $this->isHotPath($definition))) { |
1169 $code .= ' '.$this->doExport($id).' => '.$this->doExport($this->generateMethodName($id)).",\n"; | 1159 $code .= ' '.$this->doExport($id).' => '.$this->doExport($this->generateMethodName($id)).",\n"; |
1170 } | 1160 } |
1171 } | 1161 } |
1172 | 1162 |
1173 return $code ? " \$this->methodMap = array(\n{$code} );\n" : ''; | 1163 return $code ? " \$this->methodMap = [\n{$code} ];\n" : ''; |
1174 } | 1164 } |
1175 | 1165 |
1176 /** | 1166 /** |
1177 * Adds the fileMap property definition. | 1167 * Adds the fileMap property definition. |
1178 * | 1168 * |
1187 if (!$definition->isSynthetic() && $definition->isShared() && !$this->isHotPath($definition)) { | 1177 if (!$definition->isSynthetic() && $definition->isShared() && !$this->isHotPath($definition)) { |
1188 $code .= sprintf(" %s => '%s.php',\n", $this->doExport($id), $this->generateMethodName($id)); | 1178 $code .= sprintf(" %s => '%s.php',\n", $this->doExport($id), $this->generateMethodName($id)); |
1189 } | 1179 } |
1190 } | 1180 } |
1191 | 1181 |
1192 return $code ? " \$this->fileMap = array(\n{$code} );\n" : ''; | 1182 return $code ? " \$this->fileMap = [\n{$code} ];\n" : ''; |
1193 } | 1183 } |
1194 | 1184 |
1195 /** | 1185 /** |
1196 * Adds the privates property definition. | 1186 * Adds the privates property definition. |
1197 * | 1187 * |
1219 | 1209 |
1220 if (empty($code)) { | 1210 if (empty($code)) { |
1221 return ''; | 1211 return ''; |
1222 } | 1212 } |
1223 | 1213 |
1224 $out = " \$this->privates = array(\n"; | 1214 $out = " \$this->privates = [\n"; |
1225 $out .= $code; | 1215 $out .= $code; |
1226 $out .= " );\n"; | 1216 $out .= " ];\n"; |
1227 | 1217 |
1228 return $out; | 1218 return $out; |
1229 } | 1219 } |
1230 | 1220 |
1231 /** | 1221 /** |
1234 * @return string | 1224 * @return string |
1235 */ | 1225 */ |
1236 private function addAliases() | 1226 private function addAliases() |
1237 { | 1227 { |
1238 if (!$aliases = $this->container->getAliases()) { | 1228 if (!$aliases = $this->container->getAliases()) { |
1239 return $this->container->isCompiled() ? "\n \$this->aliases = array();\n" : ''; | 1229 return $this->container->isCompiled() ? "\n \$this->aliases = [];\n" : ''; |
1240 } | 1230 } |
1241 | 1231 |
1242 $code = " \$this->aliases = array(\n"; | 1232 $code = " \$this->aliases = [\n"; |
1243 ksort($aliases); | 1233 ksort($aliases); |
1244 foreach ($aliases as $alias => $id) { | 1234 foreach ($aliases as $alias => $id) { |
1245 $id = $this->container->normalizeId($id); | 1235 $id = $this->container->normalizeId($id); |
1246 while (isset($aliases[$id])) { | 1236 while (isset($aliases[$id])) { |
1247 $id = $this->container->normalizeId($aliases[$id]); | 1237 $id = $this->container->normalizeId($aliases[$id]); |
1248 } | 1238 } |
1249 $code .= ' '.$this->doExport($alias).' => '.$this->doExport($id).",\n"; | 1239 $code .= ' '.$this->doExport($alias).' => '.$this->doExport($id).",\n"; |
1250 } | 1240 } |
1251 | 1241 |
1252 return $code." );\n"; | 1242 return $code." ];\n"; |
1253 } | 1243 } |
1254 | 1244 |
1255 private function addInlineRequires() | 1245 private function addInlineRequires() |
1256 { | 1246 { |
1257 if (!$this->hotPathTag || !$this->inlineRequires) { | 1247 if (!$this->hotPathTag || !$this->inlineRequires) { |
1258 return ''; | 1248 return ''; |
1259 } | 1249 } |
1260 | 1250 |
1261 $lineage = array(); | 1251 $lineage = []; |
1262 | 1252 |
1263 foreach ($this->container->findTaggedServiceIds($this->hotPathTag) as $id => $tags) { | 1253 foreach ($this->container->findTaggedServiceIds($this->hotPathTag) as $id => $tags) { |
1264 $definition = $this->container->getDefinition($id); | 1254 $definition = $this->container->getDefinition($id); |
1265 $inlinedDefinitions = $this->getDefinitionsFromArguments(array($definition)); | 1255 $inlinedDefinitions = $this->getDefinitionsFromArguments([$definition]); |
1266 | 1256 |
1267 foreach ($inlinedDefinitions as $def) { | 1257 foreach ($inlinedDefinitions as $def) { |
1268 if (is_string($class = is_array($factory = $def->getFactory()) && is_string($factory[0]) ? $factory[0] : $def->getClass())) { | 1258 if (\is_string($class = \is_array($factory = $def->getFactory()) && \is_string($factory[0]) ? $factory[0] : $def->getClass())) { |
1269 $this->collectLineage($class, $lineage); | 1259 $this->collectLineage($class, $lineage); |
1270 } | 1260 } |
1271 } | 1261 } |
1272 } | 1262 } |
1273 | 1263 |
1292 { | 1282 { |
1293 if (!$this->container->getParameterBag()->all()) { | 1283 if (!$this->container->getParameterBag()->all()) { |
1294 return ''; | 1284 return ''; |
1295 } | 1285 } |
1296 | 1286 |
1297 $php = array(); | 1287 $php = []; |
1298 $dynamicPhp = array(); | 1288 $dynamicPhp = []; |
1299 $normalizedParams = array(); | 1289 $normalizedParams = []; |
1300 | 1290 |
1301 foreach ($this->container->getParameterBag()->all() as $key => $value) { | 1291 foreach ($this->container->getParameterBag()->all() as $key => $value) { |
1302 if ($key !== $resolvedKey = $this->container->resolveEnvPlaceholders($key)) { | 1292 if ($key !== $resolvedKey = $this->container->resolveEnvPlaceholders($key)) { |
1303 throw new InvalidArgumentException(sprintf('Parameter name cannot use env parameters: %s.', $resolvedKey)); | 1293 throw new InvalidArgumentException(sprintf('Parameter name cannot use env parameters: %s.', $resolvedKey)); |
1304 } | 1294 } |
1305 if ($key !== $lcKey = strtolower($key)) { | 1295 if ($key !== $lcKey = strtolower($key)) { |
1306 $normalizedParams[] = sprintf(' %s => %s,', $this->export($lcKey), $this->export($key)); | 1296 $normalizedParams[] = sprintf(' %s => %s,', $this->export($lcKey), $this->export($key)); |
1307 } | 1297 } |
1308 $export = $this->exportParameters(array($value)); | 1298 $export = $this->exportParameters([$value]); |
1309 $export = explode('0 => ', substr(rtrim($export, " )\n"), 7, -1), 2); | 1299 $export = explode('0 => ', substr(rtrim($export, " ]\n"), 2, -1), 2); |
1310 | 1300 |
1311 if (preg_match("/\\\$this->(?:getEnv\('(?:\w++:)*+\w++'\)|targetDirs\[\d++\])/", $export[1])) { | 1301 if (preg_match("/\\\$this->(?:getEnv\('(?:\w++:)*+\w++'\)|targetDirs\[\d++\])/", $export[1])) { |
1312 $dynamicPhp[$key] = sprintf('%scase %s: $value = %s; break;', $export[0], $this->export($key), $export[1]); | 1302 $dynamicPhp[$key] = sprintf('%scase %s: $value = %s; break;', $export[0], $this->export($key), $export[1]); |
1313 } else { | 1303 } else { |
1314 $php[] = sprintf('%s%s => %s,', $export[0], $this->export($key), $export[1]); | 1304 $php[] = sprintf('%s%s => %s,', $export[0], $this->export($key), $export[1]); |
1315 } | 1305 } |
1316 } | 1306 } |
1317 $parameters = sprintf("array(\n%s\n%s)", implode("\n", $php), str_repeat(' ', 8)); | 1307 |
1308 $parameters = sprintf("[\n%s\n%s]", implode("\n", $php), str_repeat(' ', 8)); | |
1318 | 1309 |
1319 $code = ''; | 1310 $code = ''; |
1320 if ($this->container->isCompiled()) { | 1311 if ($this->container->isCompiled()) { |
1321 $code .= <<<'EOF' | 1312 $code .= <<<'EOF' |
1322 | 1313 |
1376 if (!$this->asFiles) { | 1367 if (!$this->asFiles) { |
1377 $code = preg_replace('/^.*buildParameters.*\n.*\n.*\n/m', '', $code); | 1368 $code = preg_replace('/^.*buildParameters.*\n.*\n.*\n/m', '', $code); |
1378 } | 1369 } |
1379 | 1370 |
1380 if ($dynamicPhp) { | 1371 if ($dynamicPhp) { |
1381 $loadedDynamicParameters = $this->exportParameters(array_combine(array_keys($dynamicPhp), array_fill(0, count($dynamicPhp), false)), '', 8); | 1372 $loadedDynamicParameters = $this->exportParameters(array_combine(array_keys($dynamicPhp), array_fill(0, \count($dynamicPhp), false)), '', 8); |
1382 $getDynamicParameter = <<<'EOF' | 1373 $getDynamicParameter = <<<'EOF' |
1383 switch ($name) { | 1374 switch ($name) { |
1384 %s | 1375 %s |
1385 default: throw new InvalidArgumentException(sprintf('The dynamic parameter "%%s" must be defined.', $name)); | 1376 default: throw new InvalidArgumentException(sprintf('The dynamic parameter "%%s" must be defined.', $name)); |
1386 } | 1377 } |
1388 | 1379 |
1389 return $this->dynamicParameters[$name] = $value; | 1380 return $this->dynamicParameters[$name] = $value; |
1390 EOF; | 1381 EOF; |
1391 $getDynamicParameter = sprintf($getDynamicParameter, implode("\n", $dynamicPhp)); | 1382 $getDynamicParameter = sprintf($getDynamicParameter, implode("\n", $dynamicPhp)); |
1392 } else { | 1383 } else { |
1393 $loadedDynamicParameters = 'array()'; | 1384 $loadedDynamicParameters = '[]'; |
1394 $getDynamicParameter = str_repeat(' ', 8).'throw new InvalidArgumentException(sprintf(\'The dynamic parameter "%s" must be defined.\', $name));'; | 1385 $getDynamicParameter = str_repeat(' ', 8).'throw new InvalidArgumentException(sprintf(\'The dynamic parameter "%s" must be defined.\', $name));'; |
1395 } | 1386 } |
1396 | 1387 |
1397 $code .= <<<EOF | 1388 $code .= <<<EOF |
1398 | 1389 |
1399 private \$loadedDynamicParameters = {$loadedDynamicParameters}; | 1390 private \$loadedDynamicParameters = {$loadedDynamicParameters}; |
1400 private \$dynamicParameters = array(); | 1391 private \$dynamicParameters = []; |
1401 | 1392 |
1402 /*{$this->docStar} | 1393 /*{$this->docStar} |
1403 * Computes a dynamic parameter. | 1394 * Computes a dynamic parameter. |
1404 * | 1395 * |
1405 * @param string The name of the dynamic parameter to load | 1396 * @param string \$name The name of the dynamic parameter to load |
1406 * | 1397 * |
1407 * @return mixed The value of the dynamic parameter | 1398 * @return mixed The value of the dynamic parameter |
1408 * | 1399 * |
1409 * @throws InvalidArgumentException When the dynamic parameter does not exist | 1400 * @throws InvalidArgumentException When the dynamic parameter does not exist |
1410 */ | 1401 */ |
1414 } | 1405 } |
1415 | 1406 |
1416 | 1407 |
1417 EOF; | 1408 EOF; |
1418 | 1409 |
1419 $code .= ' private $normalizedParameterNames = '.($normalizedParams ? sprintf("array(\n%s\n );", implode("\n", $normalizedParams)) : 'array();')."\n"; | 1410 $code .= ' private $normalizedParameterNames = '.($normalizedParams ? sprintf("[\n%s\n ];", implode("\n", $normalizedParams)) : '[];')."\n"; |
1420 $code .= <<<'EOF' | 1411 $code .= <<<'EOF' |
1421 | 1412 |
1422 private function normalizeParameterName($name) | 1413 private function normalizeParameterName($name) |
1423 { | 1414 { |
1424 if (isset($this->normalizedParameterNames[$normalizedName = strtolower($name)]) || isset($this->parameters[$normalizedName]) || array_key_exists($normalizedName, $this->parameters)) { | 1415 if (isset($this->normalizedParameterNames[$normalizedName = strtolower($name)]) || isset($this->parameters[$normalizedName]) || array_key_exists($normalizedName, $this->parameters)) { |
1466 * | 1457 * |
1467 * @throws InvalidArgumentException | 1458 * @throws InvalidArgumentException |
1468 */ | 1459 */ |
1469 private function exportParameters(array $parameters, $path = '', $indent = 12) | 1460 private function exportParameters(array $parameters, $path = '', $indent = 12) |
1470 { | 1461 { |
1471 $php = array(); | 1462 $php = []; |
1472 foreach ($parameters as $key => $value) { | 1463 foreach ($parameters as $key => $value) { |
1473 if (is_array($value)) { | 1464 if (\is_array($value)) { |
1474 $value = $this->exportParameters($value, $path.'/'.$key, $indent + 4); | 1465 $value = $this->exportParameters($value, $path.'/'.$key, $indent + 4); |
1475 } elseif ($value instanceof ArgumentInterface) { | 1466 } elseif ($value instanceof ArgumentInterface) { |
1476 throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain special arguments. "%s" found in "%s".', get_class($value), $path.'/'.$key)); | 1467 throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain special arguments. "%s" found in "%s".', \get_class($value), $path.'/'.$key)); |
1477 } elseif ($value instanceof Variable) { | 1468 } elseif ($value instanceof Variable) { |
1478 throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain variable references. Variable "%s" found in "%s".', $value, $path.'/'.$key)); | 1469 throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain variable references. Variable "%s" found in "%s".', $value, $path.'/'.$key)); |
1479 } elseif ($value instanceof Definition) { | 1470 } elseif ($value instanceof Definition) { |
1480 throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain service definitions. Definition for "%s" found in "%s".', $value->getClass(), $path.'/'.$key)); | 1471 throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain service definitions. Definition for "%s" found in "%s".', $value->getClass(), $path.'/'.$key)); |
1481 } elseif ($value instanceof Reference) { | 1472 } elseif ($value instanceof Reference) { |
1487 } | 1478 } |
1488 | 1479 |
1489 $php[] = sprintf('%s%s => %s,', str_repeat(' ', $indent), $this->export($key), $value); | 1480 $php[] = sprintf('%s%s => %s,', str_repeat(' ', $indent), $this->export($key), $value); |
1490 } | 1481 } |
1491 | 1482 |
1492 return sprintf("array(\n%s\n%s)", implode("\n", $php), str_repeat(' ', $indent - 4)); | 1483 return sprintf("[\n%s\n%s]", implode("\n", $php), str_repeat(' ', $indent - 4)); |
1493 } | 1484 } |
1494 | 1485 |
1495 /** | 1486 /** |
1496 * Ends the class definition. | 1487 * Ends the class definition. |
1497 * | 1488 * |
1528 /** | 1519 /** |
1529 * Get the conditions to execute for conditional services. | 1520 * Get the conditions to execute for conditional services. |
1530 * | 1521 * |
1531 * @param string $value | 1522 * @param string $value |
1532 * | 1523 * |
1533 * @return null|string | 1524 * @return string|null |
1534 */ | 1525 */ |
1535 private function getServiceConditionals($value) | 1526 private function getServiceConditionals($value) |
1536 { | 1527 { |
1537 $conditions = array(); | 1528 $conditions = []; |
1538 foreach (ContainerBuilder::getInitializedConditionals($value) as $service) { | 1529 foreach (ContainerBuilder::getInitializedConditionals($value) as $service) { |
1539 if (!$this->container->hasDefinition($service)) { | 1530 if (!$this->container->hasDefinition($service)) { |
1540 return 'false'; | 1531 return 'false'; |
1541 } | 1532 } |
1542 $conditions[] = sprintf("isset(\$this->services['%s'])", $service); | 1533 $conditions[] = sprintf("isset(\$this->services['%s'])", $service); |
1554 } | 1545 } |
1555 | 1546 |
1556 return implode(' && ', $conditions); | 1547 return implode(' && ', $conditions); |
1557 } | 1548 } |
1558 | 1549 |
1559 /** | 1550 private function getDefinitionsFromArguments(array $arguments, \SplObjectStorage $definitions = null, array &$calls = []) |
1560 * Builds service calls from arguments. | 1551 { |
1561 */ | 1552 if (null === $definitions) { |
1562 private function getServiceCallsFromArguments(array $arguments, array &$calls, $isPreInstance, $callerId, array &$behavior = array(), $step = 1) | 1553 $definitions = new \SplObjectStorage(); |
1563 { | 1554 } |
1555 | |
1564 foreach ($arguments as $argument) { | 1556 foreach ($arguments as $argument) { |
1565 if (is_array($argument)) { | 1557 if (\is_array($argument)) { |
1566 $this->getServiceCallsFromArguments($argument, $calls, $isPreInstance, $callerId, $behavior, $step); | 1558 $this->getDefinitionsFromArguments($argument, $definitions, $calls); |
1567 } elseif ($argument instanceof Reference) { | 1559 } elseif ($argument instanceof Reference) { |
1568 $id = $this->container->normalizeId($argument); | 1560 $id = $this->container->normalizeId($argument); |
1569 | 1561 |
1570 if (!isset($calls[$id])) { | 1562 if (!isset($calls[$id])) { |
1571 $calls[$id] = (int) ($isPreInstance && isset($this->circularReferences[$callerId][$id])); | 1563 $calls[$id] = [0, $argument->getInvalidBehavior()]; |
1572 } | |
1573 if (!isset($behavior[$id])) { | |
1574 $behavior[$id] = $argument->getInvalidBehavior(); | |
1575 } else { | 1564 } else { |
1576 $behavior[$id] = min($behavior[$id], $argument->getInvalidBehavior()); | 1565 $calls[$id][1] = min($calls[$id][1], $argument->getInvalidBehavior()); |
1577 } | 1566 } |
1578 | 1567 |
1579 $calls[$id] += $step; | 1568 ++$calls[$id][0]; |
1580 } | |
1581 } | |
1582 } | |
1583 | |
1584 private function getDefinitionsFromArguments(array $arguments, \SplObjectStorage $definitions = null) | |
1585 { | |
1586 if (null === $definitions) { | |
1587 $definitions = new \SplObjectStorage(); | |
1588 } | |
1589 | |
1590 foreach ($arguments as $argument) { | |
1591 if (is_array($argument)) { | |
1592 $this->getDefinitionsFromArguments($argument, $definitions); | |
1593 } elseif (!$argument instanceof Definition) { | 1569 } elseif (!$argument instanceof Definition) { |
1594 // no-op | 1570 // no-op |
1595 } elseif (isset($definitions[$argument])) { | 1571 } elseif (isset($definitions[$argument])) { |
1596 $definitions[$argument] = 1 + $definitions[$argument]; | 1572 $definitions[$argument] = 1 + $definitions[$argument]; |
1597 } else { | 1573 } else { |
1598 $definitions[$argument] = 1; | 1574 $definitions[$argument] = 1; |
1599 $this->getDefinitionsFromArguments($argument->getArguments(), $definitions); | 1575 $arguments = [$argument->getArguments(), $argument->getFactory(), $argument->getProperties(), $argument->getMethodCalls(), $argument->getConfigurator()]; |
1600 $this->getDefinitionsFromArguments(array($argument->getFactory()), $definitions); | 1576 $this->getDefinitionsFromArguments($arguments, $definitions, $calls); |
1601 $this->getDefinitionsFromArguments($argument->getProperties(), $definitions); | |
1602 $this->getDefinitionsFromArguments($argument->getMethodCalls(), $definitions); | |
1603 $this->getDefinitionsFromArguments(array($argument->getConfigurator()), $definitions); | |
1604 // move current definition last in the list | |
1605 $nbOccurences = $definitions[$argument]; | |
1606 unset($definitions[$argument]); | |
1607 $definitions[$argument] = $nbOccurences; | |
1608 } | 1577 } |
1609 } | 1578 } |
1610 | 1579 |
1611 return $definitions; | 1580 return $definitions; |
1612 } | |
1613 | |
1614 /** | |
1615 * Checks if a service id has a reference. | |
1616 * | |
1617 * @param string $id | |
1618 * @param array $arguments | |
1619 * @param bool $deep | |
1620 * @param array $visited | |
1621 * | |
1622 * @return bool | |
1623 */ | |
1624 private function hasReference($id, array $arguments, $deep = false, array &$visited = array()) | |
1625 { | |
1626 if (!isset($this->circularReferences[$id])) { | |
1627 return false; | |
1628 } | |
1629 | |
1630 foreach ($arguments as $argument) { | |
1631 if (is_array($argument)) { | |
1632 if ($this->hasReference($id, $argument, $deep, $visited)) { | |
1633 return true; | |
1634 } | |
1635 | |
1636 continue; | |
1637 } elseif ($argument instanceof Reference) { | |
1638 $argumentId = $this->container->normalizeId($argument); | |
1639 if ($id === $argumentId) { | |
1640 return true; | |
1641 } | |
1642 | |
1643 if (!$deep || isset($visited[$argumentId]) || !isset($this->circularReferences[$id][$argumentId])) { | |
1644 continue; | |
1645 } | |
1646 | |
1647 $visited[$argumentId] = true; | |
1648 | |
1649 $service = $this->container->getDefinition($argumentId); | |
1650 } elseif ($argument instanceof Definition) { | |
1651 $service = $argument; | |
1652 } else { | |
1653 continue; | |
1654 } | |
1655 | |
1656 // if the proxy manager is enabled, disable searching for references in lazy services, | |
1657 // as these services will be instantiated lazily and don't have direct related references. | |
1658 if ($service->isLazy() && !$this->getProxyDumper() instanceof NullDumper) { | |
1659 continue; | |
1660 } | |
1661 | |
1662 if ($this->hasReference($id, array($service->getArguments(), $service->getFactory(), $service->getProperties(), $service->getMethodCalls(), $service->getConfigurator()), $deep, $visited)) { | |
1663 return true; | |
1664 } | |
1665 } | |
1666 | |
1667 return false; | |
1668 } | 1581 } |
1669 | 1582 |
1670 /** | 1583 /** |
1671 * Dumps values. | 1584 * Dumps values. |
1672 * | 1585 * |
1677 * | 1590 * |
1678 * @throws RuntimeException | 1591 * @throws RuntimeException |
1679 */ | 1592 */ |
1680 private function dumpValue($value, $interpolate = true) | 1593 private function dumpValue($value, $interpolate = true) |
1681 { | 1594 { |
1682 if (is_array($value)) { | 1595 if (\is_array($value)) { |
1683 if ($value && $interpolate && false !== $param = array_search($value, $this->container->getParameterBag()->all(), true)) { | 1596 if ($value && $interpolate && false !== $param = array_search($value, $this->container->getParameterBag()->all(), true)) { |
1684 return $this->dumpValue("%$param%"); | 1597 return $this->dumpValue("%$param%"); |
1685 } | 1598 } |
1686 $code = array(); | 1599 $code = []; |
1687 foreach ($value as $k => $v) { | 1600 foreach ($value as $k => $v) { |
1688 $code[] = sprintf('%s => %s', $this->dumpValue($k, $interpolate), $this->dumpValue($v, $interpolate)); | 1601 $code[] = sprintf('%s => %s', $this->dumpValue($k, $interpolate), $this->dumpValue($v, $interpolate)); |
1689 } | 1602 } |
1690 | 1603 |
1691 return sprintf('array(%s)', implode(', ', $code)); | 1604 return sprintf('[%s]', implode(', ', $code)); |
1692 } elseif ($value instanceof ArgumentInterface) { | 1605 } elseif ($value instanceof ArgumentInterface) { |
1693 $scope = array($this->definitionVariables, $this->referenceVariables, $this->variableCount); | 1606 $scope = [$this->definitionVariables, $this->referenceVariables]; |
1694 $this->definitionVariables = $this->referenceVariables = null; | 1607 $this->definitionVariables = $this->referenceVariables = null; |
1695 | 1608 |
1696 try { | 1609 try { |
1697 if ($value instanceof ServiceClosureArgument) { | 1610 if ($value instanceof ServiceClosureArgument) { |
1698 $value = $value->getValues()[0]; | 1611 $value = $value->getValues()[0]; |
1706 | 1619 |
1707 return sprintf("function () {\n %s\n }", $code); | 1620 return sprintf("function () {\n %s\n }", $code); |
1708 } | 1621 } |
1709 | 1622 |
1710 if ($value instanceof IteratorArgument) { | 1623 if ($value instanceof IteratorArgument) { |
1711 $operands = array(0); | 1624 $operands = [0]; |
1712 $code = array(); | 1625 $code = []; |
1713 $code[] = 'new RewindableGenerator(function () {'; | 1626 $code[] = 'new RewindableGenerator(function () {'; |
1714 | 1627 |
1715 if (!$values = $value->getValues()) { | 1628 if (!$values = $value->getValues()) { |
1716 $code[] = ' return new \EmptyIterator();'; | 1629 $code[] = ' return new \EmptyIterator();'; |
1717 } else { | 1630 } else { |
1718 $countCode = array(); | 1631 $countCode = []; |
1719 $countCode[] = 'function () {'; | 1632 $countCode[] = 'function () {'; |
1720 | 1633 |
1721 foreach ($values as $k => $v) { | 1634 foreach ($values as $k => $v) { |
1722 ($c = $this->getServiceConditionals($v)) ? $operands[] = "(int) ($c)" : ++$operands[0]; | 1635 ($c = $this->getServiceConditionals($v)) ? $operands[] = "(int) ($c)" : ++$operands[0]; |
1723 $v = $this->wrapServiceConditionals($v, sprintf(" yield %s => %s;\n", $this->dumpValue($k, $interpolate), $this->dumpValue($v, $interpolate))); | 1636 $v = $this->wrapServiceConditionals($v, sprintf(" yield %s => %s;\n", $this->dumpValue($k, $interpolate), $this->dumpValue($v, $interpolate))); |
1730 | 1643 |
1731 $countCode[] = sprintf(' return %s;', implode(' + ', $operands)); | 1644 $countCode[] = sprintf(' return %s;', implode(' + ', $operands)); |
1732 $countCode[] = ' }'; | 1645 $countCode[] = ' }'; |
1733 } | 1646 } |
1734 | 1647 |
1735 $code[] = sprintf(' }, %s)', count($operands) > 1 ? implode("\n", $countCode) : $operands[0]); | 1648 $code[] = sprintf(' }, %s)', \count($operands) > 1 ? implode("\n", $countCode) : $operands[0]); |
1736 | 1649 |
1737 return implode("\n", $code); | 1650 return implode("\n", $code); |
1738 } | 1651 } |
1739 } finally { | 1652 } finally { |
1740 list($this->definitionVariables, $this->referenceVariables, $this->variableCount) = $scope; | 1653 list($this->definitionVariables, $this->referenceVariables) = $scope; |
1741 } | 1654 } |
1742 } elseif ($value instanceof Definition) { | 1655 } elseif ($value instanceof Definition) { |
1743 if (null !== $this->definitionVariables && $this->definitionVariables->contains($value)) { | 1656 if (null !== $this->definitionVariables && $this->definitionVariables->contains($value)) { |
1744 return $this->dumpValue($this->definitionVariables[$value], $interpolate); | 1657 return $this->dumpValue($this->definitionVariables[$value], $interpolate); |
1745 } | 1658 } |
1751 } | 1664 } |
1752 if (null !== $value->getConfigurator()) { | 1665 if (null !== $value->getConfigurator()) { |
1753 throw new RuntimeException('Cannot dump definitions which have a configurator.'); | 1666 throw new RuntimeException('Cannot dump definitions which have a configurator.'); |
1754 } | 1667 } |
1755 | 1668 |
1756 $arguments = array(); | 1669 $arguments = []; |
1757 foreach ($value->getArguments() as $argument) { | 1670 foreach ($value->getArguments() as $argument) { |
1758 $arguments[] = $this->dumpValue($argument); | 1671 $arguments[] = $this->dumpValue($argument); |
1759 } | 1672 } |
1760 | 1673 |
1761 if (null !== $value->getFactory()) { | 1674 if (null !== $value->getFactory()) { |
1762 $factory = $value->getFactory(); | 1675 $factory = $value->getFactory(); |
1763 | 1676 |
1764 if (is_string($factory)) { | 1677 if (\is_string($factory)) { |
1765 return sprintf('%s(%s)', $this->dumpLiteralClass($this->dumpValue($factory)), implode(', ', $arguments)); | 1678 return sprintf('%s(%s)', $this->dumpLiteralClass($this->dumpValue($factory)), implode(', ', $arguments)); |
1766 } | 1679 } |
1767 | 1680 |
1768 if (is_array($factory)) { | 1681 if (\is_array($factory)) { |
1769 if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $factory[1])) { | 1682 if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $factory[1])) { |
1770 throw new RuntimeException(sprintf('Cannot dump definition because of invalid factory method (%s)', $factory[1] ?: 'n/a')); | 1683 throw new RuntimeException(sprintf('Cannot dump definition because of invalid factory method (%s)', $factory[1] ?: 'n/a')); |
1771 } | 1684 } |
1772 | 1685 |
1773 $class = $this->dumpValue($factory[0]); | 1686 $class = $this->dumpValue($factory[0]); |
1774 if (is_string($factory[0])) { | 1687 if (\is_string($factory[0])) { |
1775 return sprintf('%s::%s(%s)', $this->dumpLiteralClass($class), $factory[1], implode(', ', $arguments)); | 1688 return sprintf('%s::%s(%s)', $this->dumpLiteralClass($class), $factory[1], implode(', ', $arguments)); |
1776 } | 1689 } |
1777 | 1690 |
1778 if ($factory[0] instanceof Definition) { | 1691 if ($factory[0] instanceof Definition) { |
1779 if (0 === strpos($class, 'new ')) { | 1692 if (0 === strpos($class, 'new ')) { |
1780 return sprintf('(%s)->%s(%s)', $class, $factory[1], implode(', ', $arguments)); | 1693 return sprintf('(%s)->%s(%s)', $class, $factory[1], implode(', ', $arguments)); |
1781 } | 1694 } |
1782 | 1695 |
1783 return sprintf("\\call_user_func(array(%s, '%s')%s)", $class, $factory[1], count($arguments) > 0 ? ', '.implode(', ', $arguments) : ''); | 1696 return sprintf("\\call_user_func([%s, '%s']%s)", $class, $factory[1], \count($arguments) > 0 ? ', '.implode(', ', $arguments) : ''); |
1784 } | 1697 } |
1785 | 1698 |
1786 if ($factory[0] instanceof Reference) { | 1699 if ($factory[0] instanceof Reference) { |
1787 return sprintf('%s->%s(%s)', $class, $factory[1], implode(', ', $arguments)); | 1700 return sprintf('%s->%s(%s)', $class, $factory[1], implode(', ', $arguments)); |
1788 } | 1701 } |
1805 return $this->dumpValue($this->referenceVariables[$id], $interpolate); | 1718 return $this->dumpValue($this->referenceVariables[$id], $interpolate); |
1806 } | 1719 } |
1807 | 1720 |
1808 return $this->getServiceCall($id, $value); | 1721 return $this->getServiceCall($id, $value); |
1809 } elseif ($value instanceof Expression) { | 1722 } elseif ($value instanceof Expression) { |
1810 return $this->getExpressionLanguage()->compile((string) $value, array('this' => 'container')); | 1723 return $this->getExpressionLanguage()->compile((string) $value, ['this' => 'container']); |
1811 } elseif ($value instanceof Parameter) { | 1724 } elseif ($value instanceof Parameter) { |
1812 return $this->dumpParameter($value); | 1725 return $this->dumpParameter($value); |
1813 } elseif (true === $interpolate && is_string($value)) { | 1726 } elseif (true === $interpolate && \is_string($value)) { |
1814 if (preg_match('/^%([^%]+)%$/', $value, $match)) { | 1727 if (preg_match('/^%([^%]+)%$/', $value, $match)) { |
1815 // we do this to deal with non string values (Boolean, integer, ...) | 1728 // we do this to deal with non string values (Boolean, integer, ...) |
1816 // the preg_replace_callback converts them to strings | 1729 // the preg_replace_callback converts them to strings |
1817 return $this->dumpParameter($match[1]); | 1730 return $this->dumpParameter($match[1]); |
1818 } else { | 1731 } else { |
1822 | 1735 |
1823 $code = str_replace('%%', '%', preg_replace_callback('/(?<!%)(%)([^%]+)\1/', $replaceParameters, $this->export($value))); | 1736 $code = str_replace('%%', '%', preg_replace_callback('/(?<!%)(%)([^%]+)\1/', $replaceParameters, $this->export($value))); |
1824 | 1737 |
1825 return $code; | 1738 return $code; |
1826 } | 1739 } |
1827 } elseif (is_object($value) || is_resource($value)) { | 1740 } elseif (\is_object($value) || \is_resource($value)) { |
1828 throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.'); | 1741 throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.'); |
1829 } | 1742 } |
1830 | 1743 |
1831 return $this->export($value); | 1744 return $this->export($value); |
1832 } | 1745 } |
1865 { | 1778 { |
1866 if ($this->container->isCompiled() && $this->container->hasParameter($name)) { | 1779 if ($this->container->isCompiled() && $this->container->hasParameter($name)) { |
1867 $value = $this->container->getParameter($name); | 1780 $value = $this->container->getParameter($name); |
1868 $dumpedValue = $this->dumpValue($value, false); | 1781 $dumpedValue = $this->dumpValue($value, false); |
1869 | 1782 |
1870 if (!$value || !is_array($value)) { | 1783 if (!$value || !\is_array($value)) { |
1871 return $dumpedValue; | 1784 return $dumpedValue; |
1872 } | 1785 } |
1873 | 1786 |
1874 if (!preg_match("/\\\$this->(?:getEnv\('(?:\w++:)*+\w++'\)|targetDirs\[\d++\])/", $dumpedValue)) { | 1787 if (!preg_match("/\\\$this->(?:getEnv\('(?:\w++:)*+\w++'\)|targetDirs\[\d++\])/", $dumpedValue)) { |
1875 return sprintf("\$this->parameters['%s']", $name); | 1788 return sprintf("\$this->parameters['%s']", $name); |
1896 | 1809 |
1897 if ('service_container' === $id) { | 1810 if ('service_container' === $id) { |
1898 return '$this'; | 1811 return '$this'; |
1899 } | 1812 } |
1900 | 1813 |
1901 if ($this->container->hasDefinition($id) && ($definition = $this->container->getDefinition($id)) && !$definition->isSynthetic()) { | 1814 if ($this->container->hasDefinition($id) && $definition = $this->container->getDefinition($id)) { |
1902 if (null !== $reference && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $reference->getInvalidBehavior()) { | 1815 if ($definition->isSynthetic()) { |
1816 $code = sprintf('$this->get(\'%s\'%s)', $id, null !== $reference ? ', '.$reference->getInvalidBehavior() : ''); | |
1817 } elseif (null !== $reference && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $reference->getInvalidBehavior()) { | |
1903 $code = 'null'; | 1818 $code = 'null'; |
1904 if (!$definition->isShared()) { | 1819 if (!$definition->isShared()) { |
1905 return $code; | 1820 return $code; |
1906 } | 1821 } |
1907 } elseif ($this->isTrivialInstance($definition)) { | 1822 } elseif ($this->isTrivialInstance($definition)) { |
1908 $code = substr($this->addNewInstance($definition, '', '', $id), 8, -2); | 1823 $code = substr($this->addNewInstance($definition, '', '', $id), 8, -2); |
1909 if ($definition->isShared()) { | 1824 if ($definition->isShared()) { |
1910 $code = sprintf('$this->services[\'%s\'] = %s', $id, $code); | 1825 $code = sprintf('$this->services[\'%s\'] = %s', $id, $code); |
1911 } | 1826 } |
1827 $code = "($code)"; | |
1912 } elseif ($this->asFiles && $definition->isShared() && !$this->isHotPath($definition)) { | 1828 } elseif ($this->asFiles && $definition->isShared() && !$this->isHotPath($definition)) { |
1913 $code = sprintf("\$this->load('%s.php')", $this->generateMethodName($id)); | 1829 $code = sprintf("\$this->load('%s.php')", $this->generateMethodName($id)); |
1914 } else { | 1830 } else { |
1915 $code = sprintf('$this->%s()', $this->generateMethodName($id)); | 1831 $code = sprintf('$this->%s()', $this->generateMethodName($id)); |
1916 } | 1832 } |
1932 * | 1848 * |
1933 * @param string $class the container base class | 1849 * @param string $class the container base class |
1934 */ | 1850 */ |
1935 private function initializeMethodNamesMap($class) | 1851 private function initializeMethodNamesMap($class) |
1936 { | 1852 { |
1937 $this->serviceIdToMethodNameMap = array(); | 1853 $this->serviceIdToMethodNameMap = []; |
1938 $this->usedMethodNames = array(); | 1854 $this->usedMethodNames = []; |
1939 | 1855 |
1940 if ($reflectionClass = $this->container->getReflectionClass($class)) { | 1856 if ($reflectionClass = $this->container->getReflectionClass($class)) { |
1941 foreach ($reflectionClass->getMethods() as $method) { | 1857 foreach ($reflectionClass->getMethods() as $method) { |
1942 $this->usedMethodNames[strtolower($method->getName())] = true; | 1858 $this->usedMethodNames[strtolower($method->getName())] = true; |
1943 } | 1859 } |
1982 * @return string | 1898 * @return string |
1983 */ | 1899 */ |
1984 private function getNextVariableName() | 1900 private function getNextVariableName() |
1985 { | 1901 { |
1986 $firstChars = self::FIRST_CHARS; | 1902 $firstChars = self::FIRST_CHARS; |
1987 $firstCharsLength = strlen($firstChars); | 1903 $firstCharsLength = \strlen($firstChars); |
1988 $nonFirstChars = self::NON_FIRST_CHARS; | 1904 $nonFirstChars = self::NON_FIRST_CHARS; |
1989 $nonFirstCharsLength = strlen($nonFirstChars); | 1905 $nonFirstCharsLength = \strlen($nonFirstChars); |
1990 | 1906 |
1991 while (true) { | 1907 while (true) { |
1992 $name = ''; | 1908 $name = ''; |
1993 $i = $this->variableCount; | 1909 $i = $this->variableCount; |
1994 | 1910 |
2004 } | 1920 } |
2005 | 1921 |
2006 ++$this->variableCount; | 1922 ++$this->variableCount; |
2007 | 1923 |
2008 // check that the name is not reserved | 1924 // check that the name is not reserved |
2009 if (in_array($name, $this->reservedVariables, true)) { | 1925 if (\in_array($name, $this->reservedVariables, true)) { |
2010 continue; | 1926 continue; |
2011 } | 1927 } |
2012 | 1928 |
2013 return $name; | 1929 return $name; |
2014 } | 1930 } |
2046 return $this->hotPathTag && $definition->hasTag($this->hotPathTag) && !$definition->isDeprecated(); | 1962 return $this->hotPathTag && $definition->hasTag($this->hotPathTag) && !$definition->isDeprecated(); |
2047 } | 1963 } |
2048 | 1964 |
2049 private function export($value) | 1965 private function export($value) |
2050 { | 1966 { |
2051 if (null !== $this->targetDirRegex && is_string($value) && preg_match($this->targetDirRegex, $value, $matches, PREG_OFFSET_CAPTURE)) { | 1967 if (null !== $this->targetDirRegex && \is_string($value) && preg_match($this->targetDirRegex, $value, $matches, PREG_OFFSET_CAPTURE)) { |
2052 $prefix = $matches[0][1] ? $this->doExport(substr($value, 0, $matches[0][1]), true).'.' : ''; | 1968 $prefix = $matches[0][1] ? $this->doExport(substr($value, 0, $matches[0][1]), true).'.' : ''; |
2053 $suffix = $matches[0][1] + strlen($matches[0][0]); | 1969 $suffix = $matches[0][1] + \strlen($matches[0][0]); |
2054 $suffix = isset($value[$suffix]) ? '.'.$this->doExport(substr($value, $suffix), true) : ''; | 1970 $suffix = isset($value[$suffix]) ? '.'.$this->doExport(substr($value, $suffix), true) : ''; |
2055 $dirname = $this->asFiles ? '$this->containerDir' : '__DIR__'; | 1971 $dirname = $this->asFiles ? '$this->containerDir' : '__DIR__'; |
2056 $offset = 1 + $this->targetDirMaxMatches - count($matches); | 1972 $offset = 1 + $this->targetDirMaxMatches - \count($matches); |
2057 | 1973 |
2058 if ($this->asFiles || 0 < $offset) { | 1974 if ($this->asFiles || 0 < $offset) { |
2059 $dirname = sprintf('$this->targetDirs[%d]', $offset); | 1975 $dirname = sprintf('$this->targetDirs[%d]', $offset); |
2060 } | 1976 } |
2061 | 1977 |
2069 return $this->doExport($value, true); | 1985 return $this->doExport($value, true); |
2070 } | 1986 } |
2071 | 1987 |
2072 private function doExport($value, $resolveEnv = false) | 1988 private function doExport($value, $resolveEnv = false) |
2073 { | 1989 { |
2074 if (is_string($value) && false !== strpos($value, "\n")) { | 1990 if (\is_string($value) && false !== strpos($value, "\n")) { |
2075 $cleanParts = explode("\n", $value); | 1991 $cleanParts = explode("\n", $value); |
2076 $cleanParts = array_map(function ($part) { return var_export($part, true); }, $cleanParts); | 1992 $cleanParts = array_map(function ($part) { return var_export($part, true); }, $cleanParts); |
2077 $export = implode('."\n".', $cleanParts); | 1993 $export = implode('."\n".', $cleanParts); |
2078 } else { | 1994 } else { |
2079 $export = var_export($value, true); | 1995 $export = var_export($value, true); |