Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 /*
|
Chris@0
|
4 * This file is part of the Symfony package.
|
Chris@0
|
5 *
|
Chris@0
|
6 * (c) Fabien Potencier <fabien@symfony.com>
|
Chris@0
|
7 *
|
Chris@0
|
8 * For the full copyright and license information, please view the LICENSE
|
Chris@0
|
9 * file that was distributed with this source code.
|
Chris@0
|
10 */
|
Chris@0
|
11
|
Chris@0
|
12 namespace Symfony\Component\DependencyInjection\Compiler;
|
Chris@0
|
13
|
Chris@0
|
14 use Symfony\Component\DependencyInjection\ContainerBuilder;
|
Chris@0
|
15 use Symfony\Component\DependencyInjection\Exception\EnvParameterException;
|
Chris@0
|
16
|
Chris@0
|
17 /**
|
Chris@0
|
18 * This class is used to remove circular dependencies between individual passes.
|
Chris@0
|
19 *
|
Chris@0
|
20 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
Chris@0
|
21 */
|
Chris@0
|
22 class Compiler
|
Chris@0
|
23 {
|
Chris@0
|
24 private $passConfig;
|
Chris@17
|
25 private $log = [];
|
Chris@0
|
26 private $loggingFormatter;
|
Chris@0
|
27 private $serviceReferenceGraph;
|
Chris@0
|
28
|
Chris@0
|
29 public function __construct()
|
Chris@0
|
30 {
|
Chris@0
|
31 $this->passConfig = new PassConfig();
|
Chris@0
|
32 $this->serviceReferenceGraph = new ServiceReferenceGraph();
|
Chris@0
|
33 }
|
Chris@0
|
34
|
Chris@0
|
35 /**
|
Chris@0
|
36 * Returns the PassConfig.
|
Chris@0
|
37 *
|
Chris@0
|
38 * @return PassConfig The PassConfig instance
|
Chris@0
|
39 */
|
Chris@0
|
40 public function getPassConfig()
|
Chris@0
|
41 {
|
Chris@0
|
42 return $this->passConfig;
|
Chris@0
|
43 }
|
Chris@0
|
44
|
Chris@0
|
45 /**
|
Chris@0
|
46 * Returns the ServiceReferenceGraph.
|
Chris@0
|
47 *
|
Chris@0
|
48 * @return ServiceReferenceGraph The ServiceReferenceGraph instance
|
Chris@0
|
49 */
|
Chris@0
|
50 public function getServiceReferenceGraph()
|
Chris@0
|
51 {
|
Chris@0
|
52 return $this->serviceReferenceGraph;
|
Chris@0
|
53 }
|
Chris@0
|
54
|
Chris@0
|
55 /**
|
Chris@0
|
56 * Returns the logging formatter which can be used by compilation passes.
|
Chris@0
|
57 *
|
Chris@0
|
58 * @return LoggingFormatter
|
Chris@14
|
59 *
|
Chris@14
|
60 * @deprecated since version 3.3, to be removed in 4.0. Use the ContainerBuilder::log() method instead.
|
Chris@0
|
61 */
|
Chris@0
|
62 public function getLoggingFormatter()
|
Chris@0
|
63 {
|
Chris@14
|
64 if (null === $this->loggingFormatter) {
|
Chris@14
|
65 @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
|
66
|
Chris@14
|
67 $this->loggingFormatter = new LoggingFormatter();
|
Chris@14
|
68 }
|
Chris@14
|
69
|
Chris@0
|
70 return $this->loggingFormatter;
|
Chris@0
|
71 }
|
Chris@0
|
72
|
Chris@0
|
73 /**
|
Chris@0
|
74 * Adds a pass to the PassConfig.
|
Chris@0
|
75 *
|
Chris@0
|
76 * @param CompilerPassInterface $pass A compiler pass
|
Chris@0
|
77 * @param string $type The type of the pass
|
Chris@0
|
78 * @param int $priority Used to sort the passes
|
Chris@0
|
79 */
|
Chris@14
|
80 public function addPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION/*, int $priority = 0*/)
|
Chris@0
|
81 {
|
Chris@17
|
82 if (\func_num_args() >= 3) {
|
Chris@0
|
83 $priority = func_get_arg(2);
|
Chris@0
|
84 } else {
|
Chris@17
|
85 if (__CLASS__ !== \get_class($this)) {
|
Chris@0
|
86 $r = new \ReflectionMethod($this, __FUNCTION__);
|
Chris@0
|
87 if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
|
Chris@14
|
88 @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
|
89 }
|
Chris@0
|
90 }
|
Chris@0
|
91
|
Chris@0
|
92 $priority = 0;
|
Chris@0
|
93 }
|
Chris@0
|
94
|
Chris@0
|
95 $this->passConfig->addPass($pass, $type, $priority);
|
Chris@0
|
96 }
|
Chris@0
|
97
|
Chris@0
|
98 /**
|
Chris@0
|
99 * Adds a log message.
|
Chris@0
|
100 *
|
Chris@0
|
101 * @param string $string The log message
|
Chris@14
|
102 *
|
Chris@14
|
103 * @deprecated since version 3.3, to be removed in 4.0. Use the ContainerBuilder::log() method instead.
|
Chris@0
|
104 */
|
Chris@0
|
105 public function addLogMessage($string)
|
Chris@0
|
106 {
|
Chris@14
|
107 @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
|
108
|
Chris@0
|
109 $this->log[] = $string;
|
Chris@0
|
110 }
|
Chris@0
|
111
|
Chris@0
|
112 /**
|
Chris@14
|
113 * @final
|
Chris@14
|
114 */
|
Chris@14
|
115 public function log(CompilerPassInterface $pass, $message)
|
Chris@14
|
116 {
|
Chris@14
|
117 if (false !== strpos($message, "\n")) {
|
Chris@17
|
118 $message = str_replace("\n", "\n".\get_class($pass).': ', trim($message));
|
Chris@14
|
119 }
|
Chris@14
|
120
|
Chris@17
|
121 $this->log[] = \get_class($pass).': '.$message;
|
Chris@14
|
122 }
|
Chris@14
|
123
|
Chris@14
|
124 /**
|
Chris@0
|
125 * Returns the log.
|
Chris@0
|
126 *
|
Chris@0
|
127 * @return array Log array
|
Chris@0
|
128 */
|
Chris@0
|
129 public function getLog()
|
Chris@0
|
130 {
|
Chris@0
|
131 return $this->log;
|
Chris@0
|
132 }
|
Chris@0
|
133
|
Chris@0
|
134 /**
|
Chris@0
|
135 * Run the Compiler and process all Passes.
|
Chris@0
|
136 */
|
Chris@0
|
137 public function compile(ContainerBuilder $container)
|
Chris@0
|
138 {
|
Chris@0
|
139 try {
|
Chris@0
|
140 foreach ($this->passConfig->getPasses() as $pass) {
|
Chris@0
|
141 $pass->process($container);
|
Chris@0
|
142 }
|
Chris@0
|
143 } catch (\Exception $e) {
|
Chris@17
|
144 $usedEnvs = [];
|
Chris@0
|
145 $prev = $e;
|
Chris@0
|
146
|
Chris@0
|
147 do {
|
Chris@0
|
148 $msg = $prev->getMessage();
|
Chris@0
|
149
|
Chris@0
|
150 if ($msg !== $resolvedMsg = $container->resolveEnvPlaceholders($msg, null, $usedEnvs)) {
|
Chris@0
|
151 $r = new \ReflectionProperty($prev, 'message');
|
Chris@0
|
152 $r->setAccessible(true);
|
Chris@0
|
153 $r->setValue($prev, $resolvedMsg);
|
Chris@0
|
154 }
|
Chris@0
|
155 } while ($prev = $prev->getPrevious());
|
Chris@0
|
156
|
Chris@0
|
157 if ($usedEnvs) {
|
Chris@0
|
158 $e = new EnvParameterException($usedEnvs, $e);
|
Chris@0
|
159 }
|
Chris@0
|
160
|
Chris@0
|
161 throw $e;
|
Chris@14
|
162 } finally {
|
Chris@14
|
163 $this->getServiceReferenceGraph()->clear();
|
Chris@0
|
164 }
|
Chris@0
|
165 }
|
Chris@0
|
166 }
|