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;
16use Twig\Node\Node;
17
18/**
19 * Represents a block call node.
20 *
21 * @author Fabien Potencier <fabien@symfony.com>
22 */
23class BlockReferenceExpression extends AbstractExpression
24{
25    public function __construct(Node $name, ?Node $template, int $lineno, string $tag = null)
26    {
27        $nodes = ['name' => $name];
28        if (null !== $template) {
29            $nodes['template'] = $template;
30        }
31
32        parent::__construct($nodes, ['is_defined_test' => false, 'output' => false], $lineno, $tag);
33    }
34
35    public function compile(Compiler $compiler)
36    {
37        if ($this->getAttribute('is_defined_test')) {
38            $this->compileTemplateCall($compiler, 'hasBlock');
39        } else {
40            if ($this->getAttribute('output')) {
41                $compiler->addDebugInfo($this);
42
43                $this
44                    ->compileTemplateCall($compiler, 'displayBlock')
45                    ->raw(";\n");
46            } else {
47                $this->compileTemplateCall($compiler, 'renderBlock');
48            }
49        }
50    }
51
52    private function compileTemplateCall(Compiler $compiler, string $method): Compiler
53    {
54        if (!$this->hasNode('template')) {
55            $compiler->write('$this');
56        } else {
57            $compiler
58                ->write('$this->loadTemplate(')
59                ->subcompile($this->getNode('template'))
60                ->raw(', ')
61                ->repr($this->getTemplateName())
62                ->raw(', ')
63                ->repr($this->getTemplateLine())
64                ->raw(')')
65            ;
66        }
67
68        $compiler->raw(sprintf('->%s', $method));
69
70        return $this->compileBlockArguments($compiler);
71    }
72
73    private function compileBlockArguments(Compiler $compiler): Compiler
74    {
75        $compiler
76            ->raw('(')
77            ->subcompile($this->getNode('name'))
78            ->raw(', $context');
79
80        if (!$this->hasNode('template')) {
81            $compiler->raw(', $blocks');
82        }
83
84        return $compiler->raw(')');
85    }
86}
87
88class_alias('Twig\Node\Expression\BlockReferenceExpression', 'Twig_Node_Expression_BlockReference');
89