1<?php
2
3/*
4 * This file is part of Twig.
5 *
6 * (c) Fabien Potencier
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Twig\Profiler\NodeVisitor;
13
14use Twig\Environment;
15use Twig\Node\BlockNode;
16use Twig\Node\BodyNode;
17use Twig\Node\MacroNode;
18use Twig\Node\ModuleNode;
19use Twig\Node\Node;
20use Twig\NodeVisitor\AbstractNodeVisitor;
21use Twig\Profiler\Node\EnterProfileNode;
22use Twig\Profiler\Node\LeaveProfileNode;
23use Twig\Profiler\Profile;
24
25/**
26 * @author Fabien Potencier <fabien@symfony.com>
27 */
28final class ProfilerNodeVisitor extends AbstractNodeVisitor
29{
30    private $extensionName;
31
32    public function __construct(string $extensionName)
33    {
34        $this->extensionName = $extensionName;
35    }
36
37    protected function doEnterNode(Node $node, Environment $env)
38    {
39        return $node;
40    }
41
42    protected function doLeaveNode(Node $node, Environment $env)
43    {
44        if ($node instanceof ModuleNode) {
45            $varName = $this->getVarName();
46            $node->setNode('display_start', new Node([new EnterProfileNode($this->extensionName, Profile::TEMPLATE, $node->getTemplateName(), $varName), $node->getNode('display_start')]));
47            $node->setNode('display_end', new Node([new LeaveProfileNode($varName), $node->getNode('display_end')]));
48        } elseif ($node instanceof BlockNode) {
49            $varName = $this->getVarName();
50            $node->setNode('body', new BodyNode([
51                new EnterProfileNode($this->extensionName, Profile::BLOCK, $node->getAttribute('name'), $varName),
52                $node->getNode('body'),
53                new LeaveProfileNode($varName),
54            ]));
55        } elseif ($node instanceof MacroNode) {
56            $varName = $this->getVarName();
57            $node->setNode('body', new BodyNode([
58                new EnterProfileNode($this->extensionName, Profile::MACRO, $node->getAttribute('name'), $varName),
59                $node->getNode('body'),
60                new LeaveProfileNode($varName),
61            ]));
62        }
63
64        return $node;
65    }
66
67    private function getVarName(): string
68    {
69        return sprintf('__internal_%s', hash('sha256', $this->extensionName));
70    }
71
72    public function getPriority()
73    {
74        return 0;
75    }
76}
77
78class_alias('Twig\Profiler\NodeVisitor\ProfilerNodeVisitor', 'Twig_Profiler_NodeVisitor_Profiler');
79