From 5e9dee57cb3bb989258ded1766f17cf4bb578b8e Mon Sep 17 00:00:00 2001 From: Etienne Zannelli Date: Fri, 25 Feb 2022 10:51:25 +0100 Subject: [PATCH] chore: update phpstan --- composer.json | 4 ++-- src/Adapter/Amp/Internal/Deferred.php | 15 +++++++++--- src/Adapter/Amp/Internal/PromiseWrapper.php | 24 ++++++++++++++++++- .../Internal/FailingPromiseCollection.php | 8 ++++++- src/Adapter/Guzzle/CurlMultiClientWrapper.php | 12 +++++----- src/Adapter/Guzzle/HttpClient.php | 3 +++ .../ReactPhp/Internal/PromiseWrapper.php | 8 +++++++ src/Adapter/Symfony/HttpClient.php | 3 +++ src/Adapter/Tornado/EventLoop.php | 2 +- .../Tornado/Internal/PendingPromise.php | 16 ++++++++++++- .../Tornado/Internal/StreamEventLoop.php | 15 ++++++++++-- src/Adapter/Tornado/Internal/Task.php | 18 ++++++++++++-- src/Adapter/Tornado/SynchronousEventLoop.php | 2 +- src/EventLoop.php | 4 ++++ tests/Adapter/Guzzle/GuzzleMockWrapper.php | 4 ++++ tests/Adapter/Symfony/HttpClientTest.php | 6 +++-- tests/HttpClientTest.php | 2 +- 17 files changed, 123 insertions(+), 23 deletions(-) diff --git a/composer.json b/composer.json index 931ab32..23fb7d6 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "ext-curl": "^7.3|^8.0", "react/event-loop": "^1.0", "react/promise": "^2.7", - "phpstan/phpstan": "^0.12", + "phpstan/phpstan": "^1.0", "symfony/http-client": "^4.3", "psr/http-factory": "^1.0", "http-interop/http-factory-guzzle": "^1.0" @@ -51,7 +51,7 @@ "scripts": { "tests-unit": "./bin/phpunit --testsuite='Tornado Test Suite'", "tests-examples": "./bin/phpunit --testsuite='Tornado Examples'", - "static-analysis": "./bin/phpstan analyse src tests --level=7 --no-progress -vvv", + "static-analysis": "./bin/phpstan analyse src tests --level=8 --no-progress -vvv", "code-style-check": "./bin/php-cs-fixer fix --dry-run --verbose", "code-style-fix": "./bin/php-cs-fixer fix" } diff --git a/src/Adapter/Amp/Internal/Deferred.php b/src/Adapter/Amp/Internal/Deferred.php index 6b412bd..210a281 100644 --- a/src/Adapter/Amp/Internal/Deferred.php +++ b/src/Adapter/Amp/Internal/Deferred.php @@ -7,15 +7,21 @@ /** * @internal * ⚠️ You must NOT rely on this internal implementation + * + * @template TValue */ class Deferred implements \M6Web\Tornado\Deferred { - /** @var \Amp\Deferred */ + /** @var \Amp\Deferred */ private $ampDeferred; - /** @var PromiseWrapper */ + /** @var PromiseWrapper */ private $promise; + /** + * @param \Amp\Deferred $ampDeferred + * @param PromiseWrapper $promise + */ public function __construct(\Amp\Deferred $ampDeferred, PromiseWrapper $promise) { $this->ampDeferred = $ampDeferred; @@ -30,13 +36,16 @@ public function getPromise(): Promise return $this->promise; } + /** + * @return PromiseWrapper + */ public function getPromiseWrapper(): PromiseWrapper { return $this->promise; } /** - * {@inheritdoc} + * @param TValue $value */ public function resolve($value): void { diff --git a/src/Adapter/Amp/Internal/PromiseWrapper.php b/src/Adapter/Amp/Internal/PromiseWrapper.php index b5ab182..174e2ba 100644 --- a/src/Adapter/Amp/Internal/PromiseWrapper.php +++ b/src/Adapter/Amp/Internal/PromiseWrapper.php @@ -8,10 +8,14 @@ /** * @internal * ⚠️ You must NOT rely on this internal implementation + * + * @template TValue + * + * @implements Promise */ class PromiseWrapper implements Promise { - /** @var \Amp\Promise */ + /** @var \Amp\Promise */ private $ampPromise; /** @var bool */ @@ -24,6 +28,11 @@ private function __construct() { } + /** + * @param \Amp\Promise $ampPromise + * + * @return static + */ public static function createUnhandled(\Amp\Promise $ampPromise, FailingPromiseCollection $failingPromiseCollection): self { $promiseWrapper = new self(); @@ -40,6 +49,11 @@ function (?\Throwable $reason, $value) use ($promiseWrapper, $failingPromiseColl return $promiseWrapper; } + /** + * @param \Amp\Promise $ampPromise + * + * @return static + */ public static function createHandled(\Amp\Promise $ampPromise): self { $promiseWrapper = new self(); @@ -49,11 +63,19 @@ public static function createHandled(\Amp\Promise $ampPromise): self return $promiseWrapper; } + /** + * @return \Amp\Promise + */ public function getAmpPromise(): \Amp\Promise { return $this->ampPromise; } + /** + * @param Promise $promise + * + * @return static + */ public static function toHandledPromise(Promise $promise, FailingPromiseCollection $failingPromiseCollection): self { assert($promise instanceof self, new \Error('Input promise was not created by this adapter.')); diff --git a/src/Adapter/Common/Internal/FailingPromiseCollection.php b/src/Adapter/Common/Internal/FailingPromiseCollection.php index fbfd3a6..adab2e9 100644 --- a/src/Adapter/Common/Internal/FailingPromiseCollection.php +++ b/src/Adapter/Common/Internal/FailingPromiseCollection.php @@ -10,11 +10,17 @@ */ class FailingPromiseCollection { + /** + * @param Tornado\Promise $promise + */ public function watchFailingPromise(Tornado\Promise $promise, \Throwable $throwable): void { $this->registeredThrowables->attach($promise, $throwable); } + /** + * @param Tornado\Promise $promise + */ public function unwatchPromise(Tornado\Promise $promise): void { $this->registeredThrowables->detach($promise); @@ -35,6 +41,6 @@ public function __construct() $this->registeredThrowables = new \SplObjectStorage(); } - /** @var \SplObjectStorage */ + /** @var \SplObjectStorage, \Throwable> */ private $registeredThrowables; } diff --git a/src/Adapter/Guzzle/CurlMultiClientWrapper.php b/src/Adapter/Guzzle/CurlMultiClientWrapper.php index 6c72bf8..95045b0 100644 --- a/src/Adapter/Guzzle/CurlMultiClientWrapper.php +++ b/src/Adapter/Guzzle/CurlMultiClientWrapper.php @@ -13,12 +13,12 @@ final class CurlMultiClientWrapper implements GuzzleClientWrapper /** * CurlMultiClientWrapper constructor. * - * @param array $clientConfig configuration for \GuzzleHttp\Client, check corresponding documentation. - * 'handler' configuration will be ignored since built in this wrapper - * @param array $curlMultiOptions options for \GuzzleHttp\Handler\CurlMultiHandler, check corresponding documentation. - * Default value for 'select_timeout' is 0 - * @param array $middlewareStack set of name => handler to push on the top of created \GuzzleHttp\HandlerStack, - * check corresponding documentation + * @param array $clientConfig configuration for \GuzzleHttp\Client, check corresponding documentation. + * 'handler' configuration will be ignored since built in this wrapper + * @param array $curlMultiOptions options for \GuzzleHttp\Handler\CurlMultiHandler, check corresponding documentation. + * Default value for 'select_timeout' is 0 + * @param array $middlewareStack set of name => handler to push on the top of created \GuzzleHttp\HandlerStack, + * check corresponding documentation */ public function __construct(array $clientConfig = [], array $curlMultiOptions = [], array $middlewareStack = []) { diff --git a/src/Adapter/Guzzle/HttpClient.php b/src/Adapter/Guzzle/HttpClient.php index f9d469c..6b084a1 100644 --- a/src/Adapter/Guzzle/HttpClient.php +++ b/src/Adapter/Guzzle/HttpClient.php @@ -77,6 +77,9 @@ private function http2fallback(RequestInterface $request): RequestInterface return $request; } + /** + * @return \Generator> + */ private function guzzleEventLoop(): \Generator { do { diff --git a/src/Adapter/ReactPhp/Internal/PromiseWrapper.php b/src/Adapter/ReactPhp/Internal/PromiseWrapper.php index 0e2f9d9..4e1dc11 100644 --- a/src/Adapter/ReactPhp/Internal/PromiseWrapper.php +++ b/src/Adapter/ReactPhp/Internal/PromiseWrapper.php @@ -8,6 +8,9 @@ /** * @internal * ⚠️ You must NOT rely on this internal implementation + * + * @template TValue + * @implements Promise */ class PromiseWrapper implements Promise { @@ -55,6 +58,11 @@ public function getReactPromise(): \React\Promise\PromiseInterface return $this->reactPromise; } + /** + * @param Promise $promise + * + * @return static + */ public static function toHandledPromise(Promise $promise, FailingPromiseCollection $failingPromiseCollection): self { assert($promise instanceof self, new \Error('Input promise was not created by this adapter.')); diff --git a/src/Adapter/Symfony/HttpClient.php b/src/Adapter/Symfony/HttpClient.php index 8ca44e7..0c755de 100644 --- a/src/Adapter/Symfony/HttpClient.php +++ b/src/Adapter/Symfony/HttpClient.php @@ -71,6 +71,9 @@ public function sendRequest(RequestInterface $request): Promise return $deferred->getPromise(); } + /** + * @return \Generator> + */ private function symfonyEventLoop(): \Generator { do { diff --git a/src/Adapter/Tornado/EventLoop.php b/src/Adapter/Tornado/EventLoop.php index 4984fcd..31fb161 100644 --- a/src/Adapter/Tornado/EventLoop.php +++ b/src/Adapter/Tornado/EventLoop.php @@ -11,7 +11,7 @@ class EventLoop implements \M6Web\Tornado\EventLoop /** @var Internal\StreamEventLoop */ private $streamLoop; - /** @var Internal\Task[] */ + /** @var Internal\Task[] */ private $tasks = []; /** @var FailingPromiseCollection */ diff --git a/src/Adapter/Tornado/Internal/PendingPromise.php b/src/Adapter/Tornado/Internal/PendingPromise.php index 914b10e..4f97954 100644 --- a/src/Adapter/Tornado/Internal/PendingPromise.php +++ b/src/Adapter/Tornado/Internal/PendingPromise.php @@ -9,10 +9,13 @@ /** * @internal * ⚠️ You must NOT rely on this internal implementation + * @template TValue + * + * @implements Promise */ class PendingPromise implements Promise, Deferred { - /** @var mixed */ + /** @var TValue */ private $value; /** @var \Throwable */ private $throwable; @@ -46,6 +49,11 @@ public static function createHandled(): self return $promiseWrapper; } + /** + * @param Promise $promise + * + * @return static + */ public static function toHandledPromise(Promise $promise): self { assert($promise instanceof self, new \Error('Input promise was not created by this adapter.')); @@ -58,6 +66,9 @@ public static function toHandledPromise(Promise $promise): self return $promise; } + /** + * @param TValue $value + */ public function resolve($value): void { $this->settle(); @@ -78,6 +89,9 @@ public function reject(\Throwable $throwable): void $this->triggerCallbacks(); } + /** + * @return Promise + */ public function getPromise(): Promise { return $this; diff --git a/src/Adapter/Tornado/Internal/StreamEventLoop.php b/src/Adapter/Tornado/Internal/StreamEventLoop.php index 6b87409..7b6577f 100644 --- a/src/Adapter/Tornado/Internal/StreamEventLoop.php +++ b/src/Adapter/Tornado/Internal/StreamEventLoop.php @@ -3,6 +3,7 @@ namespace M6Web\Tornado\Adapter\Tornado\Internal; use M6Web\Tornado\EventLoop; +use M6Web\Tornado\Promise; /** * @internal @@ -13,11 +14,13 @@ class StreamEventLoop private $readStreams = []; /** @var resource[] */ private $writeStreams = []; - /** @var PendingPromise[] */ + /** @var PendingPromise[] */ private $pendingPromises = []; /** * @param resource $stream + * + * @return PendingPromise */ public function readable(EventLoop $eventLoop, $stream): PendingPromise { @@ -26,12 +29,17 @@ public function readable(EventLoop $eventLoop, $stream): PendingPromise /** * @param resource $stream + * + * @return PendingPromise */ public function writable(EventLoop $eventLoop, $stream): PendingPromise { return $this->recordStream($eventLoop, $stream, $this->writeStreams); } + /** + * @return \Generator> + */ private function internalLoop(EventLoop $eventLoop): \Generator { $except = null; @@ -65,7 +73,10 @@ private function internalLoop(EventLoop $eventLoop): \Generator } /** - * @param resource $stream + * @param resource $stream + * @param array $streamsList + * + * @return PendingPromise */ private function recordStream(EventLoop $eventLoop, $stream, array &$streamsList): PendingPromise { diff --git a/src/Adapter/Tornado/Internal/Task.php b/src/Adapter/Tornado/Internal/Task.php index 5753687..72ef818 100644 --- a/src/Adapter/Tornado/Internal/Task.php +++ b/src/Adapter/Tornado/Internal/Task.php @@ -2,28 +2,42 @@ namespace M6Web\Tornado\Adapter\Tornado\Internal; +use M6Web\Tornado\Promise; + /** * @internal * ⚠️ You must NOT rely on this internal implementation + * + * @template TValue */ class Task { - /** @var \Generator */ + /** @var \Generator */ private $generator; - /** @var PendingPromise */ + /** @var PendingPromise */ private $promise; + /** + * @param \Generator $generator + * @param PendingPromise $pendingPromise + */ public function __construct(\Generator $generator, PendingPromise $pendingPromise) { $this->generator = $generator; $this->promise = $pendingPromise; } + /** + * @return PendingPromise + */ public function getPromise(): PendingPromise { return $this->promise; } + /** + * @return \Generator + */ public function getGenerator(): \Generator { return $this->generator; diff --git a/src/Adapter/Tornado/SynchronousEventLoop.php b/src/Adapter/Tornado/SynchronousEventLoop.php index 307e79f..9693072 100644 --- a/src/Adapter/Tornado/SynchronousEventLoop.php +++ b/src/Adapter/Tornado/SynchronousEventLoop.php @@ -156,7 +156,7 @@ public function deferred(): Deferred $deferred = new class() implements Deferred { /** @var SynchronousEventLoop */ public $eventLoop; - /** @var ?Promise */ + /** @var ?Promise */ private $promise = null; public function getPromise(): Promise diff --git a/src/EventLoop.php b/src/EventLoop.php index 4a9f618..308a181 100644 --- a/src/EventLoop.php +++ b/src/EventLoop.php @@ -30,6 +30,8 @@ public function async(\Generator $generator): Promise; /** * Creates a promise that will be resolved with an array of all sub-promises results. + * + * @return Promise */ public function promiseAll(Promise ...$promises): Promise; @@ -43,6 +45,8 @@ public function promiseAll(Promise ...$promises): Promise; * * @param \Traversable|array $traversable Input elements * @param callable(TValue, TKey): \Generator $function + * + * @return Promise */ public function promiseForeach($traversable, callable $function): Promise; diff --git a/tests/Adapter/Guzzle/GuzzleMockWrapper.php b/tests/Adapter/Guzzle/GuzzleMockWrapper.php index d2f0696..c09c89a 100644 --- a/tests/Adapter/Guzzle/GuzzleMockWrapper.php +++ b/tests/Adapter/Guzzle/GuzzleMockWrapper.php @@ -4,6 +4,7 @@ use GuzzleHttp\Promise; use M6Web\Tornado\Adapter\Guzzle\GuzzleClientWrapper; +use Psr\Http\Message\ResponseInterface; final class GuzzleMockWrapper implements GuzzleClientWrapper { @@ -13,6 +14,9 @@ final class GuzzleMockWrapper implements GuzzleClientWrapper /** @var int */ public $ticks; + /** + * @param ResponseInterface[]|\Exception[] $queue + */ public function __construct(array $queue) { $this->ticks = 0; diff --git a/tests/Adapter/Symfony/HttpClientTest.php b/tests/Adapter/Symfony/HttpClientTest.php index 5f8a7de..0f19c55 100644 --- a/tests/Adapter/Symfony/HttpClientTest.php +++ b/tests/Adapter/Symfony/HttpClientTest.php @@ -4,7 +4,6 @@ use M6Web\Tornado\EventLoop; use M6Web\Tornado\HttpClient; -use Psr\Http\Message\ResponseInterface; class HttpClientTest extends \M6WebTest\Tornado\HttpClientTest { @@ -12,10 +11,13 @@ protected function createHttpClient(EventLoop $eventLoop, array $responsesOrExce { $callback = function ($method, $url, $options) use (&$responsesOrExceptions) { $response = array_shift($responsesOrExceptions); + if ($response === null) { + throw new \Exception('No more response to return.'); + } + if ($response instanceof \Exception) { throw $response; } - /* @var ResponseInterface $response */ return new \Symfony\Component\HttpClient\Response\MockResponse( (string) $response->getBody(), diff --git a/tests/HttpClientTest.php b/tests/HttpClientTest.php index 7c40acd..675da52 100644 --- a/tests/HttpClientTest.php +++ b/tests/HttpClientTest.php @@ -16,7 +16,7 @@ abstract class HttpClientTest extends TestCase abstract protected function createHttpClient(EventLoop $eventLoop, array $responsesOrExceptions): HttpClient; /** - * @return \Generator + * @return \Generator> */ public function eventLoopProvider(): \Generator {