Security update for Core, with self-updated composer
[yaffs-website] / vendor / symfony / dependency-injection / Compiler / FactoryReturnTypePass.php
diff --git a/vendor/symfony/dependency-injection/Compiler/FactoryReturnTypePass.php b/vendor/symfony/dependency-injection/Compiler/FactoryReturnTypePass.php
new file mode 100644 (file)
index 0000000..e4e64db
--- /dev/null
@@ -0,0 +1,89 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\DependencyInjection\Compiler;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * @author Guilhem N. <egetick@gmail.com>
+ */
+class FactoryReturnTypePass implements CompilerPassInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+        // works only since php 7.0 and hhvm 3.11
+        if (!method_exists(\ReflectionMethod::class, 'getReturnType')) {
+            return;
+        }
+
+        foreach ($container->getDefinitions() as $id => $definition) {
+            $this->updateDefinition($container, $id, $definition);
+        }
+    }
+
+    private function updateDefinition(ContainerBuilder $container, $id, Definition $definition, array $previous = array())
+    {
+        // circular reference
+        if (isset($previous[$id])) {
+            return;
+        }
+
+        $factory = $definition->getFactory();
+        if (null === $factory || null !== $definition->getClass()) {
+            return;
+        }
+
+        $class = null;
+        if (is_string($factory)) {
+            try {
+                $m = new \ReflectionFunction($factory);
+            } catch (\ReflectionException $e) {
+                return;
+            }
+        } else {
+            if ($factory[0] instanceof Reference) {
+                $previous[$id] = true;
+                $factoryDefinition = $container->findDefinition((string) $factory[0]);
+                $this->updateDefinition($container, strtolower($factory[0]), $factoryDefinition, $previous);
+                $class = $factoryDefinition->getClass();
+            } else {
+                $class = $factory[0];
+            }
+
+            try {
+                $m = new \ReflectionMethod($class, $factory[1]);
+            } catch (\ReflectionException $e) {
+                return;
+            }
+        }
+
+        $returnType = $m->getReturnType();
+        if (null !== $returnType && !$returnType->isBuiltin()) {
+            $returnType = $returnType instanceof \ReflectionNamedType ? $returnType->getName() : $returnType->__toString();
+            if (null !== $class) {
+                $declaringClass = $m->getDeclaringClass()->getName();
+                if ('self' === strtolower($returnType)) {
+                    $returnType = $declaringClass;
+                } elseif ('parent' === strtolower($returnType)) {
+                    $returnType = get_parent_class($declaringClass) ?: null;
+                }
+            }
+
+            $definition->setClass($returnType);
+        }
+    }
+}