Passed
Push — master ( 62af2e...d65fca )
by Théo
07:27 queued 04:04
created

NamespaceStmtCollection::getNodeNamespace()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3.0261

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 1
dl 0
loc 14
ccs 6
cts 7
cp 0.8571
crap 3.0261
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the humbug/php-scoper package.
7
 *
8
 * Copyright (c) 2017 Théo FIDRY <[email protected]>,
9
 *                    Pádraic Brady <[email protected]>
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 Humbug\PhpScoper\PhpParser\NodeVisitor\Collection;
16
17
use ArrayIterator;
18
use Countable;
19
use Humbug\PhpScoper\PhpParser\NodeVisitor\AppendParentNode;
20
use IteratorAggregate;
21
use PhpParser\Node;
22
use PhpParser\Node\Name;
23
use PhpParser\Node\Stmt\Namespace_;
24
25
/**
26
 * Utility class collecting all the namespaces for the scoped files allowing to easily find the namespace to which
27
 * belongs a node.
28
 *
29
 * @private
30
 */
31
final class NamespaceStmtCollection implements IteratorAggregate, Countable
32
{
33
    /**
34
     * @var Namespace_[]
35
     */
36
    private $nodes = [];
37
38
    /**
39
     * @var Name|null[] Associative array with the potentially prefixed namespace names as keys and their original name
40
     *                  as value.
41
     */
42
    private $mapping = [];
43
44
    /**
45
     * @param Namespace_ $node         New namespace, may have been prefixed.
46
     * @param Namespace_ $originalName Original unchanged namespace.
47
     */
48 368
    public function add(Namespace_ $node, Namespace_ $originalName)
49
    {
50 368
        $this->nodes[] = $originalName;
51
52 368
        $this->mapping[(string) $node->name] = $originalName->name;
53
    }
54
55 190
    public function findNamespaceForNode(Node $node): ?Name
56
    {
57 190
        if (0 === count($this->nodes)) {
58
            return null;
59
        }
60
61
        // Shortcut if there is only one namespace
62 190
        if (1 === count($this->nodes)) {
63 119
            return $this->nodes[0]->name;
64
        }
65
66 89
        return $this->getNodeNamespace($node);
67
    }
68
69 204
    public function getCurrentNamespaceName(): ?Name
70
    {
71 204
        if (0 === count($this->nodes)) {
72
            return null;
73
        }
74
75 204
        return end($this->nodes)->name;
76
    }
77
78
    /**
79
     * @inheritdoc
80
     */
81
    public function count(): int
82
    {
83
        return count($this->nodes);
84
    }
85
86 89
    private function getNodeNamespace(Node $node): ?Name
87
    {
88 89
        if (false === AppendParentNode::hasParent($node)) {
89
            return null;
90
        }
91
92 89
        $parentNode = AppendParentNode::getParent($node);
93
94 89
        if ($parentNode instanceof Namespace_) {
95 89
            return $this->mapping[(string) $parentNode->name];
96
        }
97
98 89
        return $this->getNodeNamespace($parentNode);
99
    }
100
101
    /**
102
     * @inheritdoc
103
     */
104
    public function getIterator(): iterable
105
    {
106
        return new ArrayIterator($this->nodes);
107
    }
108
}
109