Completed
Push — master ( a514ed...c80037 )
by Théo
44:56 queued 16:09
created

NamespaceStmtCollection::getNodeNamespace()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 5.667

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 1
dl 0
loc 14
ccs 1
cts 3
cp 0.3333
crap 5.667
rs 9.7998
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\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_ $node         New namespace, may have been prefixed.
47
     * @param Namespace_ $originalName Original unchanged namespace.
48
     */
49 518
    public function add(Namespace_ $node, Namespace_ $originalName)
50
    {
51 518
        $this->nodes[] = $originalName;
52
53 518
        $this->mapping[(string) $node->name] = $originalName->name;
54
    }
55
56 414
    public function findNamespaceForNode(Node $node): ?Name
57
    {
58 414
        if (0 === count($this->nodes)) {
59
            return null;
60
        }
61
62
        // Shortcut if there is only one namespace
63 414
        if (1 === count($this->nodes)) {
64 413
            return $this->nodes[0]->name;
65
        }
66
67 189
        return $this->getNodeNamespace($node);
68
    }
69
70 256
    public function findNamespaceByName(string $name): ?Name
71
    {
72 256
        foreach ($this->nodes as $node) {
73
            if ((string) $node->name === $name) {
74
                return $node->name;
75
            }
76 256
        }
77
78
        return null;
79
    }
80
81
    public function getCurrentNamespaceName(): ?Name
82
    {
83
        if (0 === count($this->nodes)) {
84
            return null;
85
        }
86
87 189
        return end($this->nodes)->name;
88
    }
89 189
90
    /**
91
     * @inheritdoc
92
     */
93 189
    public function count(): int
94
    {
95 189
        return count($this->nodes);
96 189
    }
97
98
    private function getNodeNamespace(Node $node): ?Name
99 189
    {
100
        if (false === ParentNodeAppender::hasParent($node)) {
101
            return null;
102
        }
103
104
        $parentNode = ParentNodeAppender::getParent($node);
105
106
        if ($parentNode instanceof Namespace_) {
107
            return $this->mapping[(string) $parentNode->name];
108
        }
109
110
        return $this->getNodeNamespace($parentNode);
111
    }
112
113
    /**
114
     * @inheritdoc
115
     */
116
    public function getIterator(): iterable
117
    {
118
        return new ArrayIterator($this->nodes);
119
    }
120
}
121