Dotclear

source: inc/libs/twig/Compiler.php @ 1101:7273894e61b8

Revision 1101:7273894e61b8, 6.6 KB checked in by Dsls <dsls@…>, 12 years ago (diff)

Twig 1.12.2

Line 
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 */
19class Twig_Compiler implements Twig_CompilerInterface
20{
21    protected $lastLine;
22    protected $source;
23    protected $indentation;
24    protected $env;
25    protected $debugInfo;
26    protected $sourceOffset;
27    protected $sourceLine;
28    protected $filename;
29
30    /**
31     * Constructor.
32     *
33     * @param Twig_Environment $env The twig environment instance
34     */
35    public function __construct(Twig_Environment $env)
36    {
37        $this->env = $env;
38        $this->debugInfo = array();
39    }
40
41    public function getFilename()
42    {
43        return $this->filename;
44    }
45
46    /**
47     * Returns the environment instance related to this compiler.
48     *
49     * @return Twig_Environment The environment instance
50     */
51    public function getEnvironment()
52    {
53        return $this->env;
54    }
55
56    /**
57     * Gets the current PHP code after compilation.
58     *
59     * @return string The PHP code
60     */
61    public function getSource()
62    {
63        return $this->source;
64    }
65
66    /**
67     * Compiles a node.
68     *
69     * @param Twig_NodeInterface $node        The node to compile
70     * @param integer            $indentation The current indentation
71     *
72     * @return Twig_Compiler The current compiler instance
73     */
74    public function compile(Twig_NodeInterface $node, $indentation = 0)
75    {
76        $this->lastLine = null;
77        $this->source = '';
78        $this->sourceOffset = 0;
79        // source code starts at 1 (as we then increment it when we encounter new lines)
80        $this->sourceLine = 1;
81        $this->indentation = $indentation;
82
83        if ($node instanceof Twig_Node_Module) {
84            $this->filename = $node->getAttribute('filename');
85        }
86
87        $node->compile($this);
88
89        return $this;
90    }
91
92    public function subcompile(Twig_NodeInterface $node, $raw = true)
93    {
94        if (false === $raw) {
95            $this->addIndentation();
96        }
97
98        $node->compile($this);
99
100        return $this;
101    }
102
103    /**
104     * Adds a raw string to the compiled code.
105     *
106     * @param string $string The string
107     *
108     * @return Twig_Compiler The current compiler instance
109     */
110    public function raw($string)
111    {
112        $this->source .= $string;
113
114        return $this;
115    }
116
117    /**
118     * Writes a string to the compiled code by adding indentation.
119     *
120     * @return Twig_Compiler The current compiler instance
121     */
122    public function write()
123    {
124        $strings = func_get_args();
125        foreach ($strings as $string) {
126            $this->addIndentation();
127            $this->source .= $string;
128        }
129
130        return $this;
131    }
132
133    /**
134     * Appends an indentation to the current PHP code after compilation.
135     *
136     * @return Twig_Compiler The current compiler instance
137     */
138    public function addIndentation()
139    {
140        $this->source .= str_repeat(' ', $this->indentation * 4);
141
142        return $this;
143    }
144
145    /**
146     * Adds a quoted string to the compiled code.
147     *
148     * @param string $value The string
149     *
150     * @return Twig_Compiler The current compiler instance
151     */
152    public function string($value)
153    {
154        $this->source .= sprintf('"%s"', addcslashes($value, "\0\t\"\$\\"));
155
156        return $this;
157    }
158
159    /**
160     * Returns a PHP representation of a given value.
161     *
162     * @param mixed $value The value to convert
163     *
164     * @return Twig_Compiler The current compiler instance
165     */
166    public function repr($value)
167    {
168        if (is_int($value) || is_float($value)) {
169            if (false !== $locale = setlocale(LC_NUMERIC, 0)) {
170                setlocale(LC_NUMERIC, 'C');
171            }
172
173            $this->raw($value);
174
175            if (false !== $locale) {
176                setlocale(LC_NUMERIC, $locale);
177            }
178        } elseif (null === $value) {
179            $this->raw('null');
180        } elseif (is_bool($value)) {
181            $this->raw($value ? 'true' : 'false');
182        } elseif (is_array($value)) {
183            $this->raw('array(');
184            $i = 0;
185            foreach ($value as $key => $value) {
186                if ($i++) {
187                    $this->raw(', ');
188                }
189                $this->repr($key);
190                $this->raw(' => ');
191                $this->repr($value);
192            }
193            $this->raw(')');
194        } else {
195            $this->string($value);
196        }
197
198        return $this;
199    }
200
201    /**
202     * Adds debugging information.
203     *
204     * @param Twig_NodeInterface $node The related twig node
205     *
206     * @return Twig_Compiler The current compiler instance
207     */
208    public function addDebugInfo(Twig_NodeInterface $node)
209    {
210        if ($node->getLine() != $this->lastLine) {
211            $this->write("// line {$node->getLine()}\n");
212
213            // when mbstring.func_overload is set to 2
214            // mb_substr_count() replaces substr_count()
215            // but they have different signatures!
216            if (((int) ini_get('mbstring.func_overload')) & 2) {
217                // this is much slower than the "right" version
218                $this->sourceLine += mb_substr_count(mb_substr($this->source, $this->sourceOffset), "\n");
219            } else {
220                $this->sourceLine += substr_count($this->source, "\n", $this->sourceOffset);
221            }
222            $this->sourceOffset = strlen($this->source);
223            $this->debugInfo[$this->sourceLine] = $node->getLine();
224
225            $this->lastLine = $node->getLine();
226        }
227
228        return $this;
229    }
230
231    public function getDebugInfo()
232    {
233        return $this->debugInfo;
234    }
235
236    /**
237     * Indents the generated code.
238     *
239     * @param integer $step The number of indentation to add
240     *
241     * @return Twig_Compiler The current compiler instance
242     */
243    public function indent($step = 1)
244    {
245        $this->indentation += $step;
246
247        return $this;
248    }
249
250    /**
251     * Outdents the generated code.
252     *
253     * @param integer $step The number of indentation to remove
254     *
255     * @return Twig_Compiler The current compiler instance
256     */
257    public function outdent($step = 1)
258    {
259        // can't outdent by more steps than the current indentation level
260        if ($this->indentation < $step) {
261            throw new LogicException('Unable to call outdent() as the indentation would become negative');
262        }
263
264        $this->indentation -= $step;
265
266        return $this;
267    }
268}
Note: See TracBrowser for help on using the repository browser.

Sites map