Skip to content

Commit

Permalink
Fix socket_select array types after call
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Apr 3, 2024
1 parent b2177e3 commit 24c5249
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 3 deletions.
5 changes: 5 additions & 0 deletions conf/config.neon
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,11 @@ services:
tags:
- phpstan.stubFilesExtension

-
class: PHPStan\PhpDoc\SocketSelectStubFilesExtension
tags:
- phpstan.stubFilesExtension

-
class: PHPStan\PhpDoc\DefaultStubFilesProvider
arguments:
Expand Down
2 changes: 1 addition & 1 deletion resources/functionMap.php
Original file line number Diff line number Diff line change
Expand Up @@ -10630,7 +10630,7 @@
'socket_recv' => ['int|false', 'socket'=>'resource', '&w_buf'=>'string', 'len'=>'int', 'flags'=>'int'],
'socket_recvfrom' => ['int|false', 'socket'=>'resource', '&w_buf'=>'string', 'len'=>'int', 'flags'=>'int', '&w_name'=>'string', '&w_port='=>'int'],
'socket_recvmsg' => ['int|false', 'socket'=>'resource', '&w_message'=>'string', 'flags='=>'int'],
'socket_select' => ['int|false', '&rw_read_fds'=>'resource[]|null', '&rw_write_fds'=>'resource[]|null', '&rw_except_fds'=>'resource[]|null', 'tv_sec'=>'int|null', 'tv_usec='=>'int|null'],
'socket_select' => ['int|false', '&w_read_fds'=>'resource[]|null', '&w_write_fds'=>'resource[]|null', '&w_except_fds'=>'resource[]|null', 'tv_sec'=>'int|null', 'tv_usec='=>'int|null'],
'socket_send' => ['int|false', 'socket'=>'resource', 'buf'=>'string', 'len'=>'int', 'flags'=>'int'],
'socket_sendmsg' => ['int|false', 'socket'=>'resource', 'message'=>'array', 'flags'=>'int'],
'socket_sendto' => ['int|false', 'socket'=>'resource', 'buf'=>'string', 'len'=>'int', 'flags'=>'int', 'addr'=>'string', 'port='=>'int'],
Expand Down
4 changes: 2 additions & 2 deletions resources/functionMap_php80delta.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
'proc_get_status' => ['array{command: string, pid: int, running: bool, signaled: bool, stopped: bool, exitcode: int, termsig: int, stopsig: int}', 'process'=>'resource'],
'set_error_handler' => ['?callable', 'callback'=>'null|callable(int,string,string,int):bool', 'error_types='=>'int'],
'socket_addrinfo_lookup' => ['AddressInfo[]', 'node'=>'string', 'service='=>'mixed', 'hints='=>'array'],
'socket_select' => ['int|false', '&rw_read'=>'Socket[]|null', '&rw_write'=>'Socket[]|null', '&rw_except'=>'Socket[]|null', 'seconds'=>'int|null', 'microseconds='=>'int'],
'socket_select' => ['int|false', '&w_read'=>'Socket[]|null', '&w_write'=>'Socket[]|null', '&w_except'=>'Socket[]|null', 'seconds'=>'int|null', 'microseconds='=>'int'],
'sodium_crypto_aead_chacha20poly1305_ietf_decrypt' => ['string|false', 'confidential_message'=>'string', 'public_message'=>'string', 'nonce'=>'string', 'key'=>'string'],
'str_contains' => ['bool', 'haystack'=>'string', 'needle'=>'string'],
'str_split' => ['non-empty-list<string>', 'str'=>'string', 'split_length='=>'positive-int'],
Expand Down Expand Up @@ -237,7 +237,7 @@
'read_exif_data' => ['array', 'filename'=>'string', 'sections_needed='=>'string', 'sub_arrays='=>'bool', 'read_thumbnail='=>'bool'],
'restore_include_path' => ['void'],
'round' => ['__benevolent<float|false>', 'number'=>'float', 'precision='=>'int', 'mode='=>'1|2|3|4'],
'socket_select' => ['int|false', '&rw_read_fds'=>'resource[]|null', '&rw_write_fds'=>'resource[]|null', '&rw_except_fds'=>'resource[]|null', 'tv_sec'=>'int|null', 'tv_usec='=>'int|null'],
'socket_select' => ['int|false', '&w_read_fds'=>'resource[]|null', '&w_write_fds'=>'resource[]|null', '&w_except_fds'=>'resource[]|null', 'tv_sec'=>'int|null', 'tv_usec='=>'int|null'],
'sodium_crypto_aead_chacha20poly1305_ietf_decrypt' => ['?string|?false', 'confidential_message'=>'string', 'public_message'=>'string', 'nonce'=>'string', 'key'=>'string'],
'SplFileObject::fgetss' => ['string|false', 'allowable_tags='=>'string'],
'strchr' => ['string|false', 'haystack'=>'string', 'needle'=>'string|int', 'before_needle='=>'bool'],
Expand Down
23 changes: 23 additions & 0 deletions src/PhpDoc/SocketSelectStubFilesExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php declare(strict_types = 1);

