825e117ccc0164e4b0a4d7b7864170f8fb831eda
[yaffs-website] / vendor / symfony / dependency-injection / Compiler / FactoryReturnTypePass.php
1 <?php
2
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Symfony\Component\DependencyInjection\Compiler;
13
14 use Symfony\Component\DependencyInjection\ContainerBuilder;
15 use Symfony\Component\DependencyInjection\Definition;
16 use Symfony\Component\DependencyInjection\Reference;
17
18 /**
19  * @author Guilhem N. <egetick@gmail.com>
20  *
21  * @deprecated since version 3.3, to be removed in 4.0.
22  */
23 class FactoryReturnTypePass implements CompilerPassInterface
24 {
25     private $resolveClassPass;
26
27     public function __construct(ResolveClassPass $resolveClassPass = null)
28     {
29         if (null === $resolveClassPass) {
30             @trigger_error('The '.__CLASS__.' class is deprecated since Symfony 3.3 and will be removed in 4.0.', E_USER_DEPRECATED);
31         }
32         $this->resolveClassPass = $resolveClassPass;
33     }
34
35     /**
36      * {@inheritdoc}
37      */
38     public function process(ContainerBuilder $container)
39     {
40         // works only since php 7.0 and hhvm 3.11
41         if (!method_exists(\ReflectionMethod::class, 'getReturnType')) {
42             return;
43         }
44         $resolveClassPassChanges = null !== $this->resolveClassPass ? $this->resolveClassPass->getChanges() : array();
45
46         foreach ($container->getDefinitions() as $id => $definition) {
47             $this->updateDefinition($container, $id, $definition, $resolveClassPassChanges);
48         }
49     }
50
51     private function updateDefinition(ContainerBuilder $container, $id, Definition $definition, array $resolveClassPassChanges, array $previous = array())
52     {
53         // circular reference
54         if (isset($previous[$id])) {
55             return;
56         }
57
58         $factory = $definition->getFactory();
59         if (null === $factory || (!isset($resolveClassPassChanges[$id]) && null !== $definition->getClass())) {
60             return;
61         }
62
63         $class = null;
64         if (is_string($factory)) {
65             try {
66                 $m = new \ReflectionFunction($factory);
67                 if (false !== $m->getFileName() && file_exists($m->getFileName())) {
68                     $container->fileExists($m->getFileName());
69                 }
70             } catch (\ReflectionException $e) {
71                 return;
72             }
73         } else {
74             if ($factory[0] instanceof Reference) {
75                 $previous[$id] = true;
76                 $factoryId = $container->normalizeId($factory[0]);
77                 $factoryDefinition = $container->findDefinition($factoryId);
78                 $this->updateDefinition($container, $factoryId, $factoryDefinition, $resolveClassPassChanges, $previous);
79                 $class = $factoryDefinition->getClass();
80             } else {
81                 $class = $factory[0];
82             }
83
84             if (!$m = $container->getReflectionClass($class, false)) {
85                 return;
86             }
87             try {
88                 $m = $m->getMethod($factory[1]);
89             } catch (\ReflectionException $e) {
90                 return;
91             }
92         }
93
94         $returnType = $m->getReturnType();
95         if (null !== $returnType && !$returnType->isBuiltin()) {
96             $returnType = $returnType instanceof \ReflectionNamedType ? $returnType->getName() : $returnType->__toString();
97             if (null !== $class) {
98                 $declaringClass = $m->getDeclaringClass()->getName();
99                 if ('self' === strtolower($returnType)) {
100                     $returnType = $declaringClass;
101                 } elseif ('parent' === strtolower($returnType)) {
102                     $returnType = get_parent_class($declaringClass) ?: null;
103                 }
104             }
105
106             if (null !== $returnType && (!isset($resolveClassPassChanges[$id]) || $returnType !== $resolveClassPassChanges[$id])) {
107                 @trigger_error(sprintf('Relying on its factory\'s return-type to define the class of service "%s" is deprecated since Symfony 3.3 and won\'t work in 4.0. Set the "class" attribute to "%s" on the service definition instead.', $id, $returnType), E_USER_DEPRECATED);
108             }
109             $definition->setClass($returnType);
110         }
111     }
112 }