MethodGenerator::generate()   C
last analyzed

Complexity

Conditions 11
Paths 72

Size

Total Lines 51

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 29
CRAP Score 11

Importance

Changes 0
Metric Value
dl 0
loc 51
ccs 29
cts 29
cp 1
rs 6.9224
c 0
b 0
f 0
cc 11
nc 72
nop 1
crap 11

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Leaditin\Code\Generator;
4
5
use Leaditin\Code\Argument;
6
use Leaditin\Code\DocBlock;
7
use Leaditin\Code\Member\Method;
8
use Leaditin\Code\Tag;
9
10
/**
11
 * @package Leaditin\Code
12
 * @author Igor Vuckovic <[email protected]>
13
 * @license MIT
14
 */
15
class MethodGenerator extends MemberGenerator
16
{
17
    /**
18
     * @var ArgumentGenerator
19
     */
20
    protected $argumentGenerator;
21
22
    /**
23
     * @param ArgumentGenerator $argumentGenerator
24
     * @param DocBlockGenerator $docBlockGenerator
25
     * @param TypeGenerator $typeGenerator
26
     * @param VisibilityGenerator $visibilityGenerator
27
     */
28 3
    public function __construct(
29
        ArgumentGenerator $argumentGenerator,
30
        DocBlockGenerator $docBlockGenerator,
31
        TypeGenerator $typeGenerator,
32
        VisibilityGenerator $visibilityGenerator
33
    ) {
34 3
        parent::__construct($docBlockGenerator, $typeGenerator, $visibilityGenerator);
35
36 3
        $this->argumentGenerator = $argumentGenerator;
37 3
    }
38
39
    /**
40
     * @param Method $method
41
     *
42
     * @return string
43
     */
44 3
    public function generate(Method $method): string
45
    {
46 3
        $output = $this->generateLine($this->docBlockGenerator->generate($this->generateDocBlock($method)), 0);
47
48 3
        $line = '';
49 3
        if ($method->isAbstract()) {
50 1
            $line .= 'abstract ';
51 2
        } elseif ($method->isFinal()) {
52 1
            $line .= 'final ';
53
        }
54
55 3
        $line .= $this->visibilityGenerator->generate($method->visibility());
56
57 3
        if ($method->isStatic()) {
58 1
            $line .= ' static';
59
        }
60
61 3
        $line .= ' function ' . $method->name() . '(';
62
63 3
        $arguments = [];
64 3
        foreach ($method->arguments() as $argument) {
65 2
            $arguments[] = $this->argumentGenerator->generate($argument);
66
        }
67 3
        $line .= implode(', ', $arguments);
68
69 3
        $line .= ')';
70
71 3
        if ($method->returnType() !== null) {
72 3
            $line .= ': ' . $this->typeGenerator->generate($method->returnType());
73
        }
74
75 3
        if ($method->isAbstract() || $method->scope() === Method::SCOPE_INTERFACE) {
76 1
            $output .= $this->generateLine($line . ';');
77
78 1
            return rtrim($output, static::END_OF_LINE);
79
        }
80
81 2
        $output .= $this->generateLine($line);
82 2
        $output .= $this->generateLine('{');
83
84 2
        if ($method->body() !== null) {
85 2
            foreach (explode(PHP_EOL, trim($method->body())) as $line) {
86 2
                $line = preg_replace('#^((?![a-zA-Z0-9_-]+;).+?)$#m', '$1', $line);
87 2
                $output .= $this->generateLine($line, $line === '' ? 0 : 2);
88
            }
89
        }
90
91 2
        $output .= $this->generateLine('}');
92
93 2
        return rtrim($output, static::END_OF_LINE);
94
    }
95
96
    /**
97
     * @param Method $method
98
     *
99
     * @return DocBlock
100
     */
101 3
    protected function generateDocBlock(Method $method): DocBlock
102
    {
103 3
        $docblock = '';
104 3
        $shortDescription = null;
105 3
        $longDescription = null;
106 3
        $tags = [];
107
108 3
        if ($method->docBlock() !== null) {
109 3
            $docblock = $this->docBlockGenerator->generate($method->docBlock());
110 3
            $shortDescription = $method->docBlock()->shortDescription();
111 3
            $longDescription = $method->docBlock()->longDescription();
112 3
            $tags = $method->docBlock()->tags();
113
        }
114
115 3
        foreach ($method->arguments() as $argument) {
116 2
            if (($tag = $this->generateTagFromArgument($argument, $docblock)) !== null) {
117 2
                $tags[] = $tag;
118
            }
119
        }
120
121 3
        if ($method->returnType() !== null && strpos($docblock, '@return') === false) {
122 3
            $tags[] = new Tag('return', ($method->returnType()->isNullable() ? 'null|' : '') . $method->returnType()->type());
123
        }
124
125 3
        return new DocBlock($shortDescription, $longDescription, $tags);
126
    }
127
128
    /**
129
     * @param Argument $argument
130
     * @param string $docBlock
131
     *
132
     * @return null|Tag
133
     */
134 2
    protected function generateTagFromArgument(Argument $argument, string $docBlock): ?Tag
135
    {
136 2
        $pattern = '/@param.+\$' . $argument->name() . '/';
137
138 2
        if (preg_match($pattern, $docBlock)) {
139 1
            return null;
140
        }
141
142 2
        $value = preg_replace('/\?(\w+)/', 'null|$1', $this->typeGenerator->generate($argument->type()));
143 2
        $value .= ' $' . $argument->name();
144
145 2
        return new Tag('param', $value);
146
    }
147
}
148