Compiler.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  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\Exception\EnvParameterException;
  13. /**
  14. * This class is used to remove circular dependencies between individual passes.
  15. *
  16. * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  17. */
  18. class Compiler
  19. {
  20. private $passConfig;
  21. private $log = array();
  22. private $loggingFormatter;
  23. private $serviceReferenceGraph;
  24. public function __construct()
  25. {
  26. $this->passConfig = new PassConfig();
  27. $this->serviceReferenceGraph = new ServiceReferenceGraph();
  28. }
  29. /**
  30. * Returns the PassConfig.
  31. *
  32. * @return PassConfig The PassConfig instance
  33. */
  34. public function getPassConfig()
  35. {
  36. return $this->passConfig;
  37. }
  38. /**
  39. * Returns the ServiceReferenceGraph.
  40. *
  41. * @return ServiceReferenceGraph The ServiceReferenceGraph instance
  42. */
  43. public function getServiceReferenceGraph()
  44. {
  45. return $this->serviceReferenceGraph;
  46. }
  47. /**
  48. * Returns the logging formatter which can be used by compilation passes.
  49. *
  50. * @return LoggingFormatter
  51. *
  52. * @deprecated since version 3.3, to be removed in 4.0. Use the ContainerBuilder::log() method instead.
  53. */
  54. public function getLoggingFormatter()
  55. {
  56. if (null === $this->loggingFormatter) {
  57. @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the ContainerBuilder::log() method instead.', __METHOD__), E_USER_DEPRECATED);
  58. $this->loggingFormatter = new LoggingFormatter();
  59. }
  60. return $this->loggingFormatter;
  61. }
  62. /**
  63. * Adds a pass to the PassConfig.
  64. *
  65. * @param CompilerPassInterface $pass A compiler pass
  66. * @param string $type The type of the pass
  67. * @param int $priority Used to sort the passes
  68. */
  69. public function addPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION/*, int $priority = 0*/)
  70. {
  71. if (func_num_args() >= 3) {
  72. $priority = func_get_arg(2);
  73. } else {
  74. if (__CLASS__ !== get_class($this)) {
  75. $r = new \ReflectionMethod($this, __FUNCTION__);
  76. if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
  77. @trigger_error(sprintf('Method %s() will have a third `int $priority = 0` argument in version 4.0. Not defining it is deprecated since Symfony 3.2.', __METHOD__), E_USER_DEPRECATED);
  78. }
  79. }
  80. $priority = 0;
  81. }
  82. $this->passConfig->addPass($pass, $type, $priority);
  83. }
  84. /**
  85. * Adds a log message.
  86. *
  87. * @param string $string The log message
  88. *
  89. * @deprecated since version 3.3, to be removed in 4.0. Use the ContainerBuilder::log() method instead.
  90. */
  91. public function addLogMessage($string)
  92. {
  93. @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the ContainerBuilder::log() method instead.', __METHOD__), E_USER_DEPRECATED);
  94. $this->log[] = $string;
  95. }
  96. /**
  97. * @final
  98. */
  99. public function log(CompilerPassInterface $pass, $message)
  100. {
  101. if (false !== strpos($message, "\n")) {
  102. $message = str_replace("\n", "\n".get_class($pass).': ', trim($message));
  103. }
  104. $this->log[] = get_class($pass).': '.$message;
  105. }
  106. /**
  107. * Returns the log.
  108. *
  109. * @return array Log array
  110. */
  111. public function getLog()
  112. {
  113. return $this->log;
  114. }
  115. /**
  116. * Run the Compiler and process all Passes.
  117. */
  118. public function compile(ContainerBuilder $container)
  119. {
  120. try {
  121. foreach ($this->passConfig->getPasses() as $pass) {
  122. $pass->process($container);
  123. }
  124. } catch (\Exception $e) {
  125. $usedEnvs = array();
  126. $prev = $e;
  127. do {
  128. $msg = $prev->getMessage();
  129. if ($msg !== $resolvedMsg = $container->resolveEnvPlaceholders($msg, null, $usedEnvs)) {
  130. $r = new \ReflectionProperty($prev, 'message');
  131. $r->setAccessible(true);
  132. $r->setValue($prev, $resolvedMsg);
  133. }
  134. } while ($prev = $prev->getPrevious());
  135. if ($usedEnvs) {
  136. $e = new EnvParameterException($usedEnvs, $e);
  137. }
  138. throw $e;
  139. }
  140. }
  141. }