Skip to content

Commit 9409aa7

Browse files
committed
parse union type.
1 parent 49ca58d commit 9409aa7

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

src/Php/PhpTypeExpression.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
use PhpParser\Node\Identifier;
66
use PhpParser\Node\NullableType;
7+
use PhpParser\Node\Stmt\Property;
8+
use PhpParser\Node\UnionType;
79
use PhpParser\NodeAbstract;
810

911
class PhpTypeExpression {
@@ -15,6 +17,16 @@ class PhpTypeExpression {
1517

1618
public function __construct(NodeAbstract $stmt, string $targetType) {
1719
$type = $stmt->{$targetType};
20+
if ($type instanceOf UnionType) {
21+
foreach ($type->types as $t) {
22+
$this->types[] = $this->parseType($t);
23+
}
24+
} else {
25+
$this->types[] = $this->parseType($type);
26+
}
27+
}
28+
29+
private function parseType(Property|Identifier|NullableType $type) {
1830
$nullable = false;
1931
if ($type instanceOf NullableType) {
2032
$type = $type->type;
@@ -26,7 +38,8 @@ public function __construct(NodeAbstract $stmt, string $targetType) {
2638
}
2739
$namespace = [];
2840
$typeName = array_pop($parts);
29-
$this->types[] = new PhpType($namespace, $stmt->getType(), $typeName ?? '', null, $nullable);
41+
return new PhpType($namespace, $type->getType(), $typeName ?? '', null, $nullable);
42+
3043
}
3144
/**
3245
* @return PhpType[] types

test/PhpTypeExpressionTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,23 @@ public function testNullableString(): void {
2727
$this->assertSame('string', $types[0]->getName(), 'name');
2828
$this->assertSame(true, $types[0]->getNullable(), 'nullable');
2929
}
30+
public function testIntOrString(): void {
31+
$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
32+
$filename = sprintf('%s/php8/product/Product.php', $this->fixtureDir);
33+
try {
34+
$ast = $parser->parse(file_get_contents($filename));
35+
} catch (Error $error) {
36+
throw new \Exception("Parse error: {$error->getMessage()} file: {$filename}\n");
37+
}
38+
// var_dump($ast[0]->stmts[1]->stmts[1]);die();
39+
$expression = new PhpTypeExpression($ast[0]->stmts[1]->stmts[1], PhpTypeExpression::TYPE);
40+
$types = $expression->getTypes();
41+
42+
$this->assertSame([], $types[0]->getNamespace(), 'namespace');
43+
$this->assertSame('int', $types[0]->getName(), 'name');
44+
$this->assertSame(false, $types[0]->getNullable(), 'nullable');
45+
$this->assertSame([], $types[1]->getNamespace(), 'namespace');
46+
$this->assertSame('string', $types[1]->getName(), 'name');
47+
$this->assertSame(false, $types[1]->getNullable(), 'nullable');
48+
}
3049
}

test/fixtures/php8/product/Product.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
class Product {
1010
private ?string $nullableString;
11+
private int|string $intOrString;
1112
private Name $name;
1213
private Price $price;
1314

0 commit comments

Comments
 (0)