1<?php
2
3/*
4 * This file is part of Twig.
5 *
6 * (c) Fabien Potencier
7 * (c) 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
13namespace Twig;
14
15/**
16 * Represents a Token.
17 *
18 * @author Fabien Potencier <fabien@symfony.com>
19 */
20final class Token
21{
22    private $value;
23    private $type;
24    private $lineno;
25
26    public const EOF_TYPE = -1;
27    public const TEXT_TYPE = 0;
28    public const BLOCK_START_TYPE = 1;
29    public const VAR_START_TYPE = 2;
30    public const BLOCK_END_TYPE = 3;
31    public const VAR_END_TYPE = 4;
32    public const NAME_TYPE = 5;
33    public const NUMBER_TYPE = 6;
34    public const STRING_TYPE = 7;
35    public const OPERATOR_TYPE = 8;
36    public const PUNCTUATION_TYPE = 9;
37    public const INTERPOLATION_START_TYPE = 10;
38    public const INTERPOLATION_END_TYPE = 11;
39    public const ARROW_TYPE = 12;
40
41    /**
42     * @param int    $type   The type of the token
43     * @param string $value  The token value
44     * @param int    $lineno The line position in the source
45     */
46    public function __construct($type, $value, $lineno)
47    {
48        $this->type = $type;
49        $this->value = $value;
50        $this->lineno = $lineno;
51    }
52
53    public function __toString()
54    {
55        return sprintf('%s(%s)', self::typeToString($this->type, true), $this->value);
56    }
57
58    /**
59     * Tests the current token for a type and/or a value.
60     *
61     * Parameters may be:
62     *  * just type
63     *  * type and value (or array of possible values)
64     *  * just value (or array of possible values) (NAME_TYPE is used as type)
65     *
66     * @param array|string|int  $type   The type to test
67     * @param array|string|null $values The token value
68     *
69     * @return bool
70     */
71    public function test($type, $values = null)
72    {
73        if (null === $values && !\is_int($type)) {
74            $values = $type;
75            $type = self::NAME_TYPE;
76        }
77
78        return ($this->type === $type) && (
79            null === $values ||
80            (\is_array($values) && \in_array($this->value, $values)) ||
81            $this->value == $values
82        );
83    }
84
85    /**
86     * @return int
87     */
88    public function getLine()
89    {
90        return $this->lineno;
91    }
92
93    /**
94     * @return int
95     */
96    public function getType()
97    {
98        return $this->type;
99    }
100
101    /**
102     * @return string
103     */
104    public function getValue()
105    {
106        return $this->value;
107    }
108
109    /**
110     * Returns the constant representation (internal) of a given type.
111     *
112     * @param int  $type  The type as an integer
113     * @param bool $short Whether to return a short representation or not
114     *
115     * @return string The string representation
116     */
117    public static function typeToString($type, $short = false)
118    {
119        switch ($type) {
120            case self::EOF_TYPE:
121                $name = 'EOF_TYPE';
122                break;
123            case self::TEXT_TYPE:
124                $name = 'TEXT_TYPE';
125                break;
126            case self::BLOCK_START_TYPE:
127                $name = 'BLOCK_START_TYPE';
128                break;
129            case self::VAR_START_TYPE:
130                $name = 'VAR_START_TYPE';
131                break;
132            case self::BLOCK_END_TYPE:
133                $name = 'BLOCK_END_TYPE';
134                break;
135            case self::VAR_END_TYPE:
136                $name = 'VAR_END_TYPE';
137                break;
138            case self::NAME_TYPE:
139                $name = 'NAME_TYPE';
140                break;
141            case self::NUMBER_TYPE:
142                $name = 'NUMBER_TYPE';
143                break;
144            case self::STRING_TYPE:
145                $name = 'STRING_TYPE';
146                break;
147            case self::OPERATOR_TYPE:
148                $name = 'OPERATOR_TYPE';
149                break;
150            case self::PUNCTUATION_TYPE:
151                $name = 'PUNCTUATION_TYPE';
152                break;
153            case self::INTERPOLATION_START_TYPE:
154                $name = 'INTERPOLATION_START_TYPE';
155                break;
156            case self::INTERPOLATION_END_TYPE:
157                $name = 'INTERPOLATION_END_TYPE';
158                break;
159            case self::ARROW_TYPE:
160                $name = 'ARROW_TYPE';
161                break;
162            default:
163                throw new \LogicException(sprintf('Token of type "%s" does not exist.', $type));
164        }
165
166        return $short ? $name : 'Twig\Token::'.$name;
167    }
168
169    /**
170     * Returns the English representation of a given type.
171     *
172     * @param int $type The type as an integer
173     *
174     * @return string The string representation
175     */
176    public static function typeToEnglish($type)
177    {
178        switch ($type) {
179            case self::EOF_TYPE:
180                return 'end of template';
181            case self::TEXT_TYPE:
182                return 'text';
183            case self::BLOCK_START_TYPE:
184                return 'begin of statement block';
185            case self::VAR_START_TYPE:
186                return 'begin of print statement';
187            case self::BLOCK_END_TYPE:
188                return 'end of statement block';
189            case self::VAR_END_TYPE:
190                return 'end of print statement';
191            case self::NAME_TYPE:
192                return 'name';
193            case self::NUMBER_TYPE:
194                return 'number';
195            case self::STRING_TYPE:
196                return 'string';
197            case self::OPERATOR_TYPE:
198                return 'operator';
199            case self::PUNCTUATION_TYPE:
200                return 'punctuation';
201            case self::INTERPOLATION_START_TYPE:
202                return 'begin of string interpolation';
203            case self::INTERPOLATION_END_TYPE:
204                return 'end of string interpolation';
205            case self::ARROW_TYPE:
206                return 'arrow function';
207            default:
208                throw new \LogicException(sprintf('Token of type "%s" does not exist.', $type));
209        }
210    }
211}
212
213class_alias('Twig\Token', 'Twig_Token');
214