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    private $varName;
32
33    public function __construct(string $extensionName)
34    {
35        $this->extensionName = $extensionName;
36        $this->varName = sprintf('__internal_%s', hash(\PHP_VERSION_ID < 80100 ? 'sha256' : 'xxh128', $extensionName));
37    }
38
39    protected function doEnterNode(Node $node, Environment $env)
40    {
41        return $node;
42    }
43
44    protected function doLeaveNode(Node $node, Environment $env)
45    {
46        if ($node instanceof ModuleNode) {
47            $node->setNode('display_start', new Node([new EnterProfileNode($this->extensionName, Profile::TEMPLATE, $node->getTemplateName(), $this->varName), $node->getNode('display_start')]));
48            $node->setNode('display_end', new Node([new LeaveProfileNode($this->varName), $node->getNode('display_end')]));
49        } elseif ($node instanceof BlockNode) {
50            $node->setNode('body', new BodyNode([
51                new EnterProfileNode($this->extensionName, Profile::BLOCK, $node->getAttribute('name'), $this->varName),
52                $node->getNode('body'),
53                new LeaveProfileNode($this->varName),
54            ]));
55        } elseif ($node instanceof MacroNode) {
56            $node->setNode('body', new BodyNode([
57                new EnterProfileNode($this->extensionName, Profile::MACRO, $node->getAttribute('name'), $this->varName),
58                $node->getNode('body'),
59                new LeaveProfileNode($this->varName),
60            ]));
61        }
62
63        return $node;
64    }
65
66    public function getPriority()
67    {
68        return 0;
69    }
70}
71
72class_alias('Twig\Profiler\NodeVisitor\ProfilerNodeVisitor', 'Twig_Profiler_NodeVisitor_Profiler');
73