CodeGenMethod::isReturnVoid()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 2
nc 2
nop 1
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Ray\Aop;
6
7
use Doctrine\Common\Annotations\AnnotationException;
8
use PhpParser\Node\Identifier;
9
use PhpParser\Node\Stmt;
10
use PhpParser\Node\Stmt\Class_;
11
use PhpParser\Node\Stmt\ClassMethod;
12
use PhpParser\NodeAbstract;
13
use PhpParser\Parser;
14
15
use function array_keys;
16
use function assert;
17
use function in_array;
18
19
final class CodeGenMethod
20
{
21
    /** @var Parser */
22
    private $parser;
23
24
    /**
25
     * @throws AnnotationException
26
     */
27
    public function __construct(
28
        Parser $parser
29
    ) {
30
        $this->parser = $parser;
31
    }
32
33
    /**
34
     * @return ClassMethod[]
35
     */
36
    public function getMethods(BindInterface $bind, CodeVisitor $code): array
37
    {
38
        $bindingMethods = array_keys($bind->getBindings());
39
        $classMethods = $code->classMethod;
40
        $methods = [];
41
        foreach ($classMethods as $classMethod) {
42
            $methodName = $classMethod->name->name;
43
            $isBindingMethod = in_array($methodName, $bindingMethods, true);
44
            $isPublic = $classMethod->flags === Class_::MODIFIER_PUBLIC;
45
            if ($isBindingMethod && $isPublic) {
46
                $methodInsideStatements = $this->getTemplateMethodNodeStmts(
47
                    $classMethod->getReturnType()
48
                );
49
                // replace statements in the method
50
                $classMethod->stmts = $methodInsideStatements;
51
                $methods[] = $classMethod;
52
            }
53
        }
54
55
        return $methods;
56 33
    }
57
58
    /**
59
     * @return Stmt[]
60
     */
61 33
    private function getTemplateMethodNodeStmts(?NodeAbstract $returnType): array
62 33
    {
63 33
        $code = $this->isReturnVoid($returnType) ? AopTemplate::RETURN_VOID : AopTemplate::RETURN;
64 33
        $parts = $this->parser->parse($code);
65 33
        assert(isset($parts[0]));
66
        $node = $parts[0];
67
        assert($node instanceof Class_);
68
        $methodNode = $node->getMethods()[0];
69
        assert($methodNode->stmts !== null);
70
71
        return $methodNode->stmts;
72
    }
73 17
74
    private function isReturnVoid(?NodeAbstract $returnType): bool
75 17
    {
76 17
        return $returnType instanceof Identifier && $returnType->name === 'void';
77 17
    }
78
}
79