From 8f9bf3d372eb879adf86b98eeeac7a5fcdd9b1e8 Mon Sep 17 00:00:00 2001 From: Toon Verwerft Date: Fri, 5 Apr 2024 14:33:41 +0200 Subject: [PATCH] feat(type): Introduce type constructor purity --- docs/component/type.md | 94 ++++++++++----------- src/Psl/Type/Internal/ArrayKeyType.php | 3 + src/Psl/Type/Internal/BackedEnumType.php | 2 + src/Psl/Type/Internal/ClassStringType.php | 2 + src/Psl/Type/Internal/ConvertedType.php | 2 + src/Psl/Type/Internal/DictType.php | 2 + src/Psl/Type/Internal/InstanceOfType.php | 2 + src/Psl/Type/Internal/IntersectionType.php | 2 + src/Psl/Type/Internal/IterableType.php | 2 + src/Psl/Type/Internal/LiteralScalarType.php | 2 + src/Psl/Type/Internal/MapType.php | 2 + src/Psl/Type/Internal/MutableMapType.php | 2 + src/Psl/Type/Internal/MutableVectorType.php | 2 + src/Psl/Type/Internal/NonEmptyDictType.php | 2 + src/Psl/Type/Internal/NonEmptyVecType.php | 2 + src/Psl/Type/Internal/NullableType.php | 2 + src/Psl/Type/Internal/NumType.php | 3 + src/Psl/Type/Internal/OptionalType.php | 2 + src/Psl/Type/Internal/ResourceType.php | 3 + src/Psl/Type/Internal/ScalarType.php | 3 + src/Psl/Type/Internal/ShapeType.php | 3 + src/Psl/Type/Internal/UnionType.php | 2 + src/Psl/Type/Internal/UnitEnumType.php | 2 + src/Psl/Type/Internal/VecType.php | 2 + src/Psl/Type/Internal/VectorType.php | 2 + src/Psl/Type/array_key.php | 4 + src/Psl/Type/backed_enum.php | 2 + src/Psl/Type/bool.php | 4 + src/Psl/Type/class_string.php | 2 + src/Psl/Type/converted.php | 2 + src/Psl/Type/dict.php | 2 + src/Psl/Type/f32.php | 4 + src/Psl/Type/f64.php | 4 + src/Psl/Type/float.php | 4 + src/Psl/Type/i16.php | 4 + src/Psl/Type/i32.php | 4 + src/Psl/Type/i64.php | 4 + src/Psl/Type/i8.php | 4 + src/Psl/Type/instance_of.php | 2 + src/Psl/Type/int.php | 4 + src/Psl/Type/intersection.php | 2 + src/Psl/Type/iterable.php | 2 + src/Psl/Type/literal_scalar.php | 2 + src/Psl/Type/map.php | 2 + src/Psl/Type/mixed.php | 4 + src/Psl/Type/mixed_dict.php | 2 + src/Psl/Type/mixed_vec.php | 2 + src/Psl/Type/mutable_map.php | 2 + src/Psl/Type/mutable_vector.php | 2 + src/Psl/Type/non_empty_dict.php | 2 + src/Psl/Type/non_empty_string.php | 4 + src/Psl/Type/non_empty_vec.php | 2 + src/Psl/Type/nonnull.php | 4 + src/Psl/Type/null.php | 4 + src/Psl/Type/nullable.php | 2 + src/Psl/Type/num.php | 4 + src/Psl/Type/numeric_string.php | 4 + src/Psl/Type/object.php | 4 + src/Psl/Type/optional.php | 2 + src/Psl/Type/positive_int.php | 4 + src/Psl/Type/resource.php | 2 + src/Psl/Type/scalar.php | 4 + src/Psl/Type/shape.php | 2 + src/Psl/Type/string.php | 4 + src/Psl/Type/u16.php | 4 + src/Psl/Type/u32.php | 4 + src/Psl/Type/u8.php | 4 + src/Psl/Type/uint.php | 4 + src/Psl/Type/union.php | 2 + src/Psl/Type/unit_enum.php | 2 + src/Psl/Type/vec.php | 2 + src/Psl/Type/vector.php | 2 + tests/static-analysis/Type/converted.php | 21 +++++ 73 files changed, 263 insertions(+), 47 deletions(-) create mode 100644 tests/static-analysis/Type/converted.php diff --git a/docs/component/type.md b/docs/component/type.md index bf342125..7656de12 100644 --- a/docs/component/type.md +++ b/docs/component/type.md @@ -12,54 +12,54 @@ #### `Functions` -- [array_key](./../../src/Psl/Type/array_key.php#L10) -- [backed_enum](./../../src/Psl/Type/backed_enum.php#L16) -- [bool](./../../src/Psl/Type/bool.php#L10) -- [class_string](./../../src/Psl/Type/class_string.php#L14) -- [converted](./../../src/Psl/Type/converted.php#L21) -- [dict](./../../src/Psl/Type/dict.php#L16) -- [f32](./../../src/Psl/Type/f32.php#L12) -- [f64](./../../src/Psl/Type/f64.php#L12) -- [float](./../../src/Psl/Type/float.php#L10) -- [i16](./../../src/Psl/Type/i16.php#L12) -- [i32](./../../src/Psl/Type/i32.php#L12) -- [i64](./../../src/Psl/Type/i64.php#L12) -- [i8](./../../src/Psl/Type/i8.php#L12) -- [instance_of](./../../src/Psl/Type/instance_of.php#L14) -- [int](./../../src/Psl/Type/int.php#L10) -- [intersection](./../../src/Psl/Type/intersection.php#L18) +- [array_key](./../../src/Psl/Type/array_key.php#L14) +- [backed_enum](./../../src/Psl/Type/backed_enum.php#L18) +- [bool](./../../src/Psl/Type/bool.php#L14) +- [class_string](./../../src/Psl/Type/class_string.php#L16) +- [converted](./../../src/Psl/Type/converted.php#L23) +- [dict](./../../src/Psl/Type/dict.php#L18) +- [f32](./../../src/Psl/Type/f32.php#L16) +- [f64](./../../src/Psl/Type/f64.php#L16) +- [float](./../../src/Psl/Type/float.php#L14) +- [i16](./../../src/Psl/Type/i16.php#L16) +- [i32](./../../src/Psl/Type/i32.php#L16) +- [i64](./../../src/Psl/Type/i64.php#L16) +- [i8](./../../src/Psl/Type/i8.php#L16) +- [instance_of](./../../src/Psl/Type/instance_of.php#L16) +- [int](./../../src/Psl/Type/int.php#L14) +- [intersection](./../../src/Psl/Type/intersection.php#L20) - [is_nan](./../../src/Psl/Type/is_nan.php#L14) -- [iterable](./../../src/Psl/Type/iterable.php#L16) -- [literal_scalar](./../../src/Psl/Type/literal_scalar.php#L14) -- [map](./../../src/Psl/Type/map.php#L18) -- [mixed](./../../src/Psl/Type/mixed.php#L10) -- [mixed_dict](./../../src/Psl/Type/mixed_dict.php#L10) -- [mixed_vec](./../../src/Psl/Type/mixed_vec.php#L10) -- [mutable_map](./../../src/Psl/Type/mutable_map.php#L18) -- [mutable_vector](./../../src/Psl/Type/mutable_vector.php#L16) -- [non_empty_dict](./../../src/Psl/Type/non_empty_dict.php#L16) -- [non_empty_string](./../../src/Psl/Type/non_empty_string.php#L10) -- [non_empty_vec](./../../src/Psl/Type/non_empty_vec.php#L14) -- [nonnull](./../../src/Psl/Type/nonnull.php#L12) -- [null](./../../src/Psl/Type/null.php#L10) -- [nullable](./../../src/Psl/Type/nullable.php#L14) -- [num](./../../src/Psl/Type/num.php#L10) -- [numeric_string](./../../src/Psl/Type/numeric_string.php#L10) -- [object](./../../src/Psl/Type/object.php#L10) -- [optional](./../../src/Psl/Type/optional.php#L14) -- [positive_int](./../../src/Psl/Type/positive_int.php#L12) -- [resource](./../../src/Psl/Type/resource.php#L12) -- [scalar](./../../src/Psl/Type/scalar.php#L10) -- [shape](./../../src/Psl/Type/shape.php#L15) -- [string](./../../src/Psl/Type/string.php#L10) -- [u16](./../../src/Psl/Type/u16.php#L12) -- [u32](./../../src/Psl/Type/u32.php#L12) -- [u8](./../../src/Psl/Type/u8.php#L12) -- [uint](./../../src/Psl/Type/uint.php#L12) -- [union](./../../src/Psl/Type/union.php#L16) -- [unit_enum](./../../src/Psl/Type/unit_enum.php#L16) -- [vec](./../../src/Psl/Type/vec.php#L14) -- [vector](./../../src/Psl/Type/vector.php#L16) +- [iterable](./../../src/Psl/Type/iterable.php#L18) +- [literal_scalar](./../../src/Psl/Type/literal_scalar.php#L16) +- [map](./../../src/Psl/Type/map.php#L20) +- [mixed](./../../src/Psl/Type/mixed.php#L14) +- [mixed_dict](./../../src/Psl/Type/mixed_dict.php#L12) +- [mixed_vec](./../../src/Psl/Type/mixed_vec.php#L12) +- [mutable_map](./../../src/Psl/Type/mutable_map.php#L20) +- [mutable_vector](./../../src/Psl/Type/mutable_vector.php#L18) +- [non_empty_dict](./../../src/Psl/Type/non_empty_dict.php#L18) +- [non_empty_string](./../../src/Psl/Type/non_empty_string.php#L14) +- [non_empty_vec](./../../src/Psl/Type/non_empty_vec.php#L16) +- [nonnull](./../../src/Psl/Type/nonnull.php#L16) +- [null](./../../src/Psl/Type/null.php#L14) +- [nullable](./../../src/Psl/Type/nullable.php#L16) +- [num](./../../src/Psl/Type/num.php#L14) +- [numeric_string](./../../src/Psl/Type/numeric_string.php#L14) +- [object](./../../src/Psl/Type/object.php#L14) +- [optional](./../../src/Psl/Type/optional.php#L16) +- [positive_int](./../../src/Psl/Type/positive_int.php#L16) +- [resource](./../../src/Psl/Type/resource.php#L14) +- [scalar](./../../src/Psl/Type/scalar.php#L14) +- [shape](./../../src/Psl/Type/shape.php#L17) +- [string](./../../src/Psl/Type/string.php#L14) +- [u16](./../../src/Psl/Type/u16.php#L16) +- [u32](./../../src/Psl/Type/u32.php#L16) +- [u8](./../../src/Psl/Type/u8.php#L16) +- [uint](./../../src/Psl/Type/uint.php#L16) +- [union](./../../src/Psl/Type/union.php#L18) +- [unit_enum](./../../src/Psl/Type/unit_enum.php#L18) +- [vec](./../../src/Psl/Type/vec.php#L16) +- [vector](./../../src/Psl/Type/vector.php#L18) #### `Interfaces` diff --git a/src/Psl/Type/Internal/ArrayKeyType.php b/src/Psl/Type/Internal/ArrayKeyType.php index d3be1262..02834fe3 100644 --- a/src/Psl/Type/Internal/ArrayKeyType.php +++ b/src/Psl/Type/Internal/ArrayKeyType.php @@ -14,6 +14,9 @@ */ final class ArrayKeyType extends UnionType { + /** + * @psalm-mutation-free + */ public function __construct() { /** @psalm-suppress MissingThrowsDocblock */ diff --git a/src/Psl/Type/Internal/BackedEnumType.php b/src/Psl/Type/Internal/BackedEnumType.php index 7905181b..b64f4c0d 100644 --- a/src/Psl/Type/Internal/BackedEnumType.php +++ b/src/Psl/Type/Internal/BackedEnumType.php @@ -18,6 +18,8 @@ final class BackedEnumType extends Type\Type { /** + * @psalm-mutation-free + * * @param class-string $enum */ public function __construct( diff --git a/src/Psl/Type/Internal/ClassStringType.php b/src/Psl/Type/Internal/ClassStringType.php index 04da6325..a31ab188 100644 --- a/src/Psl/Type/Internal/ClassStringType.php +++ b/src/Psl/Type/Internal/ClassStringType.php @@ -23,6 +23,8 @@ final class ClassStringType extends Type private string $classname; /** + * @psalm-mutation-free + * * @param class-string $classname */ public function __construct( diff --git a/src/Psl/Type/Internal/ConvertedType.php b/src/Psl/Type/Internal/ConvertedType.php index 04836a2b..a80a0a0d 100644 --- a/src/Psl/Type/Internal/ConvertedType.php +++ b/src/Psl/Type/Internal/ConvertedType.php @@ -24,6 +24,8 @@ final class ConvertedType extends Type\Type { /** + * @psalm-mutation-free + * * @param TypeInterface $from * @param TypeInterface $into * @param (Closure(I): O) $converter diff --git a/src/Psl/Type/Internal/DictType.php b/src/Psl/Type/Internal/DictType.php index 648368a3..a37908e7 100644 --- a/src/Psl/Type/Internal/DictType.php +++ b/src/Psl/Type/Internal/DictType.php @@ -23,6 +23,8 @@ final class DictType extends Type\Type { /** + * @psalm-mutation-free + * * @param Type\TypeInterface $key_type * @param Type\TypeInterface $value_type */ diff --git a/src/Psl/Type/Internal/InstanceOfType.php b/src/Psl/Type/Internal/InstanceOfType.php index 05d32ba8..02296fa5 100644 --- a/src/Psl/Type/Internal/InstanceOfType.php +++ b/src/Psl/Type/Internal/InstanceOfType.php @@ -23,6 +23,8 @@ final class InstanceOfType extends Type private string $classname; /** + * @psalm-mutation-free + * * @param class-string $classname */ public function __construct( diff --git a/src/Psl/Type/Internal/IntersectionType.php b/src/Psl/Type/Internal/IntersectionType.php index 9f6f2a46..99d01614 100644 --- a/src/Psl/Type/Internal/IntersectionType.php +++ b/src/Psl/Type/Internal/IntersectionType.php @@ -22,6 +22,8 @@ final class IntersectionType extends Type { /** + * @psalm-mutation-free + * * @param TypeInterface $left_type * @param TypeInterface $right_type */ diff --git a/src/Psl/Type/Internal/IterableType.php b/src/Psl/Type/Internal/IterableType.php index f817dc57..d91cabfd 100644 --- a/src/Psl/Type/Internal/IterableType.php +++ b/src/Psl/Type/Internal/IterableType.php @@ -24,6 +24,8 @@ final class IterableType extends Type\Type { /** + * @psalm-mutation-free + * * @param Type\TypeInterface $key_type * @param Type\TypeInterface $value_type */ diff --git a/src/Psl/Type/Internal/LiteralScalarType.php b/src/Psl/Type/Internal/LiteralScalarType.php index 6f64c66f..402a6be6 100644 --- a/src/Psl/Type/Internal/LiteralScalarType.php +++ b/src/Psl/Type/Internal/LiteralScalarType.php @@ -19,6 +19,8 @@ final class LiteralScalarType extends Type\Type { /** + * @psalm-mutation-free + * * @param T $value */ public function __construct( diff --git a/src/Psl/Type/Internal/MapType.php b/src/Psl/Type/Internal/MapType.php index 4e0912fe..315bdd1e 100644 --- a/src/Psl/Type/Internal/MapType.php +++ b/src/Psl/Type/Internal/MapType.php @@ -26,6 +26,8 @@ final class MapType extends Type\Type { /** + * @psalm-mutation-free + * * @param Type\TypeInterface $key_type * @param Type\TypeInterface $value_type */ diff --git a/src/Psl/Type/Internal/MutableMapType.php b/src/Psl/Type/Internal/MutableMapType.php index 7299e032..be89e1b1 100644 --- a/src/Psl/Type/Internal/MutableMapType.php +++ b/src/Psl/Type/Internal/MutableMapType.php @@ -26,6 +26,8 @@ final class MutableMapType extends Type\Type { /** + * @psalm-mutation-free + * * @param Type\TypeInterface $key_type * @param Type\TypeInterface $value_type */ diff --git a/src/Psl/Type/Internal/MutableVectorType.php b/src/Psl/Type/Internal/MutableVectorType.php index 8e8897b7..b8e3ea0c 100644 --- a/src/Psl/Type/Internal/MutableVectorType.php +++ b/src/Psl/Type/Internal/MutableVectorType.php @@ -24,6 +24,8 @@ final class MutableVectorType extends Type\Type { /** + * @psalm-mutation-free + * * @param Type\TypeInterface $value_type */ public function __construct( diff --git a/src/Psl/Type/Internal/NonEmptyDictType.php b/src/Psl/Type/Internal/NonEmptyDictType.php index 2c6c53b5..4187d5be 100644 --- a/src/Psl/Type/Internal/NonEmptyDictType.php +++ b/src/Psl/Type/Internal/NonEmptyDictType.php @@ -24,6 +24,8 @@ final class NonEmptyDictType extends Type\Type { /** + * @psalm-mutation-free + * * @param Type\TypeInterface $key_type * @param Type\TypeInterface $value_type */ diff --git a/src/Psl/Type/Internal/NonEmptyVecType.php b/src/Psl/Type/Internal/NonEmptyVecType.php index 8777d3b4..e88cb3b2 100644 --- a/src/Psl/Type/Internal/NonEmptyVecType.php +++ b/src/Psl/Type/Internal/NonEmptyVecType.php @@ -23,6 +23,8 @@ final class NonEmptyVecType extends Type\Type { /** + * @psalm-mutation-free + * * @param Type\TypeInterface $value_type */ public function __construct( diff --git a/src/Psl/Type/Internal/NullableType.php b/src/Psl/Type/Internal/NullableType.php index 5fa81e80..828fcd19 100644 --- a/src/Psl/Type/Internal/NullableType.php +++ b/src/Psl/Type/Internal/NullableType.php @@ -18,6 +18,8 @@ final class NullableType extends Type\Type { /** + * @psalm-mutation-free + * * @param Type\TypeInterface $inner */ public function __construct( diff --git a/src/Psl/Type/Internal/NumType.php b/src/Psl/Type/Internal/NumType.php index 162dfa5a..11434d3a 100644 --- a/src/Psl/Type/Internal/NumType.php +++ b/src/Psl/Type/Internal/NumType.php @@ -11,6 +11,9 @@ */ final class NumType extends UnionType { + /** + * @psalm-mutation-free + */ public function __construct() { /** @psalm-suppress MissingThrowsDocblock */ diff --git a/src/Psl/Type/Internal/OptionalType.php b/src/Psl/Type/Internal/OptionalType.php index 82274774..f330e74b 100644 --- a/src/Psl/Type/Internal/OptionalType.php +++ b/src/Psl/Type/Internal/OptionalType.php @@ -18,6 +18,8 @@ final class OptionalType extends Type\Type { /** + * @psalm-mutation-free + * * @param Type\TypeInterface $inner */ public function __construct( diff --git a/src/Psl/Type/Internal/ResourceType.php b/src/Psl/Type/Internal/ResourceType.php index 87577dbf..1f82c446 100644 --- a/src/Psl/Type/Internal/ResourceType.php +++ b/src/Psl/Type/Internal/ResourceType.php @@ -18,6 +18,9 @@ */ final class ResourceType extends Type\Type { + /** + * @psalm-mutation-free + */ public function __construct( private ?string $kind = null ) { diff --git a/src/Psl/Type/Internal/ScalarType.php b/src/Psl/Type/Internal/ScalarType.php index 8937782f..13a634dc 100644 --- a/src/Psl/Type/Internal/ScalarType.php +++ b/src/Psl/Type/Internal/ScalarType.php @@ -11,6 +11,9 @@ */ final class ScalarType extends UnionType { + /** + * @psalm-mutation-free + */ public function __construct() { /** @psalm-suppress MissingThrowsDocblock */ diff --git a/src/Psl/Type/Internal/ShapeType.php b/src/Psl/Type/Internal/ShapeType.php index 569dec88..0e307353 100644 --- a/src/Psl/Type/Internal/ShapeType.php +++ b/src/Psl/Type/Internal/ShapeType.php @@ -34,12 +34,15 @@ final class ShapeType extends Type\Type private array $requiredElements; /** + * @psalm-mutation-free + * * @param array> $elements_types */ public function __construct( private array $elements_types, private bool $allow_unknown_fields = false, ) { + /** @psalm-suppress ImpureFunctionCall - This implementation is pure. */ $this->requiredElements = array_filter( $elements_types, static fn (Type\TypeInterface $element): bool => ! $element->isOptional() diff --git a/src/Psl/Type/Internal/UnionType.php b/src/Psl/Type/Internal/UnionType.php index bce68782..7ad95c63 100644 --- a/src/Psl/Type/Internal/UnionType.php +++ b/src/Psl/Type/Internal/UnionType.php @@ -20,6 +20,8 @@ class UnionType extends Type\Type { /** + * @psalm-mutation-free + * * @param Type\TypeInterface $left_type * @param Type\TypeInterface $right_type */ diff --git a/src/Psl/Type/Internal/UnitEnumType.php b/src/Psl/Type/Internal/UnitEnumType.php index 78bc8604..58b27b6d 100644 --- a/src/Psl/Type/Internal/UnitEnumType.php +++ b/src/Psl/Type/Internal/UnitEnumType.php @@ -18,6 +18,8 @@ final class UnitEnumType extends Type\Type { /** + * @psalm-mutation-free + * * @param class-string $enum */ public function __construct( diff --git a/src/Psl/Type/Internal/VecType.php b/src/Psl/Type/Internal/VecType.php index ab49e760..afab71af 100644 --- a/src/Psl/Type/Internal/VecType.php +++ b/src/Psl/Type/Internal/VecType.php @@ -23,6 +23,8 @@ final class VecType extends Type\Type { /** + * @psalm-mutation-free + * * @param Type\TypeInterface $value_type */ public function __construct( diff --git a/src/Psl/Type/Internal/VectorType.php b/src/Psl/Type/Internal/VectorType.php index da5c8d0d..c223453d 100644 --- a/src/Psl/Type/Internal/VectorType.php +++ b/src/Psl/Type/Internal/VectorType.php @@ -24,6 +24,8 @@ final class VectorType extends Type\Type { /** + * @psalm-mutation-free + * * @param Type\TypeInterface $value_type */ public function __construct( diff --git a/src/Psl/Type/array_key.php b/src/Psl/Type/array_key.php index b11a3013..35c3a3ac 100644 --- a/src/Psl/Type/array_key.php +++ b/src/Psl/Type/array_key.php @@ -5,6 +5,10 @@ namespace Psl\Type; /** + * @psalm-pure + * + * @psalm-suppress ImpureStaticVariable - The $instance is always the same and is considered pure. + * * @return TypeInterface */ function array_key(): TypeInterface diff --git a/src/Psl/Type/backed_enum.php b/src/Psl/Type/backed_enum.php index 1c328ad6..21fc781f 100644 --- a/src/Psl/Type/backed_enum.php +++ b/src/Psl/Type/backed_enum.php @@ -7,6 +7,8 @@ use BackedEnum; /** + * @psalm-pure + * * @template T of BackedEnum * * @param class-string $enum diff --git a/src/Psl/Type/bool.php b/src/Psl/Type/bool.php index 7e9266df..d90bbf55 100644 --- a/src/Psl/Type/bool.php +++ b/src/Psl/Type/bool.php @@ -5,6 +5,10 @@ namespace Psl\Type; /** + * @psalm-pure + * + * @psalm-suppress ImpureStaticVariable - The $instance is always the same and is considered pure. + * * @return TypeInterface */ function bool(): TypeInterface diff --git a/src/Psl/Type/class_string.php b/src/Psl/Type/class_string.php index 207c1fc7..0d552e87 100644 --- a/src/Psl/Type/class_string.php +++ b/src/Psl/Type/class_string.php @@ -5,6 +5,8 @@ namespace Psl\Type; /** + * @psalm-pure + * * @template T * * @param class-string $classname diff --git a/src/Psl/Type/converted.php b/src/Psl/Type/converted.php index 87ed1544..ffaa90f7 100644 --- a/src/Psl/Type/converted.php +++ b/src/Psl/Type/converted.php @@ -7,6 +7,8 @@ use Closure; /** + * @psalm-pure + * * @template I * @template O * diff --git a/src/Psl/Type/dict.php b/src/Psl/Type/dict.php index 7bfb1220..cb282fe8 100644 --- a/src/Psl/Type/dict.php +++ b/src/Psl/Type/dict.php @@ -5,6 +5,8 @@ namespace Psl\Type; /** + * @psalm-pure + * * @template Tk of array-key * @template Tv * diff --git a/src/Psl/Type/f32.php b/src/Psl/Type/f32.php index 3965b958..2f28dab1 100644 --- a/src/Psl/Type/f32.php +++ b/src/Psl/Type/f32.php @@ -5,6 +5,10 @@ namespace Psl\Type; /** + * @psalm-pure + * + * @psalm-suppress ImpureStaticVariable - The $instance is always the same and is considered pure. + * * @ara-return TypeInterface * * @return TypeInterface diff --git a/src/Psl/Type/f64.php b/src/Psl/Type/f64.php index 86e5cd38..cd8b5114 100644 --- a/src/Psl/Type/f64.php +++ b/src/Psl/Type/f64.php @@ -5,6 +5,10 @@ namespace Psl\Type; /** + * @psalm-pure + * + * @psalm-suppress ImpureStaticVariable - The $instance is always the same and is considered pure. + * * @ara-return TypeInterface * * @return TypeInterface diff --git a/src/Psl/Type/float.php b/src/Psl/Type/float.php index 05500938..3077b961 100644 --- a/src/Psl/Type/float.php +++ b/src/Psl/Type/float.php @@ -5,6 +5,10 @@ namespace Psl\Type; /** + * @psalm-pure + * + * @psalm-suppress ImpureStaticVariable - The $instance is always the same and is considered pure. + * * @return TypeInterface */ function float(): TypeInterface diff --git a/src/Psl/Type/i16.php b/src/Psl/Type/i16.php index f6c4a490..4c5e2a6b 100644 --- a/src/Psl/Type/i16.php +++ b/src/Psl/Type/i16.php @@ -5,6 +5,10 @@ namespace Psl\Type; /** + * @psalm-pure + * + * @psalm-suppress ImpureStaticVariable - The $instance is always the same and is considered pure. + * * @ara-return TypeInterface * * @return TypeInterface> diff --git a/src/Psl/Type/i32.php b/src/Psl/Type/i32.php index 5c47897d..5ee52852 100644 --- a/src/Psl/Type/i32.php +++ b/src/Psl/Type/i32.php @@ -5,6 +5,10 @@ namespace Psl\Type; /** + * @psalm-pure + * + * @psalm-suppress ImpureStaticVariable - The $instance is always the same and is considered pure. + * * @ara-return TypeInterface * * @return TypeInterface> diff --git a/src/Psl/Type/i64.php b/src/Psl/Type/i64.php index 26982eb1..012059a6 100644 --- a/src/Psl/Type/i64.php +++ b/src/Psl/Type/i64.php @@ -5,6 +5,10 @@ namespace Psl\Type; /** + * @psalm-pure + * + * @psalm-suppress ImpureStaticVariable - The $instance is always the same and is considered pure. + * * @ara-return TypeInterface * * @return TypeInterface diff --git a/src/Psl/Type/i8.php b/src/Psl/Type/i8.php index 1b35e0f6..cb7ebec8 100644 --- a/src/Psl/Type/i8.php +++ b/src/Psl/Type/i8.php @@ -5,6 +5,10 @@ namespace Psl\Type; /** + * @psalm-pure + * + * @psalm-suppress ImpureStaticVariable - The $instance is always the same and is considered pure. + * * @ara-return TypeInterface * * @return TypeInterface> diff --git a/src/Psl/Type/instance_of.php b/src/Psl/Type/instance_of.php index 62da1866..0d4dd19f 100644 --- a/src/Psl/Type/instance_of.php +++ b/src/Psl/Type/instance_of.php @@ -5,6 +5,8 @@ namespace Psl\Type; /** + * @psalm-pure + * * @template T * * @param class-string $classname diff --git a/src/Psl/Type/int.php b/src/Psl/Type/int.php index 949a03d3..bf735acb 100644 --- a/src/Psl/Type/int.php +++ b/src/Psl/Type/int.php @@ -5,6 +5,10 @@ namespace Psl\Type; /** + * @psalm-pure + * + * @psalm-suppress ImpureStaticVariable - The $instance is always the same and is considered pure. + * * @return TypeInterface */ function int(): TypeInterface diff --git a/src/Psl/Type/intersection.php b/src/Psl/Type/intersection.php index 57886c4d..454764e0 100644 --- a/src/Psl/Type/intersection.php +++ b/src/Psl/Type/intersection.php @@ -5,6 +5,8 @@ namespace Psl\Type; /** + * @psalm-pure + * * @template TFirst * @template TSecond * @template TRest diff --git a/src/Psl/Type/iterable.php b/src/Psl/Type/iterable.php index 75aea72d..b0527250 100644 --- a/src/Psl/Type/iterable.php +++ b/src/Psl/Type/iterable.php @@ -5,6 +5,8 @@ namespace Psl\Type; /** + * @psalm-pure + * * @template Tk * @template Tv * diff --git a/src/Psl/Type/literal_scalar.php b/src/Psl/Type/literal_scalar.php index 906cba2b..a7a81f0a 100644 --- a/src/Psl/Type/literal_scalar.php +++ b/src/Psl/Type/literal_scalar.php @@ -5,6 +5,8 @@ namespace Psl\Type; /** + * @psalm-pure + * * @template T of string|int|float|bool * * @param T $value diff --git a/src/Psl/Type/map.php b/src/Psl/Type/map.php index 7b9d8ee6..9fea4741 100644 --- a/src/Psl/Type/map.php +++ b/src/Psl/Type/map.php @@ -7,6 +7,8 @@ use Psl\Collection; /** + * @psalm-pure + * * @template Tk of array-key * @template Tv * diff --git a/src/Psl/Type/mixed.php b/src/Psl/Type/mixed.php index 3d966c44..dc1f6342 100644 --- a/src/Psl/Type/mixed.php +++ b/src/Psl/Type/mixed.php @@ -5,6 +5,10 @@ namespace Psl\Type; /** + * @psalm-pure + * + * @psalm-suppress ImpureStaticVariable - The $instance is always the same and is considered pure. + * * @return TypeInterface */ function mixed(): TypeInterface diff --git a/src/Psl/Type/mixed_dict.php b/src/Psl/Type/mixed_dict.php index c1d8d3e7..0cfd49ba 100644 --- a/src/Psl/Type/mixed_dict.php +++ b/src/Psl/Type/mixed_dict.php @@ -5,6 +5,8 @@ namespace Psl\Type; /** + * @psalm-pure + * * @return TypeInterface> */ function mixed_dict(): TypeInterface diff --git a/src/Psl/Type/mixed_vec.php b/src/Psl/Type/mixed_vec.php index c6922661..93ca9628 100644 --- a/src/Psl/Type/mixed_vec.php +++ b/src/Psl/Type/mixed_vec.php @@ -5,6 +5,8 @@ namespace Psl\Type; /** + * @psalm-pure + * * @return TypeInterface> */ function mixed_vec(): TypeInterface diff --git a/src/Psl/Type/mutable_map.php b/src/Psl/Type/mutable_map.php index e66de651..54d1d3f7 100644 --- a/src/Psl/Type/mutable_map.php +++ b/src/Psl/Type/mutable_map.php @@ -7,6 +7,8 @@ use Psl\Collection; /** + * @psalm-pure + * * @template Tk of array-key * @template Tv * diff --git a/src/Psl/Type/mutable_vector.php b/src/Psl/Type/mutable_vector.php index 4614522e..be204335 100644 --- a/src/Psl/Type/mutable_vector.php +++ b/src/Psl/Type/mutable_vector.php @@ -7,6 +7,8 @@ use Psl\Collection; /** + * @psalm-pure + * * @template T * * @param TypeInterface $value_type diff --git a/src/Psl/Type/non_empty_dict.php b/src/Psl/Type/non_empty_dict.php index 8f6c0785..33991ab0 100644 --- a/src/Psl/Type/non_empty_dict.php +++ b/src/Psl/Type/non_empty_dict.php @@ -5,6 +5,8 @@ namespace Psl\Type; /** + * @psalm-pure + * * @template Tk of array-key * @template Tv * diff --git a/src/Psl/Type/non_empty_string.php b/src/Psl/Type/non_empty_string.php index 5864ac25..f7975bd4 100644 --- a/src/Psl/Type/non_empty_string.php +++ b/src/Psl/Type/non_empty_string.php @@ -5,6 +5,10 @@ namespace Psl\Type; /** + * @psalm-pure + * + * @psalm-suppress ImpureStaticVariable - The $instance is always the same and is considered pure. + * * @return TypeInterface */ function non_empty_string(): TypeInterface diff --git a/src/Psl/Type/non_empty_vec.php b/src/Psl/Type/non_empty_vec.php index b9555c1a..c57420ee 100644 --- a/src/Psl/Type/non_empty_vec.php +++ b/src/Psl/Type/non_empty_vec.php @@ -5,6 +5,8 @@ namespace Psl\Type; /** + * @psalm-pure + * * @template T * * @param TypeInterface $value_type diff --git a/src/Psl/Type/nonnull.php b/src/Psl/Type/nonnull.php index f79ec2d5..822310f2 100644 --- a/src/Psl/Type/nonnull.php +++ b/src/Psl/Type/nonnull.php @@ -5,6 +5,10 @@ namespace Psl\Type; /** + * @psalm-pure + * + * @psalm-suppress ImpureStaticVariable - The $instance is always the same and is considered pure. + * * @ara-return TypeInterface * * @return TypeInterface diff --git a/src/Psl/Type/null.php b/src/Psl/Type/null.php index d64d63fc..ec45d88a 100644 --- a/src/Psl/Type/null.php +++ b/src/Psl/Type/null.php @@ -5,6 +5,10 @@ namespace Psl\Type; /** + * @psalm-pure + * + * @psalm-suppress ImpureStaticVariable - The $instance is always the same and is considered pure. + * * @return TypeInterface */ function null(): TypeInterface diff --git a/src/Psl/Type/nullable.php b/src/Psl/Type/nullable.php index 0e21ca46..08891bce 100644 --- a/src/Psl/Type/nullable.php +++ b/src/Psl/Type/nullable.php @@ -5,6 +5,8 @@ namespace Psl\Type; /** + * @psalm-pure + * * @template T * * @param TypeInterface $inner_type diff --git a/src/Psl/Type/num.php b/src/Psl/Type/num.php index d9118b2c..000c90d5 100644 --- a/src/Psl/Type/num.php +++ b/src/Psl/Type/num.php @@ -5,6 +5,10 @@ namespace Psl\Type; /** + * @psalm-pure + * + * @psalm-suppress ImpureStaticVariable - The $instance is always the same and is considered pure. + * * @return TypeInterface */ function num(): TypeInterface diff --git a/src/Psl/Type/numeric_string.php b/src/Psl/Type/numeric_string.php index e02c3d2f..49d62985 100644 --- a/src/Psl/Type/numeric_string.php +++ b/src/Psl/Type/numeric_string.php @@ -5,6 +5,10 @@ namespace Psl\Type; /** + * @psalm-pure + * + * @psalm-suppress ImpureStaticVariable - The $instance is always the same and is considered pure. + * * @return TypeInterface */ function numeric_string(): TypeInterface diff --git a/src/Psl/Type/object.php b/src/Psl/Type/object.php index 5ede48f4..2e1b1fab 100644 --- a/src/Psl/Type/object.php +++ b/src/Psl/Type/object.php @@ -5,6 +5,10 @@ namespace Psl\Type; /** + * @psalm-pure + * + * @psalm-suppress ImpureStaticVariable - The $instance is always the same and is considered pure. + * * @return TypeInterface */ function object(): TypeInterface diff --git a/src/Psl/Type/optional.php b/src/Psl/Type/optional.php index 30a82ed4..a0e230b4 100644 --- a/src/Psl/Type/optional.php +++ b/src/Psl/Type/optional.php @@ -5,6 +5,8 @@ namespace Psl\Type; /** + * @psalm-pure + * * @template T * * @param TypeInterface $inner_type diff --git a/src/Psl/Type/positive_int.php b/src/Psl/Type/positive_int.php index d92473b8..0f2f32e9 100644 --- a/src/Psl/Type/positive_int.php +++ b/src/Psl/Type/positive_int.php @@ -5,6 +5,10 @@ namespace Psl\Type; /** + * @psalm-pure + * + * @psalm-suppress ImpureStaticVariable - The $instance is always the same and is considered pure. + * * @return TypeInterface * * @ara-return TypeInterface<0|uint> diff --git a/src/Psl/Type/resource.php b/src/Psl/Type/resource.php index 8c4a1b23..c0ffcbe7 100644 --- a/src/Psl/Type/resource.php +++ b/src/Psl/Type/resource.php @@ -5,6 +5,8 @@ namespace Psl\Type; /** + * @psalm-pure + * * @param ?string $kind The resource kind, if null, the resource type won't be validated. * * @return TypeInterface diff --git a/src/Psl/Type/scalar.php b/src/Psl/Type/scalar.php index 3b4d2e42..cb63dd24 100644 --- a/src/Psl/Type/scalar.php +++ b/src/Psl/Type/scalar.php @@ -5,6 +5,10 @@ namespace Psl\Type; /** + * @psalm-pure + * + * @psalm-suppress ImpureStaticVariable - The $instance is always the same and is considered pure. + * * @return TypeInterface */ function scalar(): TypeInterface diff --git a/src/Psl/Type/shape.php b/src/Psl/Type/shape.php index 3c98c7d3..12a567cb 100644 --- a/src/Psl/Type/shape.php +++ b/src/Psl/Type/shape.php @@ -5,6 +5,8 @@ namespace Psl\Type; /** + * @psalm-pure + * * @template Tk of array-key * @template Tv * diff --git a/src/Psl/Type/string.php b/src/Psl/Type/string.php index 5071debb..ba26c063 100644 --- a/src/Psl/Type/string.php +++ b/src/Psl/Type/string.php @@ -5,6 +5,10 @@ namespace Psl\Type; /** + * @psalm-pure + * + * @psalm-suppress ImpureStaticVariable - The $instance is always the same and is considered pure. + * * @return TypeInterface */ function string(): TypeInterface diff --git a/src/Psl/Type/u16.php b/src/Psl/Type/u16.php index 53afa82c..d6e5226c 100644 --- a/src/Psl/Type/u16.php +++ b/src/Psl/Type/u16.php @@ -5,6 +5,10 @@ namespace Psl\Type; /** + * @psalm-pure + * + * @psalm-suppress ImpureStaticVariable - The $instance is always the same and is considered pure. + * * @ara-return TypeInterface * * @return TypeInterface> diff --git a/src/Psl/Type/u32.php b/src/Psl/Type/u32.php index a3b9e1dc..01aaf531 100644 --- a/src/Psl/Type/u32.php +++ b/src/Psl/Type/u32.php @@ -5,6 +5,10 @@ namespace Psl\Type; /** + * @psalm-pure + * + * @psalm-suppress ImpureStaticVariable - The $instance is always the same and is considered pure. + * * @ara-return TypeInterface * * @return TypeInterface> diff --git a/src/Psl/Type/u8.php b/src/Psl/Type/u8.php index f1eee385..05658980 100644 --- a/src/Psl/Type/u8.php +++ b/src/Psl/Type/u8.php @@ -5,6 +5,10 @@ namespace Psl\Type; /** + * @psalm-pure + * + * @psalm-suppress ImpureStaticVariable - The $instance is always the same and is considered pure. + * * @ara-return TypeInterface * * @return TypeInterface> diff --git a/src/Psl/Type/uint.php b/src/Psl/Type/uint.php index 70838a64..e98af807 100644 --- a/src/Psl/Type/uint.php +++ b/src/Psl/Type/uint.php @@ -5,6 +5,10 @@ namespace Psl\Type; /** + * @psalm-pure + * + * @psalm-suppress ImpureStaticVariable - The $instance is always the same and is considered pure. + * * @ara-return TypeInterface * * @return TypeInterface> diff --git a/src/Psl/Type/union.php b/src/Psl/Type/union.php index 42306222..f5d7cc3f 100644 --- a/src/Psl/Type/union.php +++ b/src/Psl/Type/union.php @@ -5,6 +5,8 @@ namespace Psl\Type; /** + * @psalm-pure + * * @template T * * @param TypeInterface $first diff --git a/src/Psl/Type/unit_enum.php b/src/Psl/Type/unit_enum.php index 7292056a..123451d6 100644 --- a/src/Psl/Type/unit_enum.php +++ b/src/Psl/Type/unit_enum.php @@ -7,6 +7,8 @@ use UnitEnum; /** + * @psalm-pure + * * @template T of UnitEnum * * @param class-string $enum diff --git a/src/Psl/Type/vec.php b/src/Psl/Type/vec.php index fae769a4..3fdfad29 100644 --- a/src/Psl/Type/vec.php +++ b/src/Psl/Type/vec.php @@ -5,6 +5,8 @@ namespace Psl\Type; /** + * @psalm-pure + * * @template T * * @param TypeInterface $value_type diff --git a/src/Psl/Type/vector.php b/src/Psl/Type/vector.php index 5cfdbed5..b8330941 100644 --- a/src/Psl/Type/vector.php +++ b/src/Psl/Type/vector.php @@ -7,6 +7,8 @@ use Psl\Collection; /** + * @psalm-pure + * * @template T * * @param TypeInterface $value_type diff --git a/tests/static-analysis/Type/converted.php b/tests/static-analysis/Type/converted.php new file mode 100644 index 00000000..ae55d1e1 --- /dev/null +++ b/tests/static-analysis/Type/converted.php @@ -0,0 +1,21 @@ + + */ +function testsPurity(): Type\TypeInterface +{ + return Type\converted( + Type\int(), + Type\string(), + static fn (int $value): string => (string) $value + ); +}