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

UseStmtCollection::getIterator()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
ccs 0
cts 2
cp 0
crap 2
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\Collection;
16
17
use ArrayIterator;
18
use Humbug\PhpScoper\PhpParser\NodeVisitor\AppendParentNode;
19
use IteratorAggregate;
20
use PhpParser\Node\Expr\ConstFetch;
21
use PhpParser\Node\Expr\FuncCall;
22
use PhpParser\Node\Name;
23
use PhpParser\Node\Stmt\Use_;
24
use PhpParser\Node\Stmt\UseUse;
25
use function Humbug\PhpScoper\clone_node;
26
27
/**
28
 * Utility class collecting all the use statements for the scoped files allowing to easily find the use which a node
29
 * may use.
30
 *
31
 * @private
32
 */
33
final class UseStmtCollection implements IteratorAggregate
34
{
35
    /**
36
     * @var Use_[][]
37
     */
38
    private $nodes = [
39
        null => [],
40
    ];
41
42 204
    public function add(?Name $namespaceName, Use_ $node): void
43
    {
44 204
        $this->nodes[(string) $namespaceName][] = clone_node($node);
45
    }
46
47
    /**
48
     * Finds the statements matching the given name.
49
     *
50
     * $name = 'Foo';
51
     *
52
     * use X;
53
     * use Bar\Foo;
54
     * use Y;
55
     *
56
     * will return the use statement for `Bar\Foo`.
57
     *
58
     * @param Name|null $namespaceName
59
     * @param Name      $node
60
     *
61
     * @return null|Name
62
     */
63 190
    public function findStatementForNode(?Name $namespaceName, Name $node): ?Name
64
    {
65 190
        $name = strtolower($node->getFirst());
66
67 190
        $parentNode = AppendParentNode::findParent($node);
68
69 190
        $useStatements = $this->nodes[(string) $namespaceName] ?? [];
70
71 190
        foreach ($useStatements as $use_) {
72 100
            foreach ($use_->uses as $useStatement) {
73 100
                if ($useStatement instanceof UseUse) {
74 100
                    if ($name === strtolower($useStatement->alias)) {
75 99
                        if ($parentNode instanceof FuncCall && 1 === count($node->parts)) {
76 6
                            if (Use_::TYPE_FUNCTION === $use_->type) {
77 5
                                return $useStatement->name;
78
                            }
79
80 1
                            continue;
81
                        }
82
83 93
                        if ($parentNode instanceof ConstFetch && 1 === count($node->parts)) {
84 6
                            if (Use_::TYPE_CONSTANT === $use_->type) {
85 5
                                return $useStatement->name;
86
                            }
87
88 1
                            continue;
89
                        }
90
91
                        // Match the alias
92 87
                        return $useStatement->name;
93 17
                    } elseif (null !== $useStatement->alias) {
94 19
                        continue;
95
                    }
96
                }
97
            }
98
        }
99
100 123
        return null;
101
    }
102
103
    /**
104
     * @inheritdoc
105
     */
106
    public function getIterator(): iterable
107
    {
108
        return new ArrayIterator($this->nodes);
109
    }
110
}
111