Project

General

Profile

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
    protected $debugInfo;
26
    protected $sourceOffset;
27
    protected $sourceLine;
28

    
29
    /**
30
     * Constructor.
31
     *
32
     * @param Twig_Environment $env The twig environment instance
33
     */
34
    public function __construct(Twig_Environment $env)
35
    {
36
        $this->env = $env;
37
        $this->debugInfo = array();
38
    }
39

    
40
    /**
41
     * Returns the environment instance related to this compiler.
42
     *
43
     * @return Twig_Environment The environment instance
44
     */
45
    public function getEnvironment()
46
    {
47
        return $this->env;
48
    }
49

    
50
    /**
51
     * Gets the current PHP code after compilation.
52
     *
53
     * @return string The PHP code
54
     */
55
    public function getSource()
56
    {
57
        return $this->source;
58
    }
59

    
60
    /**
61
     * Compiles a node.
62
     *
63
     * @param Twig_NodeInterface $node        The node to compile
64
     * @param integer            $indentation The current indentation
65
     *
66
     * @return Twig_Compiler The current compiler instance
67
     */
68
    public function compile(Twig_NodeInterface $node, $indentation = 0)
69
    {
70
        $this->lastLine = null;
71
        $this->source = '';
72
        $this->sourceOffset = 0;
73
        $this->sourceLine = 0;
74
        $this->indentation = $indentation;
75

    
76
        $node->compile($this);
77

    
78
        return $this;
79
    }
80

    
81
    public function subcompile(Twig_NodeInterface $node, $raw = true)
82
    {
83
        if (false === $raw) {
84
            $this->addIndentation();
85
        }
86

    
87
        $node->compile($this);
88

    
89
        return $this;
90
    }
91

    
92
    /**
93
     * Adds a raw string to the compiled code.
94
     *
95
     * @param  string $string The string
96
     *
97
     * @return Twig_Compiler The current compiler instance
98
     */
99
    public function raw($string)
100
    {
101
        $this->source .= $string;
102

    
103
        return $this;
104
    }
105

    
106
    /**
107
     * Writes a string to the compiled code by adding indentation.
108
     *
109
     * @return Twig_Compiler The current compiler instance
110
     */
111
    public function write()
112
    {
113
        $strings = func_get_args();
114
        foreach ($strings as $string) {
115
            $this->addIndentation();
116
            $this->source .= $string;
117
        }
118

    
119
        return $this;
120
    }
121

    
122
    public function addIndentation()
123
    {
124
        $this->source .= str_repeat(' ', $this->indentation * 4);
125

    
126
        return $this;
127
    }
128

    
129
    /**
130
     * Adds a quoted string to the compiled code.
131
     *
132
     * @param  string $value The string
133
     *
134
     * @return Twig_Compiler The current compiler instance
135
     */
136
    public function string($value)
137
    {
138
        $this->source .= sprintf('"%s"', addcslashes($value, "\0\t\"\$\\"));
139

    
140
        return $this;
141
    }
142

    
143
    /**
144
     * Returns a PHP representation of a given value.
145
     *
146
     * @param  mixed $value The value to convert
147
     *
148
     * @return Twig_Compiler The current compiler instance
149
     */
150
    public function repr($value)
151
    {
152
        if (is_int($value) || is_float($value)) {
153
            if (false !== $locale = setlocale(LC_NUMERIC, 0)) {
154
                setlocale(LC_NUMERIC, 'C');
155
            }
156

    
157
            $this->raw($value);
158

    
159
            if (false !== $locale) {
160
                setlocale(LC_NUMERIC, $locale);
161
            }
162
        } elseif (null === $value) {
163
            $this->raw('null');
164
        } elseif (is_bool($value)) {
165
            $this->raw($value ? 'true' : 'false');
166
        } elseif (is_array($value)) {
167
            $this->raw('array(');
168
            $i = 0;
169
            foreach ($value as $key => $value) {
170
                if ($i++) {
171
                    $this->raw(', ');
172
                }
173
                $this->repr($key);
174
                $this->raw(' => ');
175
                $this->repr($value);
176
            }
177
            $this->raw(')');
178
        } else {
179
            $this->string($value);
180
        }
181

    
182
        return $this;
183
    }
184

    
185
    /**
186
     * Adds debugging information.
187
     *
188
     * @param Twig_NodeInterface $node The related twig node
189
     *
190
     * @return Twig_Compiler The current compiler instance
191
     */
192
    public function addDebugInfo(Twig_NodeInterface $node)
193
    {
194
        if ($node->getLine() != $this->lastLine) {
195
            $this->sourceLine += substr_count($this->source, "\n", $this->sourceOffset);
196
            $this->sourceOffset = strlen($this->source);
197
            $this->debugInfo[$this->sourceLine] = $node->getLine();
198

    
199
            $this->lastLine = $node->getLine();
200
            $this->write("// line {$node->getLine()}\n");
201
        }
202

    
203
        return $this;
204
    }
205

    
206
    public function getDebugInfo()
207
    {
208
        return $this->debugInfo;
209
    }
210

    
211
    /**
212
     * Indents the generated code.
213
     *
214
     * @param integer $step The number of indentation to add
215
     *
216
     * @return Twig_Compiler The current compiler instance
217
     */
218
    public function indent($step = 1)
219
    {
220
        $this->indentation += $step;
221

    
222
        return $this;
223
    }
224

    
225
    /**
226
     * Outdents the generated code.
227
     *
228
     * @param integer $step The number of indentation to remove
229
     *
230
     * @return Twig_Compiler The current compiler instance
231
     */
232
    public function outdent($step = 1)
233
    {
234
        $this->indentation -= $step;
235

    
236
        if ($this->indentation < 0) {
237
            throw new Twig_Error('Unable to call outdent() as the indentation would become negative');
238
        }
239

    
240
        return $this;
241
    }
242
}
(2-2/33)