-
Notifications
You must be signed in to change notification settings - Fork 506
Make ParametersAcceptorSelector::selectSingle() return union-ed conditional types #1159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
af88720
a71c977
28342ca
83b829a
fe8cae8
1337434
0c7fd11
5afa64d
7204844
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,58 @@ | ||||||
<?php declare(strict_types = 1); | ||||||
|
||||||
namespace PHPStan\Reflection; | ||||||
|
||||||
use PHPStan\Type\ConditionalType; | ||||||
use PHPStan\Type\ConditionalTypeForParameter; | ||||||
use PHPStan\Type\Generic\TemplateTypeMap; | ||||||
use PHPStan\Type\Type; | ||||||
use PHPStan\Type\TypeTraverser; | ||||||
|
||||||
class SingleParametersAcceptor implements ParametersAcceptor | ||||||
{ | ||||||
|
||||||
private ?Type $returnType = null; | ||||||
|
||||||
public function __construct(private ParametersAcceptor $acceptor) | ||||||
{ | ||||||
} | ||||||
|
||||||
public function getTemplateTypeMap(): TemplateTypeMap | ||||||
{ | ||||||
return $this->acceptor->getTemplateTypeMap(); | ||||||
} | ||||||
|
||||||
public function getResolvedTemplateTypeMap(): TemplateTypeMap | ||||||
{ | ||||||
return $this->acceptor->getResolvedTemplateTypeMap(); | ||||||
} | ||||||
|
||||||
/** | ||||||
* @return array<int, ParameterReflection> | ||||||
*/ | ||||||
public function getParameters(): array | ||||||
{ | ||||||
return $this->acceptor->getParameters(); | ||||||
} | ||||||
|
||||||
public function isVariadic(): bool | ||||||
{ | ||||||
return $this->acceptor->isVariadic(); | ||||||
} | ||||||
|
||||||
public function getReturnType(): Type | ||||||
{ | ||||||
if ($this->returnType === null) { | ||||||
return $this->returnType = TypeTraverser::map($this->acceptor->getReturnType(), static function (Type $type, callable $traverse) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. style-nit - the line is already long enough, and will return on the outer block immediately with the same value
Suggested change
|
||||||
while ($type instanceof ConditionalType || $type instanceof ConditionalTypeForParameter) { | ||||||
$type = $type->getResult(); | ||||||
} | ||||||
|
||||||
return $traverse($type); | ||||||
}); | ||||||
} | ||||||
|
||||||
return $this->returnType; | ||||||
} | ||||||
|
||||||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,20 @@ | ||||||||||||||
<?php | ||||||||||||||
|
||||||||||||||
namespace DynamicMethodReturnGetSingleConditional; | ||||||||||||||
|
||||||||||||||
use function PHPStan\Testing\assertType; | ||||||||||||||
|
||||||||||||||
abstract class Foo | ||||||||||||||
{ | ||||||||||||||
/** | ||||||||||||||
* @return ($input is 1 ? true : false) | ||||||||||||||
*/ | ||||||||||||||
abstract public function get(int $input): mixed; | ||||||||||||||
|
||||||||||||||
public function doFoo(): void | ||||||||||||||
{ | ||||||||||||||
assertType('bool', $this->get(0)); | ||||||||||||||
assertType('bool', $this->get(1)); | ||||||||||||||
assertType('bool', $this->get(2)); | ||||||||||||||
Comment on lines
+16
to
+18
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we expect a more precise type here?
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No - there is return type extension that just returns |
||||||||||||||
} | ||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't immediately get tests to pass without guarding here. I could whip up a helper class that can convert a given
ParametersAcceptor
into the same type but with the return type adjusted? That way the contract still holds.