Chris@0: Chris@0: * Chris@0: * For the full copyright and license information, please view the LICENSE Chris@0: * file that was distributed with this source code. Chris@0: */ Chris@0: Chris@0: namespace Symfony\Component\DependencyInjection\Compiler; Chris@0: Chris@0: use Symfony\Component\DependencyInjection\ContainerBuilder; Chris@0: use Symfony\Component\DependencyInjection\Exception\EnvParameterException; Chris@0: Chris@0: /** Chris@0: * This class is used to remove circular dependencies between individual passes. Chris@0: * Chris@0: * @author Johannes M. Schmitt Chris@0: */ Chris@0: class Compiler Chris@0: { Chris@0: private $passConfig; Chris@17: private $log = []; Chris@0: private $loggingFormatter; Chris@0: private $serviceReferenceGraph; Chris@0: Chris@0: public function __construct() Chris@0: { Chris@0: $this->passConfig = new PassConfig(); Chris@0: $this->serviceReferenceGraph = new ServiceReferenceGraph(); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns the PassConfig. Chris@0: * Chris@0: * @return PassConfig The PassConfig instance Chris@0: */ Chris@0: public function getPassConfig() Chris@0: { Chris@0: return $this->passConfig; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns the ServiceReferenceGraph. Chris@0: * Chris@0: * @return ServiceReferenceGraph The ServiceReferenceGraph instance Chris@0: */ Chris@0: public function getServiceReferenceGraph() Chris@0: { Chris@0: return $this->serviceReferenceGraph; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns the logging formatter which can be used by compilation passes. Chris@0: * Chris@0: * @return LoggingFormatter Chris@14: * Chris@14: * @deprecated since version 3.3, to be removed in 4.0. Use the ContainerBuilder::log() method instead. Chris@0: */ Chris@0: public function getLoggingFormatter() Chris@0: { Chris@14: if (null === $this->loggingFormatter) { Chris@14: @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); Chris@14: Chris@14: $this->loggingFormatter = new LoggingFormatter(); Chris@14: } Chris@14: Chris@0: return $this->loggingFormatter; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds a pass to the PassConfig. Chris@0: * Chris@0: * @param CompilerPassInterface $pass A compiler pass Chris@0: * @param string $type The type of the pass Chris@0: * @param int $priority Used to sort the passes Chris@0: */ Chris@14: public function addPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION/*, int $priority = 0*/) Chris@0: { Chris@17: if (\func_num_args() >= 3) { Chris@0: $priority = func_get_arg(2); Chris@0: } else { Chris@17: if (__CLASS__ !== \get_class($this)) { Chris@0: $r = new \ReflectionMethod($this, __FUNCTION__); Chris@0: if (__CLASS__ !== $r->getDeclaringClass()->getName()) { Chris@14: @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); Chris@0: } Chris@0: } Chris@0: Chris@0: $priority = 0; Chris@0: } Chris@0: Chris@0: $this->passConfig->addPass($pass, $type, $priority); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds a log message. Chris@0: * Chris@0: * @param string $string The log message Chris@14: * Chris@14: * @deprecated since version 3.3, to be removed in 4.0. Use the ContainerBuilder::log() method instead. Chris@0: */ Chris@0: public function addLogMessage($string) Chris@0: { Chris@14: @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); Chris@14: Chris@0: $this->log[] = $string; Chris@0: } Chris@0: Chris@0: /** Chris@14: * @final Chris@14: */ Chris@14: public function log(CompilerPassInterface $pass, $message) Chris@14: { Chris@14: if (false !== strpos($message, "\n")) { Chris@17: $message = str_replace("\n", "\n".\get_class($pass).': ', trim($message)); Chris@14: } Chris@14: Chris@17: $this->log[] = \get_class($pass).': '.$message; Chris@14: } Chris@14: Chris@14: /** Chris@0: * Returns the log. Chris@0: * Chris@0: * @return array Log array Chris@0: */ Chris@0: public function getLog() Chris@0: { Chris@0: return $this->log; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Run the Compiler and process all Passes. Chris@0: */ Chris@0: public function compile(ContainerBuilder $container) Chris@0: { Chris@0: try { Chris@0: foreach ($this->passConfig->getPasses() as $pass) { Chris@0: $pass->process($container); Chris@0: } Chris@0: } catch (\Exception $e) { Chris@17: $usedEnvs = []; Chris@0: $prev = $e; Chris@0: Chris@0: do { Chris@0: $msg = $prev->getMessage(); Chris@0: Chris@0: if ($msg !== $resolvedMsg = $container->resolveEnvPlaceholders($msg, null, $usedEnvs)) { Chris@0: $r = new \ReflectionProperty($prev, 'message'); Chris@0: $r->setAccessible(true); Chris@0: $r->setValue($prev, $resolvedMsg); Chris@0: } Chris@0: } while ($prev = $prev->getPrevious()); Chris@0: Chris@0: if ($usedEnvs) { Chris@0: $e = new EnvParameterException($usedEnvs, $e); Chris@0: } Chris@0: Chris@0: throw $e; Chris@14: } finally { Chris@14: $this->getServiceReferenceGraph()->clear(); Chris@0: } Chris@0: } Chris@0: }