Skip to content

Commit b0a7de1

Browse files
authored
Merge pull request #31 from rremy/fix-api-generator-doesnt-support-mixed-type
fix: api generator doesn't support mixed type.
2 parents e018273 + e2064e9 commit b0a7de1

File tree

13 files changed

+164
-12
lines changed

13 files changed

+164
-12
lines changed

CHANGELOG.md

+9
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
66

77

8+
## [5.3.0] - 2021-04-13
9+
### Added
10+
- Support for `mixed` parameter type
11+
- Support for anyOf `mixed` parameter type
12+
13+
### Fixed
14+
- `mixed` arrays rendered incorrectly
15+
- Wrong typehint in case of nullable arrays
16+
817
## [5.2.0] - 2021-04-06
918
### Added
1019
- Support for `minimum`, `maximum`, `exclusiveMinimum`, `exclusiveMaximum`, `minItems`, `maxItems`, `pattern`, `maxLength`, `minLength` validations

example/gen/src/Schema/TagCollection.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class TagCollection implements IteratorAggregate, SerializableInterface, Countab
1818
private array $items;
1919

2020
/**
21-
* @param Tag|null[] $items
21+
* @param Tag[] $items
2222
*/
2323
public function __construct(Tag ...$items)
2424
{

src/Ast/Builder/CodeBuilder.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ public function localProperty(
140140
->property($name)
141141
->makePrivate();
142142

143-
if ($this->phpVersion->isPropertyTypeHintSupported()) {
143+
if (!empty($type) && $this->phpVersion->isPropertyTypeHintSupported()) {
144144
if ($nullable) {
145145
$property->setDefault(null);
146146
$type = '?' . $type;

src/Ast/Builder/MethodBuilder.php

+5-3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
class MethodBuilder extends Method
1414
{
15+
public const RETURN_TYPE_VOID = 'void';
16+
1517
private PhpVersion $phpVersion;
1618

1719
public function __construct(string $name, PhpVersion $phpVersion)
@@ -59,13 +61,13 @@ public function composeDocBlock(
5961
*/
6062
public function setReturnType($type, $isNullable = false): self
6163
{
62-
if ($type === 'mixed') {
64+
if (empty($type)) {
6365
return $this;
6466
}
6567

66-
if ($type === null) {
68+
if ($type === self::RETURN_TYPE_VOID) {
6769
if ($this->phpVersion->isVoidReturnTypeSupported()) {
68-
return parent::setReturnType('void');
70+
return parent::setReturnType($type);
6971
}
7072

7173
return $this;

src/Ast/Builder/ParameterBuilder.php

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ public function __construct(string $name, PhpVersion $phpVersion)
2020

2121
public function setType($type, bool $isNullable = false): self
2222
{
23+
if (empty($type)) {
24+
return $this;
25+
}
26+
2327
if ($isNullable) {
2428
if ($this->phpVersion->isNullableTypeHintSupported() && is_string($type)) {
2529
return parent::setType(sprintf('?%s', $type));

src/Entity/Field.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ public function getPhpDocType(bool $allowNullable = true): string
208208

209209
if ($this->isArray() && !$this->isArrayOfObjects()) {
210210
$arraySuffix = '[]';
211-
$typeHint = $this->getArrayItem()->getPhpTypeHint();
211+
$typeHint = $this->getArrayItem()->getPhpDocType();
212212
}
213213

214214
return sprintf('%s%s%s', $typeHint, $arraySuffix, $nullableSuffix);

src/Generator/ClientGenerator.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace DoclerLabs\ApiClientGenerator\Generator;
66

7+
use DoclerLabs\ApiClientGenerator\Ast\Builder\MethodBuilder;
78
use DoclerLabs\ApiClientGenerator\Entity\Operation;
89
use DoclerLabs\ApiClientGenerator\Input\Specification;
910
use DoclerLabs\ApiClientGenerator\Naming\ClientNaming;
@@ -107,7 +108,7 @@ protected function generateAction(Operation $operation): ClassMethod
107108
->makePublic()
108109
->addParam($methodParam)
109110
->addStmt($handleResponseStmt)
110-
->setReturnType(null)
111+
->setReturnType(MethodBuilder::RETURN_TYPE_VOID)
111112
->composeDocBlock([$methodParam])
112113
->getNode();
113114
}

src/Generator/ServiceProviderGenerator.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use DoclerLabs\ApiClientException\Factory\ResponseExceptionFactory;
66
use DoclerLabs\ApiClientGenerator\Ast\Builder\CodeBuilder;
7+
use DoclerLabs\ApiClientGenerator\Ast\Builder\MethodBuilder;
78
use DoclerLabs\ApiClientGenerator\Entity\Field;
89
use DoclerLabs\ApiClientGenerator\Entity\Operation;
910
use DoclerLabs\ApiClientGenerator\Generator\Implementation\ContainerImplementationStrategy;
@@ -167,7 +168,7 @@ private function generateRegisterMethod(
167168
->addParam($param)
168169
->addStmts($statements)
169170
->composeDocBlock([$param], '', [])
170-
->setReturnType(null)
171+
->setReturnType(MethodBuilder::RETURN_TYPE_VOID)
171172
->getNode();
172173
}
173174

src/Input/Factory/FieldFactory.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public function create(
8080
$operationName,
8181
lcfirst($itemReferenceName),
8282
$sibling,
83-
$required,
83+
true,
8484
$itemReferenceName
8585
);
8686
} elseif (FieldType::isSpecificationTypeObject($type)) {

test/suite/functional/Generator/Schema/ItemPhp70.php

+43-1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ class Item implements SerializableInterface, JsonSerializable
5656
/** @var ItemMandatoryObject */
5757
private $mandatoryObject;
5858

59+
private $mandatoryMixed;
60+
61+
private $mandatoryAnyOf;
62+
5963
/** @var ItemNullableObject|null */
6064
private $nullableObject;
6165

@@ -83,6 +87,9 @@ class Item implements SerializableInterface, JsonSerializable
8387
/** @var string[]|null */
8488
private $optionalArray;
8589

90+
/** @var mixed[]|null */
91+
private $optionalMixedArray;
92+
8693
/** @var string[]|null */
8794
private $optionalArrayWithMinMaxItems;
8895

@@ -114,7 +121,7 @@ class Item implements SerializableInterface, JsonSerializable
114121
*
115122
* @throws RequestValidationException
116123
*/
117-
public function __construct(int $mandatoryInteger, string $mandatoryString, string $mandatoryEnum, DateTimeInterface $mandatoryDate, $mandatoryNullableDate, float $mandatoryFloat, bool $mandatoryBoolean, array $mandatoryArray, array $mandatoryArrayWithMinItems, ItemMandatoryObject $mandatoryObject)
124+
public function __construct(int $mandatoryInteger, string $mandatoryString, string $mandatoryEnum, DateTimeInterface $mandatoryDate, $mandatoryNullableDate, float $mandatoryFloat, bool $mandatoryBoolean, array $mandatoryArray, array $mandatoryArrayWithMinItems, ItemMandatoryObject $mandatoryObject, $mandatoryMixed, $mandatoryAnyOf)
118125
{
119126
$this->mandatoryInteger = $mandatoryInteger;
120127
$this->mandatoryString = $mandatoryString;
@@ -132,6 +139,8 @@ public function __construct(int $mandatoryInteger, string $mandatoryString, stri
132139
}
133140
$this->mandatoryArrayWithMinItems = $mandatoryArrayWithMinItems;
134141
$this->mandatoryObject = $mandatoryObject;
142+
$this->mandatoryMixed = $mandatoryMixed;
143+
$this->mandatoryAnyOf = $mandatoryAnyOf;
135144
}
136145

137146
/**
@@ -212,6 +221,16 @@ public function setOptionalArray(array $optionalArray): self
212221
return $this;
213222
}
214223

224+
/**
225+
* @param mixed[] $optionalMixedArray
226+
*/
227+
public function setOptionalMixedArray(array $optionalMixedArray): self
228+
{
229+
$this->optionalMixedArray = $optionalMixedArray;
230+
231+
return $this;
232+
}
233+
215234
/**
216235
* @param string[] $optionalArrayWithMinMaxItems
217236
*
@@ -389,6 +408,16 @@ public function getMandatoryObject(): ItemMandatoryObject
389408
return $this->mandatoryObject;
390409
}
391410

411+
public function getMandatoryMixed()
412+
{
413+
return $this->mandatoryMixed;
414+
}
415+
416+
public function getMandatoryAnyOf()
417+
{
418+
return $this->mandatoryAnyOf;
419+
}
420+
392421
/**
393422
* @return ItemNullableObject|null
394423
*/
@@ -461,6 +490,14 @@ public function getOptionalArray()
461490
return $this->optionalArray;
462491
}
463492

493+
/**
494+
* @return mixed[]|null
495+
*/
496+
public function getOptionalMixedArray()
497+
{
498+
return $this->optionalMixedArray;
499+
}
500+
464501
/**
465502
* @return string[]|null
466503
*/
@@ -538,6 +575,8 @@ public function toArray(): array
538575
$fields['mandatoryArray'] = $this->mandatoryArray;
539576
$fields['mandatoryArrayWithMinItems'] = $this->mandatoryArrayWithMinItems;
540577
$fields['mandatoryObject'] = $this->mandatoryObject->toArray();
578+
$fields['mandatoryMixed'] = $this->mandatoryMixed;
579+
$fields['mandatoryAnyOf'] = $this->mandatoryAnyOf;
541580
$fields['nullableObject'] = $this->nullableObject !== null ? $this->nullableObject->toArray() : null;
542581
$fields['nullableDate'] = $this->nullableDate !== null ? $this->nullableDate->format(DATE_RFC3339) : null;
543582
if ($this->optionalInteger !== null) {
@@ -561,6 +600,9 @@ public function toArray(): array
561600
if ($this->optionalArray !== null) {
562601
$fields['optionalArray'] = $this->optionalArray;
563602
}
603+
if ($this->optionalMixedArray !== null) {
604+
$fields['optionalMixedArray'] = $this->optionalMixedArray;
605+
}
564606
if ($this->optionalArrayWithMinMaxItems !== null) {
565607
$fields['optionalArrayWithMinMaxItems'] = $this->optionalArrayWithMinMaxItems;
566608
}

test/suite/functional/Generator/Schema/ItemPhp72.php

+43-1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ class Item implements SerializableInterface, JsonSerializable
5656
/** @var ItemMandatoryObject */
5757
private $mandatoryObject;
5858

59+
private $mandatoryMixed;
60+
61+
private $mandatoryAnyOf;
62+
5963
/** @var ItemNullableObject|null */
6064
private $nullableObject;
6165

@@ -83,6 +87,9 @@ class Item implements SerializableInterface, JsonSerializable
8387
/** @var string[]|null */
8488
private $optionalArray;
8589

90+
/** @var mixed[]|null */
91+
private $optionalMixedArray;
92+
8693
/** @var string[]|null */
8794
private $optionalArrayWithMinMaxItems;
8895

@@ -113,7 +120,7 @@ class Item implements SerializableInterface, JsonSerializable
113120
*
114121
* @throws RequestValidationException
115122
*/
116-
public function __construct(int $mandatoryInteger, string $mandatoryString, string $mandatoryEnum, DateTimeInterface $mandatoryDate, ?DateTimeInterface $mandatoryNullableDate, float $mandatoryFloat, bool $mandatoryBoolean, array $mandatoryArray, array $mandatoryArrayWithMinItems, ItemMandatoryObject $mandatoryObject)
123+
public function __construct(int $mandatoryInteger, string $mandatoryString, string $mandatoryEnum, DateTimeInterface $mandatoryDate, ?DateTimeInterface $mandatoryNullableDate, float $mandatoryFloat, bool $mandatoryBoolean, array $mandatoryArray, array $mandatoryArrayWithMinItems, ItemMandatoryObject $mandatoryObject, $mandatoryMixed, $mandatoryAnyOf)
117124
{
118125
$this->mandatoryInteger = $mandatoryInteger;
119126
$this->mandatoryString = $mandatoryString;
@@ -131,6 +138,8 @@ public function __construct(int $mandatoryInteger, string $mandatoryString, stri
131138
}
132139
$this->mandatoryArrayWithMinItems = $mandatoryArrayWithMinItems;
133140
$this->mandatoryObject = $mandatoryObject;
141+
$this->mandatoryMixed = $mandatoryMixed;
142+
$this->mandatoryAnyOf = $mandatoryAnyOf;
134143
}
135144

136145
public function setNullableObject(?ItemNullableObject $nullableObject): self
@@ -205,6 +214,16 @@ public function setOptionalArray(array $optionalArray): self
205214
return $this;
206215
}
207216

217+
/**
218+
* @param mixed[] $optionalMixedArray
219+
*/
220+
public function setOptionalMixedArray(array $optionalMixedArray): self
221+
{
222+
$this->optionalMixedArray = $optionalMixedArray;
223+
224+
return $this;
225+
}
226+
208227
/**
209228
* @param string[] $optionalArrayWithMinMaxItems
210229
*
@@ -379,6 +398,16 @@ public function getMandatoryObject(): ItemMandatoryObject
379398
return $this->mandatoryObject;
380399
}
381400

401+
public function getMandatoryMixed()
402+
{
403+
return $this->mandatoryMixed;
404+
}
405+
406+
public function getMandatoryAnyOf()
407+
{
408+
return $this->mandatoryAnyOf;
409+
}
410+
382411
public function getNullableObject(): ?ItemNullableObject
383412
{
384413
return $this->nullableObject;
@@ -427,6 +456,14 @@ public function getOptionalArray(): ?array
427456
return $this->optionalArray;
428457
}
429458

459+
/**
460+
* @return mixed[]|null
461+
*/
462+
public function getOptionalMixedArray(): ?array
463+
{
464+
return $this->optionalMixedArray;
465+
}
466+
430467
/**
431468
* @return string[]|null
432469
*/
@@ -483,6 +520,8 @@ public function toArray(): array
483520
$fields['mandatoryArray'] = $this->mandatoryArray;
484521
$fields['mandatoryArrayWithMinItems'] = $this->mandatoryArrayWithMinItems;
485522
$fields['mandatoryObject'] = $this->mandatoryObject->toArray();
523+
$fields['mandatoryMixed'] = $this->mandatoryMixed;
524+
$fields['mandatoryAnyOf'] = $this->mandatoryAnyOf;
486525
$fields['nullableObject'] = $this->nullableObject !== null ? $this->nullableObject->toArray() : null;
487526
$fields['nullableDate'] = $this->nullableDate !== null ? $this->nullableDate->format(DATE_RFC3339) : null;
488527
if ($this->optionalInteger !== null) {
@@ -506,6 +545,9 @@ public function toArray(): array
506545
if ($this->optionalArray !== null) {
507546
$fields['optionalArray'] = $this->optionalArray;
508547
}
548+
if ($this->optionalMixedArray !== null) {
549+
$fields['optionalMixedArray'] = $this->optionalMixedArray;
550+
}
509551
if ($this->optionalArrayWithMinMaxItems !== null) {
510552
$fields['optionalArrayWithMinMaxItems'] = $this->optionalArrayWithMinMaxItems;
511553
}

0 commit comments

Comments
 (0)