PHP 8 fixes

This commit is contained in:
Daniil Gentili 2020-10-08 21:35:32 +02:00
parent a937d1d994
commit ac47a23639
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
23 changed files with 314 additions and 129 deletions

View File

@ -115,24 +115,32 @@ final class APIWrapper
*/
public static function link($a, $b): void
{
foreach (self::__sleep() as $var) {
foreach (self::properties() as $var) {
Tools::setVar($a, $var, Tools::getVar($b, $var));
}
Tools::setVar($a, 'session', Tools::getVar($b, 'session'));
}
/**
* Sleep function.
*
* @internal
* Property list
*
* @return array
*/
public static function __sleep(): array
public static function properties(): array
{
return ['API', 'webApiTemplate', 'gettingApiId', 'myTelegramOrgWrapper', 'storage', 'lua'];
}
/**
* Sleep function
*
* @return array
*/
public function __sleep(): array
{
return self::properties();
}
/**
* Get MTProto instance.
*

View File

@ -152,10 +152,12 @@ abstract class AbstractAPIFactory extends AsyncConstruct
*/
public function __debugInfo(): array
{
$keys = APIWrapper::__sleep();
$keys = APIWrapper::properties();
$res = [];
foreach ($keys as $key) {
$res[$key] = Tools::getVar($this, $key);
if (Tools::hasVar($this, $key)) {
$res[$key] = Tools::getVar($this, $key);
}
}
return $res;
}

View File

@ -55,7 +55,7 @@ class ContextConnector implements Connector
$this->logger->logger('OK!', \danog\MadelineProto\Logger::WARNING);
return $result->getSocket();
} catch (\Throwable $e) {
if (@\constant("MADELINEPROTO_TEST") === 'pony') {
if (defined('MADELINEPROTO_TEST') && \constant("MADELINEPROTO_TEST") === 'pony') {
throw $e;
}
$this->logger->logger('Connection failed: '.$e, \danog\MadelineProto\Logger::ERROR);

View File

@ -280,7 +280,12 @@ final class Coroutine implements Promise, \ArrayAccess, JsonSerializable
return [self::WARNING];
}
public function jsonSerialize()
/**
* Obtain
*
* @return string
*/
public function jsonSerialize(): string
{
return self::WARNING;
}

View File

@ -289,7 +289,7 @@ class DataCenter
$this->API->logger->logger('OK!', Logger::WARNING);
return true;
} catch (\Throwable $e) {
if (@\constant("MADELINEPROTO_TEST") === 'pony') {
if (\defined("MADELINEPROTO_TEST") && \constant("MADELINEPROTO_TEST") === 'pony') {
throw $e;
}
$this->API->logger->logger("Connection failed ({$dc_number}): ".$e->getMessage(), Logger::ERROR);
@ -496,7 +496,7 @@ class DataCenter
if (empty($ctxs)) {
unset($this->sockets[$dc_number]);
$this->API->logger->logger("No info for DC {$dc_number}", Logger::ERROR);
} elseif (@\constant("MADELINEPROTO_TEST") === 'pony') {
} elseif (\defined('MADELINEPROTO_TEST') && \constant("MADELINEPROTO_TEST") === 'pony') {
return [$ctxs[0]];
}
return $ctxs;

View File

@ -38,7 +38,7 @@ trait ArrayCacheTrait
if (!isset($this->ttlValues[$key])) {
return $default;
}
$this->ttlValues[$key] = time() + $this->ttl;
$this->ttlValues[$key] = \time() + $this->ttl;
return $this->cache[$key];
}
@ -51,7 +51,7 @@ trait ArrayCacheTrait
protected function setCache(string $key, $value): void
{
$this->cache[$key] = $value;
$this->ttlValues[$key] = time() + $this->ttl;
$this->ttlValues[$key] = \time() + $this->ttl;
}
/**

View File

@ -14,5 +14,5 @@ interface DbType
*
* @return Promise<self>
*/
public static function getInstance(string $table, $value = null, $settings): Promise;
public static function getInstance(string $table, $value, $settings): Promise;
}

View File

