Skip to content

Commit f9a7dad

Browse files
committed
Better support toPhpString on more cases
- nullable arrays now show up as nullable in toPhpString - Union types are now returned as empty to indicate no type definition instead of returning the first type which is too restrictive Signed-off-by: RJ Garcia <ragboyjr@icloud.com>
1 parent 1b28597 commit f9a7dad

9 files changed

Lines changed: 75 additions & 23 deletions

File tree

src/CreateStructStatements/GettersCreateStructStatements.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public function __invoke(CreateStructStatementsArgs $args): array {
2525
if ($type && $type->toPhpString() !== $type->toString()) {
2626
$method->setDocComment("/** @return {$type->toString()} */");
2727
}
28-
if ($type) {
28+
if ($type && $type->toPhpString()) {
2929
$method->setReturnType($type->toPhpString());
3030
}
3131

src/Internal/AtomicType.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,15 @@ public function toString(): string {
4242
}
4343

4444
/** converts the type into a valid php string */
45-
public function toPhpString(): string {
46-
if ($this->isArray) {
47-
return 'array';
48-
}
49-
45+
public function toPhpString(): ?string {
5046
$res = '';
5147
if ($this->nullable) {
5248
$res .= '?';
5349
}
50+
if ($this->isArray) {
51+
return $res . 'array';
52+
}
53+
5454
$res .= $this->typeDefinition;
5555
return $res;
5656
}

src/Internal/UnionType.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ public function toString(): string {
1818
}
1919

2020
/** Converts type into a valid php type representation */
21-
public function toPhpString(): string {
21+
public function toPhpString(): ?string {
22+
if (count($this->atomicTypes) > 1) {
23+
return null; // no type is wide enough, use implicit dynamic type with null
24+
}
25+
2226
return $this->atomicTypes[0]->toPhpString();
2327
}
2428

test/Feature/CreateStructStatements/ConstructorTest.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ class Acme {
2626
public $arrays;
2727
/** @var ?Nested\Acme */
2828
public $nestedClass;
29+
/** int|string */
30+
public $union;
2931
/** @var int */
3032
public $default = 0;
3133
}
@@ -35,7 +37,7 @@ class Acme {
3537
* @param string[] $tags
3638
* @param ArrayObject[] $arrays
3739
*/
38-
public function __construct($id, string $code, array $tags, ?int $count, SplFileInfo $file, array $arrays, ?Nested\Acme $nestedClass, int $default = 0)
40+
public function __construct($id, string $code, array $tags, ?int $count, SplFileInfo $file, array $arrays, ?Nested\Acme $nestedClass, $union, int $default = 0)
3941
{
4042
$this->id = $id;
4143
$this->code = $code;
@@ -44,6 +46,7 @@ public function __construct($id, string $code, array $tags, ?int $count, SplFile
4446
$this->file = $file;
4547
$this->arrays = $arrays;
4648
$this->nestedClass = $nestedClass;
49+
$this->union = $union;
4750
$this->default = $default;
4851
}
4952
STMT

test/Feature/CreateStructStatements/FromValidatedArrayConstructorTest.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,16 @@ class Acme {
2525
public $salePrice;
2626
/** @var ?Price[] */
2727
public $allPrices = [];
28+
/** int|string */
29+
public $union;
2830
}
2931
CLASS
3032
,<<<'STMT'
3133
public static function fromValidatedArray(array $data) : self
3234
{
3335
return new self($data['id'], $data['code'], array_key_exists('tags', $data) ? $data['tags'] : [], array_key_exists('finished', $data) ? $data['finished'] : false, Price::fromValidatedArray($data['price']), $data['salePrice'] === null ? null : Price::fromValidatedArray($data['salePrice']), array_key_exists('allPrices', $data) ? \array_map(function (?array $value) : ?Price {
3436
return $value === null ? null : Price::fromValidatedArray($value);
35-
}, $data['allPrices']) : []);
37+
}, $data['allPrices']) : [], $data['union']);
3638
}
3739
STMT
3840
);

test/Feature/CreateStructStatements/GettersTest.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ class Acme {
2121
public $prices;
2222
/** @var bool */
2323
public $finished = false;
24+
/** @var bool|string */
25+
public $success = false;
2426
/** @var ?Price */
2527
public $totalPrice;
2628
}
@@ -35,19 +37,24 @@ public function code() : string
3537
return $this->code;
3638
}
3739
/** @return ?string[] */
38-
public function tags() : array
40+
public function tags() : ?array
3941
{
4042
return $this->tags;
4143
}
4244
/** @return ?Price[] */
43-
public function prices() : array
45+
public function prices() : ?array
4446
{
4547
return $this->prices;
4648
}
4749
public function finished() : bool
4850
{
4951
return $this->finished;
5052
}
53+
/** @return bool|string */
54+
public function success()
55+
{
56+
return $this->success;
57+
}
5158
public function totalPrice() : ?Price
5259
{
5360
return $this->totalPrice;

test/Feature/CreateStructStatements/ImmutableWithersTest.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ class Acme {
2323
public $finished = false;
2424
/** @var ?Price */
2525
public $totalPrice;
26+
/** int|string */
27+
public $union;
2628
}
2729
CLASS
2830
,<<<'STMT'
@@ -39,14 +41,14 @@ public function withCode(string $code) : self
3941
return $self;
4042
}
4143
/** @param ?string[] $tags */
42-
public function withTags(array $tags = []) : self
44+
public function withTags(?array $tags = []) : self
4345
{
4446
$self = clone $this;
4547
$self->tags = $tags;
4648
return $self;
4749
}
4850
/** @param ?Price[] $prices */
49-
public function withPrices(array $prices) : self
51+
public function withPrices(?array $prices) : self
5052
{
5153
$self = clone $this;
5254
$self->prices = $prices;
@@ -64,6 +66,12 @@ public function withTotalPrice(?Price $totalPrice) : self
6466
$self->totalPrice = $totalPrice;
6567
return $self;
6668
}
69+
public function withUnion($union) : self
70+
{
71+
$self = clone $this;
72+
$self->union = $union;
73+
return $self;
74+
}
6775
STMT
6876
);
6977
}

