Skip to content

Commit 370845d

Browse files
committed
Fix parsing nullable collections
Fixes phpDocumentor#163. Fixes phpDocumentor/phpDocumentor#3290. Shorthand nullable type syntax is now supported for collection types (e.g. `?array<int>`). This also prevents a misuse of the shorthand nullable type syntax with compound types, which is illegal with PHP types. This is documented in the Union Types 2.0 RFC (https://wiki.php.net/rfc/union_types_v2) by N. Popov: > Union types and the ?T nullable type notation cannot be mixed. > Writing ?T1|T2, T1|?T2 or ?(T1|T2) is not supported and T1|T2|null > needs to be used instead.
1 parent 77a3251 commit 370845d

File tree

3 files changed

+20
-8
lines changed

3 files changed

+20
-8
lines changed

src/TypeResolver.php

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -293,13 +293,8 @@ private function parseTypes(ArrayIterator $tokens, Context $context, int $parser
293293

294294
$tokens->next();
295295
} else {
296-
$type = $this->resolveSingleType($token, $context);
296+
$types[] = $this->resolveSingleType($token, $context);
297297
$tokens->next();
298-
if ($parserContext === self::PARSER_IN_NULLABLE) {
299-
return $type;
300-
}
301-
302-
$types[] = $type;
303298
}
304299
}
305300

tests/unit/CollectionResolverTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,4 +328,21 @@ public function testResolvingList(): void
328328
$this->assertInstanceOf(Types\String_::class, $valueType);
329329
$this->assertInstanceOf(Types\Integer::class, $keyType);
330330
}
331+
332+
/**
333+
* @uses \phpDocumentor\Reflection\Types\Context
334+
* @uses \phpDocumentor\Reflection\Types\Nullable
335+
*
336+
* @covers ::__construct
337+
* @covers ::resolve
338+
*/
339+
public function testResolvingNullableArray(): void
340+
{
341+
$fixture = new TypeResolver();
342+
343+
$resolvedType = $fixture->resolve('?array<int>', new Context(''));
344+
345+
$this->assertInstanceOf(Types\Nullable::class, $resolvedType);
346+
$this->assertSame('?int[]', (string) $resolvedType);
347+
}
331348
}

tests/unit/TypeResolverTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,9 +407,9 @@ public function testResolvingNullableCompoundTypes(): void
407407
{
408408
$fixture = new TypeResolver();
409409

410+
$this->expectException('RuntimeException');
411+
$this->expectExceptionMessage('Unexpected type separator');
410412
$resolvedType = $fixture->resolve('?string|null|?boolean');
411-
412-
$this->assertSame('?string|null|?bool', (string) $resolvedType);
413413
}
414414

415415
/**

0 commit comments

Comments
 (0)