Completed
Push — master ( dcddf7...d2fb4d )
by Théo
05:16 queued 03:22
created

ScopeSingleLevelUseAliasVisitor   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 60
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
dl 0
loc 60
rs 10
c 0
b 0
f 0
wmc 13
lcom 1
cbo 3

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A beforeTraverse() 0 4 1
B enterNode() 0 20 7
A scopeUseStmtIfUsedInAnyNameAsAliasedNamespace() 0 13 4
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\UseStmt;
16
17
use PhpParser\Node;
18
use PhpParser\Node\Name;
19
use PhpParser\Node\Stmt\GroupUse;
20
use PhpParser\Node\Stmt\UseUse;
21
use PhpParser\NodeVisitorAbstract;
22
23
/**
24
 * Scopes single level use statements with an alias:.
25
 *
26
 * ```
27
 * use Foo as Bar;
28
 *
29
 * new Foo();
30
 * ```
31
 *
32
 * =>
33
 *
34
 * ```
35
 * use Humbug\Foo as Bar;
36
 *
37
 * new Foo();
38
 * ```
39
 */
40
final class ScopeSingleLevelUseAliasVisitor extends NodeVisitorAbstract
41
{
42
    private $prefix;
43
44
    /**
45
     * @var array
46
     */
47
    private $aliases;
48
49
    public function __construct(string $prefix)
50
    {
51
        $this->prefix = $prefix;
52
    }
53
54
    /**
55
     * @inheritdoc
56
     */
57
    public function beforeTraverse(array $nodes)
58
    {
59
        $this->aliases = [];
60
    }
61
62
    /**
63
     * @inheritdoc
64
     */
65
    public function enterNode(Node $node): Node
66
    {
67
        // Collate all single level aliases
68
        if ($node instanceof UseUse
69
            && (false === $node->hasAttribute('parent')     // double check if this one may be removed
70
                || false === ($node->getAttribute('parent') instanceof GroupUse)
71
            )
72
            && $this->prefix !== $node->name->getFirst()
73
            // Is a one level use statement
74
            && 1 === count($node->name->parts)
75
            // Has an alias
76
            && $node->alias !== $node->name->getFirst()
77
        ) {
78
            $this->aliases[$node->alias] = $node;
79
80
            return $node;
81
        }
82
83
        return $this->scopeUseStmtIfUsedInAnyNameAsAliasedNamespace($node);
84
    }
85
86
    private function scopeUseStmtIfUsedInAnyNameAsAliasedNamespace(Node $node): Node
87
    {
88
        if ($node instanceof Name
89
            && 1 < count($node->parts)
90
            && in_array($node->getFirst(), array_keys($this->aliases))
91
        ) {
92
            $nodeToPrefix = $this->aliases[$node->getFirst()];
93
            $nodeToPrefix->name = Name::concat($this->prefix, $nodeToPrefix->name);
94
            unset($this->aliases[$node->getFirst()]);
95
        }
96
97
        return $node;
98
    }
99
}
100