Completed
Push — master ( a70c71...744f1a )
by Théo
04:21 queued 01:53
created

UseStmtCollection   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 78
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 91.67%

Importance

Changes 0
Metric Value
dl 0
loc 78
ccs 22
cts 24
cp 0.9167
rs 10
c 0
b 0
f 0
wmc 14
lcom 1
cbo 3

3 Methods

Rating   Name   Duplication   Size   Complexity  
A add() 0 4 1
C findStatementForNode() 0 39 12
A getIterator() 0 4 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\NodeVisitor\Collection;
16
17
use ArrayIterator;
18
use Humbug\PhpScoper\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
final class UseStmtCollection implements IteratorAggregate
32
{
33
    /**
34
     * @var Use_[][]
35
     */
36
    private $nodes = [
37
        null => [],
38
    ];
39
40 198
    public function add(?Name $namespaceName, Use_ $node): void
41
    {
42 198
        $this->nodes[(string) $namespaceName][] = clone_node($node);
43
    }
44
45
    /**
46
     * Finds the statements matching the given name.
47
     *
48
     * $name = 'Foo';
49
     *
50
     * use X;
51
     * use Bar\Foo;
52
     * use Y;
53
     *
54
     * will return the use statement for `Bar\Foo`.
55
     *
56
     * @param Name|null $namespaceName
57
     * @param Name      $node
58
     *
59
     * @return null|Name
60
     */
61 177
    public function findStatementForNode(?Name $namespaceName, Name $node): ?Name
62
    {
63 177
        $name = strtolower($node->getFirst());
64
65 177
        $parentNode = AppendParentNode::findParent($node);
66
67 177
        $useStatements = $this->nodes[(string) $namespaceName] ?? [];
68
69 177
        foreach ($useStatements as $use_) {
70 92
            foreach ($use_->uses as $useStatement) {
71 92
                if ($useStatement instanceof UseUse) {
72 92
                    if ($name === strtolower($useStatement->alias)) {
73 91
                        if ($parentNode instanceof FuncCall && 1 === count($node->parts)) {
74 5
                            if (Use_::TYPE_FUNCTION === $use_->type) {
75 4
                                return $useStatement->name;
76
                            }
77
78 1
                            continue;
79
                        }
80
81 86
                        if ($parentNode instanceof ConstFetch && 1 === count($node->parts)) {
82 5
                            if (Use_::TYPE_CONSTANT === $use_->type) {
83 4
                                return $useStatement->name;
84
                            }
85
86 1
                            continue;
87
                        }
88
89
                        // Match the alias
90 81
                        return $useStatement->name;
91 14
                    } elseif (null !== $useStatement->alias) {
92 16
                        continue;
93
                    }
94
                }
95
            }
96
        }
97
98 115
        return null;
99
    }
100
101
    /**
102
     * @inheritdoc
103
     */
104
    public function getIterator(): iterable
105
    {
106
        return new ArrayIterator($this->nodes);
107
    }
108
}
109