NodeWalker::next()   B
last analyzed

Complexity

Conditions 7
Paths 6

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 7

Importance

Changes 0
Metric Value
dl 0
loc 27
ccs 18
cts 18
cp 1
rs 8.5546
c 0
b 0
f 0
cc 7
nc 6
nop 0
crap 7
1
<?php
2
3
/*
4
 * This file is part of the league/commonmark package.
5
 *
6
 * (c) Colin O'Dell <[email protected]>
7
 *
8
 * Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
9
 *  - (c) John MacFarlane
10
 *
11
 * For the full copyright and license information, please view the LICENSE
12
 * file that was distributed with this source code.
13
 */
14
15
namespace League\CommonMark\Node;
16
17
final class NodeWalker
18
{
19
    /**
20
     * @var Node
21
     */
22
    private $root;
23
24
    /**
25
     * @var Node|null
26
     */
27
    private $current;
28
29
    /**
30
     * @var bool
31
     */
32
    private $entering;
33
34
    /**
35
     * @param Node $root
36
     */
37 2076
    public function __construct(Node $root)
38
    {
39 2076
        $this->root = $root;
40 2076
        $this->current = $this->root;
41 2076
        $this->entering = true;
42 2076
    }
43
44
    /**
45
     * Returns an event which contains node and entering flag
46
     * (entering is true when we enter a Node from a parent or sibling,
47
     * and false when we reenter it from child)
48
     *
49
     * @return NodeWalkerEvent|null
50
     */
51 2076
    public function next(): ?NodeWalkerEvent
52
    {
53 2076
        $current = $this->current;
54 2076
        $entering = $this->entering;
55 2076
        if (null === $current) {
56 2073
            return null;
57
        }
58
59 2076
        if ($entering && $current->isContainer()) {
60 2073
            if ($current->firstChild()) {
61 2064
                $this->current = $current->firstChild();
62 2064
                $this->entering = true;
63
            } else {
64 2073
                $this->entering = false;
65
            }
66 2076
        } elseif ($current === $this->root) {
67 2073
            $this->current = null;
68 2064
        } elseif (null === $current->next()) {
69 2064
            $this->current = $current->parent();
70 2064
            $this->entering = false;
71
        } else {
72 516
            $this->current = $current->next();
73 516
            $this->entering = true;
74
        }
75
76 2076
        return new NodeWalkerEvent($current, $entering);
77
    }
78
79
    /**
80
     * Resets the iterator to resume at the specified node
81
     *
82
     * @param Node $node
83
     * @param bool $entering
84
     */
85 3
    public function resumeAt(Node $node, bool $entering = true)
86
    {
87 3
        $this->current = $node;
88 3
        $this->entering = $entering;
89 3
    }
90
}
91