Skip to content

Commit efb6921

Browse files
committed
WIP
1 parent 53ab8ce commit efb6921

File tree

6 files changed

+158
-13
lines changed

6 files changed

+158
-13
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
],
1919

2020
"require": {
21-
"php": "^7.2 || 8.0.* || 8.1.* || 8.2.* || 8.3.* || 8.4.*",
21+
"php": "8.1.* || 8.2.* || 8.3.* || 8.4.*",
2222
"phpdocumentor/reflection-docblock": "^5.2",
2323
"sebastian/comparator": "^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0",
2424
"doctrine/instantiator": "^1.2 || ^2.0",
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Prophecy\Doubler\Generator\Node\Type;
4+
5+
abstract class AbstractType
6+
{
7+
8+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Prophecy\Doubler\Generator\Node\Type;
4+
5+
class IntersectionType extends AbstractType
6+
{
7+
private function guard(): void
8+
{
9+
// Cannot contain void, never or union
10+
}
11+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
namespace Prophecy\Doubler\Generator\Node\Type;
4+
5+
class SimpleType extends AbstractType implements \Stringable
6+
{
7+
private $type;
8+
public function __construct(string $type)
9+
{
10+
switch ($type) {
11+
// type aliases
12+
case 'double':
13+
case 'real':
14+
return 'float';
15+
case 'boolean':
16+
return 'bool';
17+
case 'integer':
18+
return 'int';
19+
20+
// built in types
21+
case 'self':
22+
case 'static':
23+
case 'array':
24+
case 'callable':
25+
case 'bool':
26+
case 'false':
27+
case 'true':
28+
case 'float':
29+
case 'int':
30+
case 'string':
31+
case 'iterable':
32+
case 'object':
33+
case 'null':
34+
case 'mixed':
35+
case 'void':
36+
case 'never':
37+
return $type;
38+
default:
39+
// Class / Interface type
40+
throw new \Exception('TODO');
41+
return $this->prefixWithNsSeparator($type);
42+
}
43+
}
44+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
namespace Prophecy\Doubler\Generator\Node\Type;
4+
5+
class UnionType extends AbstractType
6+
{
7+
/**
8+
* @param list<AbstractType> $types
9+
*/
10+
public function __construct(private array $types)
11+
{
12+
$this->guard();
13+
}
14+
15+
/**
16+
* @return list<AbstractType>
17+
*/
18+
public function getTypes(): array
19+
{
20+
return $this->types;
21+
}
22+
public function isRecursive(): bool
23+
{
24+
foreach ($this->types as $type) {
25+
if ($type instanceof IntersectionType) {
26+
return true;
27+
}
28+
}
29+
30+
return false;
31+
}
32+
33+
private function guard(): void
34+
{
35+
// Cannot contain void or never
36+
}
37+
}

src/Prophecy/Doubler/Generator/Node/TypeNodeAbstract.php

Lines changed: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,45 @@
22

33
namespace Prophecy\Doubler\Generator\Node;
44

5+
use Prophecy\Doubler\Generator\Node\Type\AbstractType;
6+
use Prophecy\Doubler\Generator\Node\Type\SimpleType;
7+
use Prophecy\Doubler\Generator\Node\Type\UnionType;
58
use Prophecy\Exception\Doubler\DoubleException;
69

710
abstract class TypeNodeAbstract
811
{
9-
/** @var array<string, string> */
10-
protected $types = [];
12+
protected AbstractType $type;
1113

12-
public function __construct(string ...$types)
14+
/**
15+
* @param string|AbstractType ...$types
16+
*/
17+
public function __construct(string|AbstractType ...$types)
1318
{
14-
foreach ($types as $type) {
15-
$type = $this->getRealType($type);
16-
$this->types[$type] = $type;
19+
$deprecation = 'Only 1 type will be supported in the future, strings are no longer supported as type.';
20+
if (count($types) !== 1) {
21+
// TODO: trigger deprecation notice
22+
} else {
23+
foreach ($types as $type) {
24+
if (!$type instanceof AbstractType) {
25+
// TODO: deprecation notice
26+
break;
27+
}
28+
}
1729
}
1830

19-
$this->guardIsValidType();
31+
// BC Layer for usage with strings
32+
foreach ($types as $index => $type) {
33+
if (is_string($type)) {
34+
$types[$index] = new SimpleType($type);
35+
}
36+
}
37+
38+
// BC Layer for usage with many types
39+
if (count($types) > 1) {
40+
$this->type = new UnionType($types);
41+
} else {
42+
$this->type = $types[0];
43+
}
2044
}
2145

2246
public function canUseNullShorthand(): bool
@@ -26,17 +50,36 @@ public function canUseNullShorthand(): bool
2650

2751
/**
2852
* @return list<string>
53+
* @deprecated use getType() instead
2954
*/
3055
public function getTypes(): array
3156
{
32-
return array_values($this->types);
57+
// TODO: add deprecation notice
58+
if ($this->type instanceof SimpleType) {
59+
return [(string) $this->type];
60+
}
61+
62+
if ($this->type instanceof UnionType && $this->type->isSimple()) {
63+
foreach ($this->type->getTypes() as $type) {
64+
$types[] = (string) $type;
65+
}
66+
}
67+
68+
return $types;
69+
}
70+
71+
public function getType(): AbstractType
72+
{
73+
return $this->type;
3374
}
3475

3576
/**
77+
* @deprecated use getType() instead
3678
* @return list<string>
3779
*/
3880
public function getNonNullTypes(): array
3981
{
82+
// @fixme
4083
$nonNullTypes = $this->types;
4184
unset($nonNullTypes['null']);
4285

@@ -60,7 +103,7 @@ protected function getRealType(string $type): string
60103
case 'integer':
61104
return 'int';
62105

63-
// built in types
106+
// built in types
64107
case 'self':
65108
case 'static':
66109
case 'array':
@@ -74,16 +117,18 @@ protected function getRealType(string $type): string
74117
case 'iterable':
75118
case 'object':
76119
case 'null':
77-
return $type;
78120
case 'mixed':
79-
return \PHP_VERSION_ID < 80000 ? $this->prefixWithNsSeparator($type) : $type;
80-
121+
case 'void':
122+
case 'never':
123+
return $type;
81124
default:
125+
// Class / Interface type
82126
return $this->prefixWithNsSeparator($type);
83127
}
84128
}
85129

86130
/**
131+
* @todo: put this in SimpleType
87132
* @return void
88133
*/
89134
protected function guardIsValidType()

0 commit comments

Comments
 (0)