Completed
Pull Request — master (#287)
by algo13
03:16
created

ResolveExpressionTrait::traverseNode()   C

Complexity

Conditions 8
Paths 6

Size

Total Lines 23
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 8.0079

Importance

Changes 0
Metric Value
cc 8
eloc 13
nc 6
nop 1
dl 0
loc 23
ccs 19
cts 20
cp 0.95
crap 8.0079
rs 6.1403
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 14
    public function resolveFunctionName(FuncCall $funcCall, Context $context)
22
    {
23 14
        $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 14
        if ($funcNameCompiledExpression->isString() && $funcNameCompiledExpression->isCorrectValue()) {
26 12
            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 Yield_ expression(s)
39
     *
40
     * @param \PhpParser\Node[] $nodes
41
     * @return \Generator
42
     */
43 9
    protected function findYieldExpression(array $nodes)
44
    {
45 9
        return $this->findNode($nodes, Yield_::class);
46
    }
47
48
    /**
49
     * @param \PhpParser\Node[] $nodes
50
     * @return \Generator
51
     */
52 3
    protected function findReturnStatement(array $nodes)
53
    {
54 3
        return $this->findNode($nodes, Return_::class);
55
    }
56
57
    /**
58
     * @param array $nodes
59
     * @param string $nodeName Class name of Node(s) what We should return
60
     * @return \Generator
61
     */
62 10
    protected function findNode(array $nodes, $nodeName)
63
    {
64 10
        foreach ($this->traverseArray($nodes) as $node) {
65 10
            if (get_class($node) === $nodeName) {
66 4
                yield $node;
67 3
            }
68 10
        }
69 10
    }
70
71
    /**
72
     * For the code above
73
     * Я атеист, но когда я начинал это писать, только Бог и я понимали, что я делаю
74
     * Сейчас остался только Бог
75
     *
76
     * @param Node $node
77
     * @return \Generator
78
     *
79
     * @todo After move to PHP 7.0+ use yield from
80
     */
81 10
    protected function traverseNode(Node $node)
82
    {
83 10
        if (($node instanceof Node\FunctionLike)
84 10
         || ($node instanceof Node\Stmt\ClassLike)
85 10
        ) {
86 1
            return;
87
        }
88 10
        foreach ($node->getSubNodeNames() as $name) {
89 10
            $subNode = &$node->$name;
90
91 10
            if (is_array($subNode)) {
92 7
                foreach ($this->traverseArray($subNode) as $rNode) {
93 7
                    yield $rNode;
94 7
                }
95 10
            } elseif ($subNode instanceof Node) {
96 8
                yield $subNode;
97
98 8
                foreach ($this->traverseNode($subNode) as $rNode) {
99 6
                    yield $rNode;
100 8
                }
101 8
            }
102 10
        }
103 10
    }
104
105
    /**
106
     * @param array $nodes
107
     * @return \Generator
108
     */
109 10
    protected function traverseArray(array $nodes)
110
    {
111 10
        foreach ($nodes as $node) {
112 10
            if (is_array($node)) {
113
                foreach ($this->traverseArray($node) as $rNode) {
114
                    yield $rNode;
115
                }
116 10
            } elseif ($node instanceof Node) {
117 10
                yield $node;
118
119 10
                foreach ($this->traverseNode($node) as $rNode) {
120 8
                    yield $rNode;
121 10
                }
122 10
            }
123 10
        }
124 10
    }
125
}
126