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\Node\Expression;
14
15use Twig\Compiler;
16
17class NameExpression extends AbstractExpression
18{
19    protected $specialVars = [
20        '_self' => '$this',
21        '_context' => '$context',
22        '_charset' => '$this->env->getCharset()',
23    ];
24
25    public function __construct($name, $lineno)
26    {
27        parent::__construct([], ['name' => $name, 'is_defined_test' => false, 'ignore_strict_check' => false, 'always_defined' => false], $lineno);
28    }
29
30    public function compile(Compiler $compiler)
31    {
32        $name = $this->getAttribute('name');
33
34        $compiler->addDebugInfo($this);
35
36        if ($this->getAttribute('is_defined_test')) {
37            if ($this->isSpecial()) {
38                $compiler->repr(true);
39            } else {
40                $compiler
41                    ->raw('(isset($context[')
42                    ->string($name)
43                    ->raw(']) || array_key_exists(')
44                    ->string($name)
45                    ->raw(', $context))');
46            }
47        } elseif ($this->isSpecial()) {
48            $compiler->raw($this->specialVars[$name]);
49        } elseif ($this->getAttribute('always_defined')) {
50            $compiler
51                ->raw('$context[')
52                ->string($name)
53                ->raw(']')
54            ;
55        } else {
56            if (\PHP_VERSION_ID >= 70000) {
57                // use PHP 7 null coalescing operator
58                $compiler
59                    ->raw('($context[')
60                    ->string($name)
61                    ->raw('] ?? ')
62                ;
63
64                if ($this->getAttribute('ignore_strict_check') || !$compiler->getEnvironment()->isStrictVariables()) {
65                    $compiler->raw('null)');
66                } else {
67                    $compiler->raw('$this->getContext($context, ')->string($name)->raw('))');
68                }
69            } elseif (\PHP_VERSION_ID >= 50400) {
70                // PHP 5.4 ternary operator performance was optimized
71                $compiler
72                    ->raw('(isset($context[')
73                    ->string($name)
74                    ->raw(']) ? $context[')
75                    ->string($name)
76                    ->raw('] : ')
77                ;
78
79                if ($this->getAttribute('ignore_strict_check') || !$compiler->getEnvironment()->isStrictVariables()) {
80                    $compiler->raw('null)');
81                } else {
82                    $compiler->raw('$this->getContext($context, ')->string($name)->raw('))');
83                }
84            } else {
85                $compiler
86                    ->raw('$this->getContext($context, ')
87                    ->string($name)
88                ;
89
90                if ($this->getAttribute('ignore_strict_check')) {
91                    $compiler->raw(', true');
92                }
93
94                $compiler
95                    ->raw(')')
96                ;
97            }
98        }
99    }
100
101    public function isSpecial()
102    {
103        return isset($this->specialVars[$this->getAttribute('name')]);
104    }
105
106    public function isSimple()
107    {
108        return !$this->isSpecial() && !$this->getAttribute('is_defined_test');
109    }
110}
111
112class_alias('Twig\Node\Expression\NameExpression', 'Twig_Node_Expression_Name');
113