blob: 91abee807dff2bafab55872e3b5e2686873d1ef1 [file] [log] [blame]
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +01001<?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\NodeVisitorInterface;
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 implements NodeVisitorInterface
29{
30 private $extensionName;
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010031 private $varName;
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010032
33 public function __construct(string $extensionName)
34 {
35 $this->extensionName = $extensionName;
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010036 $this->varName = sprintf('__internal_%s', hash(\PHP_VERSION_ID < 80100 ? 'sha256' : 'xxh128', $extensionName));
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010037 }
38
39 public function enterNode(Node $node, Environment $env): Node
40 {
41 return $node;
42 }
43
44 public function leaveNode(Node $node, Environment $env): ?Node
45 {
46 if ($node instanceof ModuleNode) {
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010047 $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')]));
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010049 } elseif ($node instanceof BlockNode) {
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010050 $node->setNode('body', new BodyNode([
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010051 new EnterProfileNode($this->extensionName, Profile::BLOCK, $node->getAttribute('name'), $this->varName),
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010052 $node->getNode('body'),
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010053 new LeaveProfileNode($this->varName),
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010054 ]));
55 } elseif ($node instanceof MacroNode) {
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010056 $node->setNode('body', new BodyNode([
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010057 new EnterProfileNode($this->extensionName, Profile::MACRO, $node->getAttribute('name'), $this->varName),
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010058 $node->getNode('body'),
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010059 new LeaveProfileNode($this->varName),
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010060 ]));
61 }
62
63 return $node;
64 }
65
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010066 public function getPriority(): int
67 {
68 return 0;
69 }
70}