Completed
Push — master ( 6ef60f...4e6f84 )
by Vitaly
02:30
created

ClassGenerator::defProtectedProperty()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 4
1
<?php declare(strict_types = 1);
2
/**
3
 * Created by Vitaly Iegorov <[email protected]>.
4
 * on 03.09.16 at 09:58
5
 */
6
namespace samsonframework\generator;
7
8
/**
9
 * Class generator class.
10
 *
11
 * @author Vitaly Egorov <[email protected]>
12
 */
13
class ClassGenerator extends AbstractGenerator
14
{
15
    use AbstractFinalTrait;
16
17
    /** OOP public visibility */
18
    const VISIBILITY_PUBLIC = 'public';
19
20
    /** OOP protected visibility */
21
    const VISIBILITY_PROTECTED = 'protected';
22
23
    /** OOP private visibility */
24
    const VISIBILITY_PRIVATE = 'private';
25
26
    /** @var string Class name */
27
    protected $className;
28
29
    /** @var string Class namespace */
30
    protected $namespace;
31
32
    /** @var array Collection of class uses */
33
    protected $uses = [];
34
35
    /** @var array Collection of class used traits */
36
    protected $traits = [];
37
38
    /** @var string Multi-line file description */
39
    protected $fileDescription;
40
41
    /**
42
     * ClassGenerator constructor.
43
     *
44
     * @param string           $className Class name
45
     * @param AbstractGenerator $parent    Parent generator
46
     */
47
    public function __construct(string $className, AbstractGenerator $parent = null)
48
    {
49
        $this->className = $className;
50
51
        parent::__construct($parent);
52
    }
53
54
    /**
55
     * Set class file description.
56
     *
57
     * @param array $description Collection of class file description lines
58
     *
59
     * @return ClassGenerator
60
     */
61
    public function defDescription(array $description) : ClassGenerator
62
    {
63
        $commentsGenerator = new CommentsGenerator($this);
64
        foreach ($description as $line) {
65
            $commentsGenerator->defLine($line);
66
        }
67
68
        $this->fileDescription = $commentsGenerator->code();
69
70
        return $this;
71
    }
72
73
    /**
74
     * Set class namespace.
75
     *
76
     * @param string $namespace
77
     *
78
     * @return ClassGenerator
79
     */
80
    public function defNamespace(string $namespace) : ClassGenerator
81
    {
82
        $this->namespace = $namespace;
83
84
        return $this;
85
    }
86
87
    /**
88
     * Set class use.
89
     *
90
     * @param string $use Use class name
91
     *
92
     * @return ClassGenerator
93
     */
94
    public function defUse(string $use) : ClassGenerator
95
    {
96
        $this->uses[] = $use;
97
98
        return $this;
99
    }
100
101
    /**
102
     * Set class trait use.
103
     *
104
     * @param string $trait Trait class name
105
     *
106
     * @return ClassGenerator
107
     */
108
    public function defTrait(string $trait) : ClassGenerator
109
    {
110
        $this->traits[] = $trait;
111
112
        return $this;
113
    }
114
115
    /**
116
     * Set protected class property.
117
     *
118
     * @param string $name        Property name
119
     * @param string $type        Property type
120
     * @param mixed  $value       Property value
121
     * @param string $description Property description
122
     *
123
     * @return PropertyGenerator
124
     */
125
    public function defProtectedProperty(string $name, string $type, $value, string $description = null) : PropertyGenerator
126
    {
127
        return $this->defProperty($name, $type, $value, $description)->defProtected();
128
    }
129
130
    /**
131
     * Set class property.
132
     *
133
     * @param string $name        Property name
134
     * @param string $type        Property type
135
     * @param mixed  $value       Property value
136
     * @param string $description Property description
137
     *
138
     * @return PropertyGenerator
139
     */
140
    public function defProperty(string $name, string $type, $value = null, string $description = null) : PropertyGenerator
141
    {
142
        return (new PropertyGenerator($name, $value, $this))
143
            ->setIndentation($this->indentation)
144
            ->increaseIndentation()
145
            ->defComment()
146
            ->defVar($type, $description)
147
            ->end();
148
    }
149
150
    /**
151
     * Set protected static class property.
152
     *
153
     * @param string $name        Property name
154
     * @param string $type        Property type
155
     * @param mixed  $value       Property value
156
     * @param string $description Property description
157
     *
158
     * @return PropertyGenerator
159
     */
160
    public function defProtectedStaticProperty(string $name, string $type, $value, string $description = null) : PropertyGenerator
161
    {
162
        return $this->defStaticProperty($name, $type, $value, $description)->defProtected();
163
    }
164
165
    /**
166
     * Set static class property.
167
     *
168
     * @param string $name        Property name
169
     * @param string $type        Property type
170
     * @param mixed  $value       Property value
171
     * @param string $description Property description
172
     *
173
     * @return PropertyGenerator
174
     */
175
    public function defStaticProperty(string $name, string $type, $value, string $description = null) : PropertyGenerator
176
    {
177
        return $this->defProperty($name, $type, $value, $description)->defStatic();
178
    }
179
180
    /**
181
     * Set protected class method.
182
     *
183
     * @param string $name Method name
184
     *
185
     * @return MethodGenerator
186
     */
187
    public function defProtectedMethod(string $name) : MethodGenerator
188
    {
189
        return $this->defMethod($name)->defProtected();
190
    }
191
192
    /**
193
     * Set public class method.
194
     *
195
     * @param string $name Method name
196
     *
197
     * @return MethodGenerator
198
     */
199
    public function defMethod(string $name) : MethodGenerator
200
    {
201
        return (new MethodGenerator($name, $this))->setIndentation($this->indentation)->increaseIndentation();
202
    }
203
204
    /**
205
     * Set protected static class method.
206
     *
207
     * @param string $name Method name
208
     *
209
     * @return MethodGenerator
210
     */
211
    public function defProtectedStaticMethod(string $name) : MethodGenerator
212
    {
213
        return $this->defStaticMethod($name)->defProtected();
214
    }
215
216
    /**
217
     * Set public static class method.
218
     *
219
     * @param string $name Method name
220
     *
221
     * @return MethodGenerator
222
     */
223
    public function defStaticMethod(string $name) : MethodGenerator
224
    {
225
        return $this->defMethod($name)->defStatic();
226
    }
227
228
    /**
229
     * Set class constant.
230
     *
231
     * @param string $name
232
     * @param mixed $value
233
     *
234
     * @return $this|ClassConstantGenerator
235
     */
236
    public function defConstant(string $name, $value, string $type, string $description) : ClassConstantGenerator
237
    {
238
        return (new ClassConstantGenerator($name, $value, $this))
239
            ->setIndentation($this->indentation)
240
            ->increaseIndentation()
241
            ->defComment()
242
                ->defLine($type.' '.$description)
243
            ->end();
244
    }
245
246
    protected function buildUsesCode(array $formattedCode) : array
247
    {
248
        // Add uses
249
        foreach ($this->uses as $use) {
250
            $formattedCode[] = 'use ' . $use . ';';
251
        }
252
253
        // One empty line after uses if we have them
254
        if (count($this->uses)) {
255
            $formattedCode[] = '';
256
        }
257
258
        return $formattedCode;
259
    }
260
261
    protected function buildCommentsCode(array $formattedCode) : array
262
    {
263
        // Add comments
264
        if (array_key_exists(CommentsGenerator::class, $this->generatedCode)) {
265
            $formattedCode[] = $this->generatedCode[CommentsGenerator::class];
266
        }
267
268
        return $formattedCode;
269
    }
270
271
    protected function buildTraitsCode(array $formattedCode, string $innerIndentation) : array
272
    {
273
        // Add traits
274
        foreach ($this->traits as $trait) {
275
            $formattedCode[] = $innerIndentation . 'use ' . $trait . ';';
276
        }
277
278
        // One empty line after traits if we have them
279
        if (count($this->traits)) {
280
            $formattedCode[] = '';
281
        }
282
283
        return $formattedCode;
284
    }
285
286
    protected function buildFileDescriptionCode(array $formattedCode) : array
287
    {
288
        // Prepend file description if present
289
        if ($this->fileDescription !== null) {
290
            array_unshift($formattedCode, $this->fileDescription);
291
        }
292
293
        return $formattedCode;
294
    }
295
296
    protected function buildConstantsCode(array $formattedCode) : array
297
    {
298
        // Add constants
299
        if (array_key_exists(ClassConstantGenerator::class, $this->generatedCode)) {
300
            $formattedCode[] = $this->generatedCode[ClassConstantGenerator::class];
301
        }
302
303
        return $formattedCode;
304
    }
305
306
    protected function buildPropertiesCode(array $formattedCode) : array
307
    {
308
        if (array_key_exists(PropertyGenerator::class, $this->generatedCode)) {
309
            $formattedCode[] = $this->generatedCode[PropertyGenerator::class];
310
        }
311
312
        return $formattedCode;
313
    }
314
315
    protected function buildMethodsCode(array $formattedCode) : array
316
    {
317
        if (array_key_exists(MethodGenerator::class, $this->generatedCode)) {
318
            $formattedCode[] = $this->generatedCode[MethodGenerator::class];
319
        }
320
321
        return $formattedCode;
322
    }
323
324
    protected function buildNamespaceCode(array $formattedCode = []) : array
325
    {
326
        if ($this->namespace === null) {
327
            throw new \InvalidArgumentException('Class namespace should be defined');
328
        }
329
330
        $formattedCode[] = 'namespace ' . $this->namespace . ';';
331
332
        // One empty line after namespace
333
        $formattedCode[] = '';
334
335
        return $formattedCode;
336
    }
337
338
    /**
339
     * {@inheritdoc}
340
     * @throws \InvalidArgumentException
341
     */
342
    public function code(int $indentation = 0) : string
343
    {
344
        $formattedCode = $this->buildNamespaceCode();
345
        $formattedCode = $this->buildFileDescriptionCode($formattedCode);
346
        $formattedCode = $this->buildUsesCode($formattedCode);
347
        $formattedCode = $this->buildCommentsCode($formattedCode);
348
349
        // Add previously generated code
350
        $formattedCode[] = $this->buildDefinition();
351
        $formattedCode[] = '{';
352
353
        $indentationString = $this->indentation($indentation);
354
        $innerIndentation = $this->indentation(1);
355
356
        $formattedCode = $this->buildTraitsCode($formattedCode, $innerIndentation);
357
        $formattedCode = $this->buildConstantsCode($formattedCode);
358
        $formattedCode = $this->buildPropertiesCode($formattedCode);
359
        $formattedCode = $this->buildMethodsCode($formattedCode);
360
361
        $formattedCode[] = '}';
362
363
        return implode("\n" . $indentationString, $formattedCode);
364
    }
365
366
    /**
367
     * Build class definition.
368
     *
369
     * @return string Function definition
370
     */
371
    protected function buildDefinition()
372
    {
373
        return ($this->isFinal ? 'final ' : '') .
374
        ($this->isAbstract ? 'abstract ' : '') .
375
        'class ' .
376
        $this->className;
377
    }
378
}
379