Completed
Pull Request — master (#186)
by Дмитрий
11:18
created

ResolveExpressionTrait::findNode()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 4
nc 3
nop 2
dl 0
loc 8
ccs 7
cts 7
cp 1
crap 3
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author Patsura Dmitry https://github.com/ovr <[email protected]>
4
 */
5
6
namespace PHPSA\Analyzer\Helper;
7
8
use PhpParser\Node;
9
use PhpParser\Node\Expr\FuncCall;
10
use PhpParser\Node\Expr\Yield_;
11
use PhpParser\Node\Stmt\Return_;
12
use PHPSA\Context;
13
14
trait ResolveExpressionTrait
15
{
16
    /**
17
     * @param FuncCall $funcCall
18
     * @param Context $context
19
     * @return string|bool
20
     */
21 12
    public function resolveFunctionName(FuncCall $funcCall, Context $context)
22
    {
23 12
        $funcNameCompiledExpression = $context->getExpressionCompiler()->compile($funcCall->name);
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $funcNameCompiledExpression exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
24
25 12
        if ($funcNameCompiledExpression->isString() && $funcNameCompiledExpression->isCorrectValue()) {
26 10
            return $funcNameCompiledExpression->getValue();
27 2
        } else if (!$funcNameCompiledExpression->isCallable()) {
28 2
            $context->debug(
29 2
                'Unexpected function name type ' . $funcNameCompiledExpression->getTypeName(),
30 2
                $funcCall->name
31 2
            );
32 2
        }
33
34 2
        return false;
35
    }
36
37
    /**
38
     * Return \Generator with Return_ statement(s)
39
     *
40
     * @param \PhpParser\Node[] $nodes
41
     * @return \Generator
42
     */
43 3
    protected function findReturnStatement(array $nodes)
44
    {
45 3
        return $this->findNode($nodes, Return_::class);
46
    }
47
48
    /**
49
     * Return \Generator with Yield_ expression(s)
50
     *
51
     * @param \PhpParser\Node[] $nodes
52
     * @return \Generator
53
     */
54 1
    protected function findYieldExpression(array $nodes)
55
    {
56 1
        return $this->findNode($nodes, Yield_::class);
57
    }
58
59
    /**
60
     * @param array $nodes
61
     * @param string $nodeName Class name of Node(s) what We should return
62
     * @return \Generator
63
     */
64 4
    protected function findNode(array $nodes, $nodeName)
65
    {
66 4
        foreach ($this->traverseArray($nodes) as $node) {
67 4
            if (get_class($node) === $nodeName) {
68 3
                yield $node;
69 3
            }
70 4
        }
71 4
    }
72
73
    /**
74
     * For the code above
75
     * Я атеист, но когда я начинал это писать, только Бог и я понимали, что я делаю
76
     * Сейчас остался только Бог
77
     *
78
     * @param Node $node
79
     * @return \Generator
80
     *
81
     * @todo After move to PHP 7.0+ use yield from
82
     */
83 4
    protected function traverseNode(Node $node)
84
    {
85 4
        foreach ($node->getSubNodeNames() as $name) {
86 4
            $subNode = &$node->$name;
87
88 4
            if (is_array($subNode)) {
89
                foreach ($this->traverseArray($subNode) as $rNode) {
90
                    yield $rNode;
91
                }
92 4
            } elseif ($subNode instanceof Node) {
93 2
                yield $subNode;
94
95 2
                foreach ($this->traverseNode($subNode) as $rNode) {
96
                    yield $rNode;
97 2
                }
98 2
            }
99 4
        }
100 4
    }
101
102
    /**
103
     * @param array $nodes
104
     * @return \Generator
105
     */
106 4
    protected function traverseArray(array $nodes)
107
    {
108 4
        foreach ($nodes as $node) {
109 4
            if (is_array($node)) {
110
                foreach ($this->traverseArray($node) as $rNode) {
111
                    yield $rNode;
112
                }
113 4
            } elseif ($node instanceof Node) {
114 4
                yield $node;
115
116 4
                foreach ($this->traverseNode($node) as $rNode) {
117 2
                    yield $rNode;
118 4
                }
119 4
            }
120 4
        }
121 4
    }
122
}
123