From 7331bc51411943dba14880434df6d7c85a744dcf Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Tue, 21 Feb 2023 21:44:56 +0100 Subject: [PATCH] Fix calling dynamic return type extensions on nullable types --- src/Analyser/MutatingScope.php | 21 ++++++++++++++++----- tests/PHPStan/Analyser/data/date-format.php | 4 ++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index 2dbecbd970..d8bf111691 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -4774,8 +4774,7 @@ private function exactInstantiation(New_ $node, string $className): ?Type ); } - /** @api */ - public function getMethodReflection(Type $typeWithMethod, string $methodName): ?ExtendedMethodReflection + private function filterTypeWithMethod(Type $typeWithMethod, string $methodName): ?Type { if ($typeWithMethod instanceof UnionType) { $newTypes = []; @@ -4796,7 +4795,18 @@ public function getMethodReflection(Type $typeWithMethod, string $methodName): ? return null; } - return $typeWithMethod->getMethod($methodName, $this); + return $typeWithMethod; + } + + /** @api */ + public function getMethodReflection(Type $typeWithMethod, string $methodName): ?ExtendedMethodReflection + { + $type = $this->filterTypeWithMethod($typeWithMethod, $methodName); + if ($type === null) { + return null; + } + + return $type->getMethod($methodName, $this); } /** @@ -4804,11 +4814,12 @@ public function getMethodReflection(Type $typeWithMethod, string $methodName): ? */ private function methodCallReturnType(Type $typeWithMethod, string $methodName, Expr $methodCall): ?Type { - $methodReflection = $this->getMethodReflection($typeWithMethod, $methodName); - if ($methodReflection === null) { + $typeWithMethod = $this->filterTypeWithMethod($typeWithMethod, $methodName); + if ($typeWithMethod === null) { return null; } + $methodReflection = $typeWithMethod->getMethod($methodName, $this); $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs( $this, $methodCall->getArgs(), diff --git a/tests/PHPStan/Analyser/data/date-format.php b/tests/PHPStan/Analyser/data/date-format.php index 0c4c9557cd..e8a6878521 100644 --- a/tests/PHPStan/Analyser/data/date-format.php +++ b/tests/PHPStan/Analyser/data/date-format.php @@ -43,3 +43,7 @@ function (\DateTimeImmutable $dt, string $s): void { assertType('numeric-string', $dt->format('Y')); assertType('numeric-string', $dt->format('Ghi')); }; + +function (?\DateTimeImmutable $d): void { + assertType('DateTimeImmutable|null', $d->modify('+1 day')); +};