Project

General

Profile

« Previous | Next » 

Revision 1852

Added by darkviper almost 12 years ago

updated Twig template engine to stable version 1.11.1 step2

View differences:

Parser.php
29 29
    protected $macros;
30 30
    protected $env;
31 31
    protected $reservedMacroNames;
32
    protected $importedFunctions;
33
    protected $tmpVarCount;
32
    protected $importedSymbols;
34 33
    protected $traits;
34
    protected $embeddedTemplates = array();
35 35

  
36 36
    /**
37 37
     * Constructor.
......
50 50

  
51 51
    public function getVarName()
52 52
    {
53
        return sprintf('__internal_%s_%d', substr($this->env->getTemplateClass($this->stream->getFilename()), strlen($this->env->getTemplateClassPrefix())), ++$this->tmpVarCount);
53
        return sprintf('__internal_%s', hash('sha1', uniqid(mt_rand(), true), false));
54 54
    }
55 55

  
56
    public function getFilename()
57
    {
58
        return $this->stream->getFilename();
59
    }
60

  
56 61
    /**
57 62
     * Converts a token stream to a node tree.
58 63
     *
59
     * @param  Twig_TokenStream $stream A token stream instance
64
     * @param Twig_TokenStream $stream A token stream instance
60 65
     *
61 66
     * @return Twig_Node_Module A node tree
62 67
     */
63
    public function parse(Twig_TokenStream $stream)
68
    public function parse(Twig_TokenStream $stream, $test = null, $dropNeedle = false)
64 69
    {
65 70
        // push all variables into the stack to keep the current state of the parser
66 71
        $vars = get_object_vars($this);
67 72
        unset($vars['stack'], $vars['env'], $vars['handlers'], $vars['visitors'], $vars['expressionParser']);
68 73
        $this->stack[] = $vars;
69 74

  
70
        $this->tmpVarCount = 0;
71

  
72 75
        // tag handlers
73 76
        if (null === $this->handlers) {
74 77
            $this->handlers = $this->env->getTokenParsers();
......
90 93
        $this->macros = array();
91 94
        $this->traits = array();
92 95
        $this->blockStack = array();
93
        $this->importedFunctions = array(array());
96
        $this->importedSymbols = array(array());
97
        $this->embeddedTemplates = array();
94 98

  
95 99
        try {
96
            $body = $this->subparse(null);
100
            $body = $this->subparse($test, $dropNeedle);
97 101

  
98 102
            if (null !== $this->parent) {
99 103
                if (null === $body = $this->filterBodyNodes($body)) {
......
101 105
                }
102 106
            }
103 107
        } catch (Twig_Error_Syntax $e) {
104
            if (null === $e->getTemplateFile()) {
105
                $e->setTemplateFile($this->stream->getFilename());
108
            if (!$e->getTemplateFile()) {
109
                $e->setTemplateFile($this->getFilename());
106 110
            }
107 111

  
112
            if (!$e->getTemplateLine()) {
113
                $e->setTemplateLine($this->stream->getCurrent()->getLine());
114
            }
115

  
108 116
            throw $e;
109 117
        }
110 118

  
111
        $node = new Twig_Node_Module(new Twig_Node_Body(array($body)), $this->parent, new Twig_Node($this->blocks), new Twig_Node($this->macros), new Twig_Node($this->traits), $this->stream->getFilename());
119
        $node = new Twig_Node_Module(new Twig_Node_Body(array($body)), $this->parent, new Twig_Node($this->blocks), new Twig_Node($this->macros), new Twig_Node($this->traits), $this->embeddedTemplates, $this->getFilename());
112 120

  
113 121
        $traverser = new Twig_NodeTraverser($this->env, $this->visitors);
114 122

  
......
145 153
                    $token = $this->getCurrentToken();
146 154

  
147 155
                    if ($token->getType() !== Twig_Token::NAME_TYPE) {
148
                        throw new Twig_Error_Syntax('A block must start with a tag name', $token->getLine(), $this->stream->getFilename());
156
                        throw new Twig_Error_Syntax('A block must start with a tag name', $token->getLine(), $this->getFilename());
149 157
                    }
150 158

  
151 159
                    if (null !== $test && call_user_func($test, $token)) {
......
163 171
                    $subparser = $this->handlers->getTokenParser($token->getValue());
164 172
                    if (null === $subparser) {
165 173
                        if (null !== $test) {
166
                            throw new Twig_Error_Syntax(sprintf('Unexpected tag name "%s" (expecting closing tag for the "%s" tag defined near line %s)', $token->getValue(), $test[0]->getTag(), $lineno), $token->getLine(), $this->stream->getFilename());
174
                            $error = sprintf('Unexpected tag name "%s"', $token->getValue());
175
                            if (is_array($test) && isset($test[0]) && $test[0] instanceof Twig_TokenParserInterface) {
176
                                $error .= sprintf(' (expecting closing tag for the "%s" tag defined near line %s)', $test[0]->getTag(), $lineno);
177
                            }
178

  
179
                            throw new Twig_Error_Syntax($error, $token->getLine(), $this->getFilename());
167 180
                        }
168 181

  
169 182
                        $message = sprintf('Unknown tag name "%s"', $token->getValue());
......
171 184
                            $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives));
172 185
                        }
173 186

  
174
                        throw new Twig_Error_Syntax($message, $token->getLine(), $this->stream->getFilename());
187
                        throw new Twig_Error_Syntax($message, $token->getLine(), $this->getFilename());
175 188
                    }
176 189

  
177 190
                    $this->stream->next();
......
183 196
                    break;
184 197

  
185 198
                default:
186
                    throw new Twig_Error_Syntax('Lexer or parser ended up in unsupported state.', -1, $this->stream->getFilename());
199
                    throw new Twig_Error_Syntax('Lexer or parser ended up in unsupported state.', 0, $this->getFilename());
187 200
            }
