Passed
Pull Request — master (#93)
by Matthias
04:16
created

UsedSymbolCollector::recordUsageOf()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace ComposerRequireChecker\NodeVisitor;
4
5
use PhpParser\Node;
6
use PhpParser\NodeVisitorAbstract;
7
8
final class UsedSymbolCollector extends NodeVisitorAbstract
9
{
10
    /**
11
     * @var mixed[]
12
     */
13
    private $collectedSymbols = [];
14
15 23
    public function __construct()
16
    {
17 23
    }
18
19
    /**
20
     * @return string[]
21
     */
22 23
    public function getCollectedSymbols(): array
23
    {
24 23
        return array_keys($this->collectedSymbols);
25
    }
26
27
    /**
28
     * {@inheritDoc}
29
     */
30 2
    public function beforeTraverse(array $nodes)
31
    {
32 2
        $this->collectedSymbols = [];
33
34 2
        return parent::beforeTraverse($nodes);
0 ignored issues
show
Bug introduced by
Are you sure the usage of parent::beforeTraverse($nodes) targeting PhpParser\NodeVisitorAbstract::beforeTraverse() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
35
    }
36
37
    /**
38
     * {@inheritDoc}
39
     */
40 23
    public function enterNode(Node $node)
41
    {
42 23
        $this->recordExtendsUsage($node);
43 23
        $this->recordImplementsUsage($node);
44 23
        $this->recordClassExpressionUsage($node);
45 23
        $this->recordCatchUsage($node);
46 23
        $this->recordFunctionCallUsage($node);
47 23
        $this->recordFunctionParameterTypesUsage($node);
48 23
        $this->recordFunctionReturnTypeUsage($node);
49 23
        $this->recordConstantFetchUsage($node);
50 23
        $this->recordTraitUsage($node);
51
52 23
        return parent::enterNode($node);
0 ignored issues
show
Bug introduced by
Are you sure the usage of parent::enterNode($node) targeting PhpParser\NodeVisitorAbstract::enterNode() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
53
    }
54
55 23
    private function recordExtendsUsage(Node $node)
56
    {
57 23
        if ($node instanceof Node\Stmt\Class_) {
58 4
            array_map([$this, 'recordUsageOf'], array_filter([$node->extends]));
59
        }
60
61 23
        if ($node instanceof Node\Stmt\Interface_) {
62 2
            array_map([$this, 'recordUsageOf'], array_filter($node->extends));
63
        }
64 23
    }
65
66 23
    private function recordImplementsUsage(Node $node)
67
    {
68 23
        if ($node instanceof Node\Stmt\Class_) {
69 4
            array_map([$this, 'recordUsageOf'], $node->implements);
70
        }
71 23
    }
72
73 23
    private function recordClassExpressionUsage(Node $node)
74
    {
75 23
        if (($node instanceof Node\Expr\StaticCall
76 22
                || $node instanceof Node\Expr\StaticPropertyFetch
77 21
                || $node instanceof Node\Expr\ClassConstFetch
78 20
                || $node instanceof Node\Expr\New_
79 23
                || $node instanceof Node\Expr\Instanceof_
80
            )
81 23
            && $node->class instanceof Node\Name
82
        ) {
83 6
            $this->recordUsageOf($node->class);
84
        }
85 23
    }
86
87 23
    private function recordCatchUsage(Node $node)
88
    {
89 23
        if ($node instanceof Node\Stmt\Catch_) {
90 2
            foreach ($node->types as $type) {
91 2
                $this->recordUsageOf($type);
92
            }
93
        }
94 23
    }
95
96 23
    private function recordFunctionCallUsage(Node $node)
97
    {
98 23
        if ($node instanceof Node\Expr\FuncCall
99 23
            && $node->name instanceof Node\Name
100
        ) {
101 2
            $this->recordUsageOf($node->name);
102
        }
103 23
    }
104
105 23
    private function recordFunctionParameterTypesUsage(Node $node)
106
    {
107 23
        if ($node instanceof Node\Stmt\Function_
108 23
            || $node instanceof Node\Stmt\ClassMethod
109
        ) {
110 9
            foreach ($node->getParams() as $param) {
111 5
                if ($param->type instanceof Node\Name) {
112 3
                    $this->recordUsageOf($param->type);
113
                }
114 5
                if (is_string($param->type) || $param->type instanceof Node\Identifier) {
115 5
                    $this->recordUsageOfByString($param->type);
116
                }
117
            }
118
        }
119 23
    }
120
121 23
    private function recordFunctionReturnTypeUsage(Node $node)
122
    {
123 23
        if ($node instanceof Node\Stmt\Function_
124 23
            || $node instanceof Node\Stmt\ClassMethod
125
        ) {
126 9
            if ($node->getReturnType() instanceof Node\Name) {
127 3
                $this->recordUsageOf($node->getReturnType());
128
            }
129 9
            if (is_string($node->getReturnType()) || $node->getReturnType() instanceof Node\Identifier) {
130 3
                $this->recordUsageOfByString($node->getReturnType());
131
            }
132
        }
133 23
    }
134
135 23
    private function recordConstantFetchUsage(Node $node)
136
    {
137 23
        if ($node instanceof Node\Expr\ConstFetch) {
138 2
            $this->recordUsageOf($node->name);
139
        }
140 23
    }
141
142 23
    private function recordTraitUsage(Node $node)
143
    {
144 23
        if (!$node instanceof Node\Stmt\TraitUse) {
145 21
            return;
146
        }
147
148 2
        array_map([$this, 'recordUsageOf'], $node->traits);
149
150 2
        foreach ($node->adaptations as $adaptation) {
151 1
            if (null !== $adaptation->trait) {
152
                $this->recordUsageOf($adaptation->trait);
153
            }
154
155 1
            if ($adaptation instanceof Node\Stmt\TraitUseAdaptation\Precedence) {
156 1
                array_map([$this, 'recordUsageOf'], $adaptation->insteadof);
157
            }
158
        }
159 2
    }
160
161
    /**
162
     * @param Node\Name $symbol
163
     *
164
     * @return void
165
     */
166 19
    private function recordUsageOf(Node\Name $symbol)
167
    {
168 19
        $this->collectedSymbols[(string)$symbol] = $symbol;
169 19
    }
170
171
    /**
172
     * @param string $symbol
173
     *
174
     * @return void
175
     */
176 5
    private function recordUsageOfByString(string $symbol)
177
    {
178 5
        $this->collectedSymbols[$symbol] = $symbol;
179 5
    }
180
}
181