Various psalm fixes

This commit is contained in:
Daniil Gentili 2020-10-04 14:55:05 +02:00
parent e3f3e19cf5
commit d49f59eec5
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
27 changed files with 100 additions and 55 deletions

View File

@ -192,12 +192,12 @@ class API extends InternalDoc
$forceFull = $forceFull || $settings->getIpc()->getSlow(); $forceFull = $forceFull || $settings->getIpc()->getSlow();
} }
/** @psalm-trace $unserialized */
[$unserialized, $this->unlock] = yield Tools::timeoutWithDefault( [$unserialized, $this->unlock] = yield Tools::timeoutWithDefault(
Serialization::unserialize($this->session, $forceFull), Serialization::unserialize($this->session, $forceFull),
30000, 30000,
[0, null] [0, null]
); );
if ($unserialized === 0) { if ($unserialized === 0) {
// Timeout // Timeout
throw new \RuntimeException("Could not connect to MadelineProto, please check the logs for more details."); throw new \RuntimeException("Could not connect to MadelineProto, please check the logs for more details.");
@ -253,7 +253,9 @@ class API extends InternalDoc
$this->logger->logger('Shutting down MadelineProto ('.static::class.')'); $this->logger->logger('Shutting down MadelineProto ('.static::class.')');
$this->destructing = true; $this->destructing = true;
if ($this->API) { if ($this->API) {
$this->API->destructing = true; if ($this->API instanceof Tools) {
$this->API->destructing = true;
}
$this->API->unreference(); $this->API->unreference();
} }
if (isset($this->wrapper) && !Magic::$signaled) { if (isset($this->wrapper) && !Magic::$signaled) {

View File

@ -88,6 +88,11 @@ final class APIWrapper
* @var AbstractAPIFactory * @var AbstractAPIFactory
*/ */
private AbstractAPIFactory $factory; private AbstractAPIFactory $factory;
/**
* Property storage.
*/
public array $storage = [];
/** /**
* API wrapper. * API wrapper.
* *

View File

@ -20,6 +20,7 @@
namespace danog\MadelineProto\ApiWrappers; namespace danog\MadelineProto\ApiWrappers;
use danog\MadelineProto\Lang; use danog\MadelineProto\Lang;
use danog\MadelineProto\Magic;
use danog\MadelineProto\MyTelegramOrgWrapper; use danog\MadelineProto\MyTelegramOrgWrapper;
use danog\MadelineProto\Settings; use danog\MadelineProto\Settings;
use danog\MadelineProto\Tools; use danog\MadelineProto\Tools;
@ -39,7 +40,7 @@ trait Start
*/ */
private function APIStart(Settings $settings): \Generator private function APIStart(Settings $settings): \Generator
{ {
if (\defined(\MADELINE_WORKER::class)) { if (Magic::$isIpcWorker) {
throw new \danog\MadelineProto\Exception('Not inited!'); throw new \danog\MadelineProto\Exception('Not inited!');
} }
if ($this->getWebAPITemplate() === 'legacy') { if ($this->getWebAPITemplate() === 'legacy') {

View File

@ -41,8 +41,9 @@ use danog\MadelineProto\Stream\Transport\WsStream;
* *
* @author Daniil Gentili <daniil@daniil.it> * @author Daniil Gentili <daniil@daniil.it>
*/ */
class Connection extends Session class Connection
{ {
use Session;
use \danog\Serializable; use \danog\Serializable;
/** /**
* Writer loop. * Writer loop.

View File

@ -33,31 +33,31 @@ interface DbArray extends DbType, \ArrayAccess, \Countable
/** /**
* Get element. * Get element.
* *
* @param string|int $offset * @param string|int $index
* *
* @psalm-return Promise<T> * @psalm-return Promise<T>
* *
* @return Promise * @return Promise
*/ */
public function offsetGet($offset): Promise; public function offsetGet($index): Promise;
/** /**
* Set element. * Set element.
* *
* @param string|int $offset * @param string|int $index
* @param mixed $value * @param mixed $value
* *
* @psalm-param T $value * @psalm-param T $value
* *
* @return void * @return void
*/ */
public function offsetSet($offset, $value); public function offsetSet($index, $value);
/** /**
* Unset element. * Unset element.
* *
* @param string|int $offset Offset * @param string|int $index Offset
* @return Promise * @return Promise
*/ */
public function offsetUnset($offset): Promise; public function offsetUnset($index): Promise;
/** /**
* Count number of elements. * Count number of elements.
* *
@ -76,9 +76,9 @@ interface DbArray extends DbType, \ArrayAccess, \Countable
* @internal * @internal
* @see DbArray::isset(); * @see DbArray::isset();
* *
* @param mixed $offset * @param mixed $index
* *
* @return bool * @return bool
*/ */
public function offsetExists($offset); public function offsetExists($index);
} }

View File

@ -37,6 +37,8 @@ abstract class SqlArray extends DriverArray
* @param DatabaseAbstract $settings * @param DatabaseAbstract $settings
* *
* @return Promise * @return Promise
*
* @psalm-return Promise<static>
*/ */
public static function getInstance(string $name, $value = null, string $tablePrefix = '', $settings): Promise public static function getInstance(string $name, $value = null, string $tablePrefix = '', $settings): Promise
{ {

View File

@ -52,10 +52,10 @@ class DoHConnector implements Connector
$this->dataCenter = $dataCenter; $this->dataCenter = $dataCenter;
$this->ctx = $ctx; $this->ctx = $ctx;
} }
public function connect(string $uri, ?ConnectContext $socketContext = null, ?CancellationToken $token = null): Promise public function connect(string $uri, ?ConnectContext $context = null, ?CancellationToken $token = null): Promise
{ {
return Tools::call((function () use ($uri, $socketContext, $token): \Generator { return Tools::call((function () use ($uri, $context, $token): \Generator {
$socketContext = $socketContext ?? new ConnectContext(); $socketContext = $context ?? new ConnectContext();
$token = $token ?? new NullCancellationToken(); $token = $token ?? new NullCancellationToken();
$attempt = 0; $attempt = 0;
$uris = []; $uris = [];
@ -117,11 +117,13 @@ class DoHConnector implements Connector
foreach ($uris as $builtUri) { foreach ($uris as $builtUri) {
try { try {
$streamContext = \stream_context_create($socketContext->withoutTlsContext()->toStreamContextArray()); $streamContext = \stream_context_create($socketContext->withoutTlsContext()->toStreamContextArray());
/** @psalm-ignore NullArgument */
if (!($socket = @\stream_socket_client($builtUri, $errno, $errstr, null, $flags, $streamContext))) { if (!($socket = @\stream_socket_client($builtUri, $errno, $errstr, null, $flags, $streamContext))) {
throw new ConnectException(\sprintf('Connection to %s failed: [Error #%d] %s%s', $uri, $errno, $errstr, $failures ? '; previous attempts: '.\implode($failures) : ''), $errno); throw new ConnectException(\sprintf('Connection to %s failed: [Error #%d] %s%s', $uri, $errno, $errstr, $failures ? '; previous attempts: '.\implode($failures) : ''), $errno);
} }
\stream_set_blocking($socket, false); \stream_set_blocking($socket, false);
$deferred = new Deferred(); $deferred = new Deferred();
/** @psalm-ignore InvalidArgument */
$watcher = Loop::onWritable($socket, [$deferred, 'resolve']); $watcher = Loop::onWritable($socket, [$deferred, 'resolve']);
$id = $token->subscribe([$deferred, 'fail']); $id = $token->subscribe([$deferred, 'fail']);
try { try {

View File

@ -87,6 +87,7 @@ trait Constructors
if (!isset($this->TL->getDescriptions()['constructors'][$constructor])) { if (!isset($this->TL->getDescriptions()['constructors'][$constructor])) {
$this->addToLang('object_'.$constructor); $this->addToLang('object_'.$constructor);
if (\danog\MadelineProto\Lang::$lang['en']['object_'.$constructor] !== '') { if (\danog\MadelineProto\Lang::$lang['en']['object_'.$constructor] !== '') {
/** @psalm-suppress InvalidArrayAssignment */
$this->TL->getDescriptions()['constructors'][$constructor]['description'] = \danog\MadelineProto\Lang::$lang['en']['object_'.$constructor]; $this->TL->getDescriptions()['constructors'][$constructor]['description'] = \danog\MadelineProto\Lang::$lang['en']['object_'.$constructor];
} }
} }
@ -150,6 +151,7 @@ trait Constructors
if (!isset($this->TL->getDescriptions()['constructors'][$constructor]['params'][$param['name']])) { if (!isset($this->TL->getDescriptions()['constructors'][$constructor]['params'][$param['name']])) {
$this->addToLang('object_'.$constructor.'_param_'.$param['name'].'_type_'.$param['type']); $this->addToLang('object_'.$constructor.'_param_'.$param['name'].'_type_'.$param['type']);
if (isset($this->TL->getDescriptions()['constructors'][$constructor]['description'])) { if (isset($this->TL->getDescriptions()['constructors'][$constructor]['description'])) {
/** @psalm-suppress InvalidArrayAssignment */
$this->TL->getDescriptions()['constructors'][$constructor]['params'][$param['name']] = \danog\MadelineProto\Lang::$lang['en']['object_'.$constructor.'_param_'.$param['name'].'_type_'.$param['type']]; $this->TL->getDescriptions()['constructors'][$constructor]['params'][$param['name']] = \danog\MadelineProto\Lang::$lang['en']['object_'.$constructor.'_param_'.$param['name'].'_type_'.$param['type']];
} }
} }

View File

@ -6160,7 +6160,7 @@ class InternalDoc extends APIFactory
* @psalm-param Promise<TReturn>|TGenerator $promise Promise to which the timeout is applied. * @psalm-param Promise<TReturn>|TGenerator $promise Promise to which the timeout is applied.
* @psalm-param TReturnAlt $default * @psalm-param TReturnAlt $default
* *
* @return Promise<TReturn|TReturnAlt> * @return Promise<TReturn>|Promise<TReturnAlt>
* *
* @throws \TypeError If $promise is not an instance of \Amp\Promise, \Generator or \React\Promise\PromiseInterface. * @throws \TypeError If $promise is not an instance of \Amp\Promise, \Generator or \React\Promise\PromiseInterface.
*/ */

View File

@ -26,7 +26,7 @@ final class ExitFailure
/** @var self|null */ /** @var self|null */
private $previous; private $previous;
/** @var self|null */ /** @var string|null */
private $localized; private $localized;
public function __construct(\Throwable $exception) public function __construct(\Throwable $exception)

View File

@ -17,7 +17,7 @@ abstract class RunnerAbstract
/** /**
* If using madeline.php, simply return madeline.php path. * If using madeline.php, simply return madeline.php path.
*/ */
if (\defined(\MADELINE_PHP::class)) { if (\defined('MADELINE_PHP')) {
return \MADELINE_PHP; return \MADELINE_PHP;
} }
// Write process runner to external file if inside a PHAR different from madeline.phar, // Write process runner to external file if inside a PHAR different from madeline.phar,

View File

@ -26,12 +26,12 @@ use danog\MadelineProto\Settings\Ipc;
use danog\MadelineProto\Tools; use danog\MadelineProto\Tools;
(static function (): void { (static function (): void {
if (\defined(\MADELINE_ENTRY::class)) { if (\defined('MADELINE_ENTRY')) {
// Already called // Already called
return; return;
} }
\define(\MADELINE_ENTRY::class, 1); \define('MADELINE_ENTRY', 1);
if (!\defined(\MADELINE_WORKER_TYPE::class)) { if (!\defined('MADELINE_WORKER_TYPE')) {
if (\count(\debug_backtrace(0)) !== 1) { if (\count(\debug_backtrace(0)) !== 1) {
// We're not being included directly // We're not being included directly
return; return;
@ -46,11 +46,11 @@ use danog\MadelineProto\Tools;
\trigger_error("Not enough arguments!", E_USER_ERROR); \trigger_error("Not enough arguments!", E_USER_ERROR);
exit(1); exit(1);
} }
\define(\MADELINE_WORKER_TYPE::class, \array_shift($arguments)); \define('MADELINE_WORKER_TYPE', \array_shift($arguments));
\define(\MADELINE_WORKER_ARGS::class, $arguments); \define('MADELINE_WORKER_ARGS', $arguments);
} }
if (\defined(\SIGHUP::class)) { if (\defined('SIGHUP')) {
try { try {
\pcntl_signal(SIGHUP, fn () => null); \pcntl_signal(SIGHUP, fn () => null);
} catch (\Throwable $e) { } catch (\Throwable $e) {
@ -82,13 +82,13 @@ use danog\MadelineProto\Tools;
\trigger_error("IPC session $ipcPath does not exist!", E_USER_ERROR); \trigger_error("IPC session $ipcPath does not exist!", E_USER_ERROR);
exit(1); exit(1);
} }
if (\function_exists(\cli_set_process_title::class)) { if (\function_exists('cli_set_process_title')) {
@\cli_set_process_title("MadelineProto worker $ipcPath"); @\cli_set_process_title("MadelineProto worker $ipcPath");
} }
if (isset($_GET['cwd'])) { if (isset($_GET['cwd'])) {
@\chdir($_GET['cwd']); @\chdir($_GET['cwd']);
} }
\define(\MADELINE_WORKER::class, 1); \define('MADELINE_WORKER', 1);
$runnerId = \MADELINE_WORKER_ARGS[1]; $runnerId = \MADELINE_WORKER_ARGS[1];
$session = new SessionPaths($ipcPath); $session = new SessionPaths($ipcPath);

View File

@ -1072,6 +1072,7 @@ class MTProto extends AsyncConstruct implements TLCallback
$this->updateHandler = $this->settings['updates']['callback']; $this->updateHandler = $this->settings['updates']['callback'];
} }
/** @psalm-suppress InvalidArrayOffset */
$this->dcList = $this->settings['connection'] ?? $this->dcList; $this->dcList = $this->settings['connection'] ?? $this->dcList;
} }
$this->settings = Settings::parseFromLegacy($this->settings); $this->settings = Settings::parseFromLegacy($this->settings);

View File

@ -19,6 +19,7 @@
namespace danog\MadelineProto\MTProtoSession; namespace danog\MadelineProto\MTProtoSession;
use danog\MadelineProto\Connection;
use danog\MadelineProto\MTProtoSession\MsgIdHandler\MsgIdHandler32; use danog\MadelineProto\MTProtoSession\MsgIdHandler\MsgIdHandler32;
use danog\MadelineProto\MTProtoSession\MsgIdHandler\MsgIdHandler64; use danog\MadelineProto\MTProtoSession\MsgIdHandler\MsgIdHandler64;
@ -29,16 +30,14 @@ abstract class MsgIdHandler
{ {
/** /**
* Session instance. * Session instance.
*
* @var Session
*/ */
protected $session; protected Connection $session;
/** /**
* Constructor. * Constructor.
* *
* @param Session $session Session * @param Connection $session Session
*/ */
private function __construct(Session $session) private function __construct(Connection $session)
{ {
$this->session = $session; $this->session = $session;
} }
@ -46,11 +45,11 @@ abstract class MsgIdHandler
/** /**
* Create MsgIdHandler instance. * Create MsgIdHandler instance.
* *
* @param Session $session Session * @param Connection $session Session
* *
* @return self * @return self
*/ */
public static function createInstance(Session $session): self public static function createInstance(Connection $session): self
{ {
if (PHP_INT_SIZE === 8) { if (PHP_INT_SIZE === 8) {
return new MsgIdHandler64($session); return new MsgIdHandler64($session);

View File

@ -20,28 +20,25 @@
namespace danog\MadelineProto\MTProtoSession\MsgIdHandler; namespace danog\MadelineProto\MTProtoSession\MsgIdHandler;
use danog\MadelineProto\MTProtoSession\MsgIdHandler; use danog\MadelineProto\MTProtoSession\MsgIdHandler;
use danog\MadelineProto\MTProtoSession\Session;
use tgseclib\Math\BigInteger; use tgseclib\Math\BigInteger;
/** /**
* Manages message ids. * Manages message ids.
*
* @property Session $session
*/ */
class MsgIdHandler32 extends MsgIdHandler class MsgIdHandler32 extends MsgIdHandler
{ {
/** /**
* Maximum incoming ID. * Maximum incoming ID.
* *
* @var BigInteger * @var ?BigInteger
*/ */
private $maxIncomingId; private $maxIncomingId = null;
/** /**
* Maximum outgoing ID. * Maximum outgoing ID.
* *
* @var BigInteger * @var ?BigInteger
*/ */
private $maxOutgoingId; private $maxOutgoingId = null;
/** /**
* Check validity of given message ID. * Check validity of given message ID.
* *

View File

@ -27,7 +27,7 @@ use danog\MadelineProto\MTProto;
* *
* @extends Connection * @extends Connection
*/ */
abstract class Session trait Session
{ {
use AckHandler; use AckHandler;
use ResponseHandler; use ResponseHandler;

View File

@ -476,7 +476,21 @@ trait PeerHandler
* *
* @return \Generator Info object * @return \Generator Info object
* *
* @psalm-return \Generator<int|mixed, \Amp\Promise|\Amp\Promise<string>|array, mixed, array|mixed> * @psalm-return \Generator<int|mixed, \Amp\Promise|\Amp\Promise<string>|array, mixed, array{
* InputPeer: array{_: string, user_id?: mixed, access_hash?: mixed, min?: mixed, chat_id?: mixed, channel_id?: mixed},
* Peer: array{_: string, user_id?: mixed, chat_id?: mixed, channel_id?: mixed},
* DialogPeer: array{_: string, peer: array{_: string, user_id?: mixed, chat_id?: mixed, channel_id?: mixed}},
* NotifyPeer: array{_: string, peer: array{_: string, user_id?: mixed, chat_id?: mixed, channel_id?: mixed}},
* InputDialogPeer: array{_: string, peer: array{_: string, user_id?: mixed, access_hash?: mixed, min?: mixed, chat_id?: mixed, channel_id?: mixed}},
* InputNotifyPeer: array{_: string, peer: array{_: string, user_id?: mixed, access_hash?: mixed, min?: mixed, chat_id?: mixed, channel_id?: mixed}},
* bot_api_id: int|string,
* user_id?: int,
* chat_id?: int,
* channel_id?: int,
* InputUser?: {_: string, user_id?: int, access_hash?: mixed, min?: bool},
* InputChannel?: {_: string, channel_id: int, access_hash: mixed, min: bool},
* type: string
* }>
*/ */
public function getInfo($id, $recursive = true): \Generator public function getInfo($id, $recursive = true): \Generator
{ {

View File

@ -234,7 +234,7 @@ class Magic
// Setup error reporting // Setup error reporting
\set_error_handler(['\\danog\\MadelineProto\\Exception', 'ExceptionErrorHandler']); \set_error_handler(['\\danog\\MadelineProto\\Exception', 'ExceptionErrorHandler']);
\set_exception_handler(['\\danog\\MadelineProto\\Exception', 'ExceptionHandler']); \set_exception_handler(['\\danog\\MadelineProto\\Exception', 'ExceptionHandler']);
self::$isIpcWorker = \defined(\MADELINE_WORKER_TYPE::class) ? \MADELINE_WORKER_TYPE === 'madeline-ipc' : false; self::$isIpcWorker = \defined('MADELINE_WORKER_TYPE') ? \MADELINE_WORKER_TYPE === 'madeline-ipc' : false;
if (PHP_SAPI !== 'cli' && PHP_SAPI !== 'phpdbg') { if (PHP_SAPI !== 'cli' && PHP_SAPI !== 'phpdbg') {
try { try {
\error_reporting(E_ALL); \error_reporting(E_ALL);
@ -251,7 +251,7 @@ class Magic
} }
// Check if we're in a console, for colorful log output // Check if we're in a console, for colorful log output
try { try {
self::$isatty = \defined(\STDOUT::class) && hasColorSupport(); self::$isatty = \defined('STDOUT') && hasColorSupport();
} catch (\danog\MadelineProto\Exception $e) { } catch (\danog\MadelineProto\Exception $e) {
} }
// Important, obtain root relative to caller script // Important, obtain root relative to caller script
@ -263,7 +263,7 @@ class Magic
} catch (\danog\MadelineProto\Exception $e) { } catch (\danog\MadelineProto\Exception $e) {
} }
// Define signal handlers // Define signal handlers
if (\defined(\SIGINT::class)) { if (\defined('SIGINT')) {
//if (function_exists('pcntl_async_signals')) pcntl_async_signals(true); //if (function_exists('pcntl_async_signals')) pcntl_async_signals(true);
try { try {
\pcntl_signal(SIGINT, fn () => null); \pcntl_signal(SIGINT, fn () => null);
@ -281,8 +281,8 @@ class Magic
} }
self::$initedLight = true; self::$initedLight = true;
if ($light) { if ($light) {
if (!\defined(\AMP_WORKER::class)) { if (!\defined('AMP_WORKER')) {
\define(\AMP_WORKER::class, true); \define('AMP_WORKER', true);
} }
return; return;
} }

View File

@ -20,10 +20,10 @@
namespace danog\MadelineProto; namespace danog\MadelineProto;
use Amp\Deferred; use Amp\Deferred;
use Amp\Ipc\Sync\ChannelledSocket;
use Amp\Loop; use Amp\Loop;
use Amp\Promise; use Amp\Promise;
use danog\MadelineProto\Db\DriverArray; use danog\MadelineProto\Db\DriverArray;
use danog\MadelineProto\Ipc\Client;
use danog\MadelineProto\Ipc\Server; use danog\MadelineProto\Ipc\Server;
use danog\MadelineProto\MTProtoSession\Session; use danog\MadelineProto\MTProtoSession\Session;
@ -104,7 +104,7 @@ abstract class Serialization
* *
* @return \Generator * @return \Generator
* *
* @psalm-return \Generator<void, mixed, mixed, array{0: callable|null, 1: Client|MTProto}> * @psalm-return \Generator<void, mixed, mixed, array{0: ChannelledSocket|APIWrapper|\Throwable|null|0, 1: callable|null}>
*/ */
public static function unserialize(SessionPaths $session, bool $forceFull = false): \Generator public static function unserialize(SessionPaths $session, bool $forceFull = false): \Generator
{ {
@ -222,7 +222,10 @@ abstract class Serialization
* @param Promise $cancelConnect Cancelation token (triggers cancellation of connection) * @param Promise $cancelConnect Cancelation token (triggers cancellation of connection)
* @param ?Deferred $cancelFull Cancelation token source (can trigger cancellation of full unserialization) * @param ?Deferred $cancelFull Cancelation token source (can trigger cancellation of full unserialization)
* *
* @psalm-param Promise<\Throwable|null> $cancelConnect
*
* @return \Generator * @return \Generator
* @psalm-return \Generator<mixed, mixed, mixed, array{0: ChannelledSocket|\Throwable|0, 1: null}>
*/ */
private static function tryConnect(string $ipcPath, Promise $cancelConnect, ?Deferred $cancelFull = null): \Generator private static function tryConnect(string $ipcPath, Promise $cancelConnect, ?Deferred $cancelFull = null): \Generator
{ {
@ -247,6 +250,7 @@ abstract class Serialization
$cancelConnect = (new Deferred)->promise(); $cancelConnect = (new Deferred)->promise();
} }
} }
return [0, null];
} }
/** /**

View File

@ -106,6 +106,8 @@ class SessionPaths
* @param string $path Object path, defaults to session path * @param string $path Object path, defaults to session path
* *
* @return \Generator * @return \Generator
*
* @psalm-return \Generator<mixed, mixed, mixed, object>
*/ */
public function unserialize(string $path = ''): \Generator public function unserialize(string $path = ''): \Generator
{ {

View File

@ -123,7 +123,7 @@ class Logger extends SettingsAbstract
*/ */
public function getType(): int public function getType(): int
{ {
return \defined(\MADELINE_WORKER::class) ? MadelineProtoLogger::FILE_LOGGER : $this->type; return \defined('MADELINE_WORKER') ? MadelineProtoLogger::FILE_LOGGER : $this->type;
} }
/** /**

View File

@ -90,7 +90,7 @@ class Snitch
*/ */
public function __wakeup() public function __wakeup()
{ {
if (\defined(\HAD_MADELINE_PHAR::class)) { if (\defined('HAD_MADELINE_PHAR')) {
$this->hadInstalled []= \HAD_MADELINE_PHAR; $this->hadInstalled []= \HAD_MADELINE_PHAR;
if (\count($this->hadInstalled) > self::MAX_NO_PHAR_STARTS) { if (\count($this->hadInstalled) > self::MAX_NO_PHAR_STARTS) {
\array_shift($this->hadInstalled); \array_shift($this->hadInstalled);

View File

@ -37,7 +37,12 @@ use Psr\Http\Message\UriInterface;
class HttpStream implements MTProtoBufferInterface, BufferedProxyStreamInterface class HttpStream implements MTProtoBufferInterface, BufferedProxyStreamInterface
{ {
use BufferedStream; use BufferedStream;
private $stream; /**
* Stream
*
* @var RawStreamInterface
*/
protected $stream;
private $code; private $code;
private $ctx; private $ctx;
private $header = ''; private $header = '';

View File

@ -694,6 +694,7 @@ trait BotAPI
{ {
$initialArray = \explode(\chr(1), \str_replace($delimiters, \chr(1), $string)); $initialArray = \explode(\chr(1), \str_replace($delimiters, \chr(1), $string));
$finalArray = []; $finalArray = [];
/** @var int */
$delimOffset = 0; $delimOffset = 0;
foreach ($initialArray as $item) { foreach ($initialArray as $item) {
$delimOffset += $this->mbStrlen($item); $delimOffset += $this->mbStrlen($item);

View File

@ -94,7 +94,7 @@ trait BotAPIFiles
switch ($fileId->getType()) { switch ($fileId->getType()) {
case PROFILE_PHOTO: case PROFILE_PHOTO:
/** /**
* @var $photoSize PhotoSizeSourceDialogPhoto * @var PhotoSizeSourceDialogPhoto $photoSize
*/ */
if ($photoSize->getDialogId() < 0) { if ($photoSize->getDialogId() < 0) {
$res['Chat'] = [ $res['Chat'] = [
@ -132,6 +132,9 @@ trait BotAPIFiles
]; ];
return $res; return $res;
case THUMBNAIL: case THUMBNAIL:
/**
* @var PhotoSizeSourceThumbnail $photoSize
*/
$res['InputFileLocation'] = [ $res['InputFileLocation'] = [
'_' => $photoSize->getThumbFileType() === THUMBNAIL ? 'inputDocumentFileLocation' : 'inputPhotoFileLocation', '_' => $photoSize->getThumbFileType() === THUMBNAIL ? 'inputDocumentFileLocation' : 'inputPhotoFileLocation',
'id' => $fileId->getId(), 'id' => $fileId->getId(),

View File

@ -1431,7 +1431,7 @@ class InternalDoc extends APIFactory
* @psalm-param Promise<TReturn>|TGenerator $promise Promise to which the timeout is applied. * @psalm-param Promise<TReturn>|TGenerator $promise Promise to which the timeout is applied.
* @psalm-param TReturnAlt $default * @psalm-param TReturnAlt $default
* *
* @return Promise<TReturn|TReturnAlt> * @return Promise<TReturn>|Promise<TReturnAlt>
* *
* @throws \TypeError If $promise is not an instance of \Amp\Promise, \Generator or \React\Promise\PromiseInterface. * @throws \TypeError If $promise is not an instance of \Amp\Promise, \Generator or \React\Promise\PromiseInterface.
*/ */

View File

@ -336,6 +336,7 @@ abstract class Tools extends StrTools
foreach ($promises as &$promise) { foreach ($promises as &$promise) {
$promise = self::call($promise); $promise = self::call($promise);
} }
/** @var Promise[] $promises */
return all($promises); return all($promises);
} }
/** /**
@ -350,6 +351,7 @@ abstract class Tools extends StrTools
foreach ($promises as &$promise) { foreach ($promises as &$promise) {
$promise = self::call($promise); $promise = self::call($promise);
} }
/** @var Promise[] $promises */
return any($promises); return any($promises);
} }
/** /**
@ -365,6 +367,7 @@ abstract class Tools extends StrTools
foreach ($promises as &$promise) { foreach ($promises as &$promise) {
$promise = self::call($promise); $promise = self::call($promise);
} }
/** @var Promise[] $promises */
return some($promises); return some($promises);
} }
/** /**
@ -379,6 +382,7 @@ abstract class Tools extends StrTools
foreach ($promises as &$promise) { foreach ($promises as &$promise) {
$promise = self::call($promise); $promise = self::call($promise);
} }
/** @var Promise[] $promises */
return first($promises); return first($promises);
} }
/** /**
@ -429,7 +433,7 @@ abstract class Tools extends StrTools
* @psalm-param Promise<TReturn>|TGenerator $promise Promise to which the timeout is applied. * @psalm-param Promise<TReturn>|TGenerator $promise Promise to which the timeout is applied.
* @psalm-param TReturnAlt $default * @psalm-param TReturnAlt $default
* *
* @return Promise<TReturn|TReturnAlt> * @return Promise<TReturn>|Promise<TReturnAlt>
* *
* @throws \TypeError If $promise is not an instance of \Amp\Promise, \Generator or \React\Promise\PromiseInterface. * @throws \TypeError If $promise is not an instance of \Amp\Promise, \Generator or \React\Promise\PromiseInterface.
*/ */