Passed
Push — master ( 6c036d...1275a4 )
by Théo
01:42
created

NamespaceStmtCollection   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 84
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 14
eloc 23
dl 0
loc 84
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A getIterator() 0 3 1
A getCurrentNamespaceName() 0 5 2
A findNamespaceForNode() 0 12 3
A count() 0 3 1
A findNamespaceByName() 0 9 3
A getNodeNamespaceName() 0 13 3
A add() 0 5 1
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\NamespaceStmt;
16
17
use ArrayIterator;
18
use Countable;
19
use Humbug\PhpScoper\PhpParser\NodeVisitor\ParentNodeAppender;
20
use IteratorAggregate;
21
use PhpParser\Node;
22
use PhpParser\Node\Name;
23
use PhpParser\Node\Stmt\Namespace_;
24
use function count;
25
26
/**
27
 * Utility class collecting all the namespaces for the scoped files allowing to easily find the namespace to which
28
 * belongs a node.
29
 *
30
 * @private
31
 */
32
final class NamespaceStmtCollection implements IteratorAggregate, Countable
33
{
34
    /**
35
     * @var Namespace_[]
36
     */
37
    private $nodes = [];
38
39
    /**
40
     * @var (Name|null)[] Associative array with the potentially prefixed namespace names as keys and their original name
41
     *                    as value.
42
     */
43
    private $mapping = [];
44
45
    /**
46
     * @param Namespace_ $namespace New namespace, may have been prefixed.
47
     */
48
    public function add(Namespace_ $namespace): void
49
    {
50
        $this->nodes[] = $namespace;
51
52
        $this->mapping[(string) $namespace->name] = NamespaceManipulator::getOriginalName($namespace);
53
    }
54
55
    public function findNamespaceForNode(Node $node): ?Name
56
    {
57
        if (0 === count($this->nodes)) {
58
            return null;
59
        }
60
61
        // Shortcut if there is only one namespace
62
        if (1 === count($this->nodes)) {
63
            return NamespaceManipulator::getOriginalName($this->nodes[0]);
64
        }
65
66
        return $this->getNodeNamespaceName($node);
67
    }
68
69
    public function findNamespaceByName(string $name): ?Name
70
    {
71
        foreach ($this->nodes as $node) {
72
            if ((string) NamespaceManipulator::getOriginalName($node) === $name) {
73
                return $node->name;
74
            }
75
        }
76
77
        return null;
78
    }
79
80
    public function getCurrentNamespaceName(): ?Name
81
    {
82
        $lastNode = end($this->nodes);
83
84
        return false === $lastNode ? null : NamespaceManipulator::getOriginalName($lastNode);
85
    }
86
87
    /**
88
     * @inheritdoc
89
     */
90
    public function count(): int
91
    {
92
        return count($this->nodes);
93
    }
94
95
    private function getNodeNamespaceName(Node $node): ?Name
96
    {
97
        if (false === ParentNodeAppender::hasParent($node)) {
98
            return null;
99
        }
100
101
        $parentNode = ParentNodeAppender::getParent($node);
102
103
        if ($parentNode instanceof Namespace_) {
104
            return $this->mapping[(string) $parentNode->name];
105
        }
106
107
        return $this->getNodeNamespaceName($parentNode);
108
    }
109
110
    /**
111
     * @inheritdoc
112
     */
113
    public function getIterator(): iterable
114
    {
115
        return new ArrayIterator($this->nodes);
116
    }
117
}
118