Completed
Push — master ( f94444...a44080 )
by Théo
02:35 queued 20s
created

FullyQualifiedNameResolver   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 55
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 55
ccs 24
cts 24
cp 1
rs 10
c 0
b 0
f 0
wmc 10
lcom 1
cbo 6

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A resolveName() 0 16 2
C resolveNodeName() 0 26 7
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\Resolver;
16
17
use Humbug\PhpScoper\NodeVisitor\AppendParentNode;
18
use Humbug\PhpScoper\NodeVisitor\Collection\NamespaceStmtCollection;
19
use Humbug\PhpScoper\NodeVisitor\Collection\UseStmtCollection;
20
use Humbug\PhpScoper\NodeVisitor\NameStmtPrefixer;
21
use PhpParser\Node\Expr\ConstFetch;
22
use PhpParser\Node\Expr\FuncCall;
23
use PhpParser\Node\Name;
24
use PhpParser\Node\Name\FullyQualified;
25
use function in_array;
26
27
/**
28
 * Attempts to resolve the node name into a fully qualified node. Returns a valid (non fully-qualified) name node on
29
 * failure.
30
 */
31
final class FullyQualifiedNameResolver
32
{
33
    private $namespaceStatements;
34
    private $useStatements;
35
36 346
    public function __construct(NamespaceStmtCollection $namespaceStatements, UseStmtCollection $useStatements)
37
    {
38 346
        $this->namespaceStatements = $namespaceStatements;
39 346
        $this->useStatements = $useStatements;
40
    }
41
42 262
    public function resolveName(Name $node): ResolvedValue
43
    {
44 262
        if ($node instanceof FullyQualified) {
45 136
            return new ResolvedValue($node, null, null);
46
        }
47
48 179
        $namespaceName = $this->namespaceStatements->findNamespaceForNode($node);
49
50 179
        $useName = $this->useStatements->findStatementForNode($namespaceName, $node);
51
52 179
        return new ResolvedValue(
53 179
            $this->resolveNodeName($node, $namespaceName, $useName),
54 179
            $namespaceName,
55 179
            $useName
56
        );
57
    }
58
59 179
    private function resolveNodeName(Name $name, ?Name $namespace, ?Name $use): Name
60
    {
61 179
        if (null !== $use) {
62 92
            return FullyQualified::concat($use, $name->slice(1), $name->getAttributes());
63
        }
64
65 117
        if (null === $namespace) {
66 60
            return new FullyQualified($name, $name->getAttributes());
67
        }
68
69 72
        if (in_array((string) $name, NameStmtPrefixer::PHP_FUNCTION_KEYWORDS, true)) {
70 1
            return $name;
71
        }
72
73 72
        $parentNode = AppendParentNode::getParent($name);
74
75
        if (
76 72
            ($parentNode instanceof ConstFetch || $parentNode instanceof FuncCall)
77 72
            && 1 === count($name->parts)
78
        ) {
79
            // Ambiguous name, cannot determine the FQ name
80 55
            return $name;
81
        }
82
83 26
        return FullyQualified::concat($namespace, $name, $name->getAttributes());
84
    }
85
}
86