Skip to content

Commit f2d2532

Browse files
alcalynnicolas-grekas
authored andcommitted
[DI] Add compiler pass to check arguments type hint
1 parent 582e94f commit f2d2532

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed

Command/ContainerLintCommand.php

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\Command;
13+
14+
use Symfony\Component\Console\Command\Command;
15+
use Symfony\Component\Console\Input\InputInterface;
16+
use Symfony\Component\Console\Input\InputOption;
17+
use Symfony\Component\Console\Output\OutputInterface;
18+
use Symfony\Component\Config\ConfigCache;
19+
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
20+
use Symfony\Component\DependencyInjection\ContainerBuilder;
21+
use Symfony\Component\DependencyInjection\Compiler\CheckTypeHintsPass;
22+
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
23+
use Symfony\Component\Config\FileLocator;
24+
25+
class ContainerLintCommand extends Command
26+
{
27+
/**
28+
* @var ContainerBuilder
29+
*/
30+
private $containerBuilder;
31+
32+
/**
33+
* {@inheritdoc}
34+
*/
35+
protected function configure()
36+
{
37+
$this
38+
->setDescription('Lints container for services arguments type hints')
39+
->setHelp('This command will parse all your defined services and check that you are injecting service without type error based on type hints.')
40+
->addOption('only-used-services', 'o', InputOption::VALUE_NONE, 'Check only services that are used in your application')
41+
;
42+
}
43+
44+
/**
45+
* {@inheritdoc}
46+
*/
47+
protected function execute(InputInterface $input, OutputInterface $output)
48+
{
49+
$container = $this->getContainerBuilder();
50+
51+
$container->setParameter('container.build_id', 'lint_container');
52+
53+
$container->addCompilerPass(
54+
new CheckTypeHintsPass(),
55+
$input->getOption('only-used-services') ? PassConfig::TYPE_AFTER_REMOVING : PassConfig::TYPE_BEFORE_OPTIMIZATION
56+
);
57+
58+
$container->compile();
59+
}
60+
61+
/**
62+
* Loads the ContainerBuilder from the cache.
63+
*
64+
* @return ContainerBuilder
65+
*
66+
* @throws \LogicException
67+
*/
68+
protected function getContainerBuilder()
69+
{
70+
if ($this->containerBuilder) {
71+
return $this->containerBuilder;
72+
}
73+
74+
$kernel = $this->getApplication()->getKernel();
75+
76+
if (!$kernel->isDebug() || !(new ConfigCache($kernel->getContainer()->getParameter('debug.container.dump'), true))->isFresh()) {
77+
$buildContainer = \Closure::bind(function () { return $this->buildContainer(); }, $kernel, get_class($kernel));
78+
$container = $buildContainer();
79+
$container->getCompilerPassConfig()->setRemovingPasses(array());
80+
$container->compile();
81+
} else {
82+
(new XmlFileLoader($container = new ContainerBuilder(), new FileLocator()))->load($kernel->getContainer()->getParameter('debug.container.dump'));
83+
}
84+
85+
return $this->containerBuilder = $container;
86+
}
87+
}

Resources/config/console.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@
7070
<tag name="console.command" command="debug:container" />
7171
</service>
7272

73+
<service id="console.command.container_lint" class="Symfony\Bundle\FrameworkBundle\Command\ContainerLintCommand">
74+
<tag name="console.command" command="lint:container" />
75+
</service>
76+
7377
<service id="console.command.debug_autowiring" class="Symfony\Bundle\FrameworkBundle\Command\DebugAutowiringCommand">
7478
<argument>null</argument>
7579
<argument type="service" id="debug.file_link_formatter" on-invalid="null"/>

0 commit comments

Comments
 (0)