[FrameworkBundle] [DependencyInjection] added logging of unused tags during container compilation
This commit is contained in:
parent
156368fa43
commit
f51fe4ac41
@ -0,0 +1,86 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler;
|
||||||
|
|
||||||
|
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find all service tags which are defined, but not used and yield a warning log message.
|
||||||
|
*
|
||||||
|
* @author Florian Pfitzer <pfitzer@wurzel3.de>
|
||||||
|
*/
|
||||||
|
class UnusedTagsPass implements CompilerPassInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* whitelisted tags
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $whitelist = array(
|
||||||
|
"console.command",
|
||||||
|
"data_collector",
|
||||||
|
"form.type",
|
||||||
|
"form.type_extension",
|
||||||
|
"form.type_guesser",
|
||||||
|
"kernel.cache_clearer",
|
||||||
|
"kernel.cache_warmer",
|
||||||
|
"kernel.event_listener",
|
||||||
|
"kernel.event_subscriber",
|
||||||
|
"kernel.fragment_renderer",
|
||||||
|
"monolog.logger",
|
||||||
|
"routing.loader",
|
||||||
|
"security.remember_me_aware",
|
||||||
|
"security.voter",
|
||||||
|
"serializer.encoder",
|
||||||
|
"templating.helper",
|
||||||
|
"translation.dumper",
|
||||||
|
"translation.extractor",
|
||||||
|
"translation.loader",
|
||||||
|
"twig.extension",
|
||||||
|
"twig.loader",
|
||||||
|
"validator.constraint_validator",
|
||||||
|
"validator.initializer",
|
||||||
|
);
|
||||||
|
|
||||||
|
public function process(ContainerBuilder $container)
|
||||||
|
{
|
||||||
|
$compiler = $container->getCompiler();
|
||||||
|
$formatter = $compiler->getLoggingFormatter();
|
||||||
|
$tags = $container->findTags();
|
||||||
|
|
||||||
|
$unusedTags = $container->findUnusedTags();
|
||||||
|
foreach ($unusedTags as $tag) {
|
||||||
|
// skip whitelisted tags
|
||||||
|
if (in_array($tag, $this->whitelist)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// check for typos
|
||||||
|
$candidates = array();
|
||||||
|
foreach ($tags as $definedTag) {
|
||||||
|
if ($definedTag === $tag) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (false !== strpos($definedTag, $tag) || levenshtein($tag, $definedTag) <= strlen($tag) / 3) {
|
||||||
|
$candidates[] = $definedTag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$services = array_keys($container->findTaggedServiceIds($tag));
|
||||||
|
$message = sprintf('Tag "%s" was defined on the service(s) %s, but was never used.', $tag, implode(',', $services));
|
||||||
|
if (!empty($candidates)) {
|
||||||
|
$message .= sprintf(' Did you mean "%s"?', implode('", "', $candidates));
|
||||||
|
}
|
||||||
|
$compiler->addLogMessage($formatter->format($this, $message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -28,6 +28,7 @@ use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CompilerDebugDum
|
|||||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslationExtractorPass;
|
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslationExtractorPass;
|
||||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslationDumperPass;
|
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslationDumperPass;
|
||||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\SerializerPass;
|
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\SerializerPass;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\UnusedTagsPass;
|
||||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ConfigCachePass;
|
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ConfigCachePass;
|
||||||
use Symfony\Component\Debug\ErrorHandler;
|
use Symfony\Component\Debug\ErrorHandler;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
@ -89,6 +90,7 @@ class FrameworkBundle extends Bundle
|
|||||||
$container->addCompilerPass(new TranslationDumperPass());
|
$container->addCompilerPass(new TranslationDumperPass());
|
||||||
$container->addCompilerPass(new FragmentRendererPass(), PassConfig::TYPE_AFTER_REMOVING);
|
$container->addCompilerPass(new FragmentRendererPass(), PassConfig::TYPE_AFTER_REMOVING);
|
||||||
$container->addCompilerPass(new SerializerPass());
|
$container->addCompilerPass(new SerializerPass());
|
||||||
|
$container->addCompilerPass(new UnusedTagsPass(), PassConfig::TYPE_AFTER_REMOVING);
|
||||||
|
|
||||||
if ($container->getParameter('kernel.debug')) {
|
if ($container->getParameter('kernel.debug')) {
|
||||||
$container->addCompilerPass(new ContainerBuilderDebugDumpPass(), PassConfig::TYPE_AFTER_REMOVING);
|
$container->addCompilerPass(new ContainerBuilderDebugDumpPass(), PassConfig::TYPE_AFTER_REMOVING);
|
||||||
|
@ -90,6 +90,11 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||||||
*/
|
*/
|
||||||
private $expressionLanguageProviders = array();
|
private $expressionLanguageProviders = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array with tag names used by findTaggedServiceIds
|
||||||
|
*/
|
||||||
|
private $usedTags = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the track resources flag.
|
* Sets the track resources flag.
|
||||||
*
|
*
|
||||||
@ -1064,6 +1069,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||||||
*/
|
*/
|
||||||
public function findTaggedServiceIds($name)
|
public function findTaggedServiceIds($name)
|
||||||
{
|
{
|
||||||
|
$this->usedTags[] = $name;
|
||||||
$tags = array();
|
$tags = array();
|
||||||
foreach ($this->getDefinitions() as $id => $definition) {
|
foreach ($this->getDefinitions() as $id => $definition) {
|
||||||
if ($definition->hasTag($name)) {
|
if ($definition->hasTag($name)) {
|
||||||
@ -1089,6 +1095,19 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||||||
return array_unique($tags);
|
return array_unique($tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all tags not queried by findTaggedServiceIds
|
||||||
|
*
|
||||||
|
* @return array An array of tags
|
||||||
|
*/
|
||||||
|
public function findUnusedTags()
|
||||||
|
{
|
||||||
|
$tags = array_values(array_diff($this->findTags(), $this->usedTags));
|
||||||
|
$tags = array_unique($tags);
|
||||||
|
|
||||||
|
return $tags;
|
||||||
|
}
|
||||||
|
|
||||||
public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider)
|
public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider)
|
||||||
{
|
{
|
||||||
$this->expressionLanguageProviders[] = $provider;
|
$this->expressionLanguageProviders[] = $provider;
|
||||||
|
@ -560,6 +560,18 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals(array(), $builder->findTaggedServiceIds('foobar'), '->findTaggedServiceIds() returns an empty array if there is annotated services');
|
$this->assertEquals(array(), $builder->findTaggedServiceIds('foobar'), '->findTaggedServiceIds() returns an empty array if there is annotated services');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testFindUnusedTags()
|
||||||
|
{
|
||||||
|
$builder = new ContainerBuilder();
|
||||||
|
$builder
|
||||||
|
->register('foo', 'Bar\FooClass')
|
||||||
|
->addTag('kernel.event_listener', array('foo' => 'foo'))
|
||||||
|
->addTag('kenrel.event_listener', array('bar' => 'bar'))
|
||||||
|
;
|
||||||
|
$builder->findTaggedServiceIds('kernel.event_listener');
|
||||||
|
$this->assertEquals(array('kenrel.event_listener'), $builder->findUnusedTags(), '->findUnusedTags() returns an array with unused tags');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::findDefinition
|
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::findDefinition
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user