Improve functions signature using union types and mixed (#191)

This commit is contained in:
Saif Eddin Gmati 2021-05-15 19:47:10 +01:00 committed by GitHub
parent cdadc62674
commit 62632502a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
73 changed files with 267 additions and 564 deletions

View File

@ -22,8 +22,8 @@ coding-standard-check:
php tools/php-codesniffer/vendor/bin/phpcs --basepath=. --standard=tools/php-codesniffer/.phpcs.xml
static-analysis:
php tools/psalm/vendor/bin/psalm -c tools/psalm/psalm.xml
php tools/psalm/vendor/bin/psalm -c tools/psalm/psalm.xml tests/static-analysis
php tools/psalm/vendor/bin/psalm -c tools/psalm/psalm.xml --show-info=true --no-cache
php tools/psalm/vendor/bin/psalm -c tools/psalm/psalm.xml tests/static-analysis --no-cache
type-coverage:
php tools/psalm/vendor/bin/psalm -c tools/psalm/psalm.xml --shepherd --stats

View File

@ -18,21 +18,21 @@
- [float](./../../src/Psl/Type/float.php#L10)
- [int](./../../src/Psl/Type/int.php#L10)
- [intersection](./../../src/Psl/Type/intersection.php#L22)
- [is_array](./../../src/Psl/Type/is_array.php#L20) ( deprecated )
- [is_arraykey](./../../src/Psl/Type/is_arraykey.php#L18) ( deprecated )
- [is_bool](./../../src/Psl/Type/is_bool.php#L20) ( deprecated )
- [is_callable](./../../src/Psl/Type/is_callable.php#L18)
- [is_float](./../../src/Psl/Type/is_float.php#L20) ( deprecated )
- [is_array](./../../src/Psl/Type/is_array.php#L18) ( deprecated )
- [is_arraykey](./../../src/Psl/Type/is_arraykey.php#L16) ( deprecated )
- [is_bool](./../../src/Psl/Type/is_bool.php#L18) ( deprecated )
- [is_callable](./../../src/Psl/Type/is_callable.php#L16)
- [is_float](./../../src/Psl/Type/is_float.php#L18) ( deprecated )
- [is_instanceof](./../../src/Psl/Type/is_instanceof.php#L22) ( deprecated )
- [is_int](./../../src/Psl/Type/is_int.php#L20) ( deprecated )
- [is_iterable](./../../src/Psl/Type/is_iterable.php#L20) ( deprecated )
- [is_int](./../../src/Psl/Type/is_int.php#L18) ( deprecated )
- [is_iterable](./../../src/Psl/Type/is_iterable.php#L18) ( deprecated )
- [is_nan](./../../src/Psl/Type/is_nan.php#L14)
- [is_null](./../../src/Psl/Type/is_null.php#L18) ( deprecated )
- [is_numeric](./../../src/Psl/Type/is_numeric.php#L20) ( deprecated )
- [is_object](./../../src/Psl/Type/is_object.php#L20) ( deprecated )
- [is_resource](./../../src/Psl/Type/is_resource.php#L22) ( deprecated )
- [is_scalar](./../../src/Psl/Type/is_scalar.php#L20) ( deprecated )
- [is_string](./../../src/Psl/Type/is_string.php#L20) ( deprecated )
- [is_null](./../../src/Psl/Type/is_null.php#L16) ( deprecated )
- [is_numeric](./../../src/Psl/Type/is_numeric.php#L18) ( deprecated )
- [is_object](./../../src/Psl/Type/is_object.php#L18) ( deprecated )
- [is_resource](./../../src/Psl/Type/is_resource.php#L20) ( deprecated )
- [is_scalar](./../../src/Psl/Type/is_scalar.php#L18) ( deprecated )
- [is_string](./../../src/Psl/Type/is_string.php#L18) ( deprecated )
- [iterable](./../../src/Psl/Type/iterable.php#L20)
- [literal_scalar](./../../src/Psl/Type/literal_scalar.php#L18)
- [map](./../../src/Psl/Type/map.php#L21)

View File

@ -22,7 +22,7 @@ use function array_fill;
* @deprecated use `Vec\fill` instead.
* @see Vec\fill()
*/
function fill($value, int $start_index, int $num): array
function fill(mixed $value, int $start_index, int $num): array
{
return array_fill($start_index, $num, $value);
}

View File

@ -124,7 +124,7 @@ interface AccessibleCollectionInterface extends CollectionInterface, IndexAccess
*
* @psalm-mutation-free
*/
public function first();
public function first(): mixed;
/**
* Returns the first key in the current `AccessibleCollectionInterface`.
@ -134,7 +134,7 @@ interface AccessibleCollectionInterface extends CollectionInterface, IndexAccess
*
* @psalm-mutation-free
*/
public function firstKey();
public function firstKey(): int|string|null;
/**
* Returns the last value in the current `AccessibleCollectionInterface`.
@ -144,7 +144,7 @@ interface AccessibleCollectionInterface extends CollectionInterface, IndexAccess
*
* @psalm-mutation-free
*/
public function last();
public function last(): mixed;
/**
* Returns the last key in the current `AccessibleCollectionInterface`.
@ -154,7 +154,7 @@ interface AccessibleCollectionInterface extends CollectionInterface, IndexAccess
*
* @psalm-mutation-free
*/
public function lastKey();
public function lastKey(): int|string|null;
/**
* Returns the index of the first element that matches the search value.
@ -168,7 +168,7 @@ interface AccessibleCollectionInterface extends CollectionInterface, IndexAccess
*
* @psalm-mutation-free
*/
public function linearSearch($search_value);
public function linearSearch(mixed $search_value): int|string|null;
/**
* Returns a `AccessibleCollectionInterface` where each element is a `array{0: Tv, 1: Tu}` that combines the

View File

@ -21,7 +21,7 @@ interface IndexAccessInterface
*
* @psalm-mutation-free
*/
public function at($k);
public function at(string|int $k): mixed;
/**
* Determines if the specified key is in the current collection.
@ -30,7 +30,7 @@ interface IndexAccessInterface
*
* @psalm-mutation-free
*/
public function contains($k): bool;
public function contains(int|string $k): bool;
/**
* Returns the value at the specified key in the current collection.
@ -41,5 +41,5 @@ interface IndexAccessInterface
*
* @psalm-mutation-free
*/
public function get($k);
public function get(string|int $k): mixed;
}

View File

@ -60,7 +60,7 @@ final class Map implements MapInterface
*
* @psalm-mutation-free
*/
public function first()
public function first(): mixed
{
/** @psalm-suppress ImpureFunctionCall - conditionally pure */
return Iter\first($this->elements);
@ -74,7 +74,7 @@ final class Map implements MapInterface
*
* @psalm-mutation-free
*/
public function firstKey()
public function firstKey(): int|string|null
{
/** @psalm-suppress ImpureFunctionCall - conditionally pure */
return Iter\first_key($this->elements);
@ -88,7 +88,7 @@ final class Map implements MapInterface
*
* @psalm-mutation-free
*/
public function last()
public function last(): mixed
{
/** @psalm-suppress ImpureFunctionCall - conditionally pure */
return Iter\last($this->elements);
@ -102,7 +102,7 @@ final class Map implements MapInterface
*
* @psalm-mutation-free
*/
public function lastKey()
public function lastKey(): int|string|null
{
/** @psalm-suppress ImpureFunctionCall - conditionally pure */
return Iter\last_key($this->elements);
@ -120,7 +120,7 @@ final class Map implements MapInterface
*
* @psalm-mutation-free
*/
public function linearSearch($search_value)
public function linearSearch(mixed $search_value): int|string|null
{
foreach ($this->elements as $key => $element) {
if ($search_value === $element) {
@ -197,7 +197,7 @@ final class Map implements MapInterface
*
* @psalm-mutation-free
*/
public function at($k)
public function at(string|int $k): mixed
{
Psl\invariant($this->contains($k), 'Key (%s) is out-of-bounds.', $k);
@ -211,7 +211,7 @@ final class Map implements MapInterface
*
* @psalm-mutation-free
*/
public function contains($k): bool
public function contains(int|string $k): bool
{
/** @psalm-suppress ImpureFunctionCall - conditionally pure */
return Iter\contains_key($this->elements, $k);
@ -226,7 +226,7 @@ final class Map implements MapInterface
*
* @psalm-mutation-free
*/
public function get($k)
public function get(string|int $k): mixed
{
return $this->elements[$k] ?? null;
}

View File

@ -117,7 +117,7 @@ interface MapInterface extends AccessibleCollectionInterface
*
* @psalm-mutation-free
*/
public function first();
public function first(): mixed;
/**
* Returns the first key in the current `MapInterface`.
@ -127,7 +127,7 @@ interface MapInterface extends AccessibleCollectionInterface
*
* @psalm-mutation-free
*/
public function firstKey();
public function firstKey(): int|string|null;
/**
* Returns the last value in the current `MapInterface`.
@ -137,7 +137,7 @@ interface MapInterface extends AccessibleCollectionInterface
*
* @psalm-mutation-free
*/
public function last();
public function last(): mixed;
/**
* Returns the last key in the current `MapInterface`.
@ -147,7 +147,7 @@ interface MapInterface extends AccessibleCollectionInterface
*
* @psalm-mutation-free
*/
public function lastKey();
public function lastKey(): int|string|null;
/**
* Returns the index of the first element that matches the search value.
@ -161,7 +161,7 @@ interface MapInterface extends AccessibleCollectionInterface
*
* @psalm-mutation-free
*/
public function linearSearch($search_value);
public function linearSearch(mixed $search_value): int|string|null;
/**
* Returns a `MapInterface` where each element is a `array{0: Tv, 1: Tu}` that combines the

View File

@ -139,7 +139,7 @@ interface MutableAccessibleCollectionInterface extends
*
* @return MutableAccessibleCollectionInterface<Tk, Tv> Returns itself.
*/
public function set($k, $v): MutableAccessibleCollectionInterface;
public function set(int|string $k, mixed $v): MutableAccessibleCollectionInterface;
/**
* For every element in the provided `iterable`, stores a value into the
@ -172,7 +172,7 @@ interface MutableAccessibleCollectionInterface extends
*
* @return MutableAccessibleCollectionInterface<Tk, Tv> Returns itself.
*/
public function remove($k): MutableAccessibleCollectionInterface;
public function remove(int|string $k): MutableAccessibleCollectionInterface;
/**
* Removes all items from the collection.

View File

@ -27,7 +27,7 @@ interface MutableIndexAccessInterface extends IndexAccessInterface
*
* @return MutableIndexAccessInterface<Tk, Tv> Returns itself
*/
public function set($k, $v): MutableIndexAccessInterface;
public function set(int|string $k, mixed $v): MutableIndexAccessInterface;
/**
* For every element in the provided `iterable`, stores a value into the
@ -57,5 +57,5 @@ interface MutableIndexAccessInterface extends IndexAccessInterface
*
* @return MutableIndexAccessInterface<Tk, Tv> Returns itself
*/
public function remove($k): MutableIndexAccessInterface;
public function remove(int|string $k): MutableIndexAccessInterface;
}

View File

@ -56,7 +56,7 @@ final class MutableMap implements MutableMapInterface
*
* @psalm-mutation-free
*/
public function first()
public function first(): mixed
{
/** @psalm-suppress ImpureFunctionCall - conditionally pure */
return Iter\first($this->elements);
@ -70,7 +70,7 @@ final class MutableMap implements MutableMapInterface
*
* @psalm-mutation-free
*/
public function firstKey()
public function firstKey(): int|string|null
{
/** @psalm-suppress ImpureFunctionCall - conditionally pure */
return Iter\first_key($this->elements);
@ -84,7 +84,7 @@ final class MutableMap implements MutableMapInterface
*
* @psalm-mutation-free
*/
public function last()
public function last(): mixed
{
/** @psalm-suppress ImpureFunctionCall - conditionally pure */
return Iter\last($this->elements);
@ -98,7 +98,7 @@ final class MutableMap implements MutableMapInterface
*
* @psalm-mutation-free
*/
public function lastKey()
public function lastKey(): int|string|null
{
/** @psalm-suppress ImpureFunctionCall - conditionally pure */
return Iter\last_key($this->elements);
@ -116,7 +116,7 @@ final class MutableMap implements MutableMapInterface
*
* @psalm-mutation-free
*/
public function linearSearch($search_value)
public function linearSearch(mixed $search_value): int|string|null
{
foreach ($this->elements as $key => $element) {
if ($search_value === $element) {
@ -193,7 +193,7 @@ final class MutableMap implements MutableMapInterface
*
* @psalm-mutation-free
*/
public function at($k)
public function at(string|int $k): mixed
{
Psl\invariant($this->contains($k), 'Key (%s) is out-of-bounds.', $k);
@ -207,7 +207,7 @@ final class MutableMap implements MutableMapInterface
*
* @psalm-mutation-free
*/
public function contains($k): bool
public function contains(int|string $k): bool
{
/** @psalm-suppress ImpureFunctionCall - conditionally pure */
return Iter\contains_key($this->elements, $k);
@ -222,7 +222,7 @@ final class MutableMap implements MutableMapInterface
*
* @psalm-mutation-free
*/
public function get($k)
public function get(string|int $k): mixed
{
return $this->elements[$k] ?? null;
}
@ -522,7 +522,7 @@ final class MutableMap implements MutableMapInterface
*
* @return MutableMap<Tk, Tv> Returns itself
*/
public function set($k, $v): MutableMap
public function set(int|string $k, mixed $v): MutableMap
{
Psl\invariant($this->contains($k), 'Key (%s) is out-of-bounds.', $k);
@ -563,7 +563,7 @@ final class MutableMap implements MutableMapInterface
*
* @return MutableMap<Tk, Tv> Returns itself
*/
public function add($k, $v): MutableMap
public function add(int|string $k, mixed $v): MutableMap
{
$this->elements[$k] = $v;
@ -600,7 +600,7 @@ final class MutableMap implements MutableMapInterface
*
* @return MutableMap<Tk, Tv> Returns itself.
*/
public function remove($k): MutableMap
public function remove(int|string $k): MutableMap
{
if ($this->contains($k)) {
unset($this->elements[$k]);

View File

@ -118,7 +118,7 @@ interface MutableMapInterface extends MapInterface, MutableAccessibleCollectionI
*
* @psalm-mutation-free
*/
public function first();
public function first(): mixed;
/**
* Returns the first key in the current `MutableMapInterface`.
@ -128,7 +128,7 @@ interface MutableMapInterface extends MapInterface, MutableAccessibleCollectionI
*
* @psalm-mutation-free
*/
public function firstKey();
public function firstKey(): int|string|null;
/**
* Returns the last value in the current `MutableMapInterface`.
@ -138,7 +138,7 @@ interface MutableMapInterface extends MapInterface, MutableAccessibleCollectionI
*
* @psalm-mutation-free
*/
public function last();
public function last(): mixed;
/**
* Returns the last key in the current `MutableMapInterface`.
@ -148,7 +148,7 @@ interface MutableMapInterface extends MapInterface, MutableAccessibleCollectionI
*
* @psalm-mutation-free
*/
public function lastKey();
public function lastKey(): int|string|null;
/**
* Returns the index of the first element that matches the search value.
@ -162,7 +162,7 @@ interface MutableMapInterface extends MapInterface, MutableAccessibleCollectionI
*
* @psalm-mutation-free
*/
public function linearSearch($search_value);
public function linearSearch(mixed $search_value): int|string|null;
/**
* Returns a `MutableMapInterface` where each element is a `array{0: Tv, 1: Tu}` that combines the
@ -275,7 +275,7 @@ interface MutableMapInterface extends MapInterface, MutableAccessibleCollectionI
* @psalm-mutation-free
*/
public function slice(int $start, int $length): MutableMapInterface;
/**
* Stores a value into the current collection with the specified key,
* overwriting the previous value associated with the key.
@ -291,7 +291,7 @@ interface MutableMapInterface extends MapInterface, MutableAccessibleCollectionI
*
* @return MutableMapInterface<Tk, Tv> Returns itself.
*/
public function set($k, $v): MutableMapInterface;
public function set(int|string $k, mixed $v): MutableMapInterface;
/**
* For every element in the provided `iterable`, stores a value into the
@ -318,7 +318,7 @@ interface MutableMapInterface extends MapInterface, MutableAccessibleCollectionI
*
* @return MutableMapInterface<Tk, Tv> Returns itself.
*/
public function add($k, $v): MutableMapInterface;
public function add(int|string $k, mixed $v): MutableMapInterface;
/**
* For every element in the provided iterable, add the value into the current collection.
@ -343,7 +343,7 @@ interface MutableMapInterface extends MapInterface, MutableAccessibleCollectionI
*
* @return MutableMapInterface<Tk, Tv> Returns itself.
*/
public function remove($k): MutableMapInterface;
public function remove(int|string $k): MutableMapInterface;
/**
* Removes all items from the collection.

View File

@ -58,7 +58,7 @@ final class MutableVector implements MutableVectorInterface
*
* @psalm-mutation-free
*/
public function first()
public function first(): mixed
{
/** @psalm-suppress ImpureFunctionCall - conditionally pure */
return Iter\first($this->elements);
@ -72,7 +72,7 @@ final class MutableVector implements MutableVectorInterface
*
* @psalm-mutation-free
*/
public function last()
public function last(): mixed
{
/** @psalm-suppress ImpureFunctionCall - conditionally pure */
return Iter\last($this->elements);
@ -146,7 +146,7 @@ final class MutableVector implements MutableVectorInterface
*
* @psalm-mutation-free
*/
public function at($k)
public function at(string|int $k): mixed
{
Psl\invariant($this->contains($k), 'Key (%s) is out-of-bounds.', $k);
@ -160,7 +160,7 @@ final class MutableVector implements MutableVectorInterface
*
* @psalm-mutation-free
*/
public function contains($k): bool
public function contains(int|string $k): bool
{
/** @psalm-suppress ImpureFunctionCall - conditionally pure */
return Iter\contains_key($this->elements, $k);
@ -175,7 +175,7 @@ final class MutableVector implements MutableVectorInterface
*
* @psalm-mutation-free
*/
public function get($k)
public function get(string|int $k): mixed
{
return $this->elements[$k] ?? null;
}
@ -220,7 +220,7 @@ final class MutableVector implements MutableVectorInterface
*
* @psalm-mutation-free
*/
public function linearSearch($search_value): ?int
public function linearSearch(mixed $search_value): ?int
{
foreach ($this->elements as $key => $element) {
if ($search_value === $element) {
@ -230,7 +230,7 @@ final class MutableVector implements MutableVectorInterface
return null;
}
/**
* Stores a value into the current vector with the specified key,
* overwriting the previous value associated with the key.
@ -248,7 +248,7 @@ final class MutableVector implements MutableVectorInterface
*
* @return MutableVector<T> returns itself
*/
public function set($k, $v): MutableVector
public function set(int|string $k, mixed $v): MutableVector
{
Psl\invariant($this->contains($k), 'Key (%s) is out-of-bounds.', $k);
@ -298,7 +298,7 @@ final class MutableVector implements MutableVectorInterface
*
* @return MutableVector<T> returns itself.
*/
public function remove($k): MutableVector
public function remove(int|string $k): MutableVector
{
if ($this->contains($k)) {
unset($this->elements[$k]);
@ -327,7 +327,7 @@ final class MutableVector implements MutableVectorInterface
*
* @return MutableVector<T> Returns itself.
*/
public function add($v): MutableVector
public function add(mixed $v): MutableVector
{
$this->elements[] = $v;

View File

@ -128,7 +128,7 @@ interface MutableVectorInterface extends MutableAccessibleCollectionInterface, V
*
* @psalm-mutation-free
*/
public function first();
public function first(): mixed;
/**
* Returns the first key in the current `MutableVectorInterface`.
@ -148,7 +148,7 @@ interface MutableVectorInterface extends MutableAccessibleCollectionInterface, V
*
* @psalm-mutation-free
*/
public function last();
public function last(): mixed;
/**
* Returns the last key in the current `MutableVectorInterface`.
@ -172,7 +172,7 @@ interface MutableVectorInterface extends MutableAccessibleCollectionInterface, V
*
* @psalm-mutation-free
*/
public function linearSearch($search_value): ?int;
public function linearSearch(mixed $search_value): ?int;
/**
* Returns a `MutableVectorInterface` where each element is a `array{0: Tv, 1: Tu}` that combines the
@ -304,7 +304,7 @@ interface MutableVectorInterface extends MutableAccessibleCollectionInterface, V
*
* @return MutableVectorInterface<T> Returns itself.
*/
public function set($k, $v): MutableVectorInterface;
public function set(int|string $k, mixed $v): MutableVectorInterface;
/**
* For every element in the provided `iterable`, stores a value into the
@ -342,7 +342,7 @@ interface MutableVectorInterface extends MutableAccessibleCollectionInterface, V
*
* @return MutableVectorInterface<T> Returns itself.
*/
public function remove($k): MutableVectorInterface;
public function remove(int|string $k): MutableVectorInterface;
/**
* Removes all items from the vector.
@ -358,7 +358,7 @@ interface MutableVectorInterface extends MutableAccessibleCollectionInterface, V
*
* @return MutableVectorInterface<T> Returns itself.
*/
public function add($v): MutableVectorInterface;
public function add(mixed $v): MutableVectorInterface;
/**
* For every element in the provided iterable, add the value into the current vector.

View File

@ -60,7 +60,7 @@ final class Vector implements VectorInterface
*
* @psalm-mutation-free
*/
public function first()
public function first(): mixed
{
/** @psalm-suppress ImpureFunctionCall - conditionally pure */
return Iter\first($this->elements);
@ -74,7 +74,7 @@ final class Vector implements VectorInterface
*
* @psalm-mutation-free
*/
public function last()
public function last(): mixed
{
/** @psalm-suppress ImpureFunctionCall - conditionally pure */
return Iter\last($this->elements);
@ -148,7 +148,7 @@ final class Vector implements VectorInterface
*
* @psalm-mutation-free
*/
public function at($k)
public function at(string|int $k): mixed
{
Psl\invariant($this->contains($k), 'Key (%s) is out-of-bounds.', $k);
@ -162,7 +162,7 @@ final class Vector implements VectorInterface
*
* @psalm-mutation-free
*/
public function contains($k): bool
public function contains(int|string $k): bool
{
/** @psalm-suppress ImpureFunctionCall - conditionally pure */
return Iter\contains_key($this->elements, $k);
@ -177,7 +177,7 @@ final class Vector implements VectorInterface
*
* @psalm-mutation-free
*/
public function get($k)
public function get(string|int $k): mixed
{
return $this->elements[$k] ?? null;
}
@ -222,7 +222,7 @@ final class Vector implements VectorInterface
*
* @psalm-mutation-free
*/
public function linearSearch($search_value): ?int
public function linearSearch(mixed $search_value): ?int
{
foreach ($this->elements as $key => $element) {
if ($search_value === $element) {

View File

@ -20,7 +20,7 @@ interface VectorInterface extends AccessibleCollectionInterface
*
* @psalm-mutation-free
*/
public function at($k);
public function at(string|int $k): mixed;
/**
* Determines if the specified key is in the current vector.
@ -29,7 +29,7 @@ interface VectorInterface extends AccessibleCollectionInterface
*
* @psalm-mutation-free
*/
public function contains($k): bool;
public function contains(int|string $k): bool;
/**
* Returns the value at the specified key in the current vector.
@ -40,7 +40,7 @@ interface VectorInterface extends AccessibleCollectionInterface
*
* @psalm-mutation-free
*/
public function get($k);
public function get(string|int $k): mixed;
/**
* Get an array copy of the current vector.
@ -156,7 +156,7 @@ interface VectorInterface extends AccessibleCollectionInterface
*
* @psalm-mutation-free
*/
public function first();
public function first(): mixed;
/**
* Returns the first key in the current `VectorInterface`.
@ -176,7 +176,7 @@ interface VectorInterface extends AccessibleCollectionInterface
*
* @psalm-mutation-free
*/
public function last();
public function last(): mixed;
/**
* Returns the last key in the current `VectorInterface`.
@ -200,7 +200,7 @@ interface VectorInterface extends AccessibleCollectionInterface
*
* @psalm-mutation-free
*/
public function linearSearch($search_value): ?int;
public function linearSearch(mixed $search_value): ?int;
/**
* Returns a `VectorInterface` where each element is a `array{0: Tv, 1: Tu}` that combines the

View File

@ -27,7 +27,7 @@ final class PriorityQueue implements PriorityQueueInterface
*
* @param T $node
*/
public function enqueue($node, int $priority = 0): void
public function enqueue(mixed $node, int $priority = 0): void
{
$nodes = $this->queue[$priority] ?? [];
$nodes[] = $node;
@ -41,7 +41,7 @@ final class PriorityQueue implements PriorityQueueInterface
*
* @return null|T
*/
public function peek()
public function peek(): mixed
{
if (0 === $this->count()) {
return null;
@ -65,7 +65,7 @@ final class PriorityQueue implements PriorityQueueInterface
*
* @return null|T
*/
public function pull()
public function pull(): mixed
{
if (0 === $this->count()) {
return null;
@ -82,7 +82,7 @@ final class PriorityQueue implements PriorityQueueInterface
*
* @return T
*/
public function dequeue()
public function dequeue(): mixed
{
Psl\invariant(0 !== $this->count(), 'Cannot dequeue a node from an empty Queue.');

View File

@ -16,5 +16,5 @@ interface PriorityQueueInterface extends QueueInterface
*
* @param T $node
*/
public function enqueue($node, int $priority = 0): void;
public function enqueue(mixed $node, int $priority = 0): void;
}

View File

@ -28,7 +28,7 @@ final class Queue implements QueueInterface
*
* @param T $node
*/
public function enqueue($node): void
public function enqueue(mixed $node): void
{
$this->queue[] = $node;
}
@ -39,7 +39,7 @@ final class Queue implements QueueInterface
*
* @return null|T
*/
public function peek()
public function peek(): mixed
{
return Iter\first($this->queue);
}
@ -50,7 +50,7 @@ final class Queue implements QueueInterface
*
* @return null|T
*/
public function pull()
public function pull(): mixed
{
if (0 === $this->count()) {
return null;
@ -67,7 +67,7 @@ final class Queue implements QueueInterface
*
* @return T
*/
public function dequeue()
public function dequeue(): mixed
{
Psl\invariant(0 !== $this->count(), 'Cannot dequeue a node from an empty Queue.');

View File

@ -21,7 +21,7 @@ interface QueueInterface extends Countable
*
* @param T $node
*/
public function enqueue($node): void;
public function enqueue(mixed $node): void;
/**
* Retrieves, but does not remove, the node at the head of this queue,
@ -29,7 +29,7 @@ interface QueueInterface extends Countable
*
* @return null|T
*/
public function peek();
public function peek(): mixed;
/**
* Retrieves and removes the node at the head of this queue,
@ -37,7 +37,7 @@ interface QueueInterface extends Countable
*
* @return null|T
*/
public function pull();
public function pull(): mixed;
/**
* Retrieves and removes the node at the head of this queue.
@ -46,7 +46,7 @@ interface QueueInterface extends Countable
*
* @return T
*/
public function dequeue();
public function dequeue(): mixed;
/**
* Count the nodes in the queue.

View File

@ -28,7 +28,7 @@ final class Stack implements StackInterface
*
* @param T $item
*/
public function push($item): void
public function push(mixed $item): void
{
$this->items[] = $item;
}
@ -39,7 +39,7 @@ final class Stack implements StackInterface
*
* @return null|T
*/
public function peek()
public function peek(): mixed
{
return Iter\last($this->items);
}
@ -50,7 +50,7 @@ final class Stack implements StackInterface
*
* @return null|T
*/
public function pull()
public function pull(): mixed
{
if (0 === $this->count()) {
return null;
@ -67,7 +67,7 @@ final class Stack implements StackInterface
*
* @return T
*/
public function pop()
public function pop(): mixed
{
Psl\invariant(0 !== ($i = $this->count()), 'Cannot pop an item from an empty Stack.');

View File

@ -21,7 +21,7 @@ interface StackInterface extends Countable
*
* @param T $item
*/
public function push($item): void;
public function push(mixed $item): void;
/**
* Retrieves, but does remove, the most recently added item that was not yet removed,
@ -29,7 +29,7 @@ interface StackInterface extends Countable
*
* @return null|T
*/
public function peek();
public function peek(): mixed;
/**
* Retrieves and removes the most recently added item that was not yet removed,
@ -37,7 +37,7 @@ interface StackInterface extends Countable
*
* @return null|T
*/
public function pull();
public function pull(): mixed;
/**
* Retrieve and removes the most recently added item that was not yet removed.
@ -46,7 +46,7 @@ interface StackInterface extends Countable
*
* @return T
*/
public function pop();
public function pop(): mixed;
/**
* Count the items in the stack.

View File

@ -5,11 +5,11 @@ declare(strict_types=1);
namespace Psl\Encoding\Base64;
use Psl\Encoding\Exception;
use Psl\Regex;
use Psl\Str;
use Psl\Type;
use function base64_decode;
use function preg_match;
/**
* Decode a base64-encoded string into raw binary.
@ -26,7 +26,8 @@ use function preg_match;
*/
function decode(string $base64): string
{
if (!preg_match('%^[a-zA-Z0-9/+]*={0,2}$%', $base64)) {
/** @psalm-suppress MissingThrowsDocblock - pattern is valid */
if (!Regex\matches($base64, '%^[a-zA-Z0-9/+]*={0,2}$%')) {
throw new Exception\RangeException(
'The given base64 string contains characters outside the base64 range.'
);

View File

@ -39,7 +39,7 @@ final class ResourceHandle implements CloseSeekReadWriteHandleInterface
* @throws Type\Exception\AssertException If $resource is not a resource.
* @throws Psl\IO\Exception\BlockingException If unable to set the handle resource to non-blocking mode.
*/
public function __construct($resource)
public function __construct(mixed $resource)
{
$this->resource = Type\resource()->assert($resource);
@ -67,7 +67,7 @@ final class ResourceHandle implements CloseSeekReadWriteHandleInterface
/**
* @param resource $resource
*/
static function ($resource) use ($bytes) {
static function (mixed $resource) use ($bytes) {
$metadata = stream_get_meta_data($resource);
if ($metadata['blocked']) {
throw new Psl\IO\Exception\BlockingException('The handle resource is blocking.');
@ -95,7 +95,7 @@ final class ResourceHandle implements CloseSeekReadWriteHandleInterface
/**
* @param resource $resource
*/
static function ($resource) use ($offset) {
static function (mixed $resource) use ($offset) {
$metadata = stream_get_meta_data($resource);
Psl\invariant($metadata['seekable'], 'Stream is not seekable.');
@ -117,7 +117,7 @@ final class ResourceHandle implements CloseSeekReadWriteHandleInterface
/**
* @param resource $resource
*/
static function ($resource) {
static function (mixed $resource): int {
$metadata = stream_get_meta_data($resource);
Psl\invariant($metadata['seekable'], 'Stream is not seekable.');
@ -145,7 +145,7 @@ final class ResourceHandle implements CloseSeekReadWriteHandleInterface
/**
* @param resource $resource
*/
static function ($resource) use ($max_bytes) {
static function (mixed $resource) use ($max_bytes): string {
Psl\invariant($max_bytes === null || $max_bytes > 0, '$max_bytes must be null, or > 0');
$metadata = stream_get_meta_data($resource);
if ($metadata['blocked']) {
@ -179,7 +179,7 @@ final class ResourceHandle implements CloseSeekReadWriteHandleInterface
/**
* @param resource $resource
*/
static function ($resource) {
static function (mixed $resource): void {
$result = fflush($resource);
if ($result === false) {
/** @var array{message: string} $error */
@ -201,7 +201,7 @@ final class ResourceHandle implements CloseSeekReadWriteHandleInterface
/**
* @param resource $resource
*/
function ($resource) {
function (mixed $resource): void {
$result = fclose($resource);
if ($result === false) {
/** @var array{message: string} $error */

View File

@ -5,15 +5,13 @@ declare(strict_types=1);
namespace Psl\Internal;
/**
* @param mixed $val
*
* @pure
*
* @codeCoverageIgnore
*
* @internal
*/
function boolean($val): bool
function boolean(mixed $val): bool
{
return (bool)$val;
}

View File

@ -4,20 +4,23 @@ declare(strict_types=1);
namespace Psl\Internal;
use function get_class;
use function gettype;
use function is_object;
use Psl\Str;
use function get_debug_type;
use function is_resource;
/**
* @param mixed $value
*
* @pure
*
* @codeCoverageIgnore
*
* @internal
*/
function type($value): string
function type(mixed $value): string
{
return is_object($value) ? get_class($value) : gettype($value);
if (is_resource($value)) {
return Str\format('resource<%s>', get_resource_type($value));
}
return get_debug_type($value);
}

View File

@ -31,7 +31,7 @@ namespace Psl\Math;
* @psalm-suppress InvalidReturnType
* @psalm-suppress InvalidReturnStatement
*/
function abs($number)
function abs(int|float $number): int|float
{
return $number < 0 ? -$number : $number;
}

View File

@ -21,7 +21,7 @@ use Psl;
*
* @pure
*/
function clamp($number, $min, $max)
function clamp(int|float $number, int|float $min, int|float $max): int|float
{
Psl\invariant($min <= $max, 'Expected $min to be lower or equal to $max.');

View File

@ -17,7 +17,7 @@ namespace Psl\Math;
*
* @pure
*/
function maxva($first, $second, ...$rest)
function maxva(int|float $first, int|float $second, int|float ...$rest): int|float
{
$max = $first > $second ? $first : $second;
foreach ($rest as $number) {

View File

@ -17,7 +17,7 @@ namespace Psl\Math;
*
* @pure
*/
function minva($first, $second, ...$rest)
function minva(int|float $first, int|float $second, int|float ...$rest): int|float
{
$min = $first < $second ? $first : $second;
foreach ($rest as $number) {

View File

@ -22,14 +22,11 @@ final class AssertException extends Exception
return $this->expected;
}
/**
* @param mixed $value
*/
public static function withValue(
$value,
mixed $value,
string $expected_type,
TypeTrace $trace
): self {
return new self(static::getDebugType($value), $expected_type, $trace);
return new self(self::getDebugType($value), $expected_type, $trace);
}
}

View File

@ -26,14 +26,11 @@ final class CoercionException extends Exception
return $this->target;
}
/**
* @param mixed $value
*/
public static function withValue(
$value,
mixed $value,
string $target,
TypeTrace $typeTrace
): self {
return new self(static::getDebugType($value), $target, $typeTrace);
return new self(self::getDebugType($value), $target, $typeTrace);
}
}

View File

@ -5,7 +5,7 @@ declare(strict_types=1);
namespace Psl\Type\Exception;
use Psl\Exception\RuntimeException;
use Psl\Str;
use Psl\Internal;
abstract class Exception extends RuntimeException implements ExceptionInterface
{
@ -33,23 +33,8 @@ abstract class Exception extends RuntimeException implements ExceptionInterface
return $this->typeTrace;
}
/**
* @param mixed $value
*/
protected static function getDebugType($value): string
protected static function getDebugType(mixed $value): string
{
if (is_object($value)) {
$actual_type = get_class($value);
} elseif (is_resource($value)) {
$actual_type = Str\format('resource<%s>', get_resource_type($value));
} elseif (is_int($value)) {
$actual_type = 'int';
} elseif (is_float($value)) {
$actual_type = 'float';
} else {
$actual_type = gettype($value);
}
return $actual_type;
return Internal\type($value);
}
}

View File

@ -18,11 +18,9 @@ use function is_bool;
final class BoolType extends Type\Type
{
/**
* @param mixed $value
*
* @psalm-assert-if-true bool $value
*/
public function matches($value): bool
public function matches(mixed $value): bool
{
return is_bool($value);
}
@ -30,7 +28,7 @@ final class BoolType extends Type\Type
/**
* @throws CoercionException
*/
public function coerce($value): bool
public function coerce(mixed $value): bool
{
if (is_bool($value)) {
return $value;
@ -52,7 +50,7 @@ final class BoolType extends Type\Type
*
* @throws AssertException
*/
public function assert($value): bool
public function assert(mixed $value): bool
{
if (is_bool($value)) {
return $value;

View File

@ -23,16 +23,6 @@ use function is_iterable;
*/
final class DictType extends Type\Type
{
/**
* @var Type\TypeInterface<Tk>
*/
private Type\TypeInterface $key_type;
/**
* @var Type\TypeInterface<Tv>
*/
private Type\TypeInterface $value_type;
/**
* @param Type\TypeInterface<Tk> $key_type
* @param Type\TypeInterface<Tv> $value_type
@ -40,26 +30,21 @@ final class DictType extends Type\Type
* @throws Psl\Exception\InvariantViolationException If $key_value, or $value_type is optional.
*/
public function __construct(
Type\TypeInterface $key_type,
Type\TypeInterface $value_type
private Type\TypeInterface $key_type,
private Type\TypeInterface $value_type
) {
Psl\invariant(
!$key_type->isOptional() && !$value_type->isOptional(),
'Optional type must be the outermost.'
);
$this->key_type = $key_type;
$this->value_type = $value_type;
}
/**
* @param mixed $value
*
* @throws CoercionException
*
* @return array<Tk, Tv>
*/
public function coerce($value): array
public function coerce(mixed $value): array
{
if (is_iterable($value)) {
$key_trace = $this->getTrace()
@ -79,7 +64,7 @@ final class DictType extends Type\Type
foreach ($value as $k => $v) {
$result[$key_type->coerce($k)] = $value_type->coerce($v);
}
return $result;
}
@ -87,15 +72,13 @@ final class DictType extends Type\Type
}
/**
* @param mixed $value
*
* @throws AssertException
*
* @return array<Tk, Tv>
*
* @psalm-assert array<Tk, Tv> $value
*/
public function assert($value): array
public function assert(mixed $value): array
{
if (is_array($value)) {
$key_trace = $this->getTrace()

View File

@ -22,21 +22,17 @@ use function is_string;
final class FloatType extends Type\Type
{
/**
* @param mixed $value
*
* @psalm-assert-if-true float $value
*/
public function matches($value): bool
public function matches(mixed $value): bool
{
return is_float($value);
}
/**
* @param mixed $value
*
* @throws CoercionException
*/
public function coerce($value): float
public function coerce(mixed $value): float
{
if (is_float($value)) {
return $value;
@ -65,13 +61,11 @@ final class FloatType extends Type\Type
}
/**
* @param mixed $value
*
* @psalm-assert float $value
*
* @throws AssertException
*/
public function assert($value): float
public function assert(mixed $value): float
{
if (is_float($value)) {
return $value;

View File

@ -22,21 +22,17 @@ use function is_string;
final class IntType extends Type\Type
{
/**
* @param mixed $value
*
* @psalm-assert-if-true int $value
*/
public function matches($value): bool
public function matches(mixed $value): bool
{
return is_int($value);
}
/**
* @param mixed $value
*
* @throws CoercionException
*/
public function coerce($value): int
public function coerce(mixed $value): int
{
if (is_int($value)) {
return $value;
@ -60,7 +56,7 @@ final class IntType extends Type\Type
return 0;
}
}
if (is_float($value)) {
$integer_value = (int) $value;
$reconstructed = (float) $integer_value;
@ -73,13 +69,11 @@ final class IntType extends Type\Type
}
/**
* @param mixed $value
*
* @psalm-assert int $value
*
* @throws AssertException
*/
public function assert($value): int
public function assert(mixed $value): int
{
if (is_int($value)) {
return $value;

View File

@ -22,16 +22,6 @@ use Psl\Type\TypeInterface;
*/
final class IntersectionType extends Type
{
/**
* @var TypeInterface<Tl>
*/
private TypeInterface $left_type;
/**
* @var TypeInterface<Tr>
*/
private TypeInterface $right_type;
/**
* @param TypeInterface<Tl> $left_type
* @param TypeInterface<Tr> $right_type
@ -39,40 +29,33 @@ final class IntersectionType extends Type
* @throws Psl\Exception\InvariantViolationException If $left_type, or $right_type is optional.
*/
public function __construct(
TypeInterface $left_type,
TypeInterface $right_type
private TypeInterface $left_type,
private TypeInterface $right_type
) {
Psl\invariant(
!$left_type->isOptional() && !$right_type->isOptional(),
'Optional type must be the outermost.'
);
$this->left_type = $left_type;
$this->right_type = $right_type;
}
/**
* @param mixed $value
*
* @psalm-assert-if-true Tl&Tr $value
*/
public function matches($value): bool
public function matches(mixed $value): bool
{
return $this->right_type->matches($value) && $this->left_type->matches($value);
}
/**
* @param mixed $value
*
* @throws CoercionException
*
* @return Tl&Tr
*/
public function coerce($value)
public function coerce(mixed $value): mixed
{
try {
return $this->assert($value);
} catch (AssertException $_exception) {
} catch (AssertException) {
// ignore
}
@ -80,7 +63,7 @@ final class IntersectionType extends Type
$value = $this->left_type->coerce($value);
/** @var Tl&Tr */
return $this->right_type->assert($value);
} catch (Exception $_exception) {
} catch (Exception) {
// ignore
}
@ -88,7 +71,7 @@ final class IntersectionType extends Type
$value = $this->right_type->coerce($value);
/** @var Tr&Tl */
return $this->left_type->assert($value);
} catch (Exception $_exception) {
} catch (Exception) {
// ignore
}
@ -96,21 +79,19 @@ final class IntersectionType extends Type
}
/**
* @param mixed $value
*
* @throws AssertException
*
* @return Tl&Tr
*
* @psalm-assert Tl&Tr $value
*/
public function assert($value)
public function assert(mixed $value): mixed
{
try {
$value = $this->left_type->assert($value);
/** @var Tl&Tr */
return $this->right_type->assert($value);
} catch (AssertException $_exception) {
} catch (AssertException) {
throw AssertException::withValue($value, $this->toString(), $this->getTrace());
}
}

View File

@ -23,16 +23,6 @@ use function is_iterable;
*/
final class IterableType extends Type\Type
{
/**
* @var Type\TypeInterface<Tk>
*/
private Type\TypeInterface $key_type;
/**
* @var Type\TypeInterface<Tv>
*/
private Type\TypeInterface $value_type;
/**
* @param Type\TypeInterface<Tk> $key_type
* @param Type\TypeInterface<Tv> $value_type
@ -40,26 +30,24 @@ final class IterableType extends Type\Type
* @throws Psl\Exception\InvariantViolationException If $key_value, or $value_type is optional.
*/
public function __construct(
Type\TypeInterface $key_type,
Type\TypeInterface $value_type
private Type\TypeInterface $key_type,
private Type\TypeInterface $value_type
) {
Psl\invariant(
!$key_type->isOptional() && !$value_type->isOptional(),
'Optional type must be the outermost.'
);
$this->key_type = $key_type;
$this->value_type = $value_type;
}
/**
* @param mixed $value
*
* @throws CoercionException
*
* @return iterable<Tk, Tv>
*/
public function coerce($value): iterable
public function coerce(mixed $value): iterable
{
if (is_iterable($value)) {
$key_trace = $this->getTrace()
@ -100,15 +88,13 @@ final class IterableType extends Type\Type
}
/**
* @param mixed $value
*
* @throws AssertException
*
* @return iterable<Tk, Tv>
*
* @psalm-assert iterable<Tk, Tv> $value
*/
public function assert($value): iterable
public function assert(mixed $value): iterable
{
if (is_iterable($value)) {
$key_trace = $this->getTrace()

View File

@ -18,37 +18,28 @@ use Psl\Type\Exception\CoercionException;
*/
final class LiteralScalarType extends Type\Type
{
/**
* @var T
*/
private $value;
/**
* @param T $value
*/
public function __construct($value)
{
$this->value = $value;
public function __construct(
private string|int|float|bool $value
) {
}
/**
* @param mixed $value
*
* @psalm-assert-if-true T $value
*/
public function matches($value): bool
public function matches(mixed $value): bool
{
return $this->value === $value;
}
/**
* @param mixed $value
*
* @throws CoercionException
*
* @return T
*/
public function coerce($value)
public function coerce(mixed $value): string|int|float|bool
{
if ($value === $this->value) {
/** @var T $value */
@ -104,13 +95,11 @@ final class LiteralScalarType extends Type\Type
}
/**
* @param mixed $value
*
* @psalm-assert T $value
*
* @throws AssertException
*/
public function assert($value)
public function assert(mixed $value): string|int|float|bool
{
if ($this->value === $value) {
/** @var T */

View File

@ -25,16 +25,6 @@ use function is_object;
*/
final class MapType extends Type\Type
{
/**
* @var Type\TypeInterface<Tk>
*/
private Type\TypeInterface $key_type;
/**
* @var Type\TypeInterface<Tv>
*/
private Type\TypeInterface $value_type;
/**
* @param Type\TypeInterface<Tk> $key_type
* @param Type\TypeInterface<Tv> $value_type
@ -42,26 +32,21 @@ final class MapType extends Type\Type
* @throws Psl\Exception\InvariantViolationException If $key_value, or $value_type is optional.
*/
public function __construct(
Type\TypeInterface $key_type,
Type\TypeInterface $value_type
private Type\TypeInterface $key_type,
private Type\TypeInterface $value_type
) {
Psl\invariant(
!$key_type->isOptional() && !$value_type->isOptional(),
'Optional type must be the outermost.'
);
$this->key_type = $key_type;
$this->value_type = $value_type;
}
/**
* @param mixed $value
*
* @throws CoercionException
*
* @return Collection\MapInterface<Tk, Tv>
*/
public function coerce($value): Collection\MapInterface
public function coerce(mixed $value): Collection\MapInterface
{
if (is_iterable($value)) {
$key_trace = $this->getTrace()->withFrame(
@ -100,15 +85,13 @@ final class MapType extends Type\Type
}
/**
* @param mixed $value
*
* @throws AssertException
*
* @return Collection\MapInterface<Tk, Tv>
*
* @psalm-assert Collection\MapInterface<Tk, Tv> $value
*/
public function assert($value): Collection\MapInterface
public function assert(mixed $value): Collection\MapInterface
{
if (is_object($value) && $value instanceof Collection\MapInterface) {
$key_trace = $this->getTrace()->withFrame(

View File

@ -14,33 +14,29 @@ use Psl\Type\Type;
final class MixedType extends Type
{
/**
* @param mixed $value
*
* @psalm-assert-if-true mixed $value
*/
public function matches($value): bool
public function matches(mixed $value): bool
{
return true;
}
/**
* @param mixed $value
* @psalm-assert mixed $value
*
* @return mixed
* @psalm-suppress MixedReturnStatement
*/
public function coerce($value)
public function coerce(mixed $value): mixed
{
return $value;
}
/**
* @param mixed $value
*
* @psalm-assert mixed $value
*
* @return mixed
* @psalm-suppress MixedReturnStatement
*/
public function assert($value)
public function assert(mixed $value): mixed
{
return $value;
}

View File

@ -25,16 +25,6 @@ use function is_object;
*/
final class MutableMapType extends Type\Type
{
/**
* @var Type\TypeInterface<Tk>
*/
private Type\TypeInterface $key_type;
/**
* @var Type\TypeInterface<Tv>
*/
private Type\TypeInterface $value_type;
/**
* @param Type\TypeInterface<Tk> $key_type
* @param Type\TypeInterface<Tv> $value_type
@ -42,26 +32,21 @@ final class MutableMapType extends Type\Type
* @throws Psl\Exception\InvariantViolationException If $key_value, or $value_type is optional.
*/
public function __construct(
Type\TypeInterface $key_type,
Type\TypeInterface $value_type
private Type\TypeInterface $key_type,
private Type\TypeInterface $value_type
) {
Psl\invariant(
!$key_type->isOptional() && !$value_type->isOptional(),
'Optional type must be the outermost.'
);
$this->key_type = $key_type;
$this->value_type = $value_type;
}
/**
* @param mixed $value
*
* @throws CoercionException
*
* @return Collection\MutableMapInterface<Tk, Tv>
*/
public function coerce($value): Collection\MutableMapInterface
public function coerce(mixed $value): Collection\MutableMapInterface
{
if (is_iterable($value)) {
$key_trace = $this->getTrace()->withFrame(
@ -103,15 +88,13 @@ final class MutableMapType extends Type\Type
}
/**
* @param mixed $value
*
* @throws AssertException
*
* @return Collection\MutableMapInterface<Tk, Tv>
*
* @psalm-assert Collection\MutableMapInterface<Tk, Tv> $value
*/
public function assert($value): Collection\MutableMapInterface
public function assert(mixed $value): Collection\MutableMapInterface
{
if (is_object($value) && $value instanceof Collection\MutableMapInterface) {
$key_trace = $this->getTrace()->withFrame(

View File

@ -23,18 +23,13 @@ use function is_object;
*/
final class MutableVectorType extends Type\Type
{
/**
* @var Type\TypeInterface<T>
*/
private Type\TypeInterface $value_type;
/**
* @param Type\TypeInterface<T> $value_type
*
* @throws Psl\Exception\InvariantViolationException If $value_type is optional.
*/
public function __construct(
Type\TypeInterface $value_type
private Type\TypeInterface $value_type
) {
Psl\invariant(!$value_type->isOptional(), 'Optional type must be the outermost.');
@ -42,13 +37,11 @@ final class MutableVectorType extends Type\Type
}
/**
* @param mixed $value
*
* @throws CoercionException
*
* @return Collection\MutableVectorInterface<T>
*/
public function coerce($value): Collection\MutableVectorInterface
public function coerce(mixed $value): Collection\MutableVectorInterface
{
if (is_iterable($value)) {
$value_trace = $this->getTrace()->withFrame(
@ -78,15 +71,13 @@ final class MutableVectorType extends Type\Type
}
/**
* @param mixed $value
*
* @throws AssertException
*
* @return Collection\MutableVectorInterface<T>
*
* @psalm-assert Collection\MutableVectorInterface<T> $value
*/
public function assert($value): Collection\MutableVectorInterface
public function assert(mixed $value): Collection\MutableVectorInterface
{
if (is_object($value) && $value instanceof Collection\MutableVectorInterface) {
$value_trace = $this->getTrace()->withFrame(

View File

@ -21,23 +21,19 @@ use function is_string;
final class NonEmptyStringType extends Type\Type
{
/**
* @param mixed $value
*
* @psalm-assert-if-true non-empty-string $value
*/
public function matches($value): bool
public function matches(mixed $value): bool
{
return is_string($value) && !Str\is_empty($value);
}
/**
* @param mixed $value
*
* @throws CoercionException
*
* @return non-empty-string
*/
public function coerce($value): string
public function coerce(mixed $value): string
{
if (is_string($value) && !Str\is_empty($value)) {
return $value;
@ -46,7 +42,6 @@ final class NonEmptyStringType extends Type\Type
if (is_int($value)) {
$str = (string) $value;
if (!Str\is_empty($str)) {
/** @var non-empty-string $str */
return $str;
}
}
@ -62,15 +57,13 @@ final class NonEmptyStringType extends Type\Type
}
/**
* @param mixed $value
*
* @throws AssertException
*
* @return non-empty-string
*
* @psalm-assert non-empty-string $value
*/
public function assert($value): string
public function assert(mixed $value): string
{
if (is_string($value) && !Str\is_empty($value)) {
return $value;

View File

@ -16,21 +16,17 @@ use Psl\Type\Exception\CoercionException;
final class NullType extends Type\Type
{
/**
* @param mixed $value
*
* @psalm-assert-if-true null $value
*/
public function matches($value): bool
public function matches(mixed $value): bool
{
return null === $value;
}
/**
* @param mixed $value
*
* @return null
*/
public function coerce($value)
public function coerce(mixed $value): mixed
{
if (null === $value) {
return null;
@ -40,13 +36,11 @@ final class NullType extends Type\Type
}
/**
* @param mixed $value
*
* @psalm-assert null $value
*
* @return null
*/
public function assert($value)
public function assert(mixed $value): mixed
{
if (null === $value) {
return null;

View File

@ -18,42 +18,31 @@ use Psl\Type\Exception\CoercionException;
*/
final class NullableType extends Type\Type
{
/**
* @var Type\TypeInterface<T>
*/
private Type\TypeInterface $inner;
/**
* @param Type\TypeInterface<T> $inner
*
* @throws Psl\Exception\InvariantViolationException If $inner is optional.
*/
public function __construct(
Type\TypeInterface $inner
private Type\TypeInterface $inner
) {
Psl\invariant(!$inner->isOptional(), 'Optional type must be the outermost.');
$this->inner = $inner;
}
/**
* @param mixed $value
*
* @psalm-assert-if-true T|null $value
*/
public function matches($value): bool
public function matches(mixed $value): bool
{
return null === $value || $this->inner->matches($value);
}
/**
* @param mixed $value
*
* @throws CoercionException
*
* @return T|null
*/
public function coerce($value)
public function coerce(mixed $value): mixed
{
if (null === $value) {
return null;
@ -63,15 +52,13 @@ final class NullableType extends Type\Type
}
/**
* @param mixed $value
*
* @throws AssertException
*
* @return T|null
*
* @psalm-assert T|null $value
*/
public function assert($value)
public function assert(mixed $value): mixed
{
if (null === $value) {
return null;

View File

@ -32,23 +32,19 @@ final class ObjectType extends Type
}
/**
* @param mixed $value
*
* @psalm-assert-if-true T $value
*/
public function matches($value): bool
public function matches(mixed $value): bool
{
return $value instanceof $this->classname;
}
/**
* @param mixed $value
*
* @throws CoercionException
*
* @return T
*/
public function coerce($value): object
public function coerce(mixed $value): object
{
if ($value instanceof $this->classname) {
return $value;
@ -58,15 +54,13 @@ final class ObjectType extends Type
}
/**
* @param mixed $value
*
* @throws AssertException
*
* @return T
*
* @psalm-assert T $value
*/
public function assert($value): object
public function assert(mixed $value): object
{
if ($value instanceof $this->classname) {
return $value;

View File

@ -17,42 +17,32 @@ use Psl\Type\Exception\CoercionException;
*/
final class OptionalType extends Type\Type
{
/**
* @var Type\TypeInterface<T>
*/
private Type\TypeInterface $inner;
/**
* @param Type\TypeInterface<T> $inner
*/
public function __construct(
Type\TypeInterface $inner
private Type\TypeInterface $inner
) {
$this->inner = $inner;
}
/**
* @param mixed $value
*
* @throws CoercionException
*
* @return T
*/
public function coerce($value)
public function coerce(mixed $value): mixed
{
return $this->inner->withTrace($this->getTrace())->coerce($value);
}
/**
* @param mixed $value
*
* @throws AssertException
*
* @return T
*
* @psalm-assert T $value
*/
public function assert($value)
public function assert(mixed $value): mixed
{
return $this->inner->withTrace($this->getTrace())->assert($value);
}

View File

@ -22,23 +22,19 @@ use function is_string;
final class PositiveIntType extends Type\Type
{
/**
* @param mixed $value
*
* @psalm-assert-if-true positive-int $value
*/
public function matches($value): bool
public function matches(mixed $value): bool
{
return is_int($value) && $value > 0;
}
/**
* @param mixed $value
*
* @throws CoercionException
*
* @return positive-int
*/
public function coerce($value): int
public function coerce(mixed $value): int
{
if (is_int($value) && $value > 0) {
return $value;
@ -75,15 +71,13 @@ final class PositiveIntType extends Type\Type
}
/**
* @param mixed $value
*
* @psalm-assert positive-int $value
*
* @throws AssertException
*
* @return positive-int
*/
public function assert($value): int
public function assert(mixed $value): int
{
if (is_int($value) && $value > 0) {
return $value;

View File

@ -18,21 +18,17 @@ use function is_resource;
*/
final class ResourceType extends Type\Type
{
private ?string $kind;
public function __construct(?string $kind = null)
{
$this->kind = $kind;
public function __construct(
private ?string $kind = null
) {
}
/**
* @param mixed $value
*
* @throws CoercionException
*
* @return resource
*/
public function coerce($value)
public function coerce(mixed $value): mixed
{
if (is_resource($value)) {
$kind = $this->kind;
@ -49,15 +45,13 @@ final class ResourceType extends Type\Type
}
/**
* @param mixed $value
*
* @throws AssertException
*
* @return resource
*
* @psalm-assert resource $value
*/
public function assert($value)
public function assert(mixed $value): mixed
{
if (is_resource($value)) {
$kind = $this->kind;

View File

@ -18,30 +18,21 @@ use Psl\Type\Exception\CoercionException;
*/
final class ShapeType extends Type\Type
{
/**
* @var array<Tk, Type\TypeInterface<Tv>> $elements_types
*/
private array $elements_types;
private bool $allow_unknown_fields;
/**
* @param array<Tk, Type\TypeInterface<Tv>> $elements_types
*/
public function __construct(array $elements_types, bool $allow_unknown_fields = false)
{
$this->elements_types = $elements_types;
$this->allow_unknown_fields = $allow_unknown_fields;
public function __construct(
private array $elements_types,
private bool $allow_unknown_fields = false,
) {
}
/**
* @param mixed $value
*
* @throws CoercionException
*
* @return array<Tk, Tv>
*/
public function coerce($value): array
public function coerce(mixed $value): array
{
/** @psalm-suppress MissingThrowsDocblock */
if (Type\iterable(Type\mixed(), Type\mixed())->matches($value)) {
@ -88,15 +79,13 @@ final class ShapeType extends Type\Type
}
/**
* @param mixed $value
*
* @throws AssertException
*
* @return array<Tk, Tv>
*
* @psalm-assert array<Tk, Tv> $value
*/
public function assert($value): array
public function assert(mixed $value): array
{
/** @psalm-suppress MissingThrowsDocblock */
if (Type\dict(Type\array_key(), Type\mixed())->matches($value)) {
@ -159,10 +148,7 @@ final class ShapeType extends Type\Type
return Str\format('array{%s}', Str\join($nodes, ', '));
}
/**
* @param array-key $element
*/
private function getElementName($element): string
private function getElementName(string|int $element): string
{
return Type\int()->matches($element) ? (string) $element : Str\format('\'%s\'', $element);
}
@ -170,12 +156,11 @@ final class ShapeType extends Type\Type
/**
* @template T
*
* @param array-key $element
* @param Type\TypeInterface<T> $type
*
* @return array{0: Type\Exception\TypeTrace, 1: Type\TypeInterface<T>}
*/
private function getTypeAndTraceForElement($element, Type\TypeInterface $type): array
private function getTypeAndTraceForElement(string|int $element, Type\TypeInterface $type): array
{
$element_name = $this->getElementName($element);
$trace = $this->getTrace()->withFrame('array{' . $element_name . ': _}');

View File

@ -20,21 +20,17 @@ use function is_string;
final class StringType extends Type\Type
{
/**
* @param mixed $value
*
* @psalm-assert-if-true string $value
*/
public function matches($value): bool
public function matches(mixed $value): bool
{
return is_string($value);
}
/**
* @param mixed $value
*
* @throws CoercionException
*/
public function coerce($value): string
public function coerce(mixed $value): string
{
if (is_string($value)) {
return $value;
@ -52,13 +48,11 @@ final class StringType extends Type\Type
}
/**
* @param mixed $value
*
* @psalm-assert string $value
*
* @throws AssertException
*/
public function assert($value): string
public function assert(mixed $value): string
{
if (is_string($value)) {
return $value;

View File

@ -20,16 +20,6 @@ use Psl\Type\Exception\CoercionException;
*/
class UnionType extends Type\Type
{
/**
* @var Type\TypeInterface<Tl>
*/
private Type\TypeInterface $left_type;
/**
* @var Type\TypeInterface<Tr>
*/
private Type\TypeInterface $right_type;
/**
* @param Type\TypeInterface<Tl> $left_type
* @param Type\TypeInterface<Tr> $right_type
@ -37,52 +27,45 @@ class UnionType extends Type\Type
* @throws Psl\Exception\InvariantViolationException If $left_type, or $right_type is optional.
*/
public function __construct(
Type\TypeInterface $left_type,
Type\TypeInterface $right_type
private Type\TypeInterface $left_type,
private Type\TypeInterface $right_type
) {
Psl\invariant(
!$left_type->isOptional() && !$right_type->isOptional(),
'Optional type must be the outermost.'
);
$this->left_type = $left_type;
$this->right_type = $right_type;
}
/**
* @param mixed $value
*
* @psalm-assert-if-true Tl|Tr $value
*/
public function matches($value): bool
public function matches(mixed $value): bool
{
return $this->left_type->matches($value) || $this->right_type->matches($value);
}
/**
* @param mixed $value
*
* @throws CoercionException
*
* @return Tl|Tr
*/
public function coerce($value)
public function coerce(mixed $value): mixed
{
try {
return $this->assert($value);
} catch (AssertException $_exception) {
} catch (AssertException) {
// ignore
}
try {
return $this->left_type->coerce($value);
} catch (CoercionException $_exception) {
} catch (CoercionException) {
// ignore
}
try {
return $this->right_type->coerce($value);
} catch (CoercionException $_exception) {
} catch (CoercionException) {
// ignore
}
@ -90,25 +73,23 @@ class UnionType extends Type\Type
}
/**
* @param mixed $value
*
* @throws AssertException
*
* @return Tl|Tr
*
* @psalm-assert Tl|Tr $value
*/
public function assert($value)
public function assert(mixed $value): mixed
{
try {
return $this->left_type->assert($value);
} catch (AssertException $_exception) {
} catch (AssertException) {
// ignore
}
try {
return $this->right_type->assert($value);
} catch (AssertException $_exception) {
} catch (AssertException) {
// ignore
}

View File

@ -21,30 +21,21 @@ use function is_iterable;
*/
final class VecType extends Type\Type
{
/**
* @var Type\TypeInterface<Tv>
*/
private Type\TypeInterface $value_type;
/**
* @param Type\TypeInterface<Tv> $value_type
*
* @throws Psl\Exception\InvariantViolationException If $value_type is optional.
*/
public function __construct(
Type\TypeInterface $value_type
private Type\TypeInterface $value_type
) {
Psl\invariant(!$value_type->isOptional(), 'Optional type must be the outermost.');
$this->value_type = $value_type;
}
/**
* @param mixed $value
*
* @psalm-assert-if-true list<Tv> $value
*/
public function matches($value): bool
public function matches(mixed $value): bool
{
if (!is_array($value)) {
return false;
@ -71,13 +62,11 @@ final class VecType extends Type\Type
}
/**
* @param mixed $value
*
* @throws CoercionException
*
* @return list<Tv>
*/
public function coerce($value): iterable
public function coerce(mixed $value): iterable
{
if (is_iterable($value)) {
$value_trace = $this->getTrace()
@ -103,15 +92,13 @@ final class VecType extends Type\Type
}
/**
* @param mixed $value
*
* @throws AssertException
*
* @return list<Tv>
*
* @psalm-assert list<Tv> $value
*/
public function assert($value): array
public function assert(mixed $value): array
{
if (is_array($value)) {
$value_trace = $this->getTrace()

View File

@ -23,32 +23,23 @@ use function is_object;
*/
final class VectorType extends Type\Type
{
/**
* @var Type\TypeInterface<T>
*/
private Type\TypeInterface $value_type;
/**
* @param Type\TypeInterface<T> $value_type
*
* @throws Psl\Exception\InvariantViolationException If $value_type is optional.
*/
public function __construct(
Type\TypeInterface $value_type
private Type\TypeInterface $value_type
) {
Psl\invariant(!$value_type->isOptional(), 'Optional type must be the outermost.');
$this->value_type = $value_type;
}
/**
* @param mixed $value
*
* @throws CoercionException
*
* @return Collection\VectorInterface<T>
*/
public function coerce($value): Collection\VectorInterface
public function coerce(mixed $value): Collection\VectorInterface
{
if (is_iterable($value)) {
$value_trace = $this->getTrace()->withFrame(
@ -86,7 +77,7 @@ final class VectorType extends Type\Type
*
* @psalm-assert Collection\VectorInterface<T> $value
*/
public function assert($value): Collection\VectorInterface
public function assert(mixed $value): Collection\VectorInterface
{
if (is_object($value) && $value instanceof Collection\VectorInterface) {
$value_trace = $this->getTrace()->withFrame(

View File

@ -17,17 +17,15 @@ abstract class Type implements TypeInterface
private ?TypeTrace $trace = null;
/**
* @param mixed $value
*
* @psalm-assert-if-true T $value
*/
public function matches($value): bool
public function matches(mixed $value): bool
{
try {
$this->assert($value);
return true;
} catch (AssertException $_e) {
} catch (AssertException) {
return false;
}
}

View File

@ -14,31 +14,25 @@ use Psl\Type\Exception\TypeTrace;
interface TypeInterface
{
/**
* @param mixed $value
*
* @psalm-assert-if-true T $value
*/
public function matches($value): bool;
public function matches(mixed $value): bool;
/**
* @param mixed $value
*
* @throws CoercionException
*
* @return T
*/
public function coerce($value);
public function coerce(mixed $value);
/**
* @param mixed $value
*
* @throws AssertException
*
* @return T
*
* @psalm-assert T $value
*/
public function assert($value);
public function assert(mixed $value);
/**
* Return whether this type is optional.

View File

@ -9,15 +9,13 @@ use function is_array as php_is_array;
/**
* Finds whether a variable is an array.
*
* @param mixed $var
*
* @psalm-assert-if-true array<array-key,mixed> $var
*
* @pure
*
* @deprecated use `Type\dict($kt, $vt)->matches($value)` instead.
*/
function is_array($var): bool
function is_array(mixed $var): bool
{
return php_is_array($var);
}

View File

@ -7,15 +7,13 @@ namespace Psl\Type;
/**
* Finds whether a variable is an array key.
*
* @param mixed $key
*
* @psalm-assert-if-true array-key $key
*
* @pure
*
* @deprecated use `Type\array_key()->matches($value)` instead.
*/
function is_arraykey($key): bool
function is_arraykey(mixed $key): bool
{
/**
* @psalm-suppress ImpureFunctionCall

View File

@ -9,15 +9,13 @@ use function is_bool as php_is_bool;
/**
* Finds whether a variable is a boolean.
*
* @param mixed $var
*
* @psalm-assert-if-true bool $var
*
* @pure
*
* @deprecated use `Type\bool()->matches($value)` instead.
*/
function is_bool($var): bool
function is_bool(mixed $var): bool
{
return php_is_bool($var);
}

View File

@ -9,13 +9,11 @@ use function is_callable as php_is_callable;
/**
* Finds whether a variable is a callable.
*
* @param mixed $var
*
* @psalm-assert-if-true callable $var
*
* @pure
*/
function is_callable($var): bool
function is_callable(mixed $var): bool
{
return php_is_callable($var, false);
}

View File

@ -9,15 +9,13 @@ use function is_float as php_is_float;
/**
* Finds whether a variable is a float.
*
* @param mixed $var
*
* @psalm-assert-if-true float $var
*
* @pure
*
* @deprecated use `Type\float()->matches($value)` instead.
*/
function is_float($var): bool
function is_float(mixed $var): bool
{
return php_is_float($var);
}

View File

@ -9,15 +9,13 @@ use function is_int as php_is_int;
/**
* Finds whether a variable is an integer.
*
* @param mixed $var
*
* @psalm-assert-if-true int $var
*
* @pure
*
* @deprecated use `Type\int()->matches($value)` instead.
*/
function is_int($var): bool
function is_int(mixed $var): bool
{
return php_is_int($var);
}

View File

@ -9,15 +9,13 @@ use function is_iterable as php_is_iterable;
/**
* Finds whether a variable is an iterable.
*
* @param mixed $var
*
* @psalm-assert-if-true iterable $var
*
* @pure
*
* @deprecated use `Type\iterable($kt, $vt)->matches($value)` instead.
*/
function is_iterable($var): bool
function is_iterable(mixed $var): bool
{
return php_is_iterable($var);
}

View File

@ -7,15 +7,13 @@ namespace Psl\Type;
/**
* Finds whether a variable is null.
*
* @param mixed $var
*
* @psalm-assert-if-true null $var
*
* @pure
*
* @deprecated use `Type\null()->matches($value)` instead.
*/
function is_null($var): bool
function is_null(mixed $var): bool
{
return null === $var;
}

View File

@ -9,15 +9,13 @@ use function is_numeric as php_is_numeric;
/**
* Finds whether a variable is numeric.
*
* @param mixed $var
*
* @psalm-assert-if-true numeric $var
*
* @pure
*
* @deprecated use `Type\num()->matches($value)` instead.
*/
function is_numeric($var): bool
function is_numeric(mixed $var): bool
{
return php_is_numeric($var);
}

View File

@ -9,15 +9,13 @@ use function is_object as php_is_object;
/**
* Finds whether a variable is an object.
*
* @param mixed $var
*
* @psalm-assert-if-true object $var
*
* @pure
*
* @deprecated use `Type\object($classname)->matches($var)` instead.
*/
function is_object($var): bool
function is_object(mixed $var): bool
{
return php_is_object($var);
}

View File

@ -11,15 +11,13 @@ use function is_resource as php_is_resource;
*
* To verify the resource type, use `Type\resource($type)->assert($var)` instead.
*
* @param mixed $var
*
* @psalm-assert-if-true resource $var
*
* @pure
*
* @deprecated use `Type\resource($type)->matches($value)` instead.
*/
function is_resource($var): bool
function is_resource(mixed $var): bool
{
return php_is_resource($var);
}

View File

@ -9,15 +9,13 @@ use function is_scalar as php_is_scalar;
/**
* Finds whether a variable is a scalar.
*
* @param mixed $var
*
* @psalm-assert-if-true scalar $var
*
* @pure
*
* @deprecated use `Type\scalar()->matches($value)` instead.
*/
function is_scalar($var): bool
function is_scalar(mixed $var): bool
{
return php_is_scalar($var);
}

View File

@ -9,15 +9,13 @@ use function is_string as php_is_string;
/**
* Finds whether a variable is a string.
*
* @param mixed $var
*
* @psalm-assert-if-true string $var
*
* @pure
*
* @deprecated use `Type\string()->matches($value)` instead.
*/
function is_string($var): bool
function is_string(mixed $var): bool
{
return php_is_string($var);
}

View File

@ -15,7 +15,7 @@ use Psl;
*
* @return TypeInterface<T>
*/
function literal_scalar($value): TypeInterface
function literal_scalar(string|int|float|bool $value): TypeInterface
{
/** @psalm-suppress MissingThrowsDocblock */
union(string(), bool(), num())->assert($value);

View File

@ -47,7 +47,7 @@ use Psl;
*
* @see https://github.com/vimeo/psalm/issues/2152#issuecomment-533363310
*/
function range($start, $end, $step = null): array
function range(int|float $start, int|float $end, int|float $step = null): array
{
if ((float) $start === (float) $end) {
return [$start];
@ -62,10 +62,7 @@ function range($start, $end, $step = null): array
Psl\invariant($step > 0, 'If $start < $end, then $step must be positive or null.');
$result = [];
Psl\invariant(is_int($step) || is_float($step), '$step must be either an integer or a float.');
for ($i = $start; $i <= $end; $i += $step) {
Psl\invariant(is_int($i) || is_float($i), '$i must be either an integer or a float.');
Psl\invariant(is_int($step) || is_float($step), '$step must be either an integer or a float.');
$result[] = $i;
}
@ -80,10 +77,7 @@ function range($start, $end, $step = null): array
Psl\invariant($step < 0, 'If $start > $end, then $step must be negative or null.');
$result = [];
Psl\invariant(is_int($step) || is_float($step), '$step must be either an integer or a float.');
for ($i = $start; $i >= $end; $i += $step) {
Psl\invariant(is_int($i) || is_float($i), '$i must be either an integer or a float.');
Psl\invariant(is_int($step) || is_float($step), '$step must be either an integer or a float.');
$result[] = $i;
}

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="dev-master@3b3065c881c052d17967da6370f0c7c96193be63">
<files psalm-version="dev-master@641587635d1fabd5539c23385ced18e9840cce45">
<file src="../../src/Psl/Filesystem/create_temporary_file.php">
<MixedArgument occurrences="2">
<code>SEPARATOR</code>