[DependencyInjection] Resolve expressions in CheckTypeDeclarationsPass
This commit is contained in:
parent
1f0070521c
commit
b6c5a54cfd
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user