vendor/twig/lib/Twig/Parser.php
author cavaliet
Mon, 07 Jul 2014 17:23:47 +0200
changeset 122 d672f7dd74dc
parent 0 7f95f8617b0b
permissions -rwxr-xr-x
Added tag V00.17 for changeset ada5f3d8b5b4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
<?php
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     2
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     3
/*
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
 * This file is part of Twig.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
 *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     6
 * (c) 2009 Fabien Potencier
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     7
 * (c) 2009 Armin Ronacher
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     8
 *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
     9
 * For the full copyright and license information, please view the LICENSE
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    10
 * file that was distributed with this source code.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    11
 */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    12
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    13
/**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
 * Default parser implementation.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
 *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
 * @package twig
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
 * @author  Fabien Potencier <fabien@symfony.com>
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
 */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
class Twig_Parser implements Twig_ParserInterface
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
{
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    21
    protected $stream;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    22
    protected $parent;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    23
    protected $handlers;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    24
    protected $visitors;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    25
    protected $expressionParser;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    26
    protected $blocks;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    27
    protected $blockStack;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
    protected $macros;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
    protected $env;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    30
    protected $reservedMacroNames;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    31
    protected $importedFunctions;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    32
    protected $tmpVarCount;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    33
    protected $traits;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    34
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    35
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    36
     * Constructor.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    37
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    38
     * @param Twig_Environment $env A Twig_Environment instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    39
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    40
    public function __construct(Twig_Environment $env)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    41
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    42
        $this->env = $env;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    43
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    44
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    45
    public function getVarName()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    46
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    47
        return sprintf('__internal_%s_%d', substr($this->env->getTemplateClass($this->stream->getFilename()), strlen($this->env->getTemplateClassPrefix())), ++$this->tmpVarCount);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    48
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    49
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    50
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    51
     * Converts a token stream to a node tree.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    52
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    53
     * @param  Twig_TokenStream $stream A token stream instance
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    54
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    55
     * @return Twig_Node_Module A node tree
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    56
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    57
    public function parse(Twig_TokenStream $stream)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    58
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    59
        $this->tmpVarCount = 0;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    60
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    61
        // tag handlers
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    62
        $this->handlers = $this->env->getTokenParsers();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    63
        $this->handlers->setParser($this);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    64
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    65
        // node visitors
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    66
        $this->visitors = $this->env->getNodeVisitors();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    67
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    68
        if (null === $this->expressionParser) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    69
            $this->expressionParser = new Twig_ExpressionParser($this, $this->env->getUnaryOperators(), $this->env->getBinaryOperators());
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    70
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    71
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    72
        $this->stream = $stream;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    73
        $this->parent = null;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    74
        $this->blocks = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    75
        $this->macros = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    76
        $this->traits = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    77
        $this->blockStack = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    78
        $this->importedFunctions = array(array());
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    79
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    80
        try {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    81
            $body = $this->subparse(null);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    82
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    83
            if (null !== $this->parent) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    84
                if (null === $body = $this->filterBodyNodes($body)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    85
                    $body = new Twig_Node();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    86
                }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    87
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    88
        } catch (Twig_Error_Syntax $e) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    89
            if (null === $e->getTemplateFile()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    90
                $e->setTemplateFile($this->stream->getFilename());
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    91
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    92
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    93
            throw $e;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    94
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    95
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    96
        $node = new Twig_Node_Module($body, $this->parent, new Twig_Node($this->blocks), new Twig_Node($this->macros), new Twig_Node($this->traits), $this->stream->getFilename());
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    97
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    98
        $traverser = new Twig_NodeTraverser($this->env, $this->visitors);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
    99
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   100
        return $traverser->traverse($node);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   101
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   102
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   103
    public function subparse($test, $dropNeedle = false)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   104
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   105
        $lineno = $this->getCurrentToken()->getLine();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   106
        $rv = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   107
        while (!$this->stream->isEOF()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   108
            switch ($this->getCurrentToken()->getType()) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   109
                case Twig_Token::TEXT_TYPE:
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   110
                    $token = $this->stream->next();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   111
                    $rv[] = new Twig_Node_Text($token->getValue(), $token->getLine());
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   112
                    break;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   113
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   114
                case Twig_Token::VAR_START_TYPE:
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   115
                    $token = $this->stream->next();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   116
                    $expr = $this->expressionParser->parseExpression();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   117
                    $this->stream->expect(Twig_Token::VAR_END_TYPE);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   118
                    $rv[] = new Twig_Node_Print($expr, $token->getLine());
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   119
                    break;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   120
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   121
                case Twig_Token::BLOCK_START_TYPE:
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   122
                    $this->stream->next();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   123
                    $token = $this->getCurrentToken();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   124
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   125
                    if ($token->getType() !== Twig_Token::NAME_TYPE) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   126
                        throw new Twig_Error_Syntax('A block must start with a tag name', $token->getLine(), $this->stream->getFilename());
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   127
                    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   128
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   129
                    if (null !== $test && call_user_func($test, $token)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   130
                        if ($dropNeedle) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   131
                            $this->stream->next();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   132
                        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   133
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   134
                        if (1 === count($rv)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   135
                            return $rv[0];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   136
                        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   137
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   138
                        return new Twig_Node($rv, array(), $lineno);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   139
                    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   140
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   141
                    $subparser = $this->handlers->getTokenParser($token->getValue());
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   142
                    if (null === $subparser) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   143
                        throw new Twig_Error_Syntax(sprintf('Unknown tag name "%s"', $token->getValue()), $token->getLine(), $this->stream->getFilename());
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   144
                    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   145
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   146
                    $this->stream->next();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   147
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   148
                    $node = $subparser->parse($token);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   149
                    if (null !== $node) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   150
                        $rv[] = $node;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   151
                    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   152
                    break;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   153
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   154
                default:
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   155
                    throw new Twig_Error_Syntax('Lexer or parser ended up in unsupported state.', -1, $this->stream->getFilename());
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   156
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   157
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   158
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   159
        if (1 === count($rv)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   160
            return $rv[0];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   161
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   162
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   163
        return new Twig_Node($rv, array(), $lineno);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   164
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   165
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   166
    public function addHandler($name, $class)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   167
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   168
        $this->handlers[$name] = $class;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   169
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   170
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   171
    public function addNodeVisitor(Twig_NodeVisitorInterface $visitor)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   172
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   173
        $this->visitors[] = $visitor;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   174
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   175
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   176
    public function getBlockStack()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   177
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   178
        return $this->blockStack;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   179
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   180
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   181
    public function peekBlockStack()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   182
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   183
        return $this->blockStack[count($this->blockStack) - 1];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   184
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   185
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   186
    public function popBlockStack()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   187
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   188
        array_pop($this->blockStack);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   189
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   190
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   191
    public function pushBlockStack($name)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   192
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   193
        $this->blockStack[] = $name;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   194
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   195
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   196
    public function hasBlock($name)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   197
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   198
        return isset($this->blocks[$name]);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   199
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   200
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   201
    public function setBlock($name, $value)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   202
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   203
        $this->blocks[$name] = $value;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   204
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   205
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   206
    public function hasMacro($name)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   207
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   208
        return isset($this->macros[$name]);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   209
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   210
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   211
    public function setMacro($name, Twig_Node_Macro $node)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   212
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   213
        if (null === $this->reservedMacroNames) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   214
            $this->reservedMacroNames = array();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   215
            $r = new ReflectionClass($this->env->getBaseTemplateClass());
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   216
            foreach ($r->getMethods() as $method) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   217
                $this->reservedMacroNames[] = $method->getName();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   218
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   219
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   220
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   221
        if (in_array($name, $this->reservedMacroNames)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   222
            throw new Twig_Error_Syntax(sprintf('"%s" cannot be used as a macro name as it is a reserved keyword', $name), $node->getLine());
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   223
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   224
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   225
        $this->macros[$name] = $node;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   226
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   227
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   228
    public function addTrait($trait)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   229
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   230
        $this->traits[] = $trait;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   231
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   232
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   233
    public function addImportedFunction($alias, $name, Twig_Node_Expression $node)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   234
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   235
        $this->importedFunctions[0][$alias] = array('name' => $name, 'node' => $node);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   236
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   237
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   238
    public function getImportedFunction($alias)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   239
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   240
        foreach ($this->importedFunctions as $functions) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   241
            if (isset($functions[$alias])) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   242
                return $functions[$alias];
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   243
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   244
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   245
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   246
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   247
    public function pushLocalScope()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   248
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   249
        array_unshift($this->importedFunctions, array());
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   250
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   251
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   252
    public function popLocalScope()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   253
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   254
        array_shift($this->importedFunctions);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   255
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   256
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   257
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   258
     * Gets the expression parser.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   259
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   260
     * @return Twig_ExpressionParser The expression parser
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   261
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   262
    public function getExpressionParser()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   263
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   264
        return $this->expressionParser;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   265
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   266
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   267
    public function getParent()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   268
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   269
        return $this->parent;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   270
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   271
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   272
    public function setParent($parent)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   273
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   274
        $this->parent = $parent;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   275
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   276
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   277
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   278
     * Gets the token stream.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   279
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   280
     * @return Twig_TokenStream The token stream
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   281
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   282
    public function getStream()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   283
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   284
        return $this->stream;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   285
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   286
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   287
    /**
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   288
     * Gets the current token.
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   289
     *
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   290
     * @return Twig_Token The current token
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   291
     */
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   292
    public function getCurrentToken()
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   293
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   294
        return $this->stream->getCurrent();
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   295
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   296
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   297
    protected function filterBodyNodes(Twig_NodeInterface $node)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   298
    {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   299
        // check that the body does not contain non-empty output nodes
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   300
        if (
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   301
            ($node instanceof Twig_Node_Text && !ctype_space($node->getAttribute('data')))
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   302
            ||
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   303
            (!$node instanceof Twig_Node_Text && !$node instanceof Twig_Node_BlockReference && $node instanceof Twig_NodeOutputInterface)
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   304
        ) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   305
            throw new Twig_Error_Syntax(sprintf('A template that extends another one cannot have a body (%s).', $node), $node->getLine(), $this->stream->getFilename());
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   306
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   307
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   308
        if ($node instanceof Twig_NodeOutputInterface) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   309
            return null;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   310
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   311
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   312
        foreach ($node as $k => $n) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   313
            if (null !== $n && null === $n = $this->filterBodyNodes($n)) {
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   314
                $node->removeNode($k);
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   315
            }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   316
        }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   317
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   318
        return $node;
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   319
    }
7f95f8617b0b first commit
ymh <ymh.work@gmail.com>
parents:
diff changeset
   320
}