Security update for Core, with self-updated composer
[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 class FactoryReturnTypePass implements CompilerPassInterface
22 {
23     /**
24      * {@inheritdoc}
25      */
26     public function process(ContainerBuilder $container)
27     {
28         // works only since php 7.0 and hhvm 3.11
29         if (!method_exists(\ReflectionMethod::class, 'getReturnType')) {
30             return;
31         }
32
33         foreach ($container->getDefinitions() as $id => $definition) {
34             $this->updateDefinition($container, $id, $definition);
35         }
36     }
37
38     private function updateDefinition(ContainerBuilder $container, $id, Definition $definition, array $previous = array())
39     {
40         // circular reference
41         if (isset($previous[$id])) {
42             return;
43         }
44
45         $factory = $definition->getFactory();
46         if (null === $factory || null !== $definition->getClass()) {
47             return;
48         }
49
50         $class = null;
51         if (is_string($factory)) {
52             try {
53                 $m = new \ReflectionFunction($factory);
54             } catch (\ReflectionException $e) {
55                 return;
56             }
57         } else {
58             if ($factory[0] instanceof Reference) {
59                 $previous[$id] = true;
60                 $factoryDefinition = $container->findDefinition((string) $factory[0]);
61                 $this->updateDefinition($container, strtolower($factory[0]), $factoryDefinition, $previous);
62                 $class = $factoryDefinition->getClass();
63             } else {
64                 $class = $factory[0];
65             }
66
67             try {
68                 $m = new \ReflectionMethod($class, $factory[1]);
69             } catch (\ReflectionException $e) {
70                 return;
71             }
72         }
73
74         $returnType = $m->getReturnType();
75         if (null !== $returnType && !$returnType->isBuiltin()) {
76             $returnType = $returnType instanceof \ReflectionNamedType ? $returnType->getName() : $returnType->__toString();
77             if (null !== $class) {
78                 $declaringClass = $m->getDeclaringClass()->getName();
79                 if ('self' === strtolower($returnType)) {
80                     $returnType = $declaringClass;
81                 } elseif ('parent' === strtolower($returnType)) {
82                     $returnType = get_parent_class($declaringClass) ?: null;
83                 }
84             }
85
86             $definition->setClass($returnType);
87         }
88     }
89 }