test/Feature/CreateStructStatements/ToArrayTest.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,16 @@ class Acme {
2323
public $finished = false;
2424
/** @var ?Price */
2525
public $totalPrice;
26+
/** int|string */
27+
public $union;
2628
}
2729
CLASS
2830
,<<<'STMT'
2931
public function toArray() : array
3032
{
3133
return ['id' => $this->id, 'code' => $this->code, 'tags' => $this->tags, 'prices' => \array_map(function (?Price $value) : ?array {
3234
return $value === null ? null : $value->toArray();
33-
}, $this->prices), 'finished' => $this->finished, 'totalPrice' => $this->totalPrice === null ? null : $this->totalPrice->toArray()];
35+
}, $this->prices), 'finished' => $this->finished, 'totalPrice' => $this->totalPrice === null ? null : $this->totalPrice->toArray(), 'union' => $this->union];
3436
}
3537
STMT
3638
);

test/Unit/TypeTest.php

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,44 @@
99
final class TypeTest extends TestCase
1010
{
1111
/** @dataProvider provide_types_to_strings */
12-
public function test_type_to_string(UnionType $type, string $expected) {
12+
public function test_type_to_string(UnionType $type, string $expected, ?string $expectedPhpString) {
1313
$this->assertEquals($expected, $type->toString());
14+
$this->assertEquals($expectedPhpString, $type->toPhpString());
1415
}
1516

1617
public function provide_types_to_strings() {
17-
yield 'scalar' => [AtomicType::asUnion('string'), 'string'];
18-
yield 'union scalar' => [new UnionType([new AtomicType('int'), new AtomicType('string')]), 'int|string'];
19-
yield 'nullable' => [AtomicType::asUnion('string', [], true), '?string'];
20-
yield 'scalar array' => [AtomicType::asUnion('string', [], false, true), 'string[]'];
21-
yield 'generics' => [AtomicType::asUnion('array', [
22-
AtomicType::asUnion('string', []),
23-
AtomicType::asUnion('int', [], true)
24-
]), 'array<string, ?int>'];
18+
yield 'scalar' => [
19+
'type' => AtomicType::asUnion('string'),
20+
'toString' => 'string',
21+
'toPhpString' => 'string'
22+
];
23+
yield 'union scalar' => [
24+
'type' => new UnionType([new AtomicType('int'), new AtomicType('string')]),
25+
'toString' => 'int|string',
26+
'toPhpString' => null,
27+
];
28+
yield 'nullable' => [
29+
'type' => AtomicType::asUnion('string', [], true),
30+
'toString' => '?string',
31+
'toPhpString' => '?string',
32+
];
33+
yield 'scalar array' => [
34+
'type' => AtomicType::asUnion('string', [], false, true),
35+
'toString' => 'string[]',
36+
'toPhpString' => 'array',
37+
];
38+
yield 'nullable scalar array' => [
39+
'type' => AtomicType::asUnion('string', [], true, true),
40+
'toString' => '?string[]',
41+
'toPhpString' => '?array',
42+
];
43+
yield 'generic array' => [
44+
'type' => AtomicType::asUnion('array', [
45+
AtomicType::asUnion('string', []),
46+
AtomicType::asUnion('int', [], true)
47+
]),
48+
'toString' => 'array<string, ?int>',
49+
'toPhpString' => 'array',
50+
];
2551
}
2652
}

0 commit comments

Comments
 (0)