-
Notifications
You must be signed in to change notification settings - Fork 519
fix parameter of strval, intval and floatval #1005
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
base: 1.5.x
Are you sure you want to change the base?
Conversation
tests/PHPStan/Rules/Functions/StrvalFamilyParametersRuleTest.php
Outdated
Show resolved
Hide resolved
class StrvalFamilyParametersRule implements Rule | ||
{ | ||
|
||
private const FUNCTIONS = [ |
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.
What about boolval
?
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'm not aware of any restrictions on boolval
. As far as I know it really accepts mixed
. Am I missing something?
Also I think I wiill remove everything but strval
. Only strval
needs special handling due to Stringable
. Everything else should be fixable by changing the function signature in functionMap
.
Errr, I thought that you want to implement a dynamic return type extension so that the result type of If you need to check the parameter type then sure, a change in |
5ea3402
to
1073a5e
Compare
$base = new ObjectType(''); | ||
|
||
if ($type instanceof ErrorType || !$base->isSuperTypeOf($type)->maybe()) { |
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.
Is there a better way, to check if this is an instance of any object?
After changing the |
86408aa
to
cc28967
Compare
resources/functionMap.php
Outdated
@@ -2020,7 +2020,7 @@ | |||
'DomXsltStylesheet::result_dump_mem' => ['string', 'xmldoc'=>'DOMDocument'], | |||
'DOTNET::__construct' => ['void', 'assembly_name'=>'string', 'class_name'=>'string', 'codepage='=>'int'], | |||
'dotnet_load' => ['int', 'assembly_name'=>'string', 'datatype_name='=>'string', 'codepage='=>'int'], | |||
'doubleval' => ['float', 'var'=>'mixed'], | |||
'doubleval' => ['float', 'var'=>'array|bool|float|int|resource|string|null'], |
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.
Is it ever useful to allow the array
and resource
here?
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'm also a bit confused - doubleval
does not accept object
here which should already be picked up by an existing rule (CallToFunctionParametersRule) but apparently isn't. Any idea why?
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.
Is it ever useful to allow the
array
andresource
here?
Probably not. I was attempting to keep (float)
and floatval()
in line and used the actual PHP behavior as a guideline along with the fact that casting to int
is possible.
I'm also a bit confused -
doubleval
does not acceptobject
here which should already be picked up by an existing rule (CallToFunctionParametersRule) but apparently isn't. Any idea why?
I have to check again, but if I remember correctly, it does pick up regular objects, but has a special rule to allow objects with a __toString
-method. Which in general is the correct behavior. intval
and floatval
are the special case, in that they accept string
but not Stringable
:
php > $stringable = new class() {public function __toString(): string {return '';}};
php > echo strlen($stringable);
0
php > echo intval($stringable);
PHP Notice: Object of class class@anonymous could not be converted to int in php shell code on line 1
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 have added a commit to forbid casting resource
to float
. I'm looking into doing the same with array
but that causes a regression for phpstan/phpstan#5162.
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.
So I looked into phpstan/phpstan#5162. The problem is, that the fix for that issue was to explicitly allow casting array
to float
. If we forbid it here again, this will obviously fail again. In order to resolve this, the underlying issue would have to be resolved:
/** @var array<string,string|array<string>> $result */
$result = $this->Get();
if ( array_key_exists('a',$result) && ! is_numeric( $result['a'] ) )
{
exit(1);
}
assertType('numeric-string', $result['a']); //this currently reports 'array<string>|string'
/** @var array<string,string|array<string>> $result2 */
$result2 = $this->Get();
if ( ! is_numeric( $result['a'] ) )
{
exit(1);
}
assertType('numeric-string', $result['a']); //this works
As far as I can tell in the first case the resolved type of $result['a']
is not updated, because it might not even exist. Obviously the type of $result['a']
could also be ERROR
if the offset doesn't exist.
However I have no idea how to fix this.
cc28967
to
3ab0c2b
Compare
ddd20b4
to
95d480b
Compare
resolves phpstan/phpstan#6560
I implemented a rule instead of a dynamic return type extension as mentioned in phpstan/phpstan#6560 (comment). I think that was a misunderstanding? After all the problem is the parameter type, not the return type of the function. For the return type StrvalFamilyFunctionReturnTypeExtension already exists.