From f8efd446842f36984b1022dd1f5c3d92bacf92b7 Mon Sep 17 00:00:00 2001 From: Niklas Keller Date: Sat, 28 Mar 2020 14:20:27 +0100 Subject: [PATCH] Add additional types for static analysis --- lib/functions.php | 96 ++++++++++++++++++++++++++++------------------- 1 file changed, 58 insertions(+), 38 deletions(-) diff --git a/lib/functions.php b/lib/functions.php index b4ad7d9..3e0fb1e 100644 --- a/lib/functions.php +++ b/lib/functions.php @@ -12,15 +12,18 @@ namespace Amp * * Use this function to create a coroutine-aware callable for a promise-aware callback caller. * - * @param callable(mixed ...$args): mixed $callback + * @template TReturn * - * @return callable(mixed ...$args): \Amp\Promise + * @param callable(mixed ...$args):(\Generator,mixed,Promise|ReactPromise|TReturn>|Promise|ReactPromise|TReturn) + * $callback + * + * @return callable(mixed ...$args):Promise * * @see asyncCoroutine() */ function coroutine(callable $callback): callable { - return function (...$args) use ($callback): Promise { + return static function (...$args) use ($callback): Promise { return call($callback, ...$args); }; } @@ -32,7 +35,10 @@ namespace Amp * * Use this function to create a coroutine-aware callable for a non-promise-aware callback caller. * - * @param callable(...$args): \Generator|\Amp\Promise|mixed $callback + * @template TReturn + * + * @param callable(mixed ...$args):(\Generator,mixed,Promise|ReactPromise|TReturn>|Promise|ReactPromise|TReturn) + * $callback * * @return callable(...$args): void * @@ -40,7 +46,7 @@ namespace Amp */ function asyncCoroutine(callable $callback): callable { - return function (...$args) use ($callback) { + return static function (...$args) use ($callback) { Promise\rethrow(call($callback, ...$args)); }; } @@ -155,7 +161,7 @@ namespace Amp\Promise } } - $promise->onResolve(function ($exception) { + $promise->onResolve(static function ($exception) { if ($exception) { throw $exception; } @@ -218,10 +224,12 @@ namespace Amp\Promise * If the timeout expires before the promise is resolved, the returned promise fails with an instance of * `Amp\TimeoutException`. * - * @param Promise|ReactPromise $promise Promise to which the timeout is applied. - * @param int $timeout Timeout in milliseconds. + * @template TReturn * - * @return Promise + * @param Promise|ReactPromise $promise Promise to which the timeout is applied. + * @param int $timeout Timeout in milliseconds. + * + * @return Promise * * @throws \TypeError If $promise is not an instance of \Amp\Promise or \React\Promise\PromiseInterface. */ @@ -237,7 +245,7 @@ namespace Amp\Promise $deferred = new Deferred; - $watcher = Loop::delay($timeout, function () use (&$deferred) { + $watcher = Loop::delay($timeout, static function () use (&$deferred) { $temp = $deferred; // prevent double resolve $deferred = null; $temp->fail(new TimeoutException); @@ -261,11 +269,13 @@ namespace Amp\Promise * * If the timeout expires before the promise is resolved, a default value is returned * - * @param Promise|ReactPromise $promise Promise to which the timeout is applied. - * @param int $timeout Timeout in milliseconds. - * @param mixed $default + * @template TReturn * - * @return Promise + * @param Promise|ReactPromise $promise Promise to which the timeout is applied. + * @param int $timeout Timeout in milliseconds. + * @param TReturn $default + * + * @return Promise * * @throws \TypeError If $promise is not an instance of \Amp\Promise or \React\Promise\PromiseInterface. */ @@ -273,7 +283,7 @@ namespace Amp\Promise { $promise = timeout($promise, $timeout); - return call(function () use ($promise, $default) { + return call(static function () use ($promise, $default) { try { return yield $promise; } catch (TimeoutException $exception) { @@ -477,7 +487,7 @@ namespace Amp\Promise } $values[$key] = $exceptions[$key] = null; // add entry to arrays to preserve order - $promise->onResolve(function ($exception, $value) use ( + $promise->onResolve(static function ($exception, $value) use ( &$values, &$exceptions, &$pending, @@ -524,7 +534,7 @@ namespace Amp\Promise $deferred = new Deferred(); - $promise->onResolve(function (\Throwable $exception = null, $result) use ($deferred, $callback) { + $promise->onResolve(static function (\Throwable $exception = null, $result) use ($deferred, $callback) { try { $result = $callback($exception, $result); } catch (\Throwable $exception) { @@ -559,7 +569,7 @@ namespace Amp\Iterator * @param array|\Traversable $iterable Elements to emit. * @param int $delay Delay between element emissions in milliseconds. * - * @return \Amp\Iterator + * @return Iterator * * @throws \TypeError If the argument is not an array or instance of \Traversable. */ @@ -571,26 +581,34 @@ namespace Amp\Iterator throw createTypeError(["array", "Traversable"], $iterable); } - return new Producer(function (callable $emit) use ($iterable, $delay) { - foreach ($iterable as $value) { - if ($delay) { + if ($delay) { + return new Producer(static function (callable $emit) use ($iterable, $delay) { + foreach ($iterable as $value) { yield new Delayed($delay); + yield $emit($value); } + }); + } + return new Producer(static function (callable $emit) use ($iterable) { + foreach ($iterable as $value) { yield $emit($value); } }); } /** - * @param \Amp\Iterator $iterator - * @param callable (mixed $value): mixed $onEmit + * @template TValue + * @template TReturn * - * @return \Amp\Iterator + * @param Iterator $iterator + * @param callable (TValue $value): TReturn $onEmit + * + * @return Iterator */ function map(Iterator $iterator, callable $onEmit): Iterator { - return new Producer(function (callable $emit) use ($iterator, $onEmit) { + return new Producer(static function (callable $emit) use ($iterator, $onEmit) { while (yield $iterator->advance()) { yield $emit($onEmit($iterator->getCurrent())); } @@ -598,14 +616,16 @@ namespace Amp\Iterator } /** - * @param \Amp\Iterator $iterator - * @param callable (mixed $value): bool $filter + * @template TValue * - * @return \Amp\Iterator + * @param Iterator $iterator + * @param callable(TValue $value):bool $filter + * + * @return Iterator */ function filter(Iterator $iterator, callable $filter): Iterator { - return new Producer(function (callable $emit) use ($iterator, $filter) { + return new Producer(static function (callable $emit) use ($iterator, $filter) { while (yield $iterator->advance()) { if ($filter($iterator->getCurrent())) { yield $emit($iterator->getCurrent()); @@ -617,16 +637,16 @@ namespace Amp\Iterator /** * Creates an iterator that emits values emitted from any iterator in the array of iterators. * - * @param \Amp\Iterator[] $iterators + * @param Iterator[] $iterators * - * @return \Amp\Iterator + * @return Iterator */ function merge(array $iterators): Iterator { $emitter = new Emitter; $result = $emitter->iterate(); - $coroutine = coroutine(function (Iterator $iterator) use (&$emitter) { + $coroutine = coroutine(static function (Iterator $iterator) use (&$emitter) { while ((yield $iterator->advance()) && $emitter !== null) { yield $emitter->emit($iterator->getCurrent()); } @@ -640,7 +660,7 @@ namespace Amp\Iterator $coroutines[] = $coroutine($iterator); } - Promise\all($coroutines)->onResolve(function ($exception) use (&$emitter) { + Promise\all($coroutines)->onResolve(static function ($exception) use (&$emitter) { if ($exception) { $emitter->fail($exception); $emitter = null; @@ -657,9 +677,9 @@ namespace Amp\Iterator * prior iterator must complete before values are emitted from any subsequent iterators. Iterators are concatenated * in the order given (iteration order of the array). * - * @param array $iterators + * @param Iterator[] $iterators * - * @return \Amp\Iterator + * @return Iterator */ function concat(array $iterators): Iterator { @@ -673,14 +693,14 @@ namespace Amp\Iterator $previous = []; $promise = Promise\all($previous); - $coroutine = coroutine(function (Iterator $iterator, callable $emit) { + $coroutine = coroutine(static function (Iterator $iterator, callable $emit) { while (yield $iterator->advance()) { yield $emit($iterator->getCurrent()); } }); foreach ($iterators as $iterator) { - $emit = coroutine(function ($value) use ($emitter, $promise) { + $emit = coroutine(static function ($value) use ($emitter, $promise) { static $pending = true, $failed = false; if ($failed) { @@ -703,7 +723,7 @@ namespace Amp\Iterator $promise = Promise\all($previous); } - $promise->onResolve(function ($exception) use ($emitter) { + $promise->onResolve(static function ($exception) use ($emitter) { if ($exception) { $emitter->fail($exception); return;