Skip to content

Commit

Permalink
Merge pull request #140 from Ocramius/feature/pure-enumerable
Browse files Browse the repository at this point in the history
Added purity markers for enumerables, improved type definitions
  • Loading branch information
marc-mabe authored Apr 5, 2020
2 parents ee57fff + c2c18a6 commit 93b7bbb
Show file tree
Hide file tree
Showing 7 changed files with 342 additions and 80 deletions.
9 changes: 9 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/.github export-ignore
/bench export-ignore
/tests export-ignore
.gitattributes export-ignore
.gitignore export-ignore
.travis.yml export-ignore
phpbench.json export-ignore
phpunit.xml.dist export-ignore
psalm.xml export-ignore
151 changes: 76 additions & 75 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,75 +1,76 @@
sudo: false
language: php

cache:
directories:
- $HOME/.composer/cache
- $HOME/.local
- $HOME/ocular.phar
- $HOME/phpDocumentor.phar

env:
global:
- CODE_COVERAGE="0"
- PHPDOC="0"

matrix:
fast_finish: true
include:
- php: 7.1
env:
- CODE_COVERAGE="1"
- php: 7.2
env:
- CODE_COVERAGE="1"
- PHPDOC="1"
- php: 7.3
env:
- CODE_COVERAGE="1"
- php: 7.4
env:
- CODE_COVERAGE="1"
- php: nightly
allow_failures:
- php: nightly

install:
- if [ "${CODE_COVERAGE}" == "0" ]; then
phpenv config-rm xdebug.ini || return 0;
fi
- if [ "${CODE_COVERAGE}" == "1" ]; then
wget -q -N -t 3 --retry-connrefused 'https://scrutinizer-ci.com/ocular.phar' || return 0;
fi
- if [ "${PHPDOC}" == "1" ]; then
wget -q -N -t 3 --retry-connrefused 'https://github.com/phpDocumentor/phpDocumentor2/releases/download/v2.9.0/phpDocumentor.phar' || return 0;
composer require --no-update --dev "evert/phpdoc-md:~0.2.0" || return 0;
fi
- composer install -n

script:
- if [ "$CODE_COVERAGE" == "1" ]; then
php -d 'zend.assertions=1' vendor/bin/phpunit --verbose --coverage-text --coverage-clover=coverage.clover;
else
php -d 'zend.assertions=1' vendor/bin/phpunit --verbose;
fi

# run benchmarks to make sure they are working fine
- php vendor/bin/phpbench run --no-interaction --revs=1 --retry-threshold=100

after_script:
- if [ "${CODE_COVERAGE}" == "1" ]; then
php ocular.phar code-coverage:upload --format=php-clover coverage.clover;
fi
- if [ "${PHPDOC}" == "1" ]; then
git clone "https://${CI_USER_TOKEN}@github.com/marc-mabe/php-enum.wiki.git" &&
php phpDocumentor.phar -d src -t docs/ --template="xml" &&
php vendor/bin/phpdocmd --lt '%c' --index 'Home.md' docs/structure.xml php-enum.wiki/ &&
cp php-enum.wiki/Home.md php-enum.wiki/_Sidebar.md &&
cd php-enum.wiki/ &&
git add . &&
git commit -m "auto generated PHP doc" &&
git push origin master:master;
fi

notifications:
email: false
sudo: false
language: php

cache:
directories:
- $HOME/.composer/cache
- $HOME/.local
- $HOME/ocular.phar
- $HOME/phpDocumentor.phar

env:
global:
- CODE_COVERAGE="0"
- PHPDOC="0"

matrix:
fast_finish: true
include:
- php: 7.1
env:
- CODE_COVERAGE="1"
- php: 7.2
env:
- CODE_COVERAGE="1"
- PHPDOC="1"
- php: 7.3
env:
- CODE_COVERAGE="1"
- php: 7.4
env:
- CODE_COVERAGE="1"
- php: nightly
allow_failures:
- php: nightly

