Completed
Push — master ( fc5bf0...7f5622 )
by Francis
02:50
created

MethodGenerator::buildMethodSignature()   B

Complexity

Conditions 6
Paths 16

Size

Total Lines 33
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 22
c 0
b 0
f 0
dl 0
loc 33
rs 8.9457
cc 6
nc 16
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Prometee\SwaggerClientGenerator\Base\Generator\Object\Method;
6
7
use Prometee\SwaggerClientGenerator\Base\Generator\Object\Other\UsesGeneratorInterface;
8
use Prometee\SwaggerClientGenerator\Base\Generator\PhpDoc\PhpDocGeneratorInterface;
9
10
class MethodGenerator implements MethodGeneratorInterface
11
{
12
    /** @var PhpDocGeneratorInterface */
13
    protected $phpDocBuilder;
14
    /** @var UsesGeneratorInterface */
15
    protected $usesBuilder;
16
    /** @var MethodParameterGeneratorInterface */
17
    protected $methodParameterBuilderSkel;
18
19
    /** @var string */
20
    protected $scope = '';
21
    /** @var string */
22
    protected $name = '';
23
    /** @var string[] */
24
    protected $returnTypes = [];
25
    /** @var bool */
26
    protected $static = false;
27
    /** @var string */
28
    protected $description = '';
29
    /** @var MethodParameterGeneratorInterface[] */
30
    protected $parameters = [];
31
    /** @var string[] */
32
    protected $lines = [];
33
    /** @var bool */
34
    protected $hasAlreadyBeenGenerated = false;
35
36
    /**
37
     * @param UsesGeneratorInterface $usesBuilder
38
     * @param PhpDocGeneratorInterface $phpDocBuilder
39
     * @param MethodParameterGeneratorInterface $methodParameterBuilderSkel
40
     */
41
    public function __construct(
42
        UsesGeneratorInterface $usesBuilder,
43
        PhpDocGeneratorInterface $phpDocBuilder,
44
        MethodParameterGeneratorInterface $methodParameterBuilderSkel
45
    )
46
    {
47
        $this->usesBuilder = $usesBuilder;
48
        $this->phpDocBuilder = $phpDocBuilder;
49
        $this->methodParameterBuilderSkel = $methodParameterBuilderSkel;
50
    }
51
52
    /**
53
     * {@inheritDoc}
54
     */
55
    public function configure(
56
        string $scope,
57
        string $name,
58
        array $returnTypes = [],
59
        bool $static = false,
60
        string $description = ''
61
    )
62
    {
63
        $this->setScope($scope);
64
        $this->setName($name);
65
        $this->setReturnTypes($returnTypes);
66
        $this->setStatic($static);
67
        $this->setDescription($description);
68
        $this->setParameters([]);
69
        $this->setLines([]);
70
71
        $this->phpDocBuilder->configure();
72
        $this->hasAlreadyBeenGenerated = false;
73
    }
74
75
    /**
76
     * {@inheritdoc}
77
     */
78
    public function generate(string $indent = null): ?string
79
    {
80
        if (count($this->lines) === 0) {
81
            return '';
82
        }
83
84
        $content = "\n";
85
86
        $this->configurePhpDocBuilder();
87
        $content .= $this->phpDocBuilder->generate($indent);
88
89
        $content .= $this->buildMethodSignature($indent);
90
        $content .= "\n";
91
92
        $content .= $indent . '{' . "\n";
93
        $content .= $this->buildMethodBody($indent);
94
        $content .= $indent . '}' . "\n";
95
96
        return $content;
97
    }
98
99
    /**
100
     * {@inheritdoc}
101
     */
102
    public function buildMethodBody(string $indent = null): string
103
    {
104
        $content = '';
105
        foreach ($this->lines as $line) {
106
            foreach (explode("\n", $line) as $innerLine) {
107
                $content .= $indent . $indent . $innerLine . "\n";
108
            }
109
        }
110
        return $content;
111
    }
112
113
    /**
114
     * {@inheritdoc}
115
     */
116
    public function buildMethodSignature(string $indent = null): string
117
    {
118
        $static = ($this->static) ? ' static ' : '';
119
        $content = $indent . $this->scope . $static . ' function ' . $this->name . '(';
120
121
        $parameters = [];
122
        foreach ($this->parameters as $methodParameterBuilder) {
123
            $parameters[] = $methodParameterBuilder->generate($indent);
124
        }
125
        $parametersStr = implode(',%1$s', $parameters);
126
127
        $parameterStart = '';
128
        $additionalIndentation = ' ';
129
        $parameterEnd = '';
130
        if (strlen($parametersStr) > $this->phpDocBuilder->getWrapOn()*0.75) {
131
            $additionalIndentation = "\n" . $indent . $indent;
132
            $parameterStart = $additionalIndentation;
133
            $parameterEnd = "\n" . $indent;
134
        }
135
136
137
        $content .= $parameterStart;
138
        $content .= sprintf(
139
            $parametersStr,
140
            $additionalIndentation
141
        );
142
        $content .= $parameterEnd;
143
144
        $content .= ')';
145
        if (!empty($this->returnTypes) && !in_array('mixed', $this->returnTypes)) {
146
            $content .= ': ' . $this->getPhpReturnType();
147
        }
148
        return $content;
149
    }
150
151
    /**
152
     * {@inheritdoc}
153
     */
154
    public function configurePhpDocBuilder(): void
155
    {
156
        if ($this->hasAlreadyBeenGenerated) {
157
            return;
158
        }
159
160
        if (!empty($this->getDescription())) {
161
            $this->phpDocBuilder->addDescriptionLine($this->getDescription());
162
        }
163
        foreach ($this->parameters as $parameter) {
164
            $type = $this->phpDocBuilder::getPossibleTypesFromTypeNames([$parameter->getType(), $parameter->getValueType()]);
165
            $this->phpDocBuilder->addParamLine($parameter->getPhpName(), $type, $parameter->getDescription());
166
        }
167
        if (!empty($this->returnTypes) && !in_array('void', $this->returnTypes)) {
168
            $type = $this->phpDocBuilder::getPossibleTypesFromTypeNames($this->returnTypes);
169
            $this->phpDocBuilder->addReturnLine($type);
170
        }
171
172
        $this->hasAlreadyBeenGenerated = true;
173
    }
174
175
    /**
176
     * {@inheritdoc}
177
     */
178
    public function getReturnTypes(): array
179
    {
180
        return $this->returnTypes;
181
    }
182
183
    /**
184
     * {@inheritdoc}
185
     */
186
    public function getPhpReturnType(): ?string
187
    {
188
        if (empty($this->returnTypes)) {
189
            return null;
190
        }
191
192
        $phpReturnType = '';
193
        if (in_array('null', $this->returnTypes)) {
194
            $phpReturnType = '?';
195
        }
196
        foreach ($this->returnTypes as $type) {
197
            if (preg_match('#\[\]$#', $type)) {
198
                $phpReturnType .= 'array';
199
                break;
200
            }
201
            if ($type !== 'null') {
202
                $phpReturnType .= $type;
203
                break;
204
            }
205
        }
206
207
        return $phpReturnType;
208
    }
209
210
    /**
211
     * {@inheritDoc}
212
     */
213
    public function setReturnTypes(array $returnTypes): void
214
    {
215
        $this->returnTypes = [];
216
        foreach ($returnTypes as $returnType) {
217
            $this->addReturnType($returnType);
218
        }
219
    }
220
221
    /**
222
     * {@inheritDoc}
223
     */
224
    public function addReturnType(string $returnType): void
225
    {
226
        $returnType = $this->usesBuilder->guessUseOrReturnType($returnType);
227
        if (false === $this->hasReturnType($returnType)) {
228
            $this->returnTypes[] = $returnType;
229
        }
230
    }
231
232
    /**
233
     * {@inheritDoc}
234
     */
235
    public function hasReturnType(string $returnType): bool
236
    {
237
        return false !== array_search($returnType, $this->returnTypes);
238
    }
239
240
    /**
241
     * {@inheritdoc}
242
     */
243
    public function addParameter(MethodParameterGeneratorInterface $methodParameterBuilder): void
244
    {
245
        if (!$this->hasParameter($methodParameterBuilder)) {
246
            $this->setParameter($methodParameterBuilder);
247
        }
248
    }
249
250
    /**
251
     * {@inheritdoc}
252
     */
253
    public function hasParameter(MethodParameterGeneratorInterface $methodParameterBuilder): bool
254
    {
255
        return isset($this->parameters[$methodParameterBuilder->getName()]);
256
    }
257
258
    /**
259
     * {@inheritdoc}
260
     */
261
    public function setParameter(MethodParameterGeneratorInterface $methodParameterBuilder): void
262
    {
263
        $this->parameters[$methodParameterBuilder->getName()] = $methodParameterBuilder;
264
    }
265
266
    /**
267
     * {@inheritdoc}
268
     */
269
    public function addLine(string $line): void
270
    {
271
        $this->lines[] = $line;
272
    }
273
274
    /**
275
     * {@inheritdoc}
276
     */
277
    public function getScope(): string
278
    {
279
        return $this->scope;
280
    }
281
282
    /**
283
     * {@inheritdoc}
284
     */
285
    public function setScope(string $scope): void
286
    {
287
        $this->scope = $scope;
288
    }
289
290
    /**
291
     * {@inheritdoc}
292
     */
293
    public function isStatic(): bool
294
    {
295
        return $this->static;
296
    }
297
298
    /**
299
     * {@inheritdoc}
300
     */
301
    public function setStatic(bool $static): void
302
    {
303
        $this->static = $static;
304
    }
305
306
    /**
307
     * {@inheritdoc}
308
     */
309
    public function getName(): string
310
    {
311
        return $this->name;
312
    }
313
314
    /**
315
     * {@inheritdoc}
316
     */
317
    public function setName(string $name): void
318
    {
319
        $this->name = $name;
320
    }
321
322
    /**
323
     * {@inheritdoc}
324
     */
325
    public function getDescription(): string
326
    {
327
        return $this->description;
328
    }
329
330
    /**
331
     * {@inheritdoc}
332
     */
333
    public function setDescription(string $description): void
334
    {
335
        $this->description = $description;
336
    }
337
338
    /**
339
     * {@inheritdoc}
340
     */
341
    public function getParameters(): array
342
    {
343
        return $this->parameters;
344
    }
345
346
    /**
347
     * {@inheritdoc}
348
     */
349
    public function setParameters(array $parameters): void
350
    {
351
        $this->parameters = $parameters;
352
    }
353
354
    /**
355
     * {@inheritdoc}
356
     */
357
    public function getLines(): array
358
    {
359
        return $this->lines;
360
    }
361
362
    /**
363
     * {@inheritdoc}
364
     */
365
    public function setLines(array $lines): void
366
    {
367
        $this->lines = $lines;
368
    }
369
370
    /**
371
     * {@inheritdoc}
372
     */
373
    public function getPhpDocBuilder(): PhpDocGeneratorInterface
374
    {
375
        return $this->phpDocBuilder;
376
    }
377
378
    /**
379
     * {@inheritdoc}
380
     */
381
    public function setPhpDocBuilder(PhpDocGeneratorInterface $phpDocBuilder): void
382
    {
383
        $this->phpDocBuilder = $phpDocBuilder;
384
    }
385
386
    /**
387
     * {@inheritdoc}
388
     */
389
    public function getUsesBuilder(): UsesGeneratorInterface
390
    {
391
        return $this->usesBuilder;
392
    }
393
394
    /**
395
     * {@inheritdoc}
396
     */
397
    public function setUsesBuilder(UsesGeneratorInterface $usesBuilder): void
398
    {
399
        $this->usesBuilder = $usesBuilder;
400
    }
401
402
    /**
403
     * {@inheritdoc}
404
     */
405
    public function getMethodParameterBuilderSkel(): MethodParameterGeneratorInterface
406
    {
407
        return $this->methodParameterBuilderSkel;
408
    }
409
410
    /**
411
     * {@inheritdoc}
412
     */
413
    public function setMethodParameterBuilderSkel(MethodParameterGeneratorInterface $methodParameterBuilderSkel): void
414
    {
415
        $this->methodParameterBuilderSkel = $methodParameterBuilderSkel;
416
    }
417
}
418