RemoveUnusedDefinitionsPass.php 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\DependencyInjection\Compiler;
  11. use Symfony\Component\DependencyInjection\ContainerBuilder;
  12. use Symfony\Component\DependencyInjection\Reference;
  13. /**
  14. * Removes unused service definitions from the container.
  15. *
  16. * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  17. * @author Nicolas Grekas <p@tchwork.com>
  18. */
  19. class RemoveUnusedDefinitionsPass extends AbstractRecursivePass
  20. {
  21. private $connectedIds = [];
  22. /**
  23. * Processes the ContainerBuilder to remove unused definitions.
  24. */
  25. public function process(ContainerBuilder $container)
  26. {
  27. try {
  28. $this->enableExpressionProcessing();
  29. $this->container = $container;
  30. $connectedIds = [];
  31. $aliases = $container->getAliases();
  32. foreach ($aliases as $id => $alias) {
  33. if ($alias->isPublic()) {
  34. $this->connectedIds[] = (string) $aliases[$id];
  35. }
  36. }
  37. foreach ($container->getDefinitions() as $id => $definition) {
  38. if ($definition->isPublic()) {
  39. $connectedIds[$id] = true;
  40. $this->processValue($definition);
  41. }
  42. }
  43. while ($this->connectedIds) {
  44. $ids = $this->connectedIds;
  45. $this->connectedIds = [];
  46. foreach ($ids as $id) {
  47. if (!isset($connectedIds[$id]) && $container->hasDefinition($id)) {
  48. $connectedIds[$id] = true;
  49. $this->processValue($container->getDefinition($id));
  50. }
  51. }
  52. }
  53. foreach ($container->getDefinitions() as $id => $definition) {
  54. if (!isset($connectedIds[$id])) {
  55. $container->removeDefinition($id);
  56. $container->resolveEnvPlaceholders(!$definition->hasErrors() ? serialize($definition) : $definition);
  57. $container->log($this, sprintf('Removed service "%s"; reason: unused.', $id));
  58. }
  59. }
  60. } finally {
  61. $this->container = null;
  62. $this->connectedIds = [];
  63. }
  64. }
  65. /**
  66. * {@inheritdoc}
  67. */
  68. protected function processValue($value, bool $isRoot = false)
  69. {
  70. if (!$value instanceof Reference) {
  71. return parent::processValue($value, $isRoot);
  72. }
  73. if (ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE !== $value->getInvalidBehavior()) {
  74. $this->connectedIds[] = (string) $value;
  75. }
  76. return $value;
  77. }
  78. }