namespace PHPStan\PhpDoc;

use PHPStan\Php\PhpVersion;

class SocketSelectStubFilesExtension implements StubFilesExtension
{

public function __construct(private PhpVersion $phpVersion)
{
}

public function getFiles(): array
{
if ($this->phpVersion->getVersionId() >= 80000) {
return [__DIR__ . '/../../stubs/socket_select_php8.stub'];
}

return [__DIR__ . '/../../stubs/socket_select.stub'];
}

}
11 changes: 11 additions & 0 deletions stubs/socket_select.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

/**
* @param array<resource>|null &$read
* @param array<resource>|null &$write
* @param array<resource>|null &$except
* @param-out ($read is not null ? array<resource> : null) $read
* @param-out ($write is not null ? array<resource> : null) $write
* @param-out ($except is not null ? array<resource> : null) $except
*/
function socket_select(?array &$read, ?array &$write, ?array &$except, ?int $seconds, int $microseconds = 0): int|false {}
11 changes: 11 additions & 0 deletions stubs/socket_select_php8.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

/**
* @param array<Socket>|null &$read
* @param array<Socket>|null &$write
* @param array<Socket>|null &$except
* @param-out ($read is not null ? array<Socket> : null) $read
* @param-out ($write is not null ? array<Socket> : null) $write
* @param-out ($except is not null ? array<Socket> : null) $except
*/
function socket_select(?array &$read, ?array &$write, ?array &$except, ?int $seconds, int $microseconds = 0): int|false {}
7 changes: 7 additions & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,13 @@ public function dataFileAsserts(): iterable
yield from $this->gatherAssertTypes(__DIR__ . '/data/generics-do-not-generalize.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-9985.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-6294.php');

if (PHP_VERSION_ID >= 80000) {
yield from $this->gatherAssertTypes(__DIR__ . '/data/discussion-10285-php8.php');
} else {
yield from $this->gatherAssertTypes(__DIR__ . '/data/discussion-10285.php');
}

yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-6462.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-2580.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-9753.php');
Expand Down
21 changes: 21 additions & 0 deletions tests/PHPStan/Analyser/data/discussion-10285-php8.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Discussion10285Php8;

use function PHPStan\Testing\assertType;

class HelloWorld
{
public function sayHello(): void
{
$socket = socket_create(AF_INET, SOCK_STREAM, 0);
if($socket === false) return;
$read = [$socket];
$write = [];
$except = null;
socket_select($read, $write, $except, 0, 1);
assertType('array<Socket>', $read);
assertType('array<Socket>', $write);
assertType('null', $except);
}
}
21 changes: 21 additions & 0 deletions tests/PHPStan/Analyser/data/discussion-10285.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Discussion10285;

use function PHPStan\Testing\assertType;

class HelloWorld
{
public function sayHello(): void
{
$socket = socket_create(AF_INET, SOCK_STREAM, 0);
if($socket === false) return;
$read = [$socket];
$write = [];
$except = null;
socket_select($read, $write, $except, 0, 1);
assertType('array<resource>', $read);
assertType('array<resource>', $write);
assertType('null', $except);
}
}

0 comments on commit 24c5249

Please sign in to comment.