RemoveUnusedDefinitionsPass.php 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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 implements RepeatablePassInterface
  20. {
  21. private $connectedIds = [];
  22. /**
  23. * {@inheritdoc}
  24. */
  25. public function setRepeatedPass(RepeatedPass $repeatedPass)
  26. {
  27. @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2.', __METHOD__), \E_USER_DEPRECATED);
  28. }
  29. /**
  30. * Processes the ContainerBuilder to remove unused definitions.
  31. */
  32. public function process(ContainerBuilder $container)
  33. {
  34. try {
  35. $this->enableExpressionProcessing();
  36. $this->container = $container;
  37. $connectedIds = [];
  38. $aliases = $container->getAliases();
  39. foreach ($aliases as $id => $alias) {
  40. if ($alias->isPublic()) {
  41. $this->connectedIds[] = (string) $aliases[$id];
  42. }
  43. }
  44. foreach ($container->getDefinitions() as $id => $definition) {
  45. if ($definition->isPublic()) {
  46. $connectedIds[$id] = true;
  47. $this->processValue($definition);
  48. }
  49. }
  50. while ($this->connectedIds) {
  51. $ids = $this->connectedIds;
  52. $this->connectedIds = [];
  53. foreach ($ids as $id) {
  54. if (!isset($connectedIds[$id]) && $container->hasDefinition($id)) {
  55. $connectedIds[$id] = true;
  56. $this->processValue($container->getDefinition($id));
  57. }
  58. }
  59. }
  60. foreach ($container->getDefinitions() as $id => $definition) {
  61. if (!isset($connectedIds[$id])) {
  62. $container->removeDefinition($id);
  63. $container->resolveEnvPlaceholders(!$definition->hasErrors() ? serialize($definition) : $definition);
  64. $container->log($this, sprintf('Removed service "%s"; reason: unused.', $id));
  65. }
  66. }
  67. } finally {
  68. $this->container = null;
  69. $this->connectedIds = [];
  70. }
  71. }
  72. /**
  73. * {@inheritdoc}
  74. */
  75. protected function processValue($value, $isRoot = false)
  76. {
  77. if (!$value instanceof Reference) {
  78. return parent::processValue($value, $isRoot);
  79. }
  80. if (ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE !== $value->getInvalidBehavior()) {
  81. $this->connectedIds[] = (string) $value;
  82. }
  83. return $value;
  84. }
  85. }