Skip to content

Commit 93b7bbb

Browse files
authored
Merge pull request #140 from Ocramius/feature/pure-enumerable
Added purity markers for enumerables, improved type definitions
2 parents ee57fff + c2c18a6 commit 93b7bbb

File tree

7 files changed

+342
-80
lines changed

7 files changed

+342
-80
lines changed

.gitattributes

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/.github export-ignore
2+
/bench export-ignore
3+
/tests export-ignore
4+
.gitattributes export-ignore
5+
.gitignore export-ignore
6+
.travis.yml export-ignore
7+
phpbench.json export-ignore
8+
phpunit.xml.dist export-ignore
9+
psalm.xml export-ignore

.travis.yml

+76-75
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,76 @@
1-
sudo: false
2-
language: php
3-
4-
cache:
5-
directories:
6-
- $HOME/.composer/cache
7-
- $HOME/.local
8-
- $HOME/ocular.phar
9-
- $HOME/phpDocumentor.phar
10-
11-
env:
12-
global:
13-
- CODE_COVERAGE="0"
14-
- PHPDOC="0"
15-
16-
matrix:
17-
fast_finish: true
18-
include:
19-
- php: 7.1
20-
env:
21-
- CODE_COVERAGE="1"
22-
- php: 7.2
23-
env:
24-
- CODE_COVERAGE="1"
25-
- PHPDOC="1"
26-
- php: 7.3
27-
env:
28-
- CODE_COVERAGE="1"
29-
- php: 7.4
30-
env:
31-
- CODE_COVERAGE="1"
32-
- php: nightly
33-
allow_failures:
34-
- php: nightly
35-
36-
install:
37-
- if [ "${CODE_COVERAGE}" == "0" ]; then
38-
phpenv config-rm xdebug.ini || return 0;
39-
fi
40-
- if [ "${CODE_COVERAGE}" == "1" ]; then
41-
wget -q -N -t 3 --retry-connrefused 'https://scrutinizer-ci.com/ocular.phar' || return 0;
42-
fi
43-
- if [ "${PHPDOC}" == "1" ]; then
44-
wget -q -N -t 3 --retry-connrefused 'https://github.com/phpDocumentor/phpDocumentor2/releases/download/v2.9.0/phpDocumentor.phar' || return 0;
45-
composer require --no-update --dev "evert/phpdoc-md:~0.2.0" || return 0;
46-
fi
47-
- composer install -n
48-
49-
script:
50-
- if [ "$CODE_COVERAGE" == "1" ]; then
51-
php -d 'zend.assertions=1' vendor/bin/phpunit --verbose --coverage-text --coverage-clover=coverage.clover;
52-
else
53-
php -d 'zend.assertions=1' vendor/bin/phpunit --verbose;
54-
fi
55-
56-
# run benchmarks to make sure they are working fine
57-
- php vendor/bin/phpbench run --no-interaction --revs=1 --retry-threshold=100
58-
59-
after_script:
60-
- if [ "${CODE_COVERAGE}" == "1" ]; then
61-
php ocular.phar code-coverage:upload --format=php-clover coverage.clover;
62-
fi
63-
- if [ "${PHPDOC}" == "1" ]; then
64-
git clone "https://${CI_USER_TOKEN}@github.com/marc-mabe/php-enum.wiki.git" &&
65-
php phpDocumentor.phar -d src -t docs/ --template="xml" &&
66-
php vendor/bin/phpdocmd --lt '%c' --index 'Home.md' docs/structure.xml php-enum.wiki/ &&
67-
cp php-enum.wiki/Home.md php-enum.wiki/_Sidebar.md &&
68-
cd php-enum.wiki/ &&
69-
git add . &&
70-
git commit -m "auto generated PHP doc" &&
71-
git push origin master:master;
72-
fi
73-
74-
notifications:
75-
email: false
1+
sudo: false
2+
language: php
3+
4+
cache:
5+
directories:
6+
- $HOME/.composer/cache
7+
- $HOME/.local
8+
- $HOME/ocular.phar
9+
- $HOME/phpDocumentor.phar
10+
11+
env:
12+
global:
13+
- CODE_COVERAGE="0"
14+
- PHPDOC="0"
15+
16+
matrix:
17+
fast_finish: true
18+
include:
19+
- php: 7.1
20+
env:
21+
- CODE_COVERAGE="1"
22+
- php: 7.2
23+
env:
24+
- CODE_COVERAGE="1"
25+
- PHPDOC="1"
26+
- php: 7.3
27+
env:
28+
- CODE_COVERAGE="1"
29+
- php: 7.4
30+
env:
31+
- CODE_COVERAGE="1"
32+
- php: nightly
33+
allow_failures:
34+
- php: nightly
35+
36+
install:
37+
- if [ "${CODE_COVERAGE}" == "0" ]; then
38+
phpenv config-rm xdebug.ini || return 0;
39+
fi
40+
- if [ "${CODE_COVERAGE}" == "1" ]; then
41+
wget -q -N -t 3 --retry-connrefused 'https://scrutinizer-ci.com/ocular.phar' || return 0;
42+
fi
43+
- if [ "${PHPDOC}" == "1" ]; then
44+
wget -q -N -t 3 --retry-connrefused 'https://github.com/phpDocumentor/phpDocumentor2/releases/download/v2.9.0/phpDocumentor.phar' || return 0;
45+
composer require --no-update --dev "evert/phpdoc-md:~0.2.0" || return 0;
46+
fi
47+
- composer install -n
48+
49+
script:
50+
- if [ "$CODE_COVERAGE" == "1" ]; then
51+
php -d 'zend.assertions=1' vendor/bin/phpunit --verbose --coverage-text --coverage-clover=coverage.clover;
52+
else
53+
php -d 'zend.assertions=1' vendor/bin/phpunit --verbose;
54+
fi
55+
56+
# run benchmarks to make sure they are working fine
57+
- php vendor/bin/phpbench run --no-interaction --revs=1 --retry-threshold=100
58+
- vendor/bin/psalm
59+
60+
after_script:
61+
- if [ "${CODE_COVERAGE}" == "1" ]; then
62+
php ocular.phar code-coverage:upload --format=php-clover coverage.clover;
63+
fi
64+
- if [ "${PHPDOC}" == "1" ]; then
65+
git clone "https://${CI_USER_TOKEN}@github.com/marc-mabe/php-enum.wiki.git" &&
66+
php phpDocumentor.phar -d src -t docs/ --template="xml" &&
67+
php vendor/bin/phpdocmd --lt '%c' --index 'Home.md' docs/structure.xml php-enum.wiki/ &&
68+
cp php-enum.wiki/Home.md php-enum.wiki/_Sidebar.md &&
69+
cd php-enum.wiki/ &&
70+
git add . &&
71+
git commit -m "auto generated PHP doc" &&
72+
git push origin master:master;
73+
fi
74+
75+
notifications:
76+
email: false

