Skip to content

Commit ac4f96a

Browse files
authored
Merge pull request #183 from schodemeiss/1.x
Add non-empty-list pseudo-type
2 parents 1478a93 + c5521c9 commit ac4f96a

File tree

5 files changed

+133
-0
lines changed

5 files changed

+133
-0
lines changed

src/PseudoTypes/NonEmptyList.php

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* This file is part of phpDocumentor.
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*
11+
* @link http://phpdoc.org
12+
*/
13+
14+
namespace phpDocumentor\Reflection\PseudoTypes;
15+
16+
use phpDocumentor\Reflection\PseudoType;
17+
use phpDocumentor\Reflection\Type;
18+
use phpDocumentor\Reflection\Types\Array_;
19+
use phpDocumentor\Reflection\Types\Integer;
20+
use phpDocumentor\Reflection\Types\Mixed_;
21+
22+
/**
23+
* Value Object representing the type 'non-empty-list'.
24+
*
25+
* @psalm-immutable
26+
*/
27+
final class NonEmptyList extends Array_ implements PseudoType
28+
{
29+
public function underlyingType(): Type
30+
{
31+
return new Array_();
32+
}
33+
34+
public function __construct(?Type $valueType = null)
35+
{
36+
parent::__construct($valueType, new Integer());
37+
}
38+
39+
/**
40+
* Returns a rendered output of the Type as it would be used in a DocBlock.
41+
*/
42+
public function __toString(): string
43+
{
44+
if ($this->valueType instanceof Mixed_) {
45+
return 'non-empty-list';
46+
}
47+
48+
return 'non-empty-list<' . $this->valueType . '>';
49+
}
50+
}

src/TypeResolver.php

+7
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
use phpDocumentor\Reflection\PseudoTypes\LiteralString;
2828
use phpDocumentor\Reflection\PseudoTypes\LowercaseString;
2929
use phpDocumentor\Reflection\PseudoTypes\NegativeInteger;
30+
use phpDocumentor\Reflection\PseudoTypes\NonEmptyList;
3031
use phpDocumentor\Reflection\PseudoTypes\NonEmptyLowercaseString;
3132
use phpDocumentor\Reflection\PseudoTypes\NonEmptyString;
3233
use phpDocumentor\Reflection\PseudoTypes\Numeric_;
@@ -157,6 +158,7 @@ final class TypeResolver
157158
'iterable' => Iterable_::class,
158159
'never' => Never_::class,
159160
'list' => List_::class,
161+
'non-empty-list' => NonEmptyList::class,
160162
];
161163

162164
/** @psalm-readonly */
@@ -333,6 +335,11 @@ private function createFromGeneric(GenericTypeNode $type, Context $context): Typ
333335
$this->createType($type->genericTypes[0], $context)
334336
);
335337

338+
case 'non-empty-list':
339+
return new NonEmptyList(
340+
$this->createType($type->genericTypes[0], $context)
341+
);
342+
336343
case 'int':
337344
if (isset($type->genericTypes[1]) === false) {
338345
throw new RuntimeException('int<min,max> has not the correct format');

tests/unit/CollectionResolverTest.php

+25
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace phpDocumentor\Reflection;
1515

1616
use phpDocumentor\Reflection\PseudoTypes\List_;
17+
use phpDocumentor\Reflection\PseudoTypes\NonEmptyList;
1718
use phpDocumentor\Reflection\Types\Array_;
1819
use phpDocumentor\Reflection\Types\Collection;
1920
use phpDocumentor\Reflection\Types\Compound;
@@ -321,6 +322,30 @@ public function testResolvingList(): void
321322
$this->assertInstanceOf(Integer::class, $keyType);
322323
}
323324

325+
/**
326+
* @uses \phpDocumentor\Reflection\Types\Context
327+
* @uses \phpDocumentor\Reflection\Types\String_
328+
*
329+
* @covers ::__construct
330+
* @covers ::resolve
331+
*/
332+
public function testResolvingNonEmptyList(): void
333+
{
334+
$fixture = new TypeResolver();
335+
336+
$resolvedType = $fixture->resolve('non-empty-list<string>', new Context(''));
337+
338+
$this->assertInstanceOf(NonEmptyList::class, $resolvedType);
339+
$this->assertSame('non-empty-list<string>', (string) $resolvedType);
340+
341+
$valueType = $resolvedType->getValueType();
342+
343+
$keyType = $resolvedType->getKeyType();
344+
345+
$this->assertInstanceOf(String_::class, $valueType);
346+
$this->assertInstanceOf(Integer::class, $keyType);
347+
}
348+
324349
/**
325350
* @uses \phpDocumentor\Reflection\Types\Context
326351
* @uses \phpDocumentor\Reflection\Types\Nullable
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 phpDocumentor.
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*
11+
* @link http://phpdoc.org
12+
*/
13+
14+
namespace phpDocumentor\Reflection\PseudoTypes;
15+
16+
use phpDocumentor\Reflection\Types\Compound;
17+
use phpDocumentor\Reflection\Types\Integer;
18+
use phpDocumentor\Reflection\Types\Mixed_;
19+
use phpDocumentor\Reflection\Types\String_;
20+
use PHPUnit\Framework\TestCase;
21+
22+
/**
23+
* @coversDefaultClass \phpDocumentor\Reflection\PseudoTypes\NonEmptyList
24+
*/
25+
class NonEmptyListTest extends TestCase
26+
{
27+
/**
28+
* @dataProvider provideArrays
29+
* @covers ::__toString
30+
*/
31+
public function testArrayStringifyCorrectly(NonEmptyList $array, string $expectedString): void
32+
{
33+
$this->assertSame($expectedString, (string) $array);
34+
}
35+
36+
/**
37+
* @return mixed[]
38+
*/
39+
public function provideArrays(): array
40+
{
41+
return [
42+
'simple non-empty-list' => [new NonEmptyList(), 'non-empty-list'],
43+
'non-empty-list of mixed' => [new NonEmptyList(new Mixed_()), 'non-empty-list'],
44+
'non-empty-list of single type' => [new NonEmptyList(new String_()), 'non-empty-list<string>'],
45+
'non-empty-list of compound type' =>
46+
[new NonEmptyList(new Compound([new Integer(), new String_()])), 'non-empty-list<int|string>'],
47+
];
48+
}
49+
}

tests/unit/TypeResolverTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
use phpDocumentor\Reflection\PseudoTypes\LiteralString;
2626
use phpDocumentor\Reflection\PseudoTypes\LowercaseString;
2727
use phpDocumentor\Reflection\PseudoTypes\NegativeInteger;
28+
use phpDocumentor\Reflection\PseudoTypes\NonEmptyList;
2829
use phpDocumentor\Reflection\PseudoTypes\NonEmptyLowercaseString;
2930
use phpDocumentor\Reflection\PseudoTypes\NonEmptyString;
3031
use phpDocumentor\Reflection\PseudoTypes\Numeric_;
@@ -784,6 +785,7 @@ public function provideKeywords(): array
784785
['never', Never_::class],
785786
['literal-string', LiteralString::class],
786787
['list', List_::class],
788+
['non-empty-list', NonEmptyList::class],
787789
];
788790
}
789791

0 commit comments

Comments
 (0)