@ -28,7 +28,7 @@ class MemoryArray extends \ArrayIterator implements DbArray
* @param Memory $settings
* @return Promise<self>
*/
public static function getInstance(string $table, $value = null, $settings): Promise
public static function getInstance(string $table, $value, $settings): Promise
{
return call(static function () use ($value) {
if ($value instanceof MemoryArray) {

View File

@ -208,8 +208,10 @@ class RedisArray extends SqlArray
return call(function () {
$iterator = $this->getIterator();
$result = [];
$len = strlen($this->rKey(''));
while (yield $iterator->advance()) {
[$key, $value] = $iterator->getCurrent();
$key = substr($key, $len);
$result[$key] = $value;
}
return $result;

View File

@ -35,7 +35,7 @@ abstract class SqlArray extends DriverArray
*
* @psalm-return Promise<static>
*/
public static function getInstance(string $table, $value = null, $settings): Promise
public static function getInstance(string $table, $value, $settings): Promise
{
if ($value instanceof static && $value->table === $table) {
$instance = &$value;

View File

@ -138,7 +138,7 @@ class MTProto extends AsyncConstruct implements TLCallback
* Bad message error codes.
*
* @internal
*
*
* @var array
*/
const BAD_MSG_ERROR_CODES = [16 => 'msg_id too low (most likely, client time is wrong; it would be worthwhile to synchronize it using msg_id notifications and re-send the original message with the “correct” msg_id or wrap it in a container with a new msg_id if the original message had waited too long on the client to be transmitted)', 17 => 'msg_id too high (similar to the previous case, the client time has to be synchronized, and the message re-sent with the correct msg_id)', 18 => 'incorrect two lower order msg_id bits (the server expects client message msg_id to be divisible by 4)', 19 => 'container msg_id is the same as msg_id of a previously received message (this must never happen)', 20 => 'message too old, and it cannot be verified whether the server has received a message with this msg_id or not', 32 => 'msg_seqno too low (the server has already received a message with a lower msg_id but with either a higher or an equal and odd seqno)', 33 => 'msg_seqno too high (similarly, there is a message with a higher msg_id but with either a lower or an equal and odd seqno)', 34 => 'an even msg_seqno expected (irrelevant message), but odd received', 35 => 'odd msg_seqno expected (relevant message), but even received', 48 => 'incorrect server salt (in this case, the bad_server_salt response is received with the correct salt, and the message is to be re-sent with it)', 64 => 'invalid container'];
@ -146,7 +146,7 @@ class MTProto extends AsyncConstruct implements TLCallback
* Localized message info flags.
*
* @internal
*
*
* @var array
*/
const MSGS_INFO_FLAGS = [1 => 'nothing is known about the message (msg_id too low, the other party may have forgotten it)', 2 => 'message not received (msg_id falls within the range of stored identifiers; however, the other party has certainly not received a message like that)', 3 => 'message not received (msg_id too high; however, the other party has certainly not received it yet)', 4 => 'message received (note that this response is also at the same time a receipt acknowledgment)', 8 => ' and message already acknowledged', 16 => ' and message not requiring acknowledgment', 32 => ' and RPC query contained in message being processed or processing already complete', 64 => ' and content-related response to message already generated', 128 => ' and other party knows for a fact that message is already received'];

View File

@ -29,7 +29,7 @@ class GarbageCollector
/**
* Whether to enable logging.
*/
public static bool $log = false;
public static bool $log = true;
/**
* Memory consumption after last cleanup.

View File

@ -155,7 +155,8 @@ trait UpdateHandler
*
* @internal
*
* @return \Generator<mixed, mixed, mixed, UpdatesState>
* @return \Generator
* @psalm-return <mixed, mixed, mixed, UpdatesState>
*/
public function loadUpdateState(): \Generator
{

View File

@ -0,0 +1,99 @@
<?php
namespace danog\MadelineProto\PhpDoc;
use danog\MadelineProto\Logger;
use danog\MadelineProto\PhpDocBuilder;
use phpDocumentor\Reflection\DocBlock\Tags\InvalidTag;
use phpDocumentor\Reflection\DocBlock\Tags\Property;
use ReflectionClass;
use ReflectionClassConstant;
use ReflectionMethod;
class ClassDoc extends GenericDoc
{
/**
* Properties.
*
* @var array<string, PropertyDoc>
*/
private array $properties = [];
/**
* Methods.
*
* @var array<string, MethodDoc>
*/
private array $methods = [];
public function __construct(ReflectionClass $reflectionClass)
{
$doc = $reflectionClass->getDocComment();
if (!$doc) {
Logger::log($reflectionClass->getName()." has no PHPDOC");
$this->ignore = true;
return;
}
$doc = PhpDocBuilder::$factory->create($doc);
parent::__construct($doc);
$tags = $doc->getTags();
foreach ($tags as $tag) {
if ($tag instanceof Property) {
$this->properties[$tag->getVariableName()] = new PropertyDoc(
$tag->getName(),
$tag->getType(),
$tag->getDescription()
);
}
if ($tag instanceof InvalidTag && $tag->getName() === 'property') {
[$type, $description] = \explode(" $", $tag->render(), 2);
$description .= ' ';
[$varName, $description] = \explode(" ", $description, 2);
$type = \str_replace('@property ', '', $type);
$description ??= '';
$this->properties[$varName] = new PropertyDoc(
$varName,
$type,
$description
);
}
}
$constants = [];
foreach ($reflectionClass->getConstants() as $key => $value) {
$refl = new ReflectionClassConstant($reflectionClass->getName(), $key);
if (!$refl->isPublic()) {
continue;
}
$description = '';
if ($refl->getDocComment()) {
$docConst = PhpDocBuilder::$factory->create($refl->getDocComment());
if (\in_array($refl->getDeclaringClass()->getName(), PhpDocBuilder::DISALLOW)) {
continue;
}
$description .= $docConst->getSummary();
if ($docConst->getDescription()) {
$description .= "\n\n";
$description .= $docConst->getDescription();
}
if ($docConst->getTagsByName('internal')) {
continue;
}
}
$description = \trim($description);
$constants[$key] = [
$value,
$description
];
}
foreach ($reflectionClass->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
if (str_starts_with($method->getName(), '__') && $method !== '__construct') continue;
$this->methods[$method->getName()] = new MethodDoc($method);
}
}
public function format(): string
{
}
}

View File

@ -0,0 +1,70 @@
<?php
namespace danog\MadelineProto\PhpDoc;
use phpDocumentor\Reflection\DocBlock;
use phpDocumentor\Reflection\DocBlock\Description;
use phpDocumentor\Reflection\DocBlock\Tags\Author;
use phpDocumentor\Reflection\DocBlock\Tags\Deprecated;
use phpDocumentor\Reflection\DocBlock\Tags\Generic;
use phpDocumentor\Reflection\DocBlock\Tags\See;
abstract class GenericDoc
{
/**
* Title.
*/
private string $title;
/**
* Description.
*/
private Description $description;
/**
* See also array.
*
* @var array<string, string>
*/
private array $seeAlso = [];
/**
* Author.
*/
private Author $author;
/**
* Ignore this class.
*/
protected bool $ignore = false;
public function __construct(DocBlock $doc)
{
$this->title = $doc->getSummary();
$this->description = $doc->getDescription();
$tags = $doc->getTags();
$this->author = new Author("Daniil Gentili", "daniil@daniil.it");
foreach ($tags as $tag) {
if ($tag instanceof Author) {
$this->author = $tag;
}
if ($tag instanceof Deprecated) {
$this->ignore = true;
break;
}
if ($tag instanceof Generic && $tag->getName() === 'internal') {
$this->ignore = true;
break;
}
if ($tag instanceof See) {
$this->seeAlso[$tag->getReference()->__toString()] = $tag->render();
}
}
}
public function format(): string
{
return '';
}
public function shouldIgnore(): bool
{
return $this->ignore;
}
}

View File

@ -0,0 +1,57 @@
<?php
namespace danog\MadelineProto\PhpDoc;
use danog\MadelineProto\Logger;
use danog\MadelineProto\PhpDocBuilder;
use phpDocumentor\Reflection\DocBlock\Description;
use phpDocumentor\Reflection\DocBlock\Tags\Generic;
use phpDocumentor\Reflection\DocBlock\Tags\Param;
use phpDocumentor\Reflection\DocBlock\Tags\Return_;
use ReflectionMethod;
class MethodDoc extends GenericDoc
{
private $return;
private array $params = [];
public function __construct(ReflectionMethod $method)
{
$doc = $method->getDocComment();
if (!$doc) {
$this->ignore = true;
Logger::log($method->getDeclaringClass()->getName().'::'.$method->getName().' has no PHPDOC!');
return;
}
$doc = PhpDocBuilder::$factory->create($doc);
parent::__construct($doc);
foreach ($doc->getTags() as $tag) {
if ($tag instanceof Param && !isset($this->params[$tag->getVariableName()])) {
$this->params[$tag->getVariableName()] = $tag;
} elseif ($tag instanceof Return_ && !$this->return) {
$this->return = $tag;
} elseif ($tag instanceof Generic && $tag->getName() === 'psalm-return') {
$this->return = $tag;
} elseif ($tag instanceof Generic && $tag->getName() === 'psalm-param') {
[$type, $description] = \explode(" $", $tag->getDescription(), 2);
$description .= ' ';
[$varName, $description] = \explode(" ", $description, 2);
if (!$description && isset($this->params[$varName])) {
$description = $this->params[$varName]->getDescription();
} else {
$description = new Description($description);
}
$this->params[$varName] = [
$type,
$description
];
}
}
}
public function render(): string
{
return '';
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace danog\MadelineProto\PhpDoc;
use phpDocumentor\Reflection\DocBlock\Tags\Property;
class PropertyDoc
{
public function __construct(string $name, $type, $description)
{
}
public function __toString()
{
}
}

View File

@ -27,6 +27,7 @@ use danog\MadelineProto\MTProtoTools\MinDatabase;
use danog\MadelineProto\MTProtoTools\PasswordCalculator;
use danog\MadelineProto\MTProtoTools\ReferenceDatabase;
use danog\MadelineProto\MTProtoTools\UpdatesState;
use danog\MadelineProto\PhpDoc\ClassDoc;
use danog\MadelineProto\TL\TL;
use danog\MadelineProto\TL\TLCallback;
use danog\MadelineProto\TL\TLConstructors;
@ -37,19 +38,13 @@ use danog\MadelineProto\TON\InternalDoc as TInternalDoc;
use danog\MadelineProto\TON\Lite;
use HaydenPierce\ClassFinder\ClassFinder;
use phpDocumentor\Reflection\DocBlock\Tags\Author;
use phpDocumentor\Reflection\DocBlock\Tags\Deprecated;
use phpDocumentor\Reflection\DocBlock\Tags\Generic;
use phpDocumentor\Reflection\DocBlock\Tags\InvalidTag;
use phpDocumentor\Reflection\DocBlock\Tags\Property;
use phpDocumentor\Reflection\DocBlock\Tags\See;
use phpDocumentor\Reflection\DocBlockFactory;
use ReflectionClass;
use ReflectionClassConstant;
use ReflectionMethod;
class PhpDocBuilder
{
private const DISALLOW = [
const DISALLOW = [
AnnotationsBuilder::class,
APIFactory::class,
APIWrapper::class,
@ -97,11 +92,11 @@ class PhpDocBuilder
\ArrayIterator::class,
];
private DocBlockFactory $factory;
public static DocBlockFactory $factory;
private string $output;
public function __construct(string $output)
{
$this->factory = DocBlockFactory::createInstance();
self::$factory = DocBlockFactory::createInstance();
$this->output = $output;
}
public function run()
@ -113,6 +108,7 @@ class PhpDocBuilder
|| str_starts_with($class, 'danog\\MadelineProto\\Loop\\Connection')
|| str_starts_with($class, 'danog\\MadelineProto\\MTProto\\')
|| str_starts_with($class, 'danog\\MadelineProto\\MTProtoSession\\')
|| str_starts_with($class, 'danog\\MadelineProto\\PhpDoc\\')
|| str_starts_with($class, 'danog\\MadelineProto\\Db\\NullCache')) {
continue;
}
@ -135,7 +131,8 @@ class PhpDocBuilder
{
$dir = \dirname($file);
if (!\file_exists($dir)) {
$this->createDir($dir);
self::createDir($dir);
\mkdir($dir);
}
return $file;
}
@ -148,91 +145,17 @@ class PhpDocBuilder
$fName .= '.md';
$handle = \fopen(self::createDir($fName), 'w+');
$doc = $class->getDocComment();
if (!$doc) {
throw new Exception("$name has no PHPDOC!");
}
$doc = $this->factory->create($doc);
$title = $doc->getSummary();
$description = $doc->getDescription();
$tags = $doc->getTags();
$seeAlso = [];
$properties = [];
$author = new Author("Daniil Gentili", "daniil@daniil.it");
foreach ($tags as $tag) {
if ($tag instanceof Author) {
$author = $tag;
}
if ($tag instanceof Deprecated) {
return;
}
if ($tag instanceof Generic && $tag->getName() === 'internal') {
return;
}
if ($tag instanceof See) {
$seeAlso[$tag->getReference()->__toString()] = $tag->render();
}
if ($tag instanceof Property) {
$properties[$tag->getVariableName()] = [
$tag->getType(),
$tag->getDescription()
];
}
if ($tag instanceof InvalidTag && $tag->getName() === 'property') {
[$type, $description] = \explode(" $", $tag->render(), 2);
$description .= ' ';
[$varName, $description] = \explode(" ", $description, 2);
$properties[$varName] = [
\str_replace('@property ', '', $type),
$description ?? ''
];
}
}
fwrite($handle, "---\n");
fwrite($handle, "title: $name: $title\n");
fwrite($handle, "description: $description\n");
fwrite($handle, "image: https://docs.madelineproto.xyz/favicons/android-chrome-256x256.png\n");
fwrite($handle, "---\n");
fwrite($handle, "# $name: $title\n");
fwrite($handle, "[Back to API index](index.md)\n\n");
fwrite($handle, "> Author: $author \n");
$constants = [];
foreach ($class->getConstants() as $key => $value) {
$refl = new ReflectionClassConstant($name, $key);
if (!$refl->isPublic()) {
continue;
}
$description = '';
if ($refl->getDocComment()) {
$docConst = $this->factory->create($refl->getDocComment());
if (\in_array($refl->getDeclaringClass()->getName(), self::DISALLOW)) {
continue;
}
$description .= $docConst->getSummary();
if ($docConst->getDescription()) {
$description .= "\n\n";
$description .= $docConst->getDescription();
}
if ($docConst->getTagsByName('internal')) {
continue;
}
}
$description = \trim($description);
$constants[$key] = [
$value,
$description
];
}
$methods = [];
foreach ($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
}
$class = new ClassDoc($class);
/*
\fwrite($handle, "---\n");
\fwrite($handle, "title: $name: $title\n");
\fwrite($handle, "description: $description\n");
\fwrite($handle, "image: https://docs.madelineproto.xyz/favicons/android-chrome-256x256.png\n");
\fwrite($handle, "---\n");
\fwrite($handle, "# $name: $title\n");
\fwrite($handle, "[Back to API index](index.md)\n\n");
\fwrite($handle, "> Author: $author \n");
*/
}
}

View File

@ -292,7 +292,7 @@ abstract class Serialization
if ($e->getFile() === 'MadelineProto' && $e->getLine() === 1) {
throw $e;
}
if (@\constant("MADELINEPROTO_TEST") === 'pony') {
if (\defined('MADELINEPROTO_TEST') && \constant("MADELINEPROTO_TEST") === 'pony') {
throw $e;
}
\class_exists('\\Volatile');

View File

@ -411,7 +411,8 @@ class Connection extends SettingsAbstract
/**
* Get proxy identifiers.
*
* @return array<class-string<StreamInterface>, array>
* @return array
* @psalm-return array<class-string<StreamInterface>, array>
*/
public function getProxies(): array
{

View File

@ -169,7 +169,7 @@ class Logger extends SettingsAbstract
*/
public function setExtra($extra): self
{
if ($this->type === MadelineProtoLogger::CALLABLE_LOGGER && !is_callable($extra)) {
if ($this->type === MadelineProtoLogger::CALLABLE_LOGGER && !\is_callable($extra)) {
$this->setType(MadelineProtoLogger::NO_LOGGER);
return $this;
}

View File

@ -25,40 +25,40 @@ namespace danog\MadelineProto\TL;
interface TLCallback
{
/**
* Called after serializing a method
*
* Called after serializing a method.
*
* @internal
*
* @var int
*/
const METHOD_CALLBACK = 0;
/**
* Called before serializing a method
*
* Called before serializing a method.
*
* @internal
*
* @var int
*/
const METHOD_BEFORE_CALLBACK = 1;
/**
* Called after serializing a constructor
*
* Called after serializing a constructor.
*
* @internal
*
* @var int
*/
const CONSTRUCTOR_CALLBACK = 2;
/**
* Called before serializing a constructor
*
* Called before serializing a constructor.
*
* @internal
*
* @var int
*/
const CONSTRUCTOR_BEFORE_CALLBACK = 3;
/**
* Called on constructor serialization
*
* Called on constructor serialization.
*
* @internal
*
* @var int

View File

@ -620,7 +620,8 @@ abstract class Tools extends StrTools
*
* @internal Generator function
*
* @return \Generator<mixed, mixed, mixed, ?callable>
* @return \Generator
* @psalm-return \Generator<mixed, mixed, mixed, ?callable>
*/
public static function flockGenerator(string $file, int $operation, float $polling, ?Promise $token = null, $failureCb = null): \Generator
{