Skip to content

Commit 155c637

Browse files
Fix and tests
1 parent 5cda01b commit 155c637

File tree

3 files changed

+34
-8
lines changed

3 files changed

+34
-8
lines changed

src/Type/Php/DateTimeModifyReturnTypeExtension.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
use PHPStan\Analyser\Scope;
99
use PHPStan\Php\PhpVersion;
1010
use PHPStan\Reflection\MethodReflection;
11+
use PHPStan\Reflection\ParametersAcceptorSelector;
1112
use PHPStan\Type\Constant\ConstantBooleanType;
1213
use PHPStan\Type\DynamicMethodReturnTypeExtension;
1314
use PHPStan\Type\NeverType;
14-
use PHPStan\Type\ObjectType;
1515
use PHPStan\Type\Type;
1616
use PHPStan\Type\TypeCombinator;
1717
use Throwable;
@@ -40,11 +40,12 @@ public function isMethodSupported(MethodReflection $methodReflection): bool
4040

4141
public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): ?Type
4242
{
43+
$args = $methodCall->getArgs();
4344
if (count($methodCall->getArgs()) < 1) {
4445
return null;
4546
}
4647

47-
$valueType = $scope->getType($methodCall->getArgs()[0]->value);
48+
$valueType = $scope->getType($args[0]->value);
4849
$constantStrings = $valueType->getConstantStrings();
4950

5051
$hasFalse = false;
@@ -78,10 +79,9 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method
7879

7980
return null;
8081
} elseif ($hasDateTime) {
81-
return TypeCombinator::intersect(
82-
$scope->getType($methodCall->var),
83-
new ObjectType(DateTimeInterface::class),
84-
);
82+
$variant = ParametersAcceptorSelector::selectFromArgs($scope, $args, $methodReflection->getVariants());
83+
84+
return TypeCombinator::remove($variant->getReturnType(), new ConstantBooleanType(false));
8585
}
8686

8787
if ($this->phpVersion->hasDateTimeExceptions()) {

tests/PHPStan/Analyser/nsrt/bug-11073.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,21 @@ public function sayHello(?DateTimeImmutable $date): void
1414
assertType('DateTimeImmutable|null', $date?->modify('+1 year')->setTime(23, 59, 59));
1515
}
1616
}
17+
18+
class Foo
19+
{
20+
public function getCode(): bool { return false; }
21+
}
22+
23+
class HelloWorld2
24+
{
25+
public function sayHello(\Throwable|Foo $foo): void
26+
{
27+
assertType('bool|int|string', $foo->getCode());
28+
}
29+
30+
public function sayHello2(\LogicException|Foo $foo): void
31+
{
32+
assertType('bool|int', $foo->getCode());
33+
}
34+
}

tests/PHPStan/Analyser/nsrt/date-format.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,15 @@ class Bar {
5757
/** @return string */
5858
public function modify($string) {}
5959
}
60+
class Bar2 {
61+
/** @return string|false */
62+
public function modify($string) {}
63+
}
64+
65+
function foo(Foo|Bar $d): void {
66+
assertType('DateFormatReturnType\Foo|string', $d->modify('+1 day'));
67+
};
6068

61-
function (Foo|Bar $d): void {
62-
assertType('(DateFormatReturnType\Bar&DateTimeInterface)|DateFormatReturnType\Foo|string', $d->modify('+1 day'));
69+
function foo2(Foo|Bar2 $d): void {
70+
assertType('DateFormatReturnType\Foo|string|false', $d->modify('+1 day'));
6371
};

0 commit comments

Comments
 (0)