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();
}
/** @psalm-trace $unserialized */
[$unserialized, $this->unlock] = yield Tools::timeoutWithDefault(
Serialization::unserialize($this->session, $forceFull),
30000,
[0, null]
);
if ($unserialized === 0) {
// Timeout
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->destructing = true;
if ($this->API) {
$this->API->destructing = true;
if ($this->API instanceof Tools) {
$this->API->destructing = true;
}
$this->API->unreference();
}
if (isset($this->wrapper) && !Magic::$signaled) {

View File

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

View File

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

View File

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

View File

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

View File

@ -37,6 +37,8 @@ abstract class SqlArray extends DriverArray
* @param DatabaseAbstract $settings
*
* @return Promise
*
* @psalm-return Promise<static>
*/
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->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 {
$socketContext = $socketContext ?? new ConnectContext();
return Tools::call((function () use ($uri, $context, $token): \Generator {
$socketContext = $context ?? new ConnectContext();
$token = $token ?? new NullCancellationToken();
$attempt = 0;
$uris = [];
@ -117,11 +117,13 @@ class DoHConnector implements Connector
foreach ($uris as $builtUri) {
try {
$streamContext = \stream_context_create($socketContext->withoutTlsContext()->toStreamContextArray());
/** @psalm-ignore NullArgument */
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);
}
\stream_set_blocking($socket, false);
$deferred = new Deferred();
/** @psalm-ignore InvalidArgument */
$watcher = Loop::onWritable($socket, [$deferred, 'resolve']);
$id = $token->subscribe([$deferred, 'fail']);
try {

View File

@ -87,6 +87,7 @@ trait Constructors
if (!isset($this->TL->getDescriptions()['constructors'][$constructor])) {
$this->addToLang('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];
}
}
@ -150,6 +151,7 @@ trait Constructors
if (!isset($this->TL->getDescriptions()['constructors'][$constructor]['params'][$param['name']])) {
$this->addToLang('object_'.$constructor.'_param_'.$param['name'].'_type_'.$param['type']);
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']];
}
}

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 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.
*/

View File

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

View File

@ -17,7 +17,7 @@ abstract class RunnerAbstract
/**
* If using madeline.php, simply return madeline.php path.
*/
if (\defined(\MADELINE_PHP::class)) {
if (\defined('MADELINE_PHP')) {
return \MADELINE_PHP;
}
// 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;
(static function (): void {
if (\defined(\MADELINE_ENTRY::class)) {
if (\defined('MADELINE_ENTRY')) {
// Already called
return;
}
\define(\MADELINE_ENTRY::class, 1);
if (!\defined(\MADELINE_WORKER_TYPE::class)) {
\define('MADELINE_ENTRY', 1);
if (!\defined('MADELINE_WORKER_TYPE')) {
if (\count(\debug_backtrace(0)) !== 1) {
// We're not being included directly
return;
@ -46,11 +46,11 @@ use danog\MadelineProto\Tools;
\trigger_error("Not enough arguments!", E_USER_ERROR);
exit(1);
}
\define(\MADELINE_WORKER_TYPE::class, \array_shift($arguments));
\define(\MADELINE_WORKER_ARGS::class, $arguments);
\define('MADELINE_WORKER_TYPE', \array_shift($arguments));
\define('MADELINE_WORKER_ARGS', $arguments);
}
if (\defined(\SIGHUP::class)) {
if (\defined('SIGHUP')) {
try {
\pcntl_signal(SIGHUP, fn () => null);
} catch (\Throwable $e) {
@ -82,13 +82,13 @@ use danog\MadelineProto\Tools;
\trigger_error("IPC session $ipcPath does not exist!", E_USER_ERROR);
exit(1);
}
if (\function_exists(\cli_set_process_title::class)) {
if (\function_exists('cli_set_process_title')) {
@\cli_set_process_title("MadelineProto worker $ipcPath");
}
if (isset($_GET['cwd'])) {
@\chdir($_GET['cwd']);
}
\define(\MADELINE_WORKER::class, 1);
\define('MADELINE_WORKER', 1);
$runnerId = \MADELINE_WORKER_ARGS[1];
$session = new SessionPaths($ipcPath);

View File

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

View File

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

View File

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

View File

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

View File

@ -476,7 +476,21 @@ trait PeerHandler
*
* @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
{

View File

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

View File

@ -20,10 +20,10 @@
namespace danog\MadelineProto;
use Amp\Deferred;
use Amp\Ipc\Sync\ChannelledSocket;
use Amp\Loop;
use Amp\Promise;
use danog\MadelineProto\Db\DriverArray;
use danog\MadelineProto\Ipc\Client;
use danog\MadelineProto\Ipc\Server;
use danog\MadelineProto\MTProtoSession\Session;
@ -104,7 +104,7 @@ abstract class Serialization
*
* @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
{
@ -222,7 +222,10 @@ abstract class Serialization
* @param Promise $cancelConnect Cancelation token (triggers cancellation of connection)
* @param ?Deferred $cancelFull Cancelation token source (can trigger cancellation of full unserialization)
*
* @psalm-param Promise<\Throwable|null> $cancelConnect
*
* @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
{
@ -247,6 +250,7 @@ abstract class Serialization
$cancelConnect = (new Deferred)->promise();
}
}
return [0, null];
}
/**

View File

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

View File

@ -123,7 +123,7 @@ class Logger extends SettingsAbstract
*/
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()
{
if (\defined(\HAD_MADELINE_PHAR::class)) {
if (\defined('HAD_MADELINE_PHAR')) {
$this->hadInstalled []= \HAD_MADELINE_PHAR;
if (\count($this->hadInstalled) > self::MAX_NO_PHAR_STARTS) {
\array_shift($this->hadInstalled);

View File

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

View File

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

View File

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

View File

@ -336,6 +336,7 @@ abstract class Tools extends StrTools
foreach ($promises as &$promise) {
$promise = self::call($promise);
}
/** @var Promise[] $promises */
return all($promises);
}
/**
@ -350,6 +351,7 @@ abstract class Tools extends StrTools
foreach ($promises as &$promise) {
$promise = self::call($promise);
}
/** @var Promise[] $promises */
return any($promises);
}
/**
@ -365,6 +367,7 @@ abstract class Tools extends StrTools
foreach ($promises as &$promise) {
$promise = self::call($promise);
}
/** @var Promise[] $promises */
return some($promises);
}
/**
@ -379,6 +382,7 @@ abstract class Tools extends StrTools
foreach ($promises as &$promise) {
$promise = self::call($promise);
}
/** @var Promise[] $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 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.
*/