Skip to content

Commit 0e7fb35

Browse files
committed
Fix #59 - Support IntersectionType (intersection types)
Ref: https://php.watch/versions/8.1/intersection-types
1 parent 6a39feb commit 0e7fb35

File tree

4 files changed

+89
-2
lines changed

4 files changed

+89
-2
lines changed

src/Parser/NodeVisitor.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
use Doctum\Parser\Node\DocBlockNode;
4242
use PhpParser\Node\Stmt\PropertyProperty;
4343
use PhpParser\Node\UnionType;
44+
use PhpParser\Node\IntersectionType;
4445

4546
class NodeVisitor extends NodeVisitorAbstract
4647
{
@@ -187,12 +188,12 @@ protected function addFunction(FunctionNode $node, ?string $namespace = null)
187188
}
188189

189190
/**
190-
* @param \PhpParser\Node\Identifier|\PhpParser\Node\Name|NullableType|UnionType|null $type Type declaration
191+
* @param \PhpParser\Node\Identifier|\PhpParser\Node\Name|NullableType|UnionType|IntersectionType|null $type Type declaration
191192
*/
192193
protected function typeToString($type): ?string
193194
{
194195
$typeString = null;
195-
if ($type !== null && ! ($type instanceof NullableType || $type instanceof UnionType)) {
196+
if ($type !== null && ! ($type instanceof NullableType || $type instanceof UnionType || $type instanceof IntersectionType)) {
196197
$typeString = $type->__toString();
197198
} elseif ($type instanceof NullableType) {
198199
$typeString = $type->type->__toString();
@@ -202,6 +203,12 @@ protected function typeToString($type): ?string
202203
$typeString[] = $type->__toString();
203204
}
204205
$typeString = implode('|', $typeString);
206+
} elseif ($type instanceof IntersectionType) {
207+
$typeString = [];
208+
foreach ($type->types as $type) {
209+
$typeString[] = $type->__toString();
210+
}
211+
$typeString = implode('&', $typeString);
205212
}
206213

207214
if ($typeString === null) {

tests/Parser/CodeParserTest.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
declare(strict_types = 1);
4+
5+
/*
6+
* This file is part of the Doctum utility.
7+
*
8+
* (c) William Desportes <[email protected]>
9+
*
10+
* This source file is subject to the MIT license that is bundled
11+
* with this source code in the file LICENSE.
12+
*/
13+
14+
namespace Doctum\Tests\Parser;
15+
16+
use Symfony\Component\Finder\Finder;
17+
use Doctum\Tests\AbstractTestCase;
18+
use Doctum\Doctum;
19+
20+
class CodeParserTest extends AbstractTestCase
21+
{
22+
23+
public function testParseCode(): void
24+
{
25+
$dir = __DIR__ . '/../phar/data';
26+
$iterator = Finder::create()
27+
->files()
28+
->name('*.php')
29+
->in($dir . '/src');
30+
31+
$doctum = new Doctum(
32+
$iterator,
33+
[
34+
'build_dir' => $dir . '/build',
35+
'cache_dir' => $dir . '/cache',
36+
]
37+
);
38+
39+
$codeParser = $this->callMethod($doctum, 'getCodeParser', []);
40+
foreach ($iterator as $file) {
41+
$fileContents = file_get_contents($file->getPathName());
42+
$this->assertIsString($fileContents);
43+
//echo 'parsing: ' . $file->getPathName() . PHP_EOL;
44+
$codeParser->parse($fileContents);
45+
//var_dump($codeParser->getContext()->getErrors());
46+
}
47+
}
48+
49+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
class Foo {}
4+
interface Bar {}
5+
6+
class Baz
7+
{
8+
public function __construct(
9+
public Foo&Bar $baz,
10+
) {}
11+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace RoundaboutIntersection;
4+
5+
class FooAndBar extends Foo implements Bar {}
6+
7+
class Baz
8+
{
9+
public Foo&Bar $fooAndBar;
10+
11+
public function baz(Foo&Bar $baz)
12+
{
13+
return;
14+
}
15+
16+
public function returnFooAndBar(): Foo&Bar
17+
{
18+
return new FooAndBar;
19+
}
20+
}

0 commit comments

Comments
 (0)