• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nette / latte / 15327892113

29 May 2025 03:50PM UTC coverage: 93.583% (-0.01%) from 93.597%
15327892113

push

github

dg
added NodeTraverser::RemoveNode constant [Closes #396]

Allows visitors to return RemoveNode to replace a node with null
during traversal. Added test coverage for both enter and leave
callback scenarios.

6 of 7 new or added lines in 1 file covered. (85.71%)

5119 of 5470 relevant lines covered (93.58%)

0.94 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.88
/src/Latte/Compiler/NodeTraverser.php
1
<?php
2

3
/**
4
 * This file is part of the Latte (https://latte.nette.org)
5
 * Copyright (c) 2008 David Grudl (https://davidgrudl.com)
6
 */
7

8
declare(strict_types=1);
9

10
namespace Latte\Compiler;
11

12

13
final class NodeTraverser
14
{
15
        public const DontTraverseChildren = 1;
16
        public const StopTraversal = 2;
17
        public const RemoveNode = 3;
18

19
        /** @var ?callable(Node): (Node|int|null) */
20
        private $enter;
21

22
        /** @var ?callable(Node): (Node|int|null) */
23
        private $leave;
24

25
        private bool $stop;
26

27

28
        public function traverse(Node $node, ?callable $enter = null, ?callable $leave = null): ?Node
1✔
29
        {
30
                $this->enter = $enter;
1✔
31
                $this->leave = $leave;
1✔
32
                $this->stop = false;
1✔
33
                return $this->traverseNode($node);
1✔
34
        }
35

36

37
        private function traverseNode(Node $node): ?Node
1✔
38
        {
39
                $children = true;
1✔
40
                if ($this->enter) {
1✔
41
                        $res = ($this->enter)($node);
1✔
42
                        if ($res instanceof Node) {
1✔
43
                                $node = $res;
1✔
44

45
                        } elseif ($res === self::DontTraverseChildren) {
1✔
46
                                $children = false;
1✔
47

48
                        } elseif ($res === self::StopTraversal) {
1✔
49
                                $this->stop = true;
1✔
50
                                return $node;
1✔
51

52
                        } elseif ($res === self::RemoveNode) {
1✔
53
                                return null;
1✔
54
                        }
55
                }
56

57
                if ($children) {
1✔
58
                        foreach ($node as &$subnode) {
1✔
59
                                $subnode = $this->traverseNode($subnode);
1✔
60
                                if ($this->stop) {
1✔
61
                                        break;
1✔
62
                                }
63
                        }
64
                }
65

66
                if (!$this->stop && $this->leave) {
1✔
67
                        $res = ($this->leave)($node);
1✔
68
                        if ($res instanceof Node) {
1✔
69
                                $node = $res;
1✔
70

71
                        } elseif ($res === self::StopTraversal) {
1✔
72
                                $this->stop = true;
1✔
73

74
                        } elseif ($res === self::RemoveNode) {
1✔
NEW
75
                                return null;
×
76
                        }
77
                }
78

79
                return $node;
1✔
80
        }
81
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc