Completed
Push — master ( a9ac3c...b00023 )
by Francis
02:09
created

MethodGenerator::getUsesGenerator()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
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 $phpDocGenerator;
14
    /** @var UsesGeneratorInterface */
15
    protected $usesGenerator;
16
    /** @var MethodParameterGeneratorInterface */
17
    protected $methodParameterGeneratorSkel;
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 $usesGenerator
38
     * @param PhpDocGeneratorInterface $phpDocGenerator
39
     * @param MethodParameterGeneratorInterface $methodParameterGeneratorSkel
40
     */
41
    public function __construct(
42
        UsesGeneratorInterface $usesGenerator,
43
        PhpDocGeneratorInterface $phpDocGenerator,
44
        MethodParameterGeneratorInterface $methodParameterGeneratorSkel
45
    )
46
    {
47
        $this->usesGenerator = $usesGenerator;
48
        $this->phpDocGenerator = $phpDocGenerator;
49
        $this->methodParameterGeneratorSkel = $methodParameterGeneratorSkel;
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->phpDocGenerator->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
        $this->configurePhpDocGenerator();
85
86
        return sprintf('%1$s%3$s%4$s%1$s%2$s{%1$s%5$s%2$s}%1$s',
87
            "\n",
88
            $indent,
89
            $this->phpDocGenerator->generate($indent),
90
            $this->buildMethodSignature($indent),
91
            $this->buildMethodBody($indent)
92
        );
93
    }
94
95
    /**
96
     * {@inheritdoc}
97
     */
98
    public function buildMethodBody(string $indent = null): string
99
    {
100
        $content = '';
101
        foreach ($this->lines as $line) {
102
            foreach (explode("\n", $line) as $innerLine) {
103
                $content .= $indent.$indent.$innerLine. "\n";
104
            }
105
        }
106
        return $content;
107
    }
108
109
    /**
110
     * {@inheritdoc}
111
     */
112
    public function buildMethodSignature(string $indent = null): string
113
    {
114
        $static = ($this->static) ? ' static ' : '';
115
116
        // result example : "string $first,%1$sstring $second,%1$sstring $third"
117
        $methodParameters = $this->buildMethodParameters($indent, '%1$s');
118
        // 3 = length of $formatVar - 1 (see line just below)
119
        // -1 because the first parameter don't have $formatVar
120
        $methodParametersLength = strlen($methodParameters) - 3*(count($this->parameters)-1);
121
        $parametersFutureFormat = '%s%s%s';
122
        $content = sprintf('%s%s%s function %s (%s)%s',
123
            $indent,
124
            $this->scope,
125
            $static,
126
            $this->name,
127
            $parametersFutureFormat,
128
            $this->buildReturnType($indent)
129
        );
130
131
        $parametersStart = '';
132
        $additionalIndentation = ' ';
133
        $parametersEnd = '';
134
        $contentLength = strlen($content) - strlen($parametersFutureFormat) + $methodParametersLength;
135
        if ($contentLength > $this->phpDocGenerator->getWrapOn()) {
136
            // Make parameters go into multiline formation
137
            $additionalIndentation = "\n".$indent.$indent;
138
            $parametersStart = $additionalIndentation;
139
            $parametersEnd = "\n".$indent;
140
        }
141
142
        return sprintf($content,
143
            $parametersStart,
144
            sprintf($methodParameters, $additionalIndentation),
145
            $parametersEnd
146
        );
147
    }
148
149
    /**
150
     * {@inheritdoc}
151
     */
152
    public function buildMethodParameters(string $indent = null, string $formatVar = ' '): string
153
    {
154
        $parameters = [];
155
156
        foreach ($this->parameters as $methodParameterGenerator) {
157
            $parameters[] = $methodParameterGenerator->generate($indent);
158
        }
159
160
        return implode(sprintf(',%s', $formatVar), $parameters);
161
    }
162
163
    /**
164
     * {@inheritdoc}
165
     */
166
    public function buildReturnType(string $indent = null): string
167
    {
168
        if (empty($this->returnTypes)) {
169
            return '';
170
        }
171
172
        if (in_array('mixed', $this->returnTypes)) {
173
            return '';
174
        }
175
176
        return sprintf (': %s', $this->getPhpReturnType());
177
    }
178
179
    /**
180
     * {@inheritdoc}
181
     */
182
    public function configurePhpDocGenerator(): void
183
    {
184
        if ($this->hasAlreadyBeenGenerated) {
185
            return;
186
        }
187
188
        if (!empty($this->getDescription())) {
189
            $this->phpDocGenerator->addDescriptionLine($this->getDescription());
190
        }
191
        foreach ($this->parameters as $parameter) {
192
            $this->phpDocGenerator->addParamLine($parameter->getPhpName(), $parameter->getType(), $parameter->getDescription());
193
        }
194
        if (!empty($this->returnTypes) && !in_array('void', $this->returnTypes)) {
195
            $this->phpDocGenerator->addReturnLine($this->getReturnType());
196
        }
197
198
        $this->hasAlreadyBeenGenerated = true;
199
    }
200
201
    /**
202
     * {@inheritDoc}
203
     */
204
    public function getReturnType(): string
205
    {
206
        return implode('|', $this->returnTypes);
207
    }
208
209
    /**
210
     * {@inheritdoc}
211
     */
212
    public function getReturnTypes(): array
213
    {
214
        return $this->returnTypes;
215
    }
216
217
    /**
218
     * {@inheritdoc}
219
     */
220
    public function getPhpReturnType(): ?string
221
    {
222
        if (empty($this->returnTypes)) {
223
            return null;
224
        }
225
226
        $phpReturnType = '';
227
        if (in_array('null', $this->returnTypes)) {
228
            $phpReturnType = '?';
229
        }
230
        foreach ($this->returnTypes as $type) {
231
            if (preg_match('#\[\]$#', $type)) {
232
                $phpReturnType .= 'array';
233
                break;
234
            }
235
            if ($type !== 'null') {
236
                $phpReturnType .= $type;
237
                break;
238
            }
239
        }
240
241
        return $phpReturnType;
242
    }
243
244
    /**
245
     * {@inheritDoc}
246
     */
247
    public function setReturnTypes(array $returnTypes): void
248
    {
249
        $this->returnTypes = [];
250
        foreach ($returnTypes as $returnType) {
251
            $this->addReturnType($returnType);
252
        }
253
    }
254
255
    /**
256
     * {@inheritDoc}
257
     */
258
    public function addReturnType(string $returnType): void
259
    {
260
        $returnType = $this->usesGenerator->guessUseOrReturnType($returnType);
261
        if (false === $this->hasReturnType($returnType)) {
262
            $this->returnTypes[] = $returnType;
263
        }
264
    }
265
266
    /**
267
     * {@inheritDoc}
268
     */
269
    public function hasReturnType(string $returnType): bool
270
    {
271
        return false !== array_search($returnType, $this->returnTypes);
272
    }
273
274
    /**
275
     * {@inheritdoc}
276
     */
277
    public function addParameter(MethodParameterGeneratorInterface $methodParameterGenerator): void
278
    {
279
        if (!$this->hasParameter($methodParameterGenerator)) {
280
            $this->setParameter($methodParameterGenerator);
281
        }
282
    }
283
284
    /**
285
     * {@inheritdoc}
286
     */
287
    public function hasParameter(MethodParameterGeneratorInterface $methodParameterGenerator): bool
288
    {
289
        return isset($this->parameters[$methodParameterGenerator->getName()]);
290
    }
291
292
    /**
293
     * {@inheritdoc}
294
     */
295
    public function setParameter(MethodParameterGeneratorInterface $methodParameterGenerator): void
296
    {
297
        $this->parameters[$methodParameterGenerator->getName()] = $methodParameterGenerator;
298
    }
299
300
    /**
301
     * {@inheritdoc}
302
     */
303
    public function addLine(string $line): void
304
    {
305
        $this->lines[] = $line;
306
    }
307
308
    /**
309
     * {@inheritdoc}
310
     */
311
    public function getScope(): string
312
    {
313
        return $this->scope;
314
    }
315
316
    /**
317
     * {@inheritdoc}
318
     */
319
    public function setScope(string $scope): void
320
    {
321
        $this->scope = $scope;
322
    }
323
324
    /**
325
     * {@inheritdoc}
326
     */
327
    public function isStatic(): bool
328
    {
329
        return $this->static;
330
    }
331
332
    /**
333
     * {@inheritdoc}
334
     */
335
    public function setStatic(bool $static): void
336
    {
337
        $this->static = $static;
338
    }
339
340
    /**
341
     * {@inheritdoc}
342
     */
343
    public function getName(): string
344
    {
345
        return $this->name;
346
    }
347
348
    /**
349
     * {@inheritdoc}
350
     */
351
    public function setName(string $name): void
352
    {
353
        $this->name = $name;
354
    }
355
356
    /**
357
     * {@inheritdoc}
358
     */
359
    public function getDescription(): string
360
    {
361
        return $this->description;
362
    }
363
364
    /**
365
     * {@inheritdoc}
366
     */
367
    public function setDescription(string $description): void
368
    {
369
        $this->description = $description;
370
    }
371
372
    /**
373
     * {@inheritdoc}
374
     */
375
    public function getParameters(): array
376
    {
377
        return $this->parameters;
378
    }
379
380
    /**
381
     * {@inheritdoc}
382
     */
383
    public function setParameters(array $parameters): void
384
    {
385
        $this->parameters = $parameters;
386
    }
387
388
    /**
389
     * {@inheritdoc}
390
     */
391
    public function getLines(): array
392
    {
393
        return $this->lines;
394
    }
395
396
    /**
397
     * {@inheritdoc}
398
     */
399
    public function setLines(array $lines): void
400
    {
401
        $this->lines = $lines;
402
    }
403
404
    /**
405
     * {@inheritdoc}
406
     */
407
    public function getPhpDocGenerator(): PhpDocGeneratorInterface
408
    {
409
        return $this->phpDocGenerator;
410
    }
411
412
    /**
413
     * {@inheritdoc}
414
     */
415
    public function setPhpDocGenerator(PhpDocGeneratorInterface $phpDocGenerator): void
416
    {
417
        $this->phpDocGenerator = $phpDocGenerator;
418
    }
419
420
    /**
421
     * {@inheritdoc}
422
     */
423
    public function getUsesGenerator(): UsesGeneratorInterface
424
    {
425
        return $this->usesGenerator;
426
    }
427
428
    /**
429
     * {@inheritdoc}
430
     */
431
    public function setUsesGenerator(UsesGeneratorInterface $usesGenerator): void
432
    {
433
        $this->usesGenerator = $usesGenerator;
434
    }
435
436
    /**
437
     * {@inheritdoc}
438
     */
439
    public function getMethodParameterGeneratorSkel(): MethodParameterGeneratorInterface
440
    {
441
        return $this->methodParameterGeneratorSkel;
442
    }
443
444
    /**
445
     * {@inheritdoc}
446
     */
447
    public function setMethodParameterGeneratorSkel(MethodParameterGeneratorInterface $methodParameterGeneratorSkel): void
448
    {
449
        $this->methodParameterGeneratorSkel = $methodParameterGeneratorSkel;
450
    }
451
}
452