install:
- if [ "${CODE_COVERAGE}" == "0" ]; then
phpenv config-rm xdebug.ini || return 0;
fi
- if [ "${CODE_COVERAGE}" == "1" ]; then
wget -q -N -t 3 --retry-connrefused 'https://scrutinizer-ci.com/ocular.phar' || return 0;
fi
- if [ "${PHPDOC}" == "1" ]; then
wget -q -N -t 3 --retry-connrefused 'https://github.com/phpDocumentor/phpDocumentor2/releases/download/v2.9.0/phpDocumentor.phar' || return 0;
composer require --no-update --dev "evert/phpdoc-md:~0.2.0" || return 0;
fi
- composer install -n

script:
- if [ "$CODE_COVERAGE" == "1" ]; then
php -d 'zend.assertions=1' vendor/bin/phpunit --verbose --coverage-text --coverage-clover=coverage.clover;
else
php -d 'zend.assertions=1' vendor/bin/phpunit --verbose;
fi

# run benchmarks to make sure they are working fine
- php vendor/bin/phpbench run --no-interaction --revs=1 --retry-threshold=100
- vendor/bin/psalm

after_script:
- if [ "${CODE_COVERAGE}" == "1" ]; then
php ocular.phar code-coverage:upload --format=php-clover coverage.clover;
fi
- if [ "${PHPDOC}" == "1" ]; then
git clone "https://${CI_USER_TOKEN}@github.com/marc-mabe/php-enum.wiki.git" &&
php phpDocumentor.phar -d src -t docs/ --template="xml" &&
php vendor/bin/phpdocmd --lt '%c' --index 'Home.md' docs/structure.xml php-enum.wiki/ &&
cp php-enum.wiki/Home.md php-enum.wiki/_Sidebar.md &&
cd php-enum.wiki/ &&
git add . &&
git commit -m "auto generated PHP doc" &&
git push origin master:master;
fi

