Completed
Push — master ( 74c262...0b4843 )
by Théo
03:38 queued 01:33
created

NameStmtPrefixer::enterNode()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 4
nc 4
nop 1
dl 0
loc 7
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\NodeVisitor;
16
17
use Humbug\PhpScoper\NodeVisitor\Resolver\FullyQualifiedNameResolver;
18
use PhpParser\Node;
19
use PhpParser\Node\Expr\ClassConstFetch;
20
use PhpParser\Node\Expr\ConstFetch;
21
use PhpParser\Node\Expr\FuncCall;
22
use PhpParser\Node\Name;
23
use PhpParser\Node\Name\FullyQualified;
24
use PhpParser\NodeVisitorAbstract;
25
26
/**
27
 * ```
28
 * new Foo\Bar();
29
 * ```.
30
 *
31
 * =>
32
 *
33
 * ```
34
 * new \Humbug\Foo\Bar();
35
 * ```
36
 *
37
 * @private
38
 */
39
final class NameStmtPrefixer extends NodeVisitorAbstract
40
{
41
    private $prefix;
42
    private $whitelist;
43
    private $globalWhitelister;
44
    private $nameResolver;
45
46
    /**
47
     * @param string                     $prefix
48
     * @param string[]                   $whitelist
49
     * @param callable                   $globalWhitelister
50
     * @param FullyQualifiedNameResolver $nameResolver
51
     */
52 View Code Duplication
    public function __construct(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
53
        string $prefix,
54
        array $whitelist,
55
        callable $globalWhitelister,
56
        FullyQualifiedNameResolver $nameResolver
57
    ) {
58
        $this->prefix = $prefix;
59
        $this->whitelist = $whitelist;
60
        $this->globalWhitelister = $globalWhitelister;
61
        $this->nameResolver = $nameResolver;
62
    }
63
64
    /**
65
     * @inheritdoc
66
     */
67
    public function enterNode(Node $node): Node
68
    {
69
        return ($node instanceof Name && AppendParentNode::hasParent($node))
70
            ? $this->prefixName($node)
71
            : $node
72
        ;
73
    }
74
75
    private function prefixName(Name $name): Node
76
    {
77
        $parentNode = AppendParentNode::getParent($name);
78
79
        if (false === (
80
                $parentNode instanceof ConstFetch
81
                || $parentNode instanceof ClassConstFetch
82
                || $parentNode instanceof Node\Param
83
                || $parentNode instanceof FuncCall
84
                || $parentNode instanceof Node\Expr\StaticCall
85
                || $parentNode instanceof Node\Expr\New_
86
            )
87
        ) {
88
            return $name;
89
        }
90
91
        $resolvedValue = $this->nameResolver->resolveName($name);
92
93
        $resolvedName = $resolvedValue->getName();
94
95
        // Skip if is already prefixed
96
        if ($this->prefix === $resolvedName->getFirst()) {
97
            return $resolvedName;
98
        }
99
100
        // Check if the class can be prefixed
101
        if (false === ($parentNode instanceof ConstFetch || $parentNode instanceof FuncCall)) {
102
            if (1 === count($resolvedName->parts)
103
                && false === ($this->globalWhitelister)($resolvedName->toString())
104
            ) {
105
                return $resolvedName;
106
            } elseif (1 < count($resolvedName->parts)
107
                && in_array($resolvedName->toString(), $this->whitelist)
108
            ) {
109
                return $resolvedName;
110
            }
111
        }
112
113 View Code Duplication
        if ($parentNode instanceof ConstFetch
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
114
            && 1 === count($resolvedName->parts)
115
            && null === $resolvedValue->getUse()
116
        ) {
117
            return $resolvedName;
118
        }
119
120 View Code Duplication
        if ($parentNode instanceof FuncCall
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
121
            && 1 === count($resolvedName->parts)
122
            && null === $resolvedValue->getUse()
123
        ) {
124
            return $resolvedName;
125
        }
126
127
        return FullyQualified::concat($this->prefix, $resolvedName->toString(), $resolvedName->getAttributes());
128
    }
129
}
130