Skip to content
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

Add more updates from Psalm and PHPStan #3

Merged
merged 2 commits into from
Jan 16, 2019
Merged

Conversation

muglug
Copy link
Contributor

@muglug muglug commented Jan 9, 2019

@@ -300,6 +300,8 @@
'array_intersect_uassoc\'1' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', '...rest'=>'array|callable(mixed,mixed):int'],
'array_intersect_ukey' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'key_compare_func'=>'callable(mixed,mixed):int'],
'array_intersect_ukey\'1' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', '...rest'=>'array|callable(mixed,mixed):int'],
'array_key_first' => ['int|string|null', 'array'=>'array'],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Speaking of which, I was planning to update this with the new signatures from https://github.com/phan/phan/blob/master/src/Phan/Language/Internal/FunctionSignatureMap_php73_delta.php when 7.3.0 was released, but haven't gotten around to it yet.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

'exif_read_data' => ['array|false', 'filename'=>'string', 'sections_needed='=>'string', 'sub_arrays='=>'bool', 'read_thumbnail='=>'bool'],
'exif_tagname' => ['string', 'index'=>'int'],
'exif_thumbnail' => ['string', 'filename'=>'string', '&w_width='=>'int', '&w_height='=>'int', '&w_imagetype='=>'int'],
'exit' => ['', 'status'=>'string|int'],
'exp' => ['float', 'number'=>'float'],
'expect_expectl' => ['int', 'expect'=>'resource', 'cases'=>'array', 'match='=>'array'],
'expect_popen' => ['resource', 'command'=>'string'],
'explode' => ['array<int,string>', 'separator'=>'string', 'str'=>'string', 'limit='=>'int'],
'explode' => ['array<int,string>|false', 'separator'=>'string', 'str'=>'string', 'limit='=>'int'],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Phan's version of the signature map, this only contains return types that would happen if the input types were valid.
Explode would always return an array given two strings (I think)

  • So changes such as imap and exif make sense (they depend on the filesystem/network and file contents and can fail), but this doesn't for Phan

