SignatureGenerator::addMethod()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
/**
3
 * @author stev leibelt <[email protected]>
4
 * @since 2015-01-04 
5
 */
6
7
namespace Net\Bazzline\Component\CodeGenerator;
8
9
/**
10
 * Class SignatureGenerator
11
 * @package Net\Bazzline\Component\CodeGenerator
12
 */
13
class SignatureGenerator extends AbstractDocumentedGenerator
14
{
15
    /**
16
     * @var boolean
17
     */
18
    private $addEmptyLine;
19
20
    /**
21
     * @param ConstantGenerator $constant
22
     * @return $this
23
     */
24
    public function addConstant(ConstantGenerator $constant)
25
    {
26
        $this->addGeneratorProperty('constants', $constant);
27
28
        return $this;
29
    }
30
31
    /**
32
     * @param MethodGenerator $method
33
     * @return $this
34
     */
35
    public function addMethod(MethodGenerator $method)
36
    {
37
        $this->addGeneratorProperty('methods', $method);
38
39
        return $this;
40
    }
41
42
    /**
43
     * @param string $fullQualifiedClassName
44
     * @param string $alias
45
     * @return $this
46
     */
47
    public function addUse($fullQualifiedClassName, $alias = '')
48
    {
49
        $use = [
50
            'alias' => $alias,
51
            'name'  => $fullQualifiedClassName
52
        ];
53
54
        $this->addGeneratorProperty('uses', $use);
55
56
        return $this;
57
    }
58
59
    /**
60
     * @param string $name
61
     * @return $this
62
     */
63
    public function setName($name)
64
    {
65
        $this->addGeneratorProperty('name', (string) $name, false);
66
67
        return $this;
68
    }
69
70
    /**
71
     * @param string $namespace
72
     * @return $this
73
     */
74
    public function setNamespace($namespace)
75
    {
76
        $this->addGeneratorProperty('namespace', (string) $namespace, false);
77
78
        return $this;
79
    }
80
81
    /**
82
     * @throws InvalidArgumentException|RuntimeException
83
     * @return string
84
     * @todo implement exception throwing if mandatory parameter is missing
85
     * @todo decouple/move fitting areas to ClassGenerator and InterfaceGenerator
86
     */
87
    public function generate()
88
    {
89
        if ($this->canBeGenerated()) {
90
            $this->executePregenertionHook();
91
            $this->addEmptyLine = false;
92
            $this->resetContent();
93
            $this->generateNamespace();
94
            $this->generateUse();
95
            $this->generateDocumentation();
96
            $this->generateSignature();
97
            $this->generateBody();
98
        }
99
100
        return $this->generateStringFromContent();
101
    }
102
103
    protected function executePregenertionHook() {}
104
105
    private function generateBody()
106
    {
107
        $this->addEmptyLine = false;
108
        $this->addContent('{');
109
        /** @var null|ConstantGenerator[] $constants */
110
        $constants = $this->getGeneratorProperty('constants');
111
        /** @var null|MethodGenerator[] $methods */
112
        $methods = $this->getGeneratorProperty('methods');
113
        /** @var null|PropertyGenerator[] $properties */
114
        $properties = $this->getGeneratorProperty('properties');
115
        /** @var null|array $traits */
116
        $traits = $this->getGeneratorProperty('traits');
117
118
        if (is_array($traits)) {
119
            $this->addContent('use ' . implode(',', $traits) . ';', true);
120
            $this->addEmptyLine = true;
121
        }
122
        if (is_array($constants)) {
123
            if ($this->addEmptyLine) {
124
                $this->addContent('');
125
            }
126
            $lastArrayKey = $this->getLastArrayKey($constants);
127
            foreach($constants as $key => $constant) {
128
                $this->addGeneratorAsContent($constant, true);
129
                if ($key !== $lastArrayKey) {
130
                    $this->addContent('');
131
                }
132
            }
133
            $this->addEmptyLine = true;
134
        }
135
        if (is_array($properties)) {
136
            if ($this->addEmptyLine) {
137
                $this->addContent('');
138
            }
139
            $lastArrayKey = $this->getLastArrayKey($properties);
140
            foreach($properties as $key => $property) {
141
                $this->addGeneratorAsContent($property, true);
142
                if ($key !== $lastArrayKey) {
143
                    $this->addContent('');
144
                }
145
            }
146
            $this->addEmptyLine = true;
147
        }
148 View Code Duplication
        if (is_array($methods)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
149
            if ($this->addEmptyLine) {
150
                $this->addContent('');
151
            }
152
            $lastArrayKey = $this->getLastArrayKey($methods);
153
            foreach($methods as $key => $method) {
154
                $this->addGeneratorAsContent($method, true);
155
                if ($key !== $lastArrayKey) {
156
                    $this->addContent('');
157
                }
158
            }
159
        }
160
161
        $this->addContent('}');
162
        $this->addEmptyLine = false;
163
    }
164
165
    private function generateNamespace()
166
    {
167
        $namespace = $this->getGeneratorProperty('namespace');
168
169
        if (!is_null($namespace)) {
170
            $this->addContent(
171
                $this->getLineGenerator(
172
                    'namespace ' . $namespace . ';'
173
                )
174
            );
175
            $this->addEmptyLine = true;
176
        }
177
    }
178
179
    private function generateDocumentation()
180
    {
181
        $documentation = $this->getGeneratorProperty('documentation');
182
183
        if ($documentation instanceof DocumentationGenerator) {
184
            if ($this->completeDocumentationAutomatically) {
185
                $isInterface    = $this->getGeneratorProperty('interface', false);
186
                $name           = $this->getGeneratorProperty('name');
187
                $namespace      = $this->getGeneratorProperty('namespace');
188
189
                if (is_string($name)) {
190
                    //@todo decouple/move fitting areas to ClassGenerator and InterfaceGenerator
191
                    if ($isInterface) {
192
                        $documentation->setInterface($name);
193
                    } else {
194
                        $documentation->setClass($name);
195
                    }
196
                }
197
                if (is_string($namespace)) {
198
                    $documentation->setPackage($namespace);
199
                }
200
            }
201
            if ($documentation->hasContent()) {
202
                if ($this->addEmptyLine) {
203
                    $this->addContent('');
204
                    $this->addEmptyLine = false;
205
                }
206
                $this->addGeneratorAsContent($documentation);
207
            }
208
        }
209
    }
210
211
    /**
212
     * @throws \Net\Bazzline\Component\CodeGenerator\RuntimeException
213
     */
214
    private function generateSignature()
215
    {
216
        $isAbstract     = $this->getGeneratorProperty('abstract', false);
217
        $isInterface    = $this->getGeneratorProperty('interface', false);
218
        $isFinal        = $this->getGeneratorProperty('final', false);
219
        $extends        = $this->getGeneratorProperty('extends');
220
        $implements     = $this->getGeneratorProperty('implements');
221
        $name           = $this->getGeneratorProperty('name');
222
223
        if (is_null($name)) {
224
            throw new RuntimeException('name is mandatory');
225
        }
226
227
        if ($this->addEmptyLine) {
228
            $this->addContent('');
229
            $this->addEmptyLine = false;
230
        }
231
232
        $line = $this->getLineGenerator();
233
        if ($isAbstract) {
234
            $line->add('abstract');
235
        } else if ($isInterface) {
236
            $line->add('interface');
237
        } else if ($isFinal) {
238
            $line->add('final');
239
        }
240
241
        //@todo decouple/move fitting areas to ClassGenerator and InterfaceGenerator
242
        if ($isInterface) {
243
            $line->add($name);
244
245
            if (is_array($extends)) {
246
                $line->add('extends');
247
                $line->add(implode(', ', $extends));
248
            }
249
        } else {
250
            $line->add('class ' . $name);
251
252
            if (is_string($extends)) {
253
                $line->add('extends');
254
                $line->add($extends);
255
            }
256
        }
257
258
        if (is_array($implements)) {
259
            $line->add('implements');
260
            $line->add(implode(', ', $implements));
261
        }
262
263
        $this->addContent($line);
264
        $this->addEmptyLine = true;
265
    }
266
267
    private function generateUse()
268
    {
269
        $uses = $this->getGeneratorProperty('uses');
270
271
        if (is_array($uses)) {
272
            if ($this->addEmptyLine) {
273
                $this->addContent('');
274
                $this->addEmptyLine = false;
275
            }
276
            foreach ($uses as $use) {
277
                $line = $this->getLineGenerator();
278
                if (strlen($use['alias']) > 0) {
279
                    $line->add('use ' . $use['name'] . ' as ' . $use['alias'] . ';');
280
                } else {
281
                    $line->add('use ' . $use['name'] . ';');
282
                }
283
                $this->addContent($line);
284
            }
285
            $this->addEmptyLine = true;
286
        }
287
    }
288
}
289