Skip to content

Commit

Permalink
Generics - fix handling optional parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed May 12, 2021
1 parent c9b5d27 commit 7306405
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 1 deletion.
5 changes: 4 additions & 1 deletion src/Reflection/Php/PhpParameterFromParserNodeReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ public function getType(): Type
$phpDocType = $this->phpDocType;
if ($phpDocType !== null && $this->defaultValue !== null) {
if ($this->defaultValue instanceof NullType) {
$phpDocType = \PHPStan\Type\TypeCombinator::addNull($phpDocType);
$inferred = $phpDocType->inferTemplateTypes($this->defaultValue);
if ($inferred->isEmpty()) {
$phpDocType = \PHPStan\Type\TypeCombinator::addNull($phpDocType);
}
}
}
$this->type = TypehintHelper::decideType($this->realType, $phpDocType);
Expand Down
1 change: 1 addition & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@ public function dataFileAsserts(): iterable
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-2413.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-3446.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/getopt.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/generics-default.php');
}

/**
Expand Down
44 changes: 44 additions & 0 deletions tests/PHPStan/Analyser/data/generics-default.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace GenericsDefault;

use function PHPStan\Testing\assertType;

class Foo
{

/**
* @template T of int
* @param T $test
* @return T
*/
public function doFoo(int $test = 0): int
{
return $test;
}

public function doBar(): void
{
assertType('0', $this->doFoo());
assertType('1', $this->doFoo(1));
}

/**
* @template T
* @param T $default
*/
public function doBaz($default = null): void
{
assertType('T (method GenericsDefault\Foo::doBaz(), argument)', $default);
}

/**
* @template T
* @param T|null $default
*/
public function doLorem($default = null): void
{
assertType('T (method GenericsDefault\Foo::doLorem(), argument)|null', $default);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,9 @@ public function testBug4011(): void
$this->analyse([__DIR__ . '/data/bug-4011.php'], []);
}

public function testBug2573(): void
{
$this->analyse([__DIR__ . '/data/bug-2573.php'], []);
}

}
13 changes: 13 additions & 0 deletions tests/PHPStan/Rules/Methods/ReturnTypeRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -490,4 +490,17 @@ public function testBug4803(): void
$this->analyse([__DIR__ . '/../../Analyser/data/bug-4803.php'], []);
}

public function testBug2573(): void
{
$this->analyse([__DIR__ . '/data/bug-2573-return.php'], []);
}

public function testBug4603(): void
{
if (PHP_VERSION_ID < 80000 && !self::$useStaticReflectionProvider) {
$this->markTestSkipped('Test requires PHP 8.0');
}
$this->analyse([__DIR__ . '/data/bug-4603.php'], []);
}

}
32 changes: 32 additions & 0 deletions tests/PHPStan/Rules/Methods/data/bug-2573-return.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace Bug2573;

class Bar
{

/**
* @template V
* @template D
*
* @param array<V> $array
* @param array-key $key
* @param D $default
* @return V|D
*/
function idx($array, $key, $default = null) {
if (array_key_exists($key, $array)) {
return $array[$key];
}
return $default;
}

/**
* @param array<int, int> $arr
* @return int
*/
function example($arr) {
return $this->idx($arr, 5, 42);
}

}
19 changes: 19 additions & 0 deletions tests/PHPStan/Rules/Methods/data/bug-2573.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Bug2573;

class Foo
{

/**
* @template T1
* @template T2
* @param T1 $a
* @param T2 $b
* @return T1|T2
*/
function chooseOne($a, $b = []) {
return rand(0, 1) ? $a : $b;
}

}
20 changes: 20 additions & 0 deletions tests/PHPStan/Rules/Methods/data/bug-4603.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php // lint >= 8.0

namespace Bug4603;

class Foo
{

/**
* @param T $val
*
* @return T
*
* @template T
*/
function fcn(mixed $val = null)
{
return $val;
}

}

0 comments on commit 7306405

Please sign in to comment.