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

NamespaceStmtPrefixer::shouldPrefixStmt()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 2
nc 3
nop 1
dl 0
loc 4
ccs 2
cts 2
cp 1
crap 3
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;
16
17
use Humbug\PhpScoper\PhpParser\NodeVisitor\Collection\NamespaceStmtCollection;
18
use PhpParser\Node;
19
use PhpParser\Node\Name;
20
use PhpParser\Node\Stmt\Class_;
21
use PhpParser\Node\Stmt\Interface_;
22
use PhpParser\Node\Stmt\Namespace_;
23
use PhpParser\NodeVisitorAbstract;
24
use function Humbug\PhpScoper\clone_node;
25
26
/**
27
 * Prefixes the relevant namespaces.
28
 *
29
 * ```
30
 * namespace Foo;
31
 * ```
32
 *
33
 * =>
34
 *
35
 * ```
36
 * namespace Humbug\Foo;
37
 * ```
38
 *
39
 * @private
40
 */
41
final class NamespaceStmtPrefixer extends NodeVisitorAbstract
42
{
43
    private $prefix;
44
    private $namespaceStatements;
45
46 371
    public function __construct(string $prefix, NamespaceStmtCollection $namespaceStatements)
47
    {
48 371
        $this->prefix = $prefix;
49 371
        $this->namespaceStatements = $namespaceStatements;
50
    }
51
52
    /**
53
     * @inheritdoc
54
     */
55 370
    public function enterNode(Node $node): Node
56
    {
57 370
        return ($node instanceof Namespace_)
58 368
            ? $this->prefixNamespaceStmt($node)
59 370
            : $node
60
        ;
61
    }
62
63 368
    private function prefixNamespaceStmt(Namespace_ $namespace): Node
64
    {
65 368
        $originalNamespace = $namespace;
66
67 368
        if ($this->shouldPrefixStmt($namespace)) {
68 365
            $originalNamespace = clone_node($namespace);
69
70 365
            $namespace->name = Name::concat($this->prefix, $namespace->name);
71
        }
72
73 368
        $this->namespaceStatements->add($namespace, $originalNamespace);
1 ignored issue
show
Bug introduced by
It seems like $originalNamespace defined by \Humbug\PhpScoper\clone_node($namespace) on line 68 can also be of type object<PhpParser\Node>; however, Humbug\PhpScoper\PhpPars...ceStmtCollection::add() does only seem to accept object<PhpParser\Node\Stmt\Namespace_>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
74
75 368
        return $namespace;
76
    }
77
78
    private function isWhitelistedNode(Node $node)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
79
    {
80
        if (($node instanceof Class_ || $node instanceof Interface_)) {
81
            return true;
82
        }
83
84
        // Check nodes in the global namespaces.
85
        if ($node instanceof Namespace_ && null === $node->name) {
86
            foreach ($node->stmts as $statement) {
87
                if ($this->isWhitelistedNode($statement)) {
88
                    return true;
89
                }
90
            }
91
        }
92
93
        return false;
94
    }
95
96 368
    private function shouldPrefixStmt(Namespace_ $namespace): bool
97
    {
98 368
        return null === $namespace->name || (null !== $namespace->name && $this->prefix !== $namespace->name->getFirst());
99
    }
100
}
101