188 201
        }
189 202

  
......
255 268
        }
256 269

  
257 270
        if (in_array($name, $this->reservedMacroNames)) {
258
            throw new Twig_Error_Syntax(sprintf('"%s" cannot be used as a macro name as it is a reserved keyword', $name), $node->getLine());
271
            throw new Twig_Error_Syntax(sprintf('"%s" cannot be used as a macro name as it is a reserved keyword', $name), $node->getLine(), $this->getFilename());
259 272
        }
260 273

  
261 274
        $this->macros[$name] = $node;
......
271 284
        return count($this->traits) > 0;
272 285
    }
273 286

  
274
    public function addImportedFunction($alias, $name, Twig_Node_Expression $node)
287
    public function embedTemplate(Twig_Node_Module $template)
275 288
    {
276
        $this->importedFunctions[0][$alias] = array('name' => $name, 'node' => $node);
289
        $template->setIndex(mt_rand());
290

  
291
        $this->embeddedTemplates[] = $template;
277 292
    }
278 293

  
279
    public function getImportedFunction($alias)
294
    public function addImportedSymbol($type, $alias, $name = null, Twig_Node_Expression $node = null)
280 295
    {
281
        foreach ($this->importedFunctions as $functions) {
282
            if (isset($functions[$alias])) {
283
                return $functions[$alias];
296
        $this->importedSymbols[0][$type][$alias] = array('name' => $name, 'node' => $node);
297
    }
298

  
299
    public function getImportedSymbol($type, $alias)
300
    {
301
        foreach ($this->importedSymbols as $functions) {
302
            if (isset($functions[$type][$alias])) {
303
                return $functions[$type][$alias];
284 304
            }
285 305
        }
286 306
    }
287 307

  
288 308
    public function isMainScope()
289 309
    {
290
        return 1 === count($this->importedFunctions);
310
        return 1 === count($this->importedSymbols);
291 311
    }
292 312

  
293 313
    public function pushLocalScope()
294 314
    {
295
        array_unshift($this->importedFunctions, array());
315
        array_unshift($this->importedSymbols, array());
296 316
    }
297 317

  
298 318
    public function popLocalScope()
299 319
    {
300
        array_shift($this->importedFunctions);
320
        array_shift($this->importedSymbols);
301 321
    }
302 322

  
303 323
    /**
......
349 369
            (!$node instanceof Twig_Node_Text && !$node instanceof Twig_Node_BlockReference && $node instanceof Twig_NodeOutputInterface)
350 370
        ) {
351 371
            if (false !== strpos((string) $node, chr(0xEF).chr(0xBB).chr(0xBF))) {
352
                throw new Twig_Error_Syntax('A template that extends another one cannot have a body but a byte order mark (BOM) has been detected; it must be removed.', $node->getLine(), $this->stream->getFilename());
372
                throw new Twig_Error_Syntax('A template that extends another one cannot have a body but a byte order mark (BOM) has been detected; it must be removed.', $node->getLine(), $this->getFilename());
353 373
            }
354 374

  
355
            throw new Twig_Error_Syntax('A template that extends another one cannot have a body.', $node->getLine(), $this->stream->getFilename());
375
            throw new Twig_Error_Syntax('A template that extends another one cannot have a body.', $node->getLine(), $this->getFilename());
356 376
        }
357 377

  
358 378
        // bypass "set" nodes as they "capture" the output

Also available in: Unified diff