From 2642d725da4669281820ea2b0d65cae0a73fcdf6 Mon Sep 17 00:00:00 2001 From: Cees-Jan Kiewiet Date: Mon, 7 Oct 2019 15:26:46 +0200 Subject: [PATCH] Enforce return type hints on all functions and require PHP 7.1+ as a consequence With #138 requiring PHP 7.0 as a minimum we can now add return type hints to all our public and private functions. To give all functions return type hints we need the `void` return type, which isn't available until PHP 7.1. So in order use that we also have to bump the the minimum required PHP version for this package to PHP 7.1. The benefit of return type hints is the assurance at language level of our return values. For ourself and our consumers. --- .travis.yml | 1 - composer.json | 2 +- src/Deferred.php | 8 +++--- src/Exception/CompositeException.php | 2 +- src/FulfilledPromise.php | 16 +++++------ src/Internal/CancellationQueue.php | 6 ++-- src/Internal/Queue.php | 4 +-- src/Promise.php | 25 +++++++++-------- src/PromiseInterface.php | 10 +++---- src/PromisorInterface.php | 2 +- src/RejectedPromise.php | 18 ++++++------ src/functions.php | 42 ++++++++++++++-------------- 12 files changed, 68 insertions(+), 68 deletions(-) diff --git a/.travis.yml b/.travis.yml index e176d1fc..bd2ae443 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: php php: - - 7.0 - 7.1 - 7.2 - 7.3 diff --git a/composer.json b/composer.json index 02f958b6..f0b279d2 100644 --- a/composer.json +++ b/composer.json @@ -6,7 +6,7 @@ {"name": "Jan Sorgalla", "email": "jsorgalla@gmail.com"} ], "require": { - "php": ">=7.0.0" + "php": ">=7.1.0" }, "require-dev": { "phpunit/phpunit": "~6.4" diff --git a/src/Deferred.php b/src/Deferred.php index ef06069f..c748633f 100644 --- a/src/Deferred.php +++ b/src/Deferred.php @@ -14,13 +14,13 @@ public function __construct(callable $canceller = null) $this->canceller = $canceller; } - public function promise() + public function promise(): PromiseInterface { if (null === $this->promise) { $canceller = $this->canceller; $this->canceller = null; - $this->promise = new Promise(function ($resolve, $reject) { + $this->promise = new Promise(function ($resolve, $reject): void { $this->resolveCallback = $resolve; $this->rejectCallback = $reject; }, $canceller); @@ -29,14 +29,14 @@ public function promise() return $this->promise; } - public function resolve($value = null) + public function resolve($value = null): void { $this->promise(); \call_user_func($this->resolveCallback, $value); } - public function reject(\Throwable $reason) + public function reject(\Throwable $reason): void { $this->promise(); diff --git a/src/Exception/CompositeException.php b/src/Exception/CompositeException.php index 1fdbab54..022bd0ae 100644 --- a/src/Exception/CompositeException.php +++ b/src/Exception/CompositeException.php @@ -23,7 +23,7 @@ public function __construct(array $throwables, $message = '', $code = 0, $previo /** * @return \Throwable[] */ - public function getThrowables() + public function getThrowables(): array { return $this->throwables; } diff --git a/src/FulfilledPromise.php b/src/FulfilledPromise.php index ecd09ba7..2bb0a060 100644 --- a/src/FulfilledPromise.php +++ b/src/FulfilledPromise.php @@ -15,14 +15,14 @@ public function __construct($value = null) $this->value = $value; } - public function then(callable $onFulfilled = null, callable $onRejected = null) + public function then(callable $onFulfilled = null, callable $onRejected = null): PromiseInterface { if (null === $onFulfilled) { return $this; } - return new Promise(function (callable $resolve, callable $reject) use ($onFulfilled) { - enqueue(function () use ($resolve, $reject, $onFulfilled) { + return new Promise(function (callable $resolve, callable $reject) use ($onFulfilled): void { + enqueue(function () use ($resolve, $reject, $onFulfilled): void { try { $resolve($onFulfilled($this->value)); } catch (\Throwable $exception) { @@ -32,7 +32,7 @@ public function then(callable $onFulfilled = null, callable $onRejected = null) }); } - public function done(callable $onFulfilled = null, callable $onRejected = null) + public function done(callable $onFulfilled = null, callable $onRejected = null): void { if (null === $onFulfilled) { return; @@ -51,21 +51,21 @@ public function done(callable $onFulfilled = null, callable $onRejected = null) }); } - public function otherwise(callable $onRejected) + public function otherwise(callable $onRejected): PromiseInterface { return $this; } - public function always(callable $onFulfilledOrRejected) + public function always(callable $onFulfilledOrRejected): PromiseInterface { - return $this->then(function ($value) use ($onFulfilledOrRejected) { + return $this->then(function ($value) use ($onFulfilledOrRejected): PromiseInterface { return resolve($onFulfilledOrRejected())->then(function () use ($value) { return $value; }); }); } - public function cancel() + public function cancel(): void { } } diff --git a/src/Internal/CancellationQueue.php b/src/Internal/CancellationQueue.php index af22c68e..52abf6e2 100644 --- a/src/Internal/CancellationQueue.php +++ b/src/Internal/CancellationQueue.php @@ -10,7 +10,7 @@ final class CancellationQueue private $started = false; private $queue = []; - public function __invoke() + public function __invoke(): void { if ($this->started) { return; @@ -20,7 +20,7 @@ public function __invoke() $this->drain(); } - public function enqueue($cancellable) + public function enqueue($cancellable): void { if (!\method_exists($cancellable, 'then') || !\method_exists($cancellable, 'cancel')) { return; @@ -33,7 +33,7 @@ public function enqueue($cancellable) } } - private function drain() + private function drain(): void { for ($i = \key($this->queue); isset($this->queue[$i]); $i++) { $cancellable = $this->queue[$i]; diff --git a/src/Internal/Queue.php b/src/Internal/Queue.php index 6b4bfe0b..19939881 100644 --- a/src/Internal/Queue.php +++ b/src/Internal/Queue.php @@ -9,14 +9,14 @@ final class Queue { private $queue = []; - public function enqueue(callable $task) + public function enqueue(callable $task): void { if (1 === \array_push($this->queue, $task)) { $this->drain(); } } - private function drain() + private function drain(): void { for ($i = \key($this->queue); isset($this->queue[$i]); $i++) { $task = $this->queue[$i]; diff --git a/src/Promise.php b/src/Promise.php index f25d3667..824a46cc 100644 --- a/src/Promise.php +++ b/src/Promise.php @@ -17,7 +17,7 @@ public function __construct(callable $resolver, callable $canceller = null) $this->call($resolver); } - public function then(callable $onFulfilled = null, callable $onRejected = null) + public function then(callable $onFulfilled = null, callable $onRejected = null): PromiseInterface { if (null !== $this->result) { return $this->result->then($onFulfilled, $onRejected); @@ -38,10 +38,11 @@ public function then(callable $onFulfilled = null, callable $onRejected = null) }); } - public function done(callable $onFulfilled = null, callable $onRejected = null) + public function done(callable $onFulfilled = null, callable $onRejected = null): void { if (null !== $this->result) { - return $this->result->done($onFulfilled, $onRejected); + $this->result->done($onFulfilled, $onRejected); + return; } $this->handlers[] = function (PromiseInterface $promise) use ($onFulfilled, $onRejected) { @@ -50,7 +51,7 @@ public function done(callable $onFulfilled = null, callable $onRejected = null) }; } - public function otherwise(callable $onRejected) + public function otherwise(callable $onRejected): PromiseInterface { return $this->then(null, function ($reason) use ($onRejected) { if (!_checkTypehint($onRejected, $reason)) { @@ -61,7 +62,7 @@ public function otherwise(callable $onRejected) }); } - public function always(callable $onFulfilledOrRejected) + public function always(callable $onFulfilledOrRejected): PromiseInterface { return $this->then(function ($value) use ($onFulfilledOrRejected) { return resolve($onFulfilledOrRejected())->then(function () use ($value) { @@ -74,7 +75,7 @@ public function always(callable $onFulfilledOrRejected) }); } - public function cancel() + public function cancel(): void { $canceller = $this->canceller; $this->canceller = null; @@ -109,7 +110,7 @@ public function cancel() } } - private function resolver(callable $onFulfilled = null, callable $onRejected = null) + private function resolver(callable $onFulfilled = null, callable $onRejected = null): callable { return function ($resolve, $reject) use ($onFulfilled, $onRejected) { $this->handlers[] = function (PromiseInterface $promise) use ($onFulfilled, $onRejected, $resolve, $reject) { @@ -120,7 +121,7 @@ private function resolver(callable $onFulfilled = null, callable $onRejected = n }; } - private function resolve($value = null) + private function resolve($value = null): void { if (null !== $this->result) { return; @@ -129,7 +130,7 @@ private function resolve($value = null) $this->settle(resolve($value)); } - private function reject(\Throwable $reason) + private function reject(\Throwable $reason): void { if (null !== $this->result) { return; @@ -138,7 +139,7 @@ private function reject(\Throwable $reason) $this->settle(reject($reason)); } - private function settle(PromiseInterface $result) + private function settle(PromiseInterface $result): void { $result = $this->unwrap($result); @@ -165,7 +166,7 @@ private function settle(PromiseInterface $result) } } - private function unwrap($promise) + private function unwrap($promise): PromiseInterface { while ($promise instanceof self && null !== $promise->result) { $promise = $promise->result; @@ -174,7 +175,7 @@ private function unwrap($promise) return $promise; } - private function call(callable $callback) + private function call(callable $callback): void { // Use reflection to inspect number of arguments expected by this callback. // We did some careful benchmarking here: Using reflection to avoid unneeded diff --git a/src/PromiseInterface.php b/src/PromiseInterface.php index 6612834a..3f854b94 100644 --- a/src/PromiseInterface.php +++ b/src/PromiseInterface.php @@ -32,7 +32,7 @@ interface PromiseInterface * @param callable|null $onRejected * @return PromiseInterface */ - public function then(callable $onFulfilled = null, callable $onRejected = null); + public function then(?callable $onFulfilled = null, ?callable $onRejected = null): PromiseInterface; /** * Consumes the promise's ultimate value if the promise fulfills, or handles the @@ -48,7 +48,7 @@ public function then(callable $onFulfilled = null, callable $onRejected = null); * @param callable|null $onRejected * @return void */ - public function done(callable $onFulfilled = null, callable $onRejected = null); + public function done(callable $onFulfilled = null, callable $onRejected = null): void; /** * Registers a rejection handler for promise. It is a shortcut for: @@ -63,7 +63,7 @@ public function done(callable $onFulfilled = null, callable $onRejected = null); * @param callable $onRejected * @return PromiseInterface */ - public function otherwise(callable $onRejected); + public function otherwise(callable $onRejected): PromiseInterface; /** * Allows you to execute "cleanup" type tasks in a promise chain. @@ -110,7 +110,7 @@ public function otherwise(callable $onRejected); * @param callable $onFulfilledOrRejected * @return PromiseInterface */ - public function always(callable $onFulfilledOrRejected); + public function always(callable $onFulfilledOrRejected): PromiseInterface; /** * The `cancel()` method notifies the creator of the promise that there is no @@ -121,5 +121,5 @@ public function always(callable $onFulfilledOrRejected); * * @return void */ - public function cancel(); + public function cancel(): void; } diff --git a/src/PromisorInterface.php b/src/PromisorInterface.php index bd644008..87e999c1 100644 --- a/src/PromisorInterface.php +++ b/src/PromisorInterface.php @@ -9,5 +9,5 @@ interface PromisorInterface * * @return PromiseInterface */ - public function promise(); + public function promise(): PromiseInterface; } diff --git a/src/RejectedPromise.php b/src/RejectedPromise.php index d256b98f..2da6d532 100644 --- a/src/RejectedPromise.php +++ b/src/RejectedPromise.php @@ -11,14 +11,14 @@ public function __construct(\Throwable $reason) $this->reason = $reason; } - public function then(callable $onFulfilled = null, callable $onRejected = null) + public function then(callable $onFulfilled = null, callable $onRejected = null): PromiseInterface { if (null === $onRejected) { return $this; } - return new Promise(function (callable $resolve, callable $reject) use ($onRejected) { - enqueue(function () use ($resolve, $reject, $onRejected) { + return new Promise(function (callable $resolve, callable $reject) use ($onRejected): void { + enqueue(function () use ($resolve, $reject, $onRejected): void { try { $resolve($onRejected($this->reason)); } catch (\Throwable $exception) { @@ -28,7 +28,7 @@ public function then(callable $onFulfilled = null, callable $onRejected = null) }); } - public function done(callable $onFulfilled = null, callable $onRejected = null) + public function done(callable $onFulfilled = null, callable $onRejected = null): void { enqueue(function () use ($onRejected) { if (null === $onRejected) { @@ -51,7 +51,7 @@ public function done(callable $onFulfilled = null, callable $onRejected = null) }); } - public function otherwise(callable $onRejected) + public function otherwise(callable $onRejected): PromiseInterface { if (!_checkTypehint($onRejected, $this->reason)) { return $this; @@ -60,16 +60,16 @@ public function otherwise(callable $onRejected) return $this->then(null, $onRejected); } - public function always(callable $onFulfilledOrRejected) + public function always(callable $onFulfilledOrRejected): PromiseInterface { - return $this->then(null, function (\Throwable $reason) use ($onFulfilledOrRejected) { - return resolve($onFulfilledOrRejected())->then(function () use ($reason) { + return $this->then(null, function (\Throwable $reason) use ($onFulfilledOrRejected): PromiseInterface { + return resolve($onFulfilledOrRejected())->then(function () use ($reason): PromiseInterface { return new RejectedPromise($reason); }); }); } - public function cancel() + public function cancel(): void { } } diff --git a/src/functions.php b/src/functions.php index 4f2dc54f..2439c77c 100644 --- a/src/functions.php +++ b/src/functions.php @@ -19,7 +19,7 @@ * @return PromiseInterface */ -function resolve($promiseOrValue = null) +function resolve($promiseOrValue = null): PromiseInterface { if ($promiseOrValue instanceof PromiseInterface) { return $promiseOrValue; @@ -32,7 +32,7 @@ function resolve($promiseOrValue = null) $canceller = [$promiseOrValue, 'cancel']; } - return new Promise(function ($resolve, $reject) use ($promiseOrValue) { + return new Promise(function ($resolve, $reject) use ($promiseOrValue): void { $promiseOrValue->then($resolve, $reject); }, $canceller); } @@ -56,7 +56,7 @@ function resolve($promiseOrValue = null) * @param \Throwable $reason * @return PromiseInterface */ -function reject(\Throwable $reason) +function reject(\Throwable $reason): PromiseInterface { return new RejectedPromise($reason); } @@ -70,7 +70,7 @@ function reject(\Throwable $reason) * @param array $promisesOrValues * @return PromiseInterface */ -function all(array $promisesOrValues) +function all(array $promisesOrValues): PromiseInterface { return map($promisesOrValues, function ($val) { return $val; @@ -87,15 +87,15 @@ function all(array $promisesOrValues) * @param array $promisesOrValues * @return PromiseInterface */ -function race(array $promisesOrValues) +function race(array $promisesOrValues): PromiseInterface { if (!$promisesOrValues) { - return new Promise(function () {}); + return new Promise(function (): void {}); } $cancellationQueue = new Internal\CancellationQueue(); - return new Promise(function ($resolve, $reject) use ($promisesOrValues, $cancellationQueue) { + return new Promise(function ($resolve, $reject) use ($promisesOrValues, $cancellationQueue): void { foreach ($promisesOrValues as $promiseOrValue) { $cancellationQueue->enqueue($promiseOrValue); @@ -119,7 +119,7 @@ function race(array $promisesOrValues) * @param array $promisesOrValues * @return PromiseInterface */ -function any(array $promisesOrValues) +function any(array $promisesOrValues): PromiseInterface { return some($promisesOrValues, 1) ->then(function ($val) { @@ -145,7 +145,7 @@ function any(array $promisesOrValues) * @param int $howMany * @return PromiseInterface */ -function some(array $promisesOrValues, $howMany) +function some(array $promisesOrValues, $howMany): PromiseInterface { if ($howMany < 1) { return resolve([]); @@ -169,14 +169,14 @@ function some(array $promisesOrValues, $howMany) $cancellationQueue = new Internal\CancellationQueue(); - return new Promise(function ($resolve, $reject) use ($len, $promisesOrValues, $howMany, $cancellationQueue) { + return new Promise(function ($resolve, $reject) use ($len, $promisesOrValues, $howMany, $cancellationQueue): void { $toResolve = $howMany; $toReject = ($len - $toResolve) + 1; $values = []; $reasons = []; foreach ($promisesOrValues as $i => $promiseOrValue) { - $fulfiller = function ($val) use ($i, &$values, &$toResolve, $toReject, $resolve) { + $fulfiller = function ($val) use ($i, &$values, &$toResolve, $toReject, $resolve): void { if ($toResolve < 1 || $toReject < 1) { return; } @@ -188,7 +188,7 @@ function some(array $promisesOrValues, $howMany) } }; - $rejecter = function (\Throwable $reason) use ($i, &$reasons, &$toReject, $toResolve, $reject) { + $rejecter = function (\Throwable $reason) use ($i, &$reasons, &$toReject, $toResolve, $reject): void { if ($toResolve < 1 || $toReject < 1) { return; } @@ -224,7 +224,7 @@ function some(array $promisesOrValues, $howMany) * @param callable $mapFunc * @return PromiseInterface */ -function map(array $promisesOrValues, callable $mapFunc) +function map(array $promisesOrValues, callable $mapFunc): PromiseInterface { if (!$promisesOrValues) { return resolve([]); @@ -232,7 +232,7 @@ function map(array $promisesOrValues, callable $mapFunc) $cancellationQueue = new Internal\CancellationQueue(); - return new Promise(function ($resolve, $reject) use ($promisesOrValues, $mapFunc, $cancellationQueue) { + return new Promise(function ($resolve, $reject) use ($promisesOrValues, $mapFunc, $cancellationQueue): void { $toResolve = \count($promisesOrValues); $values = []; @@ -243,7 +243,7 @@ function map(array $promisesOrValues, callable $mapFunc) resolve($promiseOrValue) ->then($mapFunc) ->done( - function ($mapped) use ($i, &$values, &$toResolve, $resolve) { + function ($mapped) use ($i, &$values, &$toResolve, $resolve): void { $values[$i] = $mapped; if (0 === --$toResolve) { @@ -267,15 +267,15 @@ function ($mapped) use ($i, &$values, &$toResolve, $resolve) { * @param mixed $initialValue * @return PromiseInterface */ -function reduce(array $promisesOrValues, callable $reduceFunc, $initialValue = null) +function reduce(array $promisesOrValues, callable $reduceFunc, $initialValue = null): PromiseInterface { $cancellationQueue = new Internal\CancellationQueue(); - return new Promise(function ($resolve, $reject) use ($promisesOrValues, $reduceFunc, $initialValue, $cancellationQueue) { + return new Promise(function ($resolve, $reject) use ($promisesOrValues, $reduceFunc, $initialValue, $cancellationQueue): void { $total = \count($promisesOrValues); $i = 0; - $wrappedReduceFunc = function ($current, $val) use ($reduceFunc, $cancellationQueue, $total, &$i) { + $wrappedReduceFunc = function ($current, $val) use ($reduceFunc, $cancellationQueue, $total, &$i): PromiseInterface { $cancellationQueue->enqueue($val); return $current @@ -297,7 +297,7 @@ function reduce(array $promisesOrValues, callable $reduceFunc, $initialValue = n /** * @internal */ -function enqueue(callable $task) +function enqueue(callable $task): void { static $queue; @@ -311,7 +311,7 @@ function enqueue(callable $task) /** * @internal */ -function fatalError($error) +function fatalError($error): void { try { \trigger_error($error, E_USER_ERROR); @@ -324,7 +324,7 @@ function fatalError($error) /** * @internal */ -function _checkTypehint(callable $callback, \Throwable $reason) +function _checkTypehint(callable $callback, \Throwable $reason): bool { if (\is_array($callback)) { $callbackReflection = new \ReflectionMethod($callback[0], $callback[1]);