This is so that --strict-types would correctly analyze uses of the return types. (It'd warn about param types with the right settings)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explode would always return an array given two strings (I think)

Nah, not quite:

If delimiter is an empty string (""), explode() will return FALSE.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should really create a plugin to check for that LiteralStringType as an argument to explode (and any other surprising edge cases in other internal functions)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I’ve done that in Psalm

@@ -6074,7 +6078,7 @@
'kadm5_get_principals' => ['array', 'handle'=>'resource'],
'kadm5_init_with_password' => ['resource', 'admin_server'=>'string', 'realm'=>'string', 'principal'=>'string', 'password'=>'string'],
'kadm5_modify_principal' => ['bool', 'handle'=>'resource', 'principal'=>'string', 'options'=>'array'],
'key' => ['int|string|null', 'array_arg'=>'array'],
'key' => ['int|string|null', 'array_arg'=>'array|object'],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not know about this, but key works. Thankfully, array_key_first only takes arrays.

'OCI_Collection::max' => ['int'],
'OCI_Collection::size' => ['int'],
'OCI_Collection::trim' => ['bool', 'num'=>'int'],
'OCI-Collection::append' => ['bool', 'value'=>'mixed'],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might just remove OCI-Collection's signatures from Phan entirely, because it can't analyze them. (or change everything added elsewhere from OCI-Lob to OCI_Lob

It assumes internal modules declares classes with valid FQSENs, which is true for everything except the oci module.

phan/phan#2222 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I don't think Psalm can analyse them either (but nobody's ever asked, and I'm hoping nobody ever does)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And it seems like it'd cause a crash in Psalm as well

It might be analyzable with the correct stub files for the underscore version (but users might be mislead about what the class name is).

            if (stripos($return_type, 'oci-') !== false) {
                return;
            }

Copy link
Contributor Author

@muglug muglug Jan 13, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now it doesn’t cause a crash in Psalm

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a comment suggesting how to migrate PHP away from the name oci-collection in https://bugs.php.net/bug.php?id=58319

'OCI_Collection::size' => ['int'],
'OCI_Collection::trim' => ['bool', 'num'=>'int'],
'OCI-Collection::append' => ['bool', 'value'=>'mixed'],
'OCI-Collection::assign' => ['bool', 'from'=>'OCI_Collection'],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: If this is in other analyzers, the 'from' should be OCI-Collection.

'preg_replace_callback_array' => ['string|array', 'pattern'=>'array<string,callable(array):string>', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int'],
'preg_split' => ['array<int, string>', 'pattern'=>'string', 'subject'=>'string', 'limit='=>'?int', 'flags='=>'int'],
'prev' => ['mixed', '&rw_array_arg'=>'array'],
'preg_replace_callback' => ['string|array|null', 'regex'=>'string|array', 'callback'=>'callable(array):string', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int'],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment about mb_ereg and preg_replace_callback only including return types for valid regexes and argument types. (to reduce false positives with --strict-types)

Phan's at least able to detect invalid regexes through https://github.com/phan/phan/blob/master/.phan/plugins/PregRegexCheckerPlugin.php (but not mb_ereg)

Copy link
Contributor Author

@muglug muglug Jan 9, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

preg_split etc. can return null if there are invalid UTF-8 characters in the mix. Dunno what --strict-types does, but I've added a specific config in Psalm to allow people to care about internal function null returns (by default they're ignored).

@@ -10205,12 +10210,12 @@
'Redis::getTimeout' => ['float|false'],
'Redis::hDel' => ['int|false', 'key'=>'string', 'hashKey1'=>'string', 'hashKey2='=>'string', 'hashKeyN='=>'string'],
'Redis::hExists' => ['bool', 'key'=>'string', 'hashKey'=>'string'],
'Redis::hGet' => ['string', 'key'=>'string', 'hashKey'=>'string'],
'Redis::hGet' => ['string|false', 'key'=>'string', 'hashKey'=>'string'],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

'Redis::select' => ['bool', 'dbindex'=>'int'],
'Redis::sendEcho' => ['string', 'msg'=>'string'],
'Redis::set' => ['bool', 'key'=>'string', 'value'=>'string', 'options='=>'array'],
'Redis::set\'1' => ['bool', 'key'=>'string', 'value'=>'string', 'timeout='=>'int'],
'Redis::setBit' => ['int', 'key'=>'string', 'offset'=>'int', 'value'=>'int'],
'Redis::setEx' => ['bool', 'key'=>'string', 'ttl'=>'int', 'value'=>'string'],
'Redis::setex' => ['bool', 'key'=>'string', 'ttl'=>'int', 'value'=>'string'],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this, this is the same case-insensitive method name as setEx. Same for setnx

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oof sorry

@@ -13717,7 +13724,7 @@
'Threaded::unlock' => ['bool'],
'Threaded::wait' => ['bool', 'timeout='=>'int'],
'Throwable::__toString' => ['string'],
'Throwable::getCode' => ['int'],
'Throwable::getCode' => ['int|string'],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returns the exception code as integer in Exception but possibly as other type in Exception descendants (for example as string in PDOException).

Ok, then this makes sense

@@ -12784,7 +12791,7 @@
'sqlsrv_server_info' => ['array', 'conn'=>'resource'],
'sqrt' => ['float', 'number'=>'float'],
'srand' => ['void', 'seed='=>'int', 'mode='=>'int'],
'sscanf' => ['mixed', 'str'=>'string', 'format'=>'string', '&...w_vars='=>'string|int|float'],
'sscanf' => ['mixed', 'str'=>'string', 'format'=>'string', '&...w_vars='=>'string|int|float|null'],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, that seems like it would increase false positives. What's the motiviation for this?

Also, &...w_vars= means that this is write-only, and Phan completely ignores the input types.

Are there scanf format strings that would set arguments to null (If all arguments were read successfully and argument counts were correct)?

Copy link
Contributor Author

@muglug muglug Jan 9, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the motiviation for this?

Just because it can be null.

@TysonAndre TysonAndre merged commit 8f49cb0 into phan:master Jan 16, 2019
TysonAndre added a commit that referenced this pull request Jan 16, 2019
Conflicts:
	FunctionSignatureMap.php

This was amended to follow what was typical
for Phan's choices of signatures.

Source: #3
@TysonAndre
Copy link
Member

Thanks, this was amended and merged

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants