Passed
Pull Request — master (#648)
by Théo
02:25
created

NamespaceStmtCollection::findNamespaceByName()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 4
nc 3
nop 1
dl 0
loc 9
rs 10
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\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 Traversable;
25
26
use function count;
27
use function end;
28
29
/**
30
 * Utility class collecting all the namespaces for the scoped files allowing to easily find the namespace to which
31
 * belongs a node.
32
 *
33
 * @private
34
 */
35
final class NamespaceStmtCollection implements IteratorAggregate, Countable
36
{
37
    /**
38
     * @var Namespace_[]
39
     */
40
    private array $nodes = [];
41
42
    /**
43
     * @var (Name|null)[] Associative array with the potentially prefixed namespace names as keys and their original name
44
     *                    as value.
45
     */
46
    private array $mapping = [];
47
48
    /**
49
     * @param Namespace_ $namespace New namespace, may have been prefixed.
50
     */
51
    public function add(Namespace_ $namespace): void
52
    {
53
        $this->nodes[] = $namespace;
54
55
        $this->mapping[(string) $namespace->name] = NamespaceManipulator::getOriginalName($namespace);
56
    }
57
58
    public function findNamespaceForNode(Node $node): ?Name
59
    {
60
        if (0 === count($this->nodes)) {
61
            return null;
62
        }
63
64
        // Shortcut if there is only one namespace
65
        if (1 === count($this->nodes)) {
66
            return NamespaceManipulator::getOriginalName($this->nodes[0]);
67
        }
68
69
        return $this->getNodeNamespaceName($node);
70
    }
71
72
    public function getCurrentNamespaceName(): ?Name
73
    {
74
        $lastNode = end($this->nodes);
75
76
        return false === $lastNode ? null : NamespaceManipulator::getOriginalName($lastNode);
77
    }
78
79
    public function count(): int
80
    {
81
        return count($this->nodes);
82
    }
83
84
    private function getNodeNamespaceName(Node $node): ?Name
85
    {
86
        if (!ParentNodeAppender::hasParent($node)) {
87
            throw new InvalidArgumentException('Unexpected case. Please report it.');
0 ignored issues
show
Bug introduced by
The type Humbug\PhpScoper\PhpPars...nvalidArgumentException was not found. Did you mean InvalidArgumentException? If so, make sure to prefix the type with \.
Loading history...
88
            //return null;
89
        }
90
91
        $parentNode = ParentNodeAppender::getParent($node);
92
93
        if ($parentNode instanceof Namespace_) {
94
            return $this->mapping[(string) $parentNode->name];
95
        }
96
97
        return $this->getNodeNamespaceName($parentNode);
98
    }
99
100
    public function getIterator(): Traversable
101
    {
102
        return new ArrayIterator($this->nodes);
103
    }
104
}
105