composer.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@
2121
"ext-reflection": "*"
2222
},
2323
"require-dev": {
24-
"phpunit/phpunit": "^6.0",
25-
"phpbench/phpbench": "^0.16.1"
24+
"phpunit/phpunit": "^7.0",
25+
"phpbench/phpbench": "^0.16.1",
26+
"vimeo/psalm": "^3.10"
2627
},
2728
"autoload": {
2829
"psr-4": {

psalm.xml

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0"?>
2+
<psalm
3+
totallyTyped="true"
4+
errorLevel="1"
5+
resolveFromConfigFile="true"
6+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
7+
xmlns="https://getpsalm.org/schema/config"
8+
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
9+
>
10+
<projectFiles>
11+
<directory name="tests/MabeEnumStaticAnalysis" />
12+
<ignoreFiles>
13+
<directory name="vendor" />
14+
</ignoreFiles>
15+
</projectFiles>
16+
</psalm>

src/Enum.php

+42-3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
* @copyright 2019 Marc Bennewitz
1515
* @license http://github.com/marc-mabe/php-enum/blob/master/LICENSE.txt New BSD License
1616
* @link http://github.com/marc-mabe/php-enum for the canonical source repository
17+
*
18+
* @psalm-immutable
1719
*/
1820
abstract class Enum
1921
{
@@ -87,6 +89,8 @@ final private function __clone()
8789
/**
8890
* @throws LogicException Enums are not serializable
8991
* because instances are implemented as singletons
92+
*
93+
* @psalm-return never-return
9094
*/
9195
final public function __sleep()
9296
{
@@ -96,6 +100,8 @@ final public function __sleep()
96100
/**
97101
* @throws LogicException Enums are not serializable
98102
* because instances are implemented as singletons
103+
*
104+
* @psalm-return never-return
99105
*/
100106
final public function __wakeup()
101107
{
@@ -116,6 +122,8 @@ final public function getValue()
116122
* Get the name of the enumerator
117123
*
118124
* @return string
125+
*
126+
* @psalm-return non-empty-string
119127
*/
120128
final public function getName()
121129
{
@@ -170,6 +178,8 @@ final public function is($enumerator)
170178
* @return static
171179
* @throws InvalidArgumentException On an unknown or invalid value
172180
* @throws LogicException On ambiguous constant values
181+
*
182+
* @psalm-pure
173183
*/
174184
final public static function get($enumerator)
175185
{
@@ -187,6 +197,8 @@ final public static function get($enumerator)
187197
* @return static
188198
* @throws InvalidArgumentException On an unknown or invalid value
189199
* @throws LogicException On ambiguous constant values
200+
*
201+
* @psalm-pure
190202
*/
191203
final public static function byValue($value)
192204
{
@@ -214,6 +226,8 @@ final public static function byValue($value)
214226
* @return static
215227
* @throws InvalidArgumentException On an invalid or unknown name
216228
* @throws LogicException On ambiguous values
229+
*
230+
* @psalm-pure
217231
*/
218232
final public static function byName(string $name)
219233
{
@@ -241,6 +255,8 @@ final public static function byName(string $name)
241255
* @return static
242256
* @throws InvalidArgumentException On an invalid ordinal number
243257
* @throws LogicException On ambiguous values
258+
*
259+
* @psalm-pure
244260
*/
245261
final public static function byOrdinal(int $ordinal)
246262
{
@@ -263,6 +279,9 @@ final public static function byOrdinal(int $ordinal)
263279
* Get a list of enumerator instances ordered by ordinal number
264280
*
265281
* @return static[]
282+
*
283+
* @psalm-return list<static>
284+
* @psalm-pure
266285
*/
267286
final public static function getEnumerators()
268287
{
@@ -276,6 +295,9 @@ final public static function getEnumerators()
276295
* Get a list of enumerator values ordered by ordinal number
277296
*
278297
* @return mixed[]
298+
*
299+
* @psalm-return list<null|bool|int|float|string|array>
300+
* @psalm-pure
279301
*/
280302
final public static function getValues()
281303
{
@@ -286,6 +308,9 @@ final public static function getValues()
286308
* Get a list of enumerator names ordered by ordinal number
287309
*
288310
* @return string[]
311+
*
312+
* @psalm-return list<non-empty-string>
313+
* @psalm-pure
289314
*/
290315
final public static function getNames()
291316
{
@@ -294,11 +319,14 @@ final public static function getNames()
294319
}
295320
return self::$names[static::class];
296321
}
297-
322+
298323
/**
299324
* Get a list of enumerator ordinal numbers
300325
*
301326
* @return int[]
327+
*
328+
* @psalm-return list<int>
329+
* @psalm-pure
302330
*/
303331
final public static function getOrdinals()
304332
{
@@ -309,8 +337,11 @@ final public static function getOrdinals()
309337
/**
310338
* Get all available constants of the called class
311339
*
312-
* @return array
340+
* @return mixed[]
313341
* @throws LogicException On ambiguous constant values
342+
*
343+
* @psalm-return array<non-empty-string, null|bool|int|float|string|array>
344+
* @psalm-pure
314345
*/
315346
final public static function getConstants()
316347
{
@@ -361,9 +392,11 @@ private static function noAmbiguousValues($constants)
361392

362393
/**
363394
* Test if the given enumerator is part of this enumeration
364-
*
395+
*
365396
* @param static|null|bool|int|float|string|array $enumerator
366397
* @return bool
398+
*
399+
* @psalm-pure
367400
*/
368401
final public static function has($enumerator)
369402
{
@@ -376,6 +409,8 @@ final public static function has($enumerator)
376409
*
377410
* @param null|bool|int|float|string|array $value
378411
* @return bool
412+
*
413+
* @psalm-pure
379414
*/
380415
final public static function hasValue($value)
381416
{
@@ -387,6 +422,8 @@ final public static function hasValue($value)
387422
*
388423
* @param string $name
389424
* @return bool
425+
*
426+
* @psalm-pure
390427
*/
391428
final public static function hasName(string $name)
392429
{
@@ -404,6 +441,8 @@ final public static function hasName(string $name)
404441
* @return static
405442
* @throws InvalidArgumentException On an invalid or unknown name
406443
* @throws LogicException On ambiguous constant values
444+
*
445+
* @psalm-pure
407446
*/
408447
final public static function __callStatic(string $method, array $args)
409448
{
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MabeEnumStaticAnalysis;
6+
7+
use MabeEnum\Enum;
8+
9+
/** @psalm-immutable enums are immutable */
10+
final class DummyEnum extends Enum
11+
{
12+
public const A = 'A_VALUE';
13+
public const B = 'B_VALUE';
14+
15+
/** @psalm-pure */
16+
public static function a(): self
17+
{
18+
return self::get(self::A);
19+
}
20+
21+
/** @psalm-pure */
22+
public static function b(): self
23+
{
24+
return self::get(self::B);
25+
}
26+
}

0 commit comments

Comments
 (0)