-
-
Notifications
You must be signed in to change notification settings - Fork 9.7k
added logging of unused tags #15963
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
added logging of unused tags #15963
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
…during container compilation
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <[email protected]> | ||
* | ||
* 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 <[email protected]> | ||
*/ | ||
class UnusedTagsPass implements CompilerPassInterface | ||
{ | ||
/** | ||
* whitelisted tags | ||
* | ||
* @var array | ||
*/ | ||
protected $whitelist = array( | ||
"console.command", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use single quotes please There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indeed |
||
"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)); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -90,6 +90,11 @@ class ContainerBuilder extends Container implements TaggedContainerInterface | |
*/ | ||
private $expressionLanguageProviders = array(); | ||
|
||
/** | ||
* @var array with tag names used by findTaggedServiceIds | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. string[] |
||
*/ | ||
private $usedTags = array(); | ||
|
||
/** | ||
* Sets the track resources flag. | ||
* | ||
|
@@ -1064,6 +1069,7 @@ public function resolveServices($value) | |
*/ | ||
public function findTaggedServiceIds($name) | ||
{ | ||
$this->usedTags[] = $name; | ||
$tags = array(); | ||
foreach ($this->getDefinitions() as $id => $definition) { | ||
if ($definition->hasTag($name)) { | ||
|
@@ -1089,6 +1095,19 @@ public function findTags() | |
return array_unique($tags); | ||
} | ||
|
||
/** | ||
* Returns all tags not queried by findTaggedServiceIds | ||
* | ||
* @return array An array of tags | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lets use |
||
*/ | ||
public function findUnusedTags() | ||
{ | ||
$tags = array_values(array_diff($this->findTags(), $this->usedTags)); | ||
$tags = array_unique($tags); | ||
|
||
return $tags; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. actually, the array_unique is useless because There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yep |
||
} | ||
|
||
public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider) | ||
{ | ||
$this->expressionLanguageProviders[] = $provider; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't make it protected by default. If we want to offer an extension point, I'd recommend a separate method to add a tag to the whitelist.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to private. I've just added some tests to an existing PR, but that should have been private from the get go.