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

UseStmtPrefixer::enterNode()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 4
nc 2
nop 1
dl 0
loc 8
ccs 4
cts 4
cp 1
crap 3
rs 9.4285
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\UseStmt;
16
17
use Humbug\PhpScoper\PhpParser\NodeVisitor\AppendParentNode;
18
use Humbug\PhpScoper\Reflector;
19
use PhpParser\Node;
20
use PhpParser\Node\Name;
21
use PhpParser\Node\Stmt\Use_;
22
use PhpParser\Node\Stmt\UseUse;
23
use PhpParser\NodeVisitorAbstract;
24
25
/**
26
 * Prefixes the use statements.
27
 *
28
 * @private
29
 */
30
final class UseStmtPrefixer extends NodeVisitorAbstract
31
{
32
    private $prefix;
33
    private $reflector;
34
35 371
    public function __construct(string $prefix, Reflector $reflector)
36
    {
37 371
        $this->prefix = $prefix;
38 371
        $this->reflector = $reflector;
39
    }
40
41
    /**
42
     * @inheritdoc
43
     */
44 370
    public function enterNode(Node $node)
45
    {
46 370
        if ($node instanceof UseUse && $this->shouldPrefixUseStmt($node)) {
47 164
            $node->name = Name::concat($this->prefix, $node->name, $node->name->getAttributes());
48
        }
49
50 370
        return $node;
51
    }
52
53 204
    private function shouldPrefixUseStmt(UseUse $use): bool
54
    {
55 204
        $useType = $this->findUseType($use);
56
57
        // If is already from the prefix namespace
58 204
        if ($this->prefix === $use->name->getFirst()) {
59 11
            return false;
60
        }
61
62
        // Is not from the Composer namespace
63 193
        if ('Composer' === $use->name->getFirst()) {
64
            return false;
65
        }
66
67 193
        if (Use_::TYPE_FUNCTION === $useType) {
68 17
            return false === $this->reflector->isFunctionInternal((string) $use->name);
69
        }
70
71 177
        if (Use_::TYPE_CONSTANT === $useType) {
72 18
            return false === $this->reflector->isConstantInternal((string) $use->name);
73
        }
74
75 160
        return Use_::TYPE_NORMAL !== $useType || false === $this->reflector->isClassInternal((string) $use->name);
76
    }
77
78
    /**
79
     * Finds the type of the use statement.
80
     *
81
     * @param UseUse $use
82
     *
83
     * @return int See \PhpParser\Node\Stmt\Use_ type constants.
84
     */
85 204
    private function findUseType(UseUse $use): int
86
    {
87 204
        if (Use_::TYPE_UNKNOWN === $use->type) {
88
            /** @var Use_ $parentNode */
89 199
            $parentNode = AppendParentNode::getParent($use);
90
91 199
            return $parentNode->type;
92
        }
93
94 5
        return $use->type;
95
    }
96
}
97