Skip to content

Commit

Permalink
list and list<foo> support
Browse files Browse the repository at this point in the history
  • Loading branch information
orklah authored and ondrejmirtes committed Jan 4, 2020
1 parent 92df236 commit a2c0403
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/PhpDoc/TypeNodeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ private function resolveIdentifierTypeNode(IdentifierTypeNode $typeNode, NameSco
return new NeverType(true);

case 'list':
return new ErrorType();
return new ArrayType(new IntegerType(), new MixedType());
}

if ($nameScope->getClassName() !== null) {
Expand Down Expand Up @@ -313,6 +313,12 @@ private function resolveGenericTypeNode(GenericTypeNode $typeNode, NameScope $na
return new ArrayType($genericTypes[0], $genericTypes[1]);
}

} elseif ($mainTypeName === 'list') {
if (count($genericTypes) === 1) { // list<ValueType>
return new ArrayType(new IntegerType(), $genericTypes[0]);
}

return new ErrorType();
} elseif ($mainTypeName === 'iterable') {
if (count($genericTypes) === 1) { // iterable<ValueType>
return new IterableType(new MixedType(true), $genericTypes[0]);
Expand Down
6 changes: 6 additions & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9737,6 +9737,11 @@ public function dataPhpDocInheritanceParameterRemapping(): array
return $this->gatherAssertTypes(__DIR__ . '/data/inheritdoc-parameter-remapping.php');
}

public function dataListType(): array
{
return $this->gatherAssertTypes(__DIR__ . '/data/list-type.php');
}

/**
* @dataProvider dataBug2574
* @dataProvider dataBug2577
Expand All @@ -9757,6 +9762,7 @@ public function dataPhpDocInheritanceParameterRemapping(): array
* @dataProvider dataBug2648
* @dataProvider dataBug2740
* @dataProvider dataPhpDocInheritanceParameterRemapping
* @dataProvider dataListType
* @param ConstantStringType $expectedType
* @param Type $actualType
*/
Expand Down
97 changes: 97 additions & 0 deletions tests/PHPStan/Analyser/data/list-type.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php

namespace ListType;

use function PHPStan\Analyser\assertType;

class Foo
{
/** @param list $list */
public function directAssertion($list): void
{
assertType('array<int, mixed>', $list);
}

/** @param list $list */
public function directAssertionParamHint(array $list): void
{
assertType('array<int, mixed>', $list);
}

/** @param list $list */
public function directAssertionNullableParamHint(array $list = null): void
{
assertType('array<int, mixed>|null', $list);
}

/** @param list<\DateTime> $list */
public function directAssertionObjectParamHint($list): void
{
assertType('array<int, DateTime>', $list);
}

public function withoutGenerics(): void
{
/** @var list $list */
$list = [];
$list[] = '1';
$list[] = true;
$list[] = new \stdClass();
assertType('array<int, mixed>', $list);
}


public function withMixedType(): void
{
/** @var list<mixed> $list */
$list = [];
$list[] = '1';
$list[] = true;
$list[] = new \stdClass();
assertType('array<int, mixed>', $list);
}

public function withObjectType(): void
{
/** @var list<\DateTime> $list */
$list = [];
$list[] = new \DateTime();
assertType('array<int, DateTime>', $list);
}

/** @return list<scalar> */
public function withScalarGoodContent(): void
{
/** @var list<scalar> $list */
$list = [];
$list[] = '1';
$list[] = true;
assertType('array<int, bool|float|int|string>', $list);
}

public function withNumericKey(): void
{
/** @var list $list */
$list = [];
$list[] = '1';
$list['1'] = true;
assertType('array<int, mixed>', $list);
}

public function withFullListFunctionality(): void
{
// These won't output errors for now but should when list type will be fully implemented
/** @var list $list */
$list = [];
$list[] = '1';
$list[] = '2';
unset($list[0]);//break list behaviour
assertType('array<int, mixed>', $list);

/** @var list $list2 */
$list2 = [];
$list2[2] = '1';//Most likely to create a gap in indexes
assertType('array<int, mixed>', $list2);
}

}

0 comments on commit a2c0403

Please sign in to comment.