|
1 <?php |
|
2 |
|
3 /* |
|
4 * This file is part of Twig. |
|
5 * |
|
6 * (c) 2009 Fabien Potencier |
|
7 * (c) 2009 Armin Ronacher |
|
8 * |
|
9 * For the full copyright and license information, please view the LICENSE |
|
10 * file that was distributed with this source code. |
|
11 */ |
|
12 |
|
13 /** |
|
14 * Compiles a node to PHP code. |
|
15 * |
|
16 * @package twig |
|
17 * @author Fabien Potencier <fabien@symfony.com> |
|
18 */ |
|
19 class Twig_Compiler implements Twig_CompilerInterface |
|
20 { |
|
21 protected $lastLine; |
|
22 protected $source; |
|
23 protected $indentation; |
|
24 protected $env; |
|
25 |
|
26 /** |
|
27 * Constructor. |
|
28 * |
|
29 * @param Twig_Environment $env The twig environment instance |
|
30 */ |
|
31 public function __construct(Twig_Environment $env) |
|
32 { |
|
33 $this->env = $env; |
|
34 } |
|
35 |
|
36 /** |
|
37 * Returns the environment instance related to this compiler. |
|
38 * |
|
39 * @return Twig_Environment The environment instance |
|
40 */ |
|
41 public function getEnvironment() |
|
42 { |
|
43 return $this->env; |
|
44 } |
|
45 |
|
46 /** |
|
47 * Gets the current PHP code after compilation. |
|
48 * |
|
49 * @return string The PHP code |
|
50 */ |
|
51 public function getSource() |
|
52 { |
|
53 return $this->source; |
|
54 } |
|
55 |
|
56 /** |
|
57 * Compiles a node. |
|
58 * |
|
59 * @param Twig_NodeInterface $node The node to compile |
|
60 * @param integer $indent The current indentation |
|
61 * |
|
62 * @return Twig_Compiler The current compiler instance |
|
63 */ |
|
64 public function compile(Twig_NodeInterface $node, $indentation = 0) |
|
65 { |
|
66 $this->lastLine = null; |
|
67 $this->source = ''; |
|
68 $this->indentation = $indentation; |
|
69 |
|
70 $node->compile($this); |
|
71 |
|
72 return $this; |
|
73 } |
|
74 |
|
75 public function subcompile(Twig_NodeInterface $node, $raw = true) |
|
76 { |
|
77 if (false === $raw) { |
|
78 $this->addIndentation(); |
|
79 } |
|
80 |
|
81 $node->compile($this); |
|
82 |
|
83 return $this; |
|
84 } |
|
85 |
|
86 /** |
|
87 * Adds a raw string to the compiled code. |
|
88 * |
|
89 * @param string $string The string |
|
90 * |
|
91 * @return Twig_Compiler The current compiler instance |
|
92 */ |
|
93 public function raw($string) |
|
94 { |
|
95 $this->source .= $string; |
|
96 |
|
97 return $this; |
|
98 } |
|
99 |
|
100 /** |
|
101 * Writes a string to the compiled code by adding indentation. |
|
102 * |
|
103 * @return Twig_Compiler The current compiler instance |
|
104 */ |
|
105 public function write() |
|
106 { |
|
107 $strings = func_get_args(); |
|
108 foreach ($strings as $string) { |
|
109 $this->addIndentation(); |
|
110 $this->source .= $string; |
|
111 } |
|
112 |
|
113 return $this; |
|
114 } |
|
115 |
|
116 public function addIndentation() |
|
117 { |
|
118 $this->source .= str_repeat(' ', $this->indentation * 4); |
|
119 |
|
120 return $this; |
|
121 } |
|
122 |
|
123 /** |
|
124 * Adds a quoted string to the compiled code. |
|
125 * |
|
126 * @param string $string The string |
|
127 * |
|
128 * @return Twig_Compiler The current compiler instance |
|
129 */ |
|
130 public function string($value) |
|
131 { |
|
132 $this->source .= sprintf('"%s"', addcslashes($value, "\0\t\"\$\\")); |
|
133 |
|
134 return $this; |
|
135 } |
|
136 |
|
137 /** |
|
138 * Returns a PHP representation of a given value. |
|
139 * |
|
140 * @param mixed $value The value to convert |
|
141 * |
|
142 * @return Twig_Compiler The current compiler instance |
|
143 */ |
|
144 public function repr($value) |
|
145 { |
|
146 if (is_int($value) || is_float($value)) { |
|
147 $this->raw($value); |
|
148 } else if (null === $value) { |
|
149 $this->raw('null'); |
|
150 } else if (is_bool($value)) { |
|
151 $this->raw($value ? 'true' : 'false'); |
|
152 } else if (is_array($value)) { |
|
153 $this->raw('array('); |
|
154 $i = 0; |
|
155 foreach ($value as $key => $value) { |
|
156 if ($i++) { |
|
157 $this->raw(', '); |
|
158 } |
|
159 $this->repr($key); |
|
160 $this->raw(' => '); |
|
161 $this->repr($value); |
|
162 } |
|
163 $this->raw(')'); |
|
164 } else { |
|
165 $this->string($value); |
|
166 } |
|
167 |
|
168 return $this; |
|
169 } |
|
170 |
|
171 /** |
|
172 * Adds debugging information. |
|
173 * |
|
174 * @param Twig_NodeInterface $node The related twig node |
|
175 * |
|
176 * @return Twig_Compiler The current compiler instance |
|
177 */ |
|
178 public function addDebugInfo(Twig_NodeInterface $node) |
|
179 { |
|
180 if ($node->getLine() != $this->lastLine) { |
|
181 $this->lastLine = $node->getLine(); |
|
182 $this->write("// line {$node->getLine()}\n"); |
|
183 } |
|
184 |
|
185 return $this; |
|
186 } |
|
187 |
|
188 /** |
|
189 * Indents the generated code. |
|
190 * |
|
191 * @param integer $indent The number of indentation to add |
|
192 * |
|
193 * @return Twig_Compiler The current compiler instance |
|
194 */ |
|
195 public function indent($step = 1) |
|
196 { |
|
197 $this->indentation += $step; |
|
198 |
|
199 return $this; |
|
200 } |
|
201 |
|
202 /** |
|
203 * Outdents the generated code. |
|
204 * |
|
205 * @param integer $indent The number of indentation to remove |
|
206 * |
|
207 * @return Twig_Compiler The current compiler instance |
|
208 */ |
|
209 public function outdent($step = 1) |
|
210 { |
|
211 $this->indentation -= $step; |
|
212 |
|
213 if ($this->indentation < 0) { |
|
214 throw new Twig_Error('Unable to call outdent() as the indentation would become negative'); |
|
215 } |
|
216 |
|
217 return $this; |
|
218 } |
|
219 } |