diff --git a/.travis.yml b/.travis.yml index a9f9cd8..c6ac198 100755 --- a/.travis.yml +++ b/.travis.yml @@ -18,6 +18,7 @@ before_script: script: - vendor/bin/phpunit + - vendor/bin/psalm --shepherd # Use Travis' new container-based infrastructure. # See http://docs.travis-ci.com/user/migrating-from-legacy/#How-can-I-use-container-based-infrastructure%3F diff --git a/README.md b/README.md index 7bdd4f8..6065f49 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![Build Status](https://travis-ci.org/myclabs/php-enum.png?branch=master)](https://travis-ci.org/myclabs/php-enum) [![Latest Stable Version](https://poser.pugx.org/myclabs/php-enum/version.png)](https://packagist.org/packages/myclabs/php-enum) [![Total Downloads](https://poser.pugx.org/myclabs/php-enum/downloads.png)](https://packagist.org/packages/myclabs/php-enum) +[![psalm](https://shepherd.dev/github/myclabs/php-enum/coverage.svg)](https://shepherd.dev/github/myclabs/php-enum) Maintenance for this project is [supported via Tidelift](https://tidelift.com/subscription/pkg/packagist-myclabs-php-enum?utm_source=packagist-myclabs-php-enum&utm_medium=referral&utm_campaign=readme). diff --git a/composer.json b/composer.json index 871156d..1c7ba1c 100644 --- a/composer.json +++ b/composer.json @@ -23,10 +23,11 @@ }, "require": { "php": ">=7.1", - "ext-json": "*" + "ext-json": "*", + "vimeo/psalm": "^3.8" }, "require-dev": { - "phpunit/phpunit": "^4.8.35|^5.7|^6.0", + "phpunit/phpunit": "^7", "squizlabs/php_codesniffer": "1.*" } } diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 0000000..b07e929 --- /dev/null +++ b/psalm.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + diff --git a/src/Enum.php b/src/Enum.php index 3bce0dc..5c15251 100644 --- a/src/Enum.php +++ b/src/Enum.php @@ -14,6 +14,9 @@ * @author Matthieu Napoli * @author Daniel Costa * @author Mirosław Filip + * + * @template T + * @psalm-immutable */ abstract class Enum implements \JsonSerializable { @@ -21,6 +24,7 @@ abstract class Enum implements \JsonSerializable * Enum value * * @var mixed + * @psalm-var T */ protected $value; @@ -28,6 +32,7 @@ abstract class Enum implements \JsonSerializable * Store existing constants in a static cache per object. * * @var array + * @psalm-var array> */ protected static $cache = []; @@ -36,6 +41,8 @@ abstract class Enum implements \JsonSerializable * * @param mixed $value * + * @psalm-param T $value + * @psalm-suppress InvalidCast * @throws \UnexpectedValueException if incompatible type is given. */ public function __construct($value) @@ -45,7 +52,7 @@ public function __construct($value) } if (!$this->isValid($value)) { - throw new \UnexpectedValueException("Value '$value' is not part of the enum " . \get_called_class()); + throw new \UnexpectedValueException("Value '$value' is not part of the enum " . static::class); } $this->value = $value; @@ -53,6 +60,7 @@ public function __construct($value) /** * @return mixed + * @psalm-return T */ public function getValue() { @@ -62,6 +70,7 @@ public function getValue() /** * Returns the enum key (i.e. the constant name). * + * @psalm-pure * @return mixed */ public function getKey() @@ -70,6 +79,7 @@ public function getKey() } /** + * @psalm-suppress InvalidCast * @return string */ public function __toString() @@ -83,13 +93,14 @@ public function __toString() * * This method is final, for more information read https://github.com/myclabs/php-enum/issues/4 * + * @psalm-param mixed $variable * @return bool */ final public function equals($variable = null): bool { return $variable instanceof self && $this->getValue() === $variable->getValue() - && \get_called_class() === \get_class($variable); + && static::class === \get_class($variable); } /** @@ -121,11 +132,14 @@ public static function values() /** * Returns all possible values as an array * + * @psalm-pure + * @psalm-return array * @return array Constant name in key, constant value in value */ public static function toArray() { - $class = \get_called_class(); + $class = static::class; + if (!isset(static::$cache[$class])) { $reflection = new \ReflectionClass($class); static::$cache[$class] = $reflection->getConstants(); @@ -138,6 +152,7 @@ public static function toArray() * Check if is valid enum value * * @param $value + * @psalm-param mixed $value * * @return bool */ @@ -150,6 +165,7 @@ public static function isValid($value) * Check if is valid enum key * * @param $key + * @psalm-param string $key * * @return bool */ @@ -165,6 +181,8 @@ public static function isValidKey($key) * * @param $value * + * @psalm-param mixed $value + * @psalm-pure * @return mixed */ public static function search($value) @@ -188,7 +206,7 @@ public static function __callStatic($name, $arguments) return new static($array[$name]); } - throw new \BadMethodCallException("No static method or enum constant '$name' in class " . \get_called_class()); + throw new \BadMethodCallException("No static method or enum constant '$name' in class " . static::class); } /**