Completed
Push — master ( ce9df9...d45fda )
by Vitaly
02:32
created

ClassGenerator::defTrait()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
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 samsonphp\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
    /** @var array Class methods */
42
    protected $methods;
43
44
    /**
45
     * ClassGenerator constructor.
46
     *
47
     * @param string           $className Class name
48
     * @param GenericGenerator $parent    Parent generator
49
     */
50
    public function __construct(string $className, GenericGenerator $parent = null)
51
    {
52
        $this->className = $className;
53
54
        parent::__construct($parent);
55
    }
56
57
    /**
58
     * Set class file description.
59
     *
60
     * @param array $description Collection of class file description lines
61
     *
62
     * @return ClassGenerator
63
     */
64
    public function defDescription(array $description) : ClassGenerator
65
    {
66
        $commentsGenerator = new CommentsGenerator($this);
67
        foreach ($description as $line) {
68
            $commentsGenerator->defLine($line);
69
        }
70
71
        $this->fileDescription = $commentsGenerator->code();
72
73
        return $this;
74
    }
75
76
    /**
77
     * Set class namespace.
78
     *
79
     * @param string $namespace
80
     *
81
     * @return ClassGenerator
82
     */
83
    public function defNamespace(string $namespace) : ClassGenerator
84
    {
85
        $this->namespace = $namespace;
86
87
        return $this;
88
    }
89
90
    /**
91
     * Set class use.
92
     *
93
     * @param string $use Use class name
94
     *
95
     * @return ClassGenerator
96
     */
97
    public function defUse(string $use) : ClassGenerator
98
    {
99
        $this->uses[] = $use;
100
101
        return $this;
102
    }
103
104
    /**
105
     * Set class trait use.
106
     *
107
     * @param string $trait Trait class name
108
     *
109
     * @return ClassGenerator
110
     */
111
    public function defTrait(string $trait) : ClassGenerator
112
    {
113
        $this->traits[] = $trait;
114
115
        return $this;
116
    }
117
118
    /**
119
     * Set protected class property.
120
     *
121
     * @param string $name        Property name
122
     * @param string $type        Property type
123
     * @param mixed  $value       Property value
124
     * @param string $description Property description
125
     *
126
     * @return PropertyGenerator
127
     */
128
    public function defProtectedProperty(string $name, string $type, $value, string $description = null) : PropertyGenerator
129
    {
130
        return $this->defProperty($name, $type, $value, $description)->defProtected();
131
    }
132
133
    /**
134
     * Set class property.
135
     *
136
     * @param string $name        Property name
137
     * @param string $type        Property type
138
     * @param mixed  $value       Property value
139
     * @param string $description Property description
140
     *
141
     * @return PropertyGenerator
142
     */
143
    public function defProperty(string $name, string $type, $value, string $description = null) : PropertyGenerator
144
    {
145
        return (new PropertyGenerator($name, $value, $this))
146
            ->increaseIndentation()
147
            ->defComment()
148
            ->defVar($type, $description)
149
            ->end();
150
    }
151
152
    /**
153
     * Set protected static class property.
154
     *
155
     * @param string $name        Property name
156
     * @param string $type        Property type
157
     * @param mixed  $value       Property value
158
     * @param string $description Property description
159
     *
160
     * @return PropertyGenerator
161
     */
162
    public function defProtectedStaticProperty(string $name, string $type, $value, string $description = null) : PropertyGenerator
163
    {
164
        return $this->defStaticProperty($name, $type, $value, $description)->defProtected();
165
    }
166
167
    /**
168
     * Set static class property.
169
     *
170
     * @param string $name        Property name
171
     * @param string $type        Property type
172
     * @param mixed  $value       Property value
173
     * @param string $description Property description
174
     *
175
     * @return PropertyGenerator
176
     */
177
    public function defStaticProperty(string $name, string $type, $value, string $description = null) : PropertyGenerator
