Skip to content

Commit e73fd77

Browse files
Handle default value in phpstan-assert
1 parent 745ae5a commit e73fd77

File tree

2 files changed

+121
-0
lines changed

2 files changed

+121
-0
lines changed

src/Analyser/TypeSpecifier.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use PhpParser\Node\Name;
2222
use PHPStan\DependencyInjection\AutowiredService;
2323
use PHPStan\Node\Expr\AlwaysRememberedExpr;
24+
use PHPStan\Node\Expr\TypeExpr;
2425
use PHPStan\Node\IssetExpr;
2526
use PHPStan\Node\Printer\ExprPrinter;
2627
use PHPStan\Php\PhpVersion;
@@ -1451,6 +1452,14 @@ private function specifyTypesFromAsserts(TypeSpecifierContext $context, Expr\Cal
14511452

14521453
$argsMap[$paramName][] = $arg->value;
14531454
}
1455+
foreach ($parameters as $parameter) {
1456+
$name = $parameter->getName();
1457+
$defaultValue = $parameter->getDefaultValue();
1458+
if (isset($argsMap[$name]) || $defaultValue === null) {
1459+
continue;
1460+
}
1461+
$argsMap[$name][] = new TypeExpr($defaultValue);
1462+
}
14541463

14551464
if ($call instanceof MethodCall) {
14561465
$argsMap['this'] = [$call->var];
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Bug9435;
6+
7+
use function PHPStan\Testing\assertType;
8+
9+
function x(): mixed
10+
{
11+
return null;
12+
}
13+
14+
/** @phpstan-assert ($allow_null is true ? string|null : string) $input */
15+
function trueCheck(mixed $input, bool $allow_null = false): void
16+
{
17+
}
18+
19+
$a = x();
20+
trueCheck($a);
21+
assertType('string', $a); // incorrect: should be string but is string|null
22+
23+
$a = x();
24+
trueCheck($a, false);
25+
assertType('string', $a); // correct (string)
26+
27+
$a = x();
28+
trueCheck($a, allow_null: false);
29+
assertType('string', $a); // correct (string)
30+
31+
$a = x();
32+
trueCheck($a, true);
33+
assertType('string|null', $a); // correct (string|null)
34+
35+
$a = x();
36+
trueCheck($a, allow_null: true);
37+
assertType('string|null', $a); // correct (string|null)
38+
39+
/** @phpstan-assert ($allow_null is false ? string : string|null) $input */
40+
function falseCheck(mixed $input, bool $allow_null = false): void
41+
{
42+
}
43+
44+
$a = x();
45+
falseCheck($a);
46+
assertType('string', $a); // incorrect: should be string but is string|null
47+
48+
$a = x();
49+
falseCheck($a, false);
50+
assertType('string', $a); // correct (string)
51+
52+
$a = x();
53+
falseCheck($a, allow_null: false);
54+
assertType('string', $a); // correct (string)
55+
56+
$a = x();
57+
falseCheck($a, true);
58+
assertType('string|null', $a); // correct (string|null)
59+
60+
$a = x();
61+
falseCheck($a, allow_null: true);
62+
assertType('string|null', $a); // correct (string|null)
63+
64+
/** @phpstan-assert ($allow_null is not true ? string : string|null) $input */
65+
function notTrueCheck(mixed $input, bool $allow_null = false): void
66+
{
67+
}
68+
69+
$a = x();
70+
notTrueCheck($a);
71+
assertType('string', $a); // incorrect: should be string but is string|null
72+
73+
$a = x();
74+
notTrueCheck($a, false);
75+
assertType('string', $a); // correct (string)
76+
77+
$a = x();
78+
notTrueCheck($a, allow_null: false);
79+
assertType('string', $a); // correct (string)
80+
81+
$a = x();
82+
notTrueCheck($a, true);
83+
assertType('string|null', $a); // correct (string|null)
84+
85+
$a = x();
86+
notTrueCheck($a, allow_null: true);
87+
assertType('string|null', $a); // correct (string|null)
88+
89+
/** @phpstan-assert ($allow_null is not false ? string|null : string) $input */
90+
function notFalseCheck(mixed $input, bool $allow_null = false): void
91+
{
92+
}
93+
94+
$a = x();
95+
notFalseCheck($a);
96+
assertType('string', $a); // incorrect: should be string but is string|null
97+
98+
$a = x();
99+
notFalseCheck($a, false);
100+
assertType('string', $a); // correct (string)
101+
102+
$a = x();
103+
notFalseCheck($a, allow_null: false);
104+
assertType('string', $a); // correct (string)
105+
106+
$a = x();
107+
notFalseCheck($a, true);
108+
assertType('string|null', $a); // correct (string|null)
109+
110+
$a = x();
111+
notFalseCheck($a, allow_null: true);
112+
assertType('string|null', $a); // correct (string|null)

0 commit comments

Comments
 (0)