Completed
Push — master ( bdaaad...4f4372 )
by personal
06:57 queued 04:36
created

NodeTraverser   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 71
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 71
rs 10
c 0
b 0
f 0
wmc 18
lcom 1
cbo 2

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 16 4
C traverseArray() 0 46 14
1
<?php
2
3
/*
4
 * (c) Jean-François Lépine <https://twitter.com/Halleck45>
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
namespace Hal\Component\Ast;
11
12
use PhpParser\Node;
13
use PhpParser\NodeTraverser as Mother;
14
15
/**
16
 * Custom Ast Traverser
17
 *
18
 * @author Jean-François Lépine <https://twitter.com/Halleck45>
19
 */
20
class NodeTraverser extends Mother
21
{
22
    protected $stopCondition;
23
24
    public function __construct($cloneNodes = false, $stopCondition = null)
25
    {
26
        parent::__construct($cloneNodes);
27
28
        if(null === $stopCondition) {
29
            $stopCondition = function($node) {
30
                if($node instanceof Node\Stmt\Class_ || $node instanceof Node\Stmt\Interface_) {
31
                    return false;
32
                }
33
34
                return true;
35
            };
36
        }
37
38
        $this->stopCondition = $stopCondition;
39
    }
40
41
    protected function traverseArray(array $nodes) {
42
        $doNodes = array();
43
44
        foreach ($nodes as $i => &$node) {
45
            if (is_array($node)) {
46
                $node = $this->traverseArray($node);
47
            } elseif ($node instanceof Node) {
48
                $traverseChildren = call_user_func($this->stopCondition, $node);
49
50
                foreach ($this->visitors as $visitor) {
51
                    $return = $visitor->enterNode($node);
52
                    if (self::DONT_TRAVERSE_CHILDREN === $return) {
53
                        $traverseChildren = false;
54
                    } else if (null !== $return) {
55
                        $node = $return;
56
                    }
57
                }
58
59
                if ($traverseChildren) {
60
                    $node = $this->traverseNode($node);
61
                }
62
63
                foreach ($this->visitors as $visitor) {
64
                    $return = $visitor->leaveNode($node);
65
66
                    if (self::REMOVE_NODE === $return) {
67
                        $doNodes[] = array($i, array());
68
                        break;
69
                    } elseif (is_array($return)) {
70
                        $doNodes[] = array($i, $return);
71
                        break;
72
                    } elseif (null !== $return) {
73
                        $node = $return;
74
                    }
75
                }
76
            }
77
        }
78
79
        if (!empty($doNodes)) {
80
            while (list($i, $replace) = array_pop($doNodes)) {
81
                array_splice($nodes, $i, 1, $replace);
82
            }
83
        }
84
85
        return $nodes;
86
    }
87
88
89
90
}
91