Updated to Drupal 8.5. Core Media not yet in use.
[yaffs-website] / vendor / symfony / dependency-injection / Compiler / ResolveInstanceofConditionalsPass.php
diff --git a/vendor/symfony/dependency-injection/Compiler/ResolveInstanceofConditionalsPass.php b/vendor/symfony/dependency-injection/Compiler/ResolveInstanceofConditionalsPass.php
new file mode 100644 (file)
index 0000000..1511026
--- /dev/null
@@ -0,0 +1,153 @@
+<?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\ChildDefinition;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+use Symfony\Component\DependencyInjection\Exception\RuntimeException;
+use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
+
+/**
+ * Applies instanceof conditionals to definitions.
+ *
+ * @author Nicolas Grekas <p@tchwork.com>
+ */
+class ResolveInstanceofConditionalsPass implements CompilerPassInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function process(ContainerBuilder $container)
+    {
+        foreach ($container->getAutoconfiguredInstanceof() as $interface => $definition) {
+            if ($definition->getArguments()) {
+                throw new InvalidArgumentException(sprintf('Autoconfigured instanceof for type "%s" defines arguments but these are not supported and should be removed.', $interface));
+            }
+            if ($definition->getMethodCalls()) {
+                throw new InvalidArgumentException(sprintf('Autoconfigured instanceof for type "%s" defines method calls but these are not supported and should be removed.', $interface));
+            }
+        }
+
+        foreach ($container->getDefinitions() as $id => $definition) {
+            if ($definition instanceof ChildDefinition) {
+                // don't apply "instanceof" to children: it will be applied to their parent
+                continue;
+            }
+            $container->setDefinition($id, $this->processDefinition($container, $id, $definition));
+        }
+    }
+
+    private function processDefinition(ContainerBuilder $container, $id, Definition $definition)
+    {
+        $instanceofConditionals = $definition->getInstanceofConditionals();
+        $autoconfiguredInstanceof = $definition->isAutoconfigured() ? $container->getAutoconfiguredInstanceof() : array();
+        if (!$instanceofConditionals && !$autoconfiguredInstanceof) {
+            return $definition;
+        }
+
+        if (!$class = $container->getParameterBag()->resolveValue($definition->getClass())) {
+            return $definition;
+        }
+
+        $conditionals = $this->mergeConditionals($autoconfiguredInstanceof, $instanceofConditionals, $container);
+
+        $definition->setInstanceofConditionals(array());
+        $parent = $shared = null;
+        $instanceofTags = array();
+
+        foreach ($conditionals as $interface => $instanceofDefs) {
+            if ($interface !== $class && (!$container->getReflectionClass($class, false))) {
+                continue;
+            }
+
+            if ($interface !== $class && !is_subclass_of($class, $interface)) {
+                continue;
+            }
+
+            foreach ($instanceofDefs as $key => $instanceofDef) {
+                /** @var ChildDefinition $instanceofDef */
+                $instanceofDef = clone $instanceofDef;
+                $instanceofDef->setAbstract(true)->setParent($parent ?: 'abstract.instanceof.'.$id);
+                $parent = 'instanceof.'.$interface.'.'.$key.'.'.$id;
+                $container->setDefinition($parent, $instanceofDef);
+                $instanceofTags[] = $instanceofDef->getTags();
+                $instanceofDef->setTags(array());
+
+                if (isset($instanceofDef->getChanges()['shared'])) {
+                    $shared = $instanceofDef->isShared();
+                }
+            }
+        }
+
+        if ($parent) {
+            $bindings = $definition->getBindings();
+            $abstract = $container->setDefinition('abstract.instanceof.'.$id, $definition);
+
+            // cast Definition to ChildDefinition
+            $definition->setBindings(array());
+            $definition = serialize($definition);
+            $definition = substr_replace($definition, '53', 2, 2);
+            $definition = substr_replace($definition, 'Child', 44, 0);
+            $definition = unserialize($definition);
+            $definition->setParent($parent);
+
+            if (null !== $shared && !isset($definition->getChanges()['shared'])) {
+                $definition->setShared($shared);
+            }
+
+            $i = count($instanceofTags);
+            while (0 <= --$i) {
+                foreach ($instanceofTags[$i] as $k => $v) {
+                    foreach ($v as $v) {
+                        if ($definition->hasTag($k) && in_array($v, $definition->getTag($k))) {
+                            continue;
+                        }
+                        $definition->addTag($k, $v);
+                    }
+                }
+            }
+
+            // reset fields with "merge" behavior
+            $abstract
+                ->setBindings($bindings)
+                ->setArguments(array())
+                ->setMethodCalls(array())
+                ->setDecoratedService(null)
+                ->setTags(array())
+                ->setAbstract(true);
+        }
+
+        return $definition;
+    }
+
+    private function mergeConditionals(array $autoconfiguredInstanceof, array $instanceofConditionals, ContainerBuilder $container)
+    {
+        // make each value an array of ChildDefinition
+        $conditionals = array_map(function ($childDef) { return array($childDef); }, $autoconfiguredInstanceof);
+
+        foreach ($instanceofConditionals as $interface => $instanceofDef) {
+            // make sure the interface/class exists (but don't validate automaticInstanceofConditionals)
+            if (!$container->getReflectionClass($interface)) {
+                throw new RuntimeException(sprintf('"%s" is set as an "instanceof" conditional, but it does not exist.', $interface));
+            }
+
+            if (!isset($autoconfiguredInstanceof[$interface])) {
+                $conditionals[$interface] = array();
+            }
+
+            $conditionals[$interface][] = $instanceofDef;
+        }
+
+        return $conditionals;
+    }
+}