@@ -22,7 +22,7 @@ abstract class Enum
2222 /**
2323 * The selected enumerator value
2424 *
25- * @var null|bool|int|float|string|array
25+ * @var null|bool|int|float|string|array<mixed>
2626 */
2727 private $ value ;
2828
@@ -36,29 +36,29 @@ abstract class Enum
3636 /**
3737 * A map of enumerator names and values by enumeration class
3838 *
39- * @var array ["$ class" => ["$name" => $value, ...], ...]
39+ * @var array< class-string<Enum>, array<string, null|bool|int|float|string|array<mixed>>>
4040 */
4141 private static $ constants = [];
4242
4343 /**
4444 * A List of available enumerator names by enumeration class
4545 *
46- * @var array ["$ class" => ["$name0", ...], ...]
46+ * @var array< class-string<Enum>, string[]>
4747 */
4848 private static $ names = [];
4949
5050 /**
51- * Already instantiated enumerators
51+ * A map of enumerator names and instances by enumeration class
5252 *
53- * @var array ["$ class" => ["$name" => $instance, ...], ...]
53+ * @var array< class-string<Enum>, array<string, Enum>>
5454 */
5555 private static $ instances = [];
5656
5757 /**
5858 * Constructor
5959 *
60- * @param null|bool|int|float|string|array $value The value of the enumerator
61- * @param int|null $ordinal The ordinal number of the enumerator
60+ * @param null|bool|int|float|string|array<mixed> $value The value of the enumerator
61+ * @param int|null $ordinal The ordinal number of the enumerator
6262 */
6363 final private function __construct ($ value , $ ordinal = null )
6464 {
@@ -111,7 +111,7 @@ final public function __wakeup()
111111 /**
112112 * Get the value of the enumerator
113113 *
114- * @return null|bool|int|float|string|array
114+ * @return null|bool|int|float|string|array<mixed>
115115 */
116116 final public function getValue ()
117117 {
@@ -123,6 +123,7 @@ final public function getValue()
123123 *
124124 * @return string
125125 *
126+ * @phpstan-return string
126127 * @psalm-return non-empty-string
127128 */
128129 final public function getName ()
@@ -157,7 +158,7 @@ final public function getOrdinal()
157158 /**
158159 * Compare this enumerator against another and check if it's the same.
159160 *
160- * @param static|null|bool|int|float|string|array $enumerator An enumerator object or value
161+ * @param static|null|bool|int|float|string|array<mixed> $enumerator An enumerator object or value
161162 * @return bool
162163 */
163164 final public function is ($ enumerator )
@@ -174,7 +175,7 @@ final public function is($enumerator)
174175 /**
175176 * Get an enumerator instance of the given enumerator value or instance
176177 *
177- * @param static|null|bool|int|float|string|array $enumerator An enumerator object or value
178+ * @param static|null|bool|int|float|string|array<mixed> $enumerator An enumerator object or value
178179 * @return static
179180 * @throws InvalidArgumentException On an unknown or invalid value
180181 * @throws LogicException On ambiguous constant values
@@ -183,7 +184,15 @@ final public function is($enumerator)
183184 */
184185 final public static function get ($ enumerator )
185186 {
186- if ($ enumerator instanceof static && \get_class ($ enumerator ) === static ::class) {
187+ if ($ enumerator instanceof static) {
188+ if (\get_class ($ enumerator ) !== static ::class) {
189+ throw new InvalidArgumentException (sprintf (
190+ 'Invalid value of type %s for enumeration %s ' ,
191+ \get_class ($ enumerator ),
192+ static ::class
193+ ));
194+ }
195+
187196 return $ enumerator ;
188197 }
189198
@@ -193,7 +202,7 @@ final public static function get($enumerator)
193202 /**
194203 * Get an enumerator instance by the given value
195204 *
196- * @param null|bool|int|float|string|array $value Enumerator value
205+ * @param null|bool|int|float|string|array<mixed> $value Enumerator value
197206 * @return static
198207 * @throws InvalidArgumentException On an unknown or invalid value
199208 * @throws LogicException On ambiguous constant values
@@ -202,6 +211,8 @@ final public static function get($enumerator)
202211 */
203212 final public static function byValue ($ value )
204213 {
214+ /** @var mixed $value */
215+
205216 $ constants = self ::$ constants [static ::class] ?? static ::getConstants ();
206217
207218 $ name = \array_search ($ value , $ constants , true );
@@ -215,8 +226,11 @@ final public static function byValue($value)
215226 ));
216227 }
217228
218- return self ::$ instances [static ::class][$ name ]
229+ /** @var static $instance */
230+ $ instance = self ::$ instances [static ::class][$ name ]
219231 ?? self ::$ instances [static ::class][$ name ] = new static ($ constants [$ name ]);
232+
233+ return $ instance ;
220234 }
221235
222236 /**
@@ -232,7 +246,9 @@ final public static function byValue($value)
232246 final public static function byName (string $ name )
233247 {
234248 if (isset (self ::$ instances [static ::class][$ name ])) {
235- return self ::$ instances [static ::class][$ name ];
249+ /** @var static $instance */
250+ $ instance = self ::$ instances [static ::class][$ name ];
251+ return $ instance ;
236252 }
237253
238254 $ const = static ::class . ":: {$ name }" ;
@@ -271,15 +287,20 @@ final public static function byOrdinal(int $ordinal)
271287 }
272288
273289 $ name = self ::$ names [static ::class][$ ordinal ];
274- return self ::$ instances [static ::class][$ name ]
290+
291+ /** @var static $instance */
292+ $ instance = self ::$ instances [static ::class][$ name ]
275293 ?? self ::$ instances [static ::class][$ name ] = new static ($ constants [$ name ], $ ordinal );
294+
295+ return $ instance ;
276296 }
277297
278298 /**
279299 * Get a list of enumerator instances ordered by ordinal number
280300 *
281301 * @return static[]
282302 *
303+ * @phpstan-return array<int, static>
283304 * @psalm-return list<static>
284305 * @psalm-pure
285306 */
@@ -288,14 +309,18 @@ final public static function getEnumerators()
288309 if (!isset (self ::$ names [static ::class])) {
289310 static ::getConstants ();
290311 }
291- return \array_map ([static ::class, 'byName ' ], self ::$ names [static ::class]);
312+
313+ /** @var callable $byNameFn */
314+ $ byNameFn = [static ::class, 'byName ' ];
315+ return \array_map ($ byNameFn , self ::$ names [static ::class]);
292316 }
293317
294318 /**
295319 * Get a list of enumerator values ordered by ordinal number
296320 *
297- * @return mixed []
321+ * @return (null|bool|int|float|string|array) []
298322 *
323+ * @phpstan-return array<int, null|bool|int|float|string|array>
299324 * @psalm-return list<null|bool|int|float|string|array>
300325 * @psalm-pure
301326 */
@@ -309,6 +334,7 @@ final public static function getValues()
309334 *
310335 * @return string[]
311336 *
337+ * @phpstan-return array<int, string>
312338 * @psalm-return list<non-empty-string>
313339 * @psalm-pure
314340 */
@@ -325,6 +351,7 @@ final public static function getNames()
325351 *
326352 * @return int[]
327353 *
354+ * @phpstan-return array<int, int>
328355 * @psalm-return list<int>
329356 * @psalm-pure
330357 */
@@ -337,9 +364,10 @@ final public static function getOrdinals()
337364 /**
338365 * Get all available constants of the called class
339366 *
340- * @return mixed []
367+ * @return (null|bool|int|float|string|array) []
341368 * @throws LogicException On ambiguous constant values
342369 *
370+ * @phpstan-return array<string, null|bool|int|float|string|array>
343371 * @psalm-return array<non-empty-string, null|bool|int|float|string|array>
344372 * @psalm-pure
345373 */
@@ -375,7 +403,7 @@ final public static function getConstants()
375403
376404 /**
377405 * Test that the given constants does not contain ambiguous values
378- * @param array $constants
406+ * @param array<string, null|bool|int|float|string|array<mixed>> $constants
379407 * @return bool
380408 */
381409 private static function noAmbiguousValues ($ constants )
@@ -393,21 +421,24 @@ private static function noAmbiguousValues($constants)
393421 /**
394422 * Test if the given enumerator is part of this enumeration
395423 *
396- * @param static|null|bool|int|float|string|array $enumerator
424+ * @param static|null|bool|int|float|string|array<mixed> $enumerator
397425 * @return bool
398426 *
399427 * @psalm-pure
400428 */
401429 final public static function has ($ enumerator )
402430 {
403- return ($ enumerator instanceof static && \get_class ($ enumerator ) === static ::class)
404- || static ::hasValue ($ enumerator );
431+ if ($ enumerator instanceof static) {
432+ return \get_class ($ enumerator ) === static ::class;
433+ }
434+
435+ return static ::hasValue ($ enumerator );
405436 }
406437
407438 /**
408439 * Test if the given enumerator value is part of this enumeration
409440 *
410- * @param null|bool|int|float|string|array $value
441+ * @param null|bool|int|float|string|array<mixed> $value
411442 * @return bool
412443 *
413444 * @psalm-pure
@@ -436,8 +467,8 @@ final public static function hasName(string $name)
436467 * This will be called automatically on calling a method
437468 * with the same name of a defined enumerator.
438469 *
439- * @param string $method The name of the enumerator (called as method)
440- * @param array $args There should be no arguments
470+ * @param string $method The name of the enumerator (called as method)
471+ * @param array<mixed> $args There should be no arguments
441472 * @return static
442473 * @throws InvalidArgumentException On an invalid or unknown name
443474 * @throws LogicException On ambiguous constant values
0 commit comments