[DependencyInjection] Resolve expressions in CheckTypeDeclarationsPass

This commit is contained in:
Thomas Calvet 2019-12-03 21:47:51 +01:00
parent 1f0070521c
commit b6c5a54cfd
2 changed files with 30 additions and 0 deletions

View File

@ -17,9 +17,11 @@ use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\InvalidParameterTypeException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ExpressionLanguage;
use Symfony\Component\DependencyInjection\Parameter;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ServiceLocator;
use Symfony\Component\ExpressionLanguage\Expression;
/**
* Checks whether injected parameters are compatible with type declarations.
@ -39,6 +41,8 @@ final class CheckTypeDeclarationsPass extends AbstractRecursivePass
private $autoload;
private $expressionLanguage;
/**
* @param bool $autoload Whether services who's class in not loaded should be checked or not.
* Defaults to false to save loading code during compilation.
@ -172,6 +176,8 @@ final class CheckTypeDeclarationsPass extends AbstractRecursivePass
if ($value instanceof Parameter) {
$value = $this->container->getParameter($value);
} elseif ($value instanceof Expression) {
$value = $this->getExpressionLanguage()->evaluate($value, ['container' => $this->container]);
} elseif (\is_string($value) && '%' === ($value[0] ?? '') && preg_match('/^%([^%]+)%$/', $value, $match)) {
$value = $this->container->getParameter($match[1]);
}
@ -202,4 +208,13 @@ final class CheckTypeDeclarationsPass extends AbstractRecursivePass
throw new InvalidParameterTypeException($this->currentId, \is_object($value) ? \get_class($value) : \gettype($value), $parameter);
}
}
private function getExpressionLanguage(): ExpressionLanguage
{
if (null === $this->expressionLanguage) {
$this->expressionLanguage = new ExpressionLanguage(null, $this->container->getExpressionLanguageProviders());
}
return $this->expressionLanguage;
}
}

View File

@ -23,6 +23,7 @@ use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPa
use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\BarOptionalArgumentNotNull;
use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\Foo;
use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\FooObject;
use Symfony\Component\ExpressionLanguage\Expression;
/**
* @author Nicolas Grekas <p@tchwork.com>
@ -569,4 +570,18 @@ class CheckTypeDeclarationsPassTest extends TestCase
$this->assertInstanceOf(\stdClass::class, $container->get('bar')->foo);
}
public function testProcessResolveExpressions()
{
$container = new ContainerBuilder();
$container->setParameter('ccc', ['array']);
$container
->register('foobar', BarMethodCall::class)
->addMethodCall('setArray', [new Expression("parameter('ccc')")]);
(new CheckTypeDeclarationsPass(true))->process($container);
$this->addToAssertionCount(1);
}
}