[DI] fix perf issue with lazy autowire error messages

This commit is contained in:
Nicolas Grekas 2019-07-24 16:20:30 +02:00
parent 1fc080b8aa
commit 3c3bda5423

View File

@ -37,6 +37,7 @@ class AutowirePass extends AbstractRecursivePass
private $getPreviousValue;
private $decoratedMethodIndex;
private $decoratedMethodArgumentIndex;
private $typesClone;
public function __construct(bool $throwOnAutowireException = true)
{
@ -49,16 +50,16 @@ class AutowirePass extends AbstractRecursivePass
public function process(ContainerBuilder $container)
{
try {
$this->typesClone = clone $this;
parent::process($container);
} finally {
$this->types = null;
$this->ambiguousServiceTypes = null;
$this->decoratedClass = null;
$this->decoratedId = null;
$this->methodCalls = null;
$this->getPreviousValue = null;
$this->decoratedMethodIndex = null;
$this->decoratedMethodArgumentIndex = null;
$this->typesClone = null;
}
}
@ -375,20 +376,22 @@ class AutowirePass extends AbstractRecursivePass
private function createTypeNotFoundMessageCallback(TypedReference $reference, $label)
{
$container = new ContainerBuilder($this->container->getParameterBag());
$container->setAliases($this->container->getAliases());
$container->setDefinitions($this->container->getDefinitions());
$container->setResourceTracking(false);
if (null === $this->typesClone->container) {
$this->typesClone->container = new ContainerBuilder($this->container->getParameterBag());
$this->typesClone->container->setAliases($this->container->getAliases());
$this->typesClone->container->setDefinitions($this->container->getDefinitions());
$this->typesClone->container->setResourceTracking(false);
}
$currentId = $this->currentId;
return function () use ($container, $reference, $label, $currentId) {
return $this->createTypeNotFoundMessage($container, $reference, $label, $currentId);
};
return (function () use ($reference, $label, $currentId) {
return $this->createTypeNotFoundMessage($reference, $label, $currentId);
})->bindTo($this->typesClone);
}
private function createTypeNotFoundMessage(ContainerBuilder $container, TypedReference $reference, $label, string $currentId)
private function createTypeNotFoundMessage(TypedReference $reference, $label, string $currentId)
{
if (!$r = $container->getReflectionClass($type = $reference->getType(), false)) {
if (!$r = $this->container->getReflectionClass($type = $reference->getType(), false)) {
// either $type does not exist or a parent class does not exist
try {
$resource = new ClassExistenceResource($type, false);
@ -401,8 +404,8 @@ class AutowirePass extends AbstractRecursivePass
$message = sprintf('has type "%s" but this class %s.', $type, $parentMsg ? sprintf('is missing a parent class (%s)', $parentMsg) : 'was not found');
} else {
$alternatives = $this->createTypeAlternatives($container, $reference);
$message = $container->has($type) ? 'this service is abstract' : 'no such service exists';
$alternatives = $this->createTypeAlternatives($this->container, $reference);
$message = $this->container->has($type) ? 'this service is abstract' : 'no such service exists';
$message = sprintf('references %s "%s" but %s.%s', $r->isInterface() ? 'interface' : 'class', $type, $message, $alternatives);
if ($r->isInterface() && !$alternatives) {