X-Git-Url: http://www.aleph1.co.uk/gitweb/?a=blobdiff_plain;f=vendor%2Fsymfony%2Fdependency-injection%2FCompiler%2FAutowirePass.php;fp=vendor%2Fsymfony%2Fdependency-injection%2FCompiler%2FAutowirePass.php;h=ae1f24d31780559b59426bf029d7490411556b90;hb=9917807b03b64faf00f6a1f29dcb6eafc454efa5;hp=b2795485531615ff281e0fa7479a4bb5a86e7360;hpb=aea91e65e895364e460983b890e295aa5d5540a5;p=yaffs-website diff --git a/vendor/symfony/dependency-injection/Compiler/AutowirePass.php b/vendor/symfony/dependency-injection/Compiler/AutowirePass.php index b27954855..ae1f24d31 100644 --- a/vendor/symfony/dependency-injection/Compiler/AutowirePass.php +++ b/vendor/symfony/dependency-injection/Compiler/AutowirePass.php @@ -11,6 +11,7 @@ namespace Symfony\Component\DependencyInjection\Compiler; +use Symfony\Component\DependencyInjection\Config\AutowireServiceResource; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Exception\RuntimeException; @@ -27,7 +28,7 @@ class AutowirePass implements CompilerPassInterface private $reflectionClasses = array(); private $definedTypes = array(); private $types; - private $notGuessableTypes = array(); + private $ambiguousServiceTypes = array(); private $autowired = array(); /** @@ -45,23 +46,38 @@ class AutowirePass implements CompilerPassInterface $this->completeDefinition($id, $definition); } } - } catch (\Exception $e) { - } catch (\Throwable $e) { + } finally { + spl_autoload_unregister($throwingAutoloader); + + // Free memory and remove circular reference to container + $this->reflectionClasses = array(); + $this->definedTypes = array(); + $this->types = null; + $this->ambiguousServiceTypes = array(); + $this->autowired = array(); } + } - spl_autoload_unregister($throwingAutoloader); + /** + * Creates a resource to help know if this service has changed. + * + * @param \ReflectionClass $reflectionClass + * + * @return AutowireServiceResource + */ + public static function createResourceForClass(\ReflectionClass $reflectionClass) + { + $metadata = array(); - // Free memory and remove circular reference to container - $this->container = null; - $this->reflectionClasses = array(); - $this->definedTypes = array(); - $this->types = null; - $this->notGuessableTypes = array(); - $this->autowired = array(); + if ($constructor = $reflectionClass->getConstructor()) { + $metadata['__construct'] = self::getResourceMetadataForMethod($constructor); + } - if (isset($e)) { - throw $e; + foreach (self::getSetters($reflectionClass) as $reflectionMethod) { + $metadata[$reflectionMethod->name] = self::getResourceMetadataForMethod($reflectionMethod); } + + return new AutowireServiceResource($reflectionClass->name, $reflectionClass->getFileName(), $metadata); } /** @@ -74,7 +90,7 @@ class AutowirePass implements CompilerPassInterface */ private function completeDefinition($id, Definition $definition) { - if ($definition->getFactory() || $definition->getFactoryClass(false) || $definition->getFactoryService(false)) { + if ($definition->getFactory()) { throw new RuntimeException(sprintf('Service "%s" can use either autowiring or a factory, not both.', $id)); } @@ -82,7 +98,9 @@ class AutowirePass implements CompilerPassInterface return; } - $this->container->addClassResource($reflectionClass); + if ($this->container->isTrackingResources()) { + $this->container->addResource(static::createResourceForClass($reflectionClass)); + } if (!$constructor = $reflectionClass->getConstructor()) { return; @@ -124,7 +142,7 @@ class AutowirePass implements CompilerPassInterface $this->populateAvailableTypes(); } - if (isset($this->types[$typeHint->name]) && !isset($this->notGuessableTypes[$typeHint->name])) { + if (isset($this->types[$typeHint->name])) { $value = new Reference($this->types[$typeHint->name]); } else { try { @@ -197,7 +215,7 @@ class AutowirePass implements CompilerPassInterface foreach ($definition->getAutowiringTypes() as $type) { $this->definedTypes[$type] = true; $this->types[$type] = $id; - unset($this->notGuessableTypes[$type]); + unset($this->ambiguousServiceTypes[$type]); } if (!$reflectionClass = $this->getReflectionClass($id, $definition)) { @@ -225,22 +243,26 @@ class AutowirePass implements CompilerPassInterface return; } - if (!isset($this->types[$type])) { - $this->types[$type] = $id; + // is this already a type/class that is known to match multiple services? + if (isset($this->ambiguousServiceTypes[$type])) { + $this->ambiguousServiceTypes[$type][] = $id; return; } - if ($this->types[$type] === $id) { + // check to make sure the type doesn't match multiple services + if (!isset($this->types[$type]) || $this->types[$type] === $id) { + $this->types[$type] = $id; + return; } - if (!isset($this->notGuessableTypes[$type])) { - $this->notGuessableTypes[$type] = true; - $this->types[$type] = (array) $this->types[$type]; + // keep an array of all services matching this type + if (!isset($this->ambiguousServiceTypes[$type])) { + $this->ambiguousServiceTypes[$type] = array($this->types[$type]); + unset($this->types[$type]); } - - $this->types[$type][] = $id; + $this->ambiguousServiceTypes[$type][] = $id; } /** @@ -255,9 +277,9 @@ class AutowirePass implements CompilerPassInterface */ private function createAutowiredDefinition(\ReflectionClass $typeHint, $id) { - if (isset($this->notGuessableTypes[$typeHint->name])) { + if (isset($this->ambiguousServiceTypes[$typeHint->name])) { $classOrInterface = $typeHint->isInterface() ? 'interface' : 'class'; - $matchingServices = implode(', ', $this->types[$typeHint->name]); + $matchingServices = implode(', ', $this->ambiguousServiceTypes[$typeHint->name]); throw new RuntimeException(sprintf('Unable to autowire argument of type "%s" for the service "%s". Multiple services exist for this %s (%s).', $typeHint->name, $id, $classOrInterface, $matchingServices)); } @@ -331,4 +353,40 @@ class AutowirePass implements CompilerPassInterface return $this->reflectionClasses[$id] = $reflector; } + + /** + * @param \ReflectionClass $reflectionClass + * + * @return \ReflectionMethod[] + */ + private static function getSetters(\ReflectionClass $reflectionClass) + { + foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflectionMethod) { + if (!$reflectionMethod->isStatic() && 1 === $reflectionMethod->getNumberOfParameters() && 0 === strpos($reflectionMethod->name, 'set')) { + yield $reflectionMethod; + } + } + } + + private static function getResourceMetadataForMethod(\ReflectionMethod $method) + { + $methodArgumentsMetadata = array(); + foreach ($method->getParameters() as $parameter) { + try { + $class = $parameter->getClass(); + } catch (\ReflectionException $e) { + // type-hint is against a non-existent class + $class = false; + } + + $isVariadic = method_exists($parameter, 'isVariadic') && $parameter->isVariadic(); + $methodArgumentsMetadata[] = array( + 'class' => $class, + 'isOptional' => $parameter->isOptional(), + 'defaultValue' => ($parameter->isOptional() && !$isVariadic) ? $parameter->getDefaultValue() : null, + ); + } + + return $methodArgumentsMetadata; + } }