Completed
Push — develop ( 7336c7...a13f6a )
by Paul
01:53
created

MethodNodeParser::getter()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 11
nc 3
nop 2
dl 0
loc 20
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace PhpUnitGen\Parser\NodeParser;
4
5
use PhpParser\Node;
6
use PhpUnitGen\Annotation\GetAnnotation;
7
use PhpUnitGen\Annotation\SetAnnotation;
8
use PhpUnitGen\Exception\Exception;
9
use PhpUnitGen\Model\FunctionModel;
10
use PhpUnitGen\Model\ModelInterface\InterfaceModelInterface;
11
use PhpUnitGen\Model\ModelInterface\TraitModelInterface;
12
use PhpUnitGen\Model\PropertyInterface\NodeInterface;
13
use PhpUnitGen\Parser\NodeParserUtil\MethodVisibilityHelper;
14
use Respect\Validation\Validator;
15
16
/**
17
 * Class MethodNodeParser.
18
 *
19
 * @author     Paul Thébaud <[email protected]>.
20
 * @copyright  2017-2018 Paul Thébaud <[email protected]>.
21
 * @license    https://opensource.org/licenses/MIT The MIT license.
22
 * @link       https://github.com/paul-thebaud/phpunit-generator
23
 * @since      Class available since Release 2.0.0.
24
 */
25
class MethodNodeParser extends AbstractFunctionNodeParser
26
{
27
    /**
28
     * Parse a node to update the parent node model.
29
     *
30
     * @param mixed         $node   The node to parse.
31
     * @param NodeInterface $parent The parent node.
32
     */
33
    public function invoke($node, NodeInterface $parent): void
34
    {
35
        if (! $node instanceof Node\Stmt\ClassMethod || ! $parent instanceof InterfaceModelInterface) {
36
            throw new Exception('MethodNodeParser is made to parse a method node');
37
        }
38
39
        $function = new FunctionModel();
40
        $function->setParentNode($parent);
41
        $function->setName($node->name);
42
        $function->setIsFinal($node->isFinal());
43
        $function->setIsStatic($node->isStatic());
44
        $function->setIsAbstract($node->isAbstract());
45
        $function->setVisibility(MethodVisibilityHelper::getMethodVisibility($node));
46
47
        $this->parseFunction($node, $function);
48
49
        $parent->addFunction($function);
50
51
        if ($this->autoGetterOrSetter($function, $parent)) {
52
            return;
53
        }
54
        if (($documentation = $node->getDocComment()) !== null) {
55
            $this->documentationNodeParser->invoke($documentation, $function);
56
        }
57
    }
58
59
    /**
60
     * Check if auto generation is enabled, and try to generate getter or setter annotation.
61
     *
62
     * @param FunctionModel           $function The function to check for.
63
     * @param InterfaceModelInterface $parent   The parent to use.
64
     *
65
     * @return bool True if a getter or a setter annotation has been created.
66
     */
67
    private function autoGetterOrSetter(FunctionModel $function, InterfaceModelInterface $parent): bool
68
    {
69
        if ($this->config->hasAuto() && $parent instanceof TraitModelInterface) {
70
            if ($this->getter($function, $parent)) {
71
                return true;
72
            }
73
            if ($this->setter($function, $parent)) {
74
                return true;
75
            }
76
        }
77
        return false;
78
    }
79
80
    /**
81
     * Try to create a getter annotation for function.
82
     *
83
     * @param FunctionModel       $function The function to check for.
84
     * @param TraitModelInterface $parent The parent to use.
85
     *
86
     * @return bool True if a getter annotation has been created.
87
     */
88
    private function getter(FunctionModel $function, TraitModelInterface $parent): bool
89
    {
90
        // Check if function name matches
91
        preg_match('/^get(.+)$/', $function->getName(), $matches);
92
93
        if (Validator::arrayType()->length(2, 2)->validate($matches)) {
94
            // Check if property exists
95
            $property = lcfirst($matches[1]);
96
            if ($parent->hasAttribute($property, $function->isStatic())) {
97
                $annotation = new GetAnnotation();
98
                $annotation->setName('@PhpUnitGen\\getter');
99
                $function->addAnnotation($annotation);
100
                $annotation->setParentNode($function);
101
                $annotation->compile();
102
103
                return true;
104
            }
105
        }
106
107
        return false;
108
    }
109
110
    /**
111
     * Try to create a setter annotation for function.
112
     *
113
     * @param FunctionModel       $function The function to check for.
114
     * @param TraitModelInterface $parent The parent to use.
115
     *
116
     * @return bool True if a setter annotation has been created.
117
     */
118
    private function setter(FunctionModel $function, TraitModelInterface $parent): bool
119
    {
120
        // Check if function name matches
121
        preg_match('/^set(.+)$/', $function->getName(), $matches);
122
123
        if (Validator::arrayType()->length(2, 2)->validate($matches)) {
124
            // Check if property exists
125
            $property = lcfirst($matches[1]);
126
            if ($parent->hasAttribute($property, $function->isStatic())) {
127
                $annotation = new SetAnnotation();
128
                $annotation->setName('@PhpUnitGen\\setter');
129
                $annotation->setParentNode($function);
130
                $function->addAnnotation($annotation);
131
                $annotation->compile();
132
133
                return true;
134
            }
135
        }
136
137
        return false;
138
    }
139
}
140