Skip to content

Commit

Permalink
improve phpstan type
Browse files Browse the repository at this point in the history
  • Loading branch information
ShockedPlot7560 committed Jul 2, 2023
1 parent d2b1a30 commit 71040ef
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 27 deletions.
7 changes: 4 additions & 3 deletions src/Adapter/PocketminePromiseAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Plutonium\Promise\Adapter;

use Closure;
use Plutonium\Promise\PromiseInterface;
use pocketmine\promise\Promise;
use pocketmine\Server;
Expand All @@ -17,19 +18,19 @@ public function __construct(
) {
}

public function then(?callable $onFulfilled = null, ?callable $onRejected = null) : PromiseInterface {
public function then(?Closure $onFulfilled = null, ?Closure $onRejected = null) : PromiseInterface {
throw new \Exception("Not supported");
}

public function cancel() : void {
throw new \Exception("Not supported");
}

public function catch(callable $onRejected) : PromiseInterface {
public function catch(Closure $onRejected) : PromiseInterface {
throw new \Exception("Not supported");
}

public function finally(callable $onFulfilledOrRejected) : PromiseInterface {
public function finally(Closure $onFulfilledOrRejected) : PromiseInterface {
throw new \Exception("Not supported");
}

Expand Down
24 changes: 23 additions & 1 deletion src/Deferred.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,23 @@

namespace Plutonium\Promise;

use Closure;
use Throwable;

/**
* @template ResolveResult
* @template RejectResult of Throwable
*/
final class Deferred
{
private $promise;
/**
* @phpstan-var Closure(ResolveResult): void
*/
private $resolveCallback;
/**
* @phpstan-var Closure(RejectResult): void
*/
private $rejectCallback;

public function __construct(callable $canceller = null)
Expand All @@ -16,17 +29,26 @@ public function __construct(callable $canceller = null)
}, $canceller);
}

/**
* @phpstan-return PromiseInterface<ResolveResult, RejectResult>
*/
public function promise(): PromiseInterface
{
return $this->promise;
}

/**
* @phpstan-param ResolveResult $value
*/
public function resolve($value): void
{
($this->resolveCallback)($value);
}

public function reject(\Throwable $reason): void
/**
* @phpstan-param RejectResult $reason
*/
public function reject(Throwable $reason): void
{
($this->rejectCallback)($reason);
}
Expand Down
31 changes: 28 additions & 3 deletions src/Internal/FulfilledPromise.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,25 @@

use Plutonium\Promise\PromiseInterface;
use function Plutonium\Promise\resolve;
use Closure;

/**
* @internal
*
* @template Value
* @template PromiseError
* @template-implements PromiseInterface<Value, PromiseError>
*/
final class FulfilledPromise implements PromiseInterface
{
/**
* @phpstan-var Value
*/
private $value;

/**
* @phpstan-param Value $value
*/
public function __construct($value = null)
{
if ($value instanceof PromiseInterface) {
Expand All @@ -21,7 +32,15 @@ public function __construct($value = null)
$this->value = $value;
}

public function then(callable $onFulfilled = null, callable $onRejected = null): PromiseInterface
/**
* @template ClosureReturn
*
* @phpstan-param null|Closure(Value): ClosureReturn $onFulfilled
* @phpstan-param null|Closure(PromiseError): mixed $onRejected
*
* @phpstan-return PromiseInterface<Value, PromiseError>
*/
public function then(Closure $onFulfilled = null, Closure $onRejected = null): PromiseInterface
{
if (null === $onFulfilled) {
return $this;
Expand All @@ -34,12 +53,18 @@ public function then(callable $onFulfilled = null, callable $onRejected = null):
}
}

public function catch(callable $onRejected): PromiseInterface
/**
* @phpstan-param Closure(PromiseError): mixed $onRejected
*/
public function catch(Closure $onRejected): PromiseInterface
{
return $this;
}

public function finally(callable $onFulfilledOrRejected): PromiseInterface
/**
* @phpstan-param Closure(): mixed $onFulfilledOrRejected
*/
public function finally(Closure $onFulfilledOrRejected): PromiseInterface
{
return $this->then(function ($value) use ($onFulfilledOrRejected): PromiseInterface {
return resolve($onFulfilledOrRejected())->then(function () use ($value) {
Expand Down
32 changes: 26 additions & 6 deletions src/Internal/RejectedPromise.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,53 @@

namespace Plutonium\Promise\Internal;

use Closure;
use Plutonium\Promise\PromiseInterface;
use Throwable;
use function Plutonium\Promise\_checkTypehint;
use function Plutonium\Promise\resolve;

/**
* @internal
*
* @template Value of Throwable
*/
final class RejectedPromise implements PromiseInterface
{
/**
* @var Value $reason
*/
private $reason;

public function __construct(\Throwable $reason)
/**
* @phpstan-param Value $reason
*/
public function __construct(Throwable $reason)
{
$this->reason = $reason;
}

public function then(callable $onFulfilled = null, callable $onRejected = null): PromiseInterface
/**
* @phpstan-param null|Closure(): mixed $onFulfilled
* @phpstan-param null|Closure(Value): mixed $onRejected
*/
public function then(Closure $onFulfilled = null, Closure $onRejected = null): PromiseInterface
{
if (null === $onRejected) {
return $this;
}

try {
return resolve($onRejected($this->reason));
} catch (\Throwable $exception) {
} catch (Throwable $exception) {
return new RejectedPromise($exception);
}
}

public function catch(callable $onRejected): PromiseInterface
/**
* @phpstan-param Closure(Value): mixed $onRejected
*/
public function catch(Closure $onRejected): PromiseInterface
{
if (!_checkTypehint($onRejected, $this->reason)) {
return $this;
Expand All @@ -40,9 +57,12 @@ public function catch(callable $onRejected): PromiseInterface
return $this->then(null, $onRejected);
}

public function finally(callable $onFulfilledOrRejected): PromiseInterface
/**
* @phpstan-param Closure(): mixed $onFulfilledOrRejected
*/
public function finally(Closure $onFulfilledOrRejected): PromiseInterface
{
return $this->then(null, function (\Throwable $reason) use ($onFulfilledOrRejected): PromiseInterface {
return $this->then(null, function (Throwable $reason) use ($onFulfilledOrRejected): PromiseInterface {
return resolve($onFulfilledOrRejected())->then(function () use ($reason): PromiseInterface {
return new RejectedPromise($reason);
});
Expand Down
7 changes: 4 additions & 3 deletions src/Promise.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Plutonium\Promise\Internal\RejectedPromise;
use Plutonium\Promise\Utils\PromiseWaiter;
use Closure;

final class Promise implements PromiseInterface
{
Expand All @@ -26,7 +27,7 @@ public function __construct(callable $resolver, callable $canceller = null)
$this->call($cb);
}

public function then(callable $onFulfilled = null, callable $onRejected = null): PromiseInterface
public function then(Closure $onFulfilled = null, Closure $onRejected = null): PromiseInterface
{
if (null !== $this->result) {
return $this->result->then($onFulfilled, $onRejected);
Expand Down Expand Up @@ -58,7 +59,7 @@ static function () use (&$parent) {
);
}

public function catch(callable $onRejected): PromiseInterface
public function catch(Closure $onRejected): PromiseInterface
{
return $this->then(null, static function ($reason) use ($onRejected) {
if (!_checkTypehint($onRejected, $reason)) {
Expand All @@ -69,7 +70,7 @@ public function catch(callable $onRejected): PromiseInterface
});
}

public function finally(callable $onFulfilledOrRejected): PromiseInterface
public function finally(Closure $onFulfilledOrRejected): PromiseInterface
{
return $this->then(static function ($value) use ($onFulfilledOrRejected) {
return resolve($onFulfilledOrRejected())->then(function () use ($value) {
Expand Down
34 changes: 23 additions & 11 deletions src/PromiseInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

namespace Plutonium\Promise;

use Closure;
use Plutonium\Promise\Exception\TimeoutException;

/**
* @template PromiseResult
* @template PromiseError
*/
interface PromiseInterface
{
/**
Expand All @@ -28,11 +35,14 @@ interface PromiseInterface
* 2. `$onFulfilled` and `$onRejected` will never be called more
* than once.
*
* @param callable|null $onFulfilled
* @param callable|null $onRejected
* @return PromiseInterface
* @template ClosureResult
*
* @phpstan-param null|Closure(PromiseResult): ClosureResult $onFulfilled
* @phpstan-param null|Closure(PromiseError): mixed $onRejected
*
* @phpstan-return PromiseInterface<ClosureResult|PromiseResult, PromiseError>
*/
public function then(?callable $onFulfilled = null, ?callable $onRejected = null): PromiseInterface;
public function then(?Closure $onFulfilled = null, ?Closure $onRejected = null): PromiseInterface;

/**
* Registers a rejection handler for promise. It is a shortcut for:
Expand All @@ -43,11 +53,11 @@ public function then(?callable $onFulfilled = null, ?callable $onRejected = null
*
* Additionally, you can type hint the `$reason` argument of `$onRejected` to catch
* only specific errors.
*
* @param callable $onRejected
* @return PromiseInterface
*
* @phpstan-param Closure(PromiseError) : mixed $onRejected
* @phpstan-return PromiseInterface<PromiseResult, PromiseError>
*/
public function catch(callable $onRejected): PromiseInterface;
public function catch(Closure $onRejected): PromiseInterface;

/**
* Allows you to execute "cleanup" type tasks in a promise chain.
Expand Down Expand Up @@ -91,10 +101,10 @@ public function catch(callable $onRejected): PromiseInterface;
* ->finally('cleanup');
* ```
*
* @param callable $onFulfilledOrRejected
* @return PromiseInterface
* @phpstan-param Closure() : mixed $onFulfilledOrRejected
* @phpstan-return PromiseInterface<PromiseResult, PromiseError>
*/
public function finally(callable $onFulfilledOrRejected): PromiseInterface;
public function finally(Closure $onFulfilledOrRejected): PromiseInterface;

/**
* The `cancel()` method notifies the creator of the promise that there is no
Expand Down Expand Up @@ -144,6 +154,8 @@ public function always(callable $onFulfilledOrRejected): PromiseInterface;
/**
* Waits for the promise to be fulfilled or rejected.
* Use this method only if you know what you are doing, it can cause deadlocks.
*
* @throws TimeoutException
*/
public function wait() : void;

Expand Down

0 comments on commit 71040ef

Please sign in to comment.