notifications:
email: false
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@
"ext-reflection": "*"
},
"require-dev": {
"phpunit/phpunit": "^6.0",
"phpbench/phpbench": "^0.16.1"
"phpunit/phpunit": "^7.0",
"phpbench/phpbench": "^0.16.1",
"vimeo/psalm": "^3.10"
},
"autoload": {
"psr-4": {
Expand Down
16 changes: 16 additions & 0 deletions psalm.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0"?>
<psalm
totallyTyped="true"
errorLevel="1"
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
<projectFiles>
<directory name="tests/MabeEnumStaticAnalysis" />
<ignoreFiles>
<directory name="vendor" />
</ignoreFiles>
</projectFiles>
</psalm>
45 changes: 42 additions & 3 deletions src/Enum.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
* @copyright 2019 Marc Bennewitz
* @license http://github.com/marc-mabe/php-enum/blob/master/LICENSE.txt New BSD License
* @link http://github.com/marc-mabe/php-enum for the canonical source repository
*
* @psalm-immutable
*/
abstract class Enum
{
Expand Down Expand Up @@ -87,6 +89,8 @@ final private function __clone()
/**
* @throws LogicException Enums are not serializable
* because instances are implemented as singletons
*
* @psalm-return never-return
*/
final public function __sleep()
{
Expand All @@ -96,6 +100,8 @@ final public function __sleep()
/**
* @throws LogicException Enums are not serializable
* because instances are implemented as singletons
*
* @psalm-return never-return
*/
final public function __wakeup()
{
Expand All @@ -116,6 +122,8 @@ final public function getValue()
* Get the name of the enumerator
*
* @return string
*
* @psalm-return non-empty-string
*/
final public function getName()
{
Expand Down Expand Up @@ -170,6 +178,8 @@ final public function is($enumerator)
* @return static
* @throws InvalidArgumentException On an unknown or invalid value
* @throws LogicException On ambiguous constant values
*
* @psalm-pure
*/
final public static function get($enumerator)
{
Expand All @@ -187,6 +197,8 @@ final public static function get($enumerator)
* @return static
* @throws InvalidArgumentException On an unknown or invalid value
* @throws LogicException On ambiguous constant values
*
* @psalm-pure
*/
final public static function byValue($value)
{
Expand Down Expand Up @@ -214,6 +226,8 @@ final public static function byValue($value)
* @return static
* @throws InvalidArgumentException On an invalid or unknown name
* @throws LogicException On ambiguous values
*
* @psalm-pure
*/
final public static function byName(string $name)
{
Expand Down Expand Up @@ -241,6 +255,8 @@ final public static function byName(string $name)
* @return static
* @throws InvalidArgumentException On an invalid ordinal number
* @throws LogicException On ambiguous values
*
* @psalm-pure
*/
final public static function byOrdinal(int $ordinal)
{
Expand All @@ -263,6 +279,9 @@ final public static function byOrdinal(int $ordinal)
* Get a list of enumerator instances ordered by ordinal number
*
* @return static[]
*
* @psalm-return list<static>
* @psalm-pure
*/
final public static function getEnumerators()
{
Expand All @@ -276,6 +295,9 @@ final public static function getEnumerators()
* Get a list of enumerator values ordered by ordinal number
*
* @return mixed[]
*
* @psalm-return list<null|bool|int|float|string|array>
* @psalm-pure
*/
final public static function getValues()
{
Expand All @@ -286,6 +308,9 @@ final public static function getValues()
* Get a list of enumerator names ordered by ordinal number
*
* @return string[]
*
* @psalm-return list<non-empty-string>
* @psalm-pure
*/
final public static function getNames()
{
Expand All @@ -294,11 +319,14 @@ final public static function getNames()
}
return self::$names[static::class];
}

/**
* Get a list of enumerator ordinal numbers
*
* @return int[]
*
* @psalm-return list<int>
* @psalm-pure
*/
final public static function getOrdinals()
{
Expand All @@ -309,8 +337,11 @@ final public static function getOrdinals()
/**
* Get all available constants of the called class
*
* @return array
* @return mixed[]
* @throws LogicException On ambiguous constant values
*
* @psalm-return array<non-empty-string, null|bool|int|float|string|array>
* @psalm-pure
*/
final public static function getConstants()
{
Expand Down Expand Up @@ -361,9 +392,11 @@ private static function noAmbiguousValues($constants)

/**
* Test if the given enumerator is part of this enumeration
*
*
* @param static|null|bool|int|float|string|array $enumerator
* @return bool
*
* @psalm-pure
*/
final public static function has($enumerator)
{
Expand All @@ -376,6 +409,8 @@ final public static function has($enumerator)
*
* @param null|bool|int|float|string|array $value
* @return bool
*
* @psalm-pure
*/
final public static function hasValue($value)
{
Expand All @@ -387,6 +422,8 @@ final public static function hasValue($value)
*
* @param string $name
* @return bool
*
* @psalm-pure
*/
final public static function hasName(string $name)
{
Expand All @@ -404,6 +441,8 @@ final public static function hasName(string $name)
* @return static
* @throws InvalidArgumentException On an invalid or unknown name
* @throws LogicException On ambiguous constant values
*
* @psalm-pure
*/
final public static function __callStatic(string $method, array $args)
{
Expand Down
26 changes: 26 additions & 0 deletions tests/MabeEnumStaticAnalysis/DummyEnum.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace MabeEnumStaticAnalysis;

use MabeEnum\Enum;

/** @psalm-immutable enums are immutable */
final class DummyEnum extends Enum
{
public const A = 'A_VALUE';
public const B = 'B_VALUE';

/** @psalm-pure */
public static function a(): self
{
return self::get(self::A);
}

/** @psalm-pure */
public static function b(): self
{
return self::get(self::B);
}
}
Loading

0 comments on commit 93b7bbb

Please sign in to comment.