178
    {
179
        return $this->defProperty($name, $type, $value, $description)->defStatic();
180
    }
181
182
    /**
183
     * Set protected class method.
184
     *
185
     * @param string $name Method name
186
     *
187
     * @return MethodGenerator
188
     */
189
    public function defProtectedMethod(string $name) : MethodGenerator
190
    {
191
        return $this->defMethod($name)->defProtected();
192
    }
193
194
    /**
195
     * Set public class method.
196
     *
197
     * @param string $name Method name
198
     *
199
     * @return MethodGenerator
200
     */
201
    public function defMethod(string $name) : MethodGenerator
202
    {
203
        return (new MethodGenerator($name, $this))->increaseIndentation();
204
    }
205
206
    /**
207
     * Set protected static class method.
208
     *
209
     * @param string $name Method name
210
     *
211
     * @return MethodGenerator
212
     */
213
    public function defProtectedStaticMethod(string $name) : MethodGenerator
214
    {
215
        return $this->defStaticMethod($name)->defProtected();
216
    }
217
218
    /**
219
     * Set public static class method.
220
     *
221
     * @param string $name Method name
222
     *
223
     * @return MethodGenerator
224
     */
225
    public function defStaticMethod(string $name) : MethodGenerator
226
    {
227
        return $this->defMethod($name)->defStatic();
228
    }
229
230
    /**
231
     * {@inheritdoc}
232
     * @throws \InvalidArgumentException
233
     */
234
    public function code(int $indentation = 0) : string
235
    {
236
        if ($this->namespace === null) {
237
            throw new \InvalidArgumentException('Class namespace should be defined');
238
        }
239
240
        $formattedCode = ['namespace ' . $this->namespace . ';'];
241
242
        // One empty line after namespace
243
        $formattedCode[] = '';
244
245
        // Add uses
246
        foreach ($this->uses as $use) {
247
            $formattedCode[] = 'use ' . $use . ';';
248
        }
249
250
        // One empty line after uses if we have them
251
        if (count($this->uses)) {
252
            $formattedCode[] = '';
253
        }
254
255
        // Add comments
256
        if (array_key_exists(CommentsGenerator::class, $this->generatedCode)) {
257
            $formattedCode[] = $this->generatedCode[CommentsGenerator::class];
258
        }
259
260
        // Add previously generated code
261
        $formattedCode[] = $this->buildDefinition();
262
        $formattedCode[] = '{';
263
264
        $indentationString = $this->indentation($indentation);
265
        $innerIndentation = $this->indentation(1);
266
267
        // Add traits
268
        foreach ($this->traits as $trait) {
269
            $formattedCode[] = $innerIndentation . 'use ' . $trait . ';';
270
        }
271
272
        // One empty line after traits if we have them
273
        if (count($this->traits)) {
274
            $formattedCode[] = '';
275
        }
276
277
        // Prepend file description if present
278
        if ($this->fileDescription !== null) {
279
            array_unshift($formattedCode, $this->fileDescription);
280
        }
281
282
        // Add properties
283
        if (array_key_exists(PropertyGenerator::class, $this->generatedCode)) {
284
            $formattedCode[] = $this->generatedCode[PropertyGenerator::class];
285
        }
286
287
        // Add properties
288
        if (array_key_exists(MethodGenerator::class, $this->generatedCode)) {
289
            $formattedCode[] = $this->generatedCode[MethodGenerator::class];
290
        }
291
292
        $formattedCode[] = '}';
293
294
        $code = implode("\n" . $indentationString, $formattedCode);
295
296
        return $code;
297
    }
298
299
    /**
300
     * Build function definition.
301
     *
302
     * @return string Function definition
303
     */
304
    protected function buildDefinition()
305
    {
306
        return ($this->isFinal ? 'final ' : '') .
307
        ($this->isAbstract ? 'abstract ' : '') .
308
        'class ' .
309
        $this->className;
310
    }
311
}
312