1313
1414
1515/**
16- * Class/Interface/Trait description.
16+ * Class/Interface/Trait/Enum description.
1717 *
1818 * @property Method[] $methods
1919 * @property Property[] $properties
@@ -27,7 +27,8 @@ final class ClassType
2727 public const
2828 TYPE_CLASS = 'class ' ,
2929 TYPE_INTERFACE = 'interface ' ,
30- TYPE_TRAIT = 'trait ' ;
30+ TYPE_TRAIT = 'trait ' ,
31+ TYPE_ENUM = 'enum ' ;
3132
3233 public const
3334 VISIBILITY_PUBLIC = 'public ' ,
@@ -67,6 +68,9 @@ final class ClassType
6768 /** @var Method[] name => Method */
6869 private $ methods = [];
6970
71+ /** @var EnumCase[] name => EnumCase */
72+ private $ cases = [];
73+
7074
7175 public static function class (string $ name = null , PhpNamespace $ namespace = null ): self
7276 {
@@ -86,6 +90,12 @@ public static function trait(string $name = null, PhpNamespace $namespace = null
8690 }
8791
8892
93+ public static function enum (string $ name = null , PhpNamespace $ namespace = null ): self
94+ {
95+ return (new self ($ name , $ namespace ))->setType (self ::TYPE_ENUM );
96+ }
97+
98+
8999 /**
90100 * @param string|object $class
91101 */
@@ -191,11 +201,17 @@ public function isTrait(): bool
191201 }
192202
193203
204+ public function isEnum (): bool
205+ {
206+ return $ this ->type === self ::TYPE_ENUM ;
207+ }
208+
209+
194210 /** @return static */
195211 public function setType (string $ type ): self
196212 {
197- if (!in_array ($ type , [self ::TYPE_CLASS , self ::TYPE_INTERFACE , self ::TYPE_TRAIT ], true )) {
198- throw new Nette \InvalidArgumentException ('Argument must be class|interface|trait. ' );
213+ if (!in_array ($ type , [self ::TYPE_CLASS , self ::TYPE_INTERFACE , self ::TYPE_TRAIT , self :: TYPE_ENUM ], true )) {
214+ throw new Nette \InvalidArgumentException ('Argument must be class|interface|trait|enum . ' );
199215 }
200216 $ this ->type = $ type ;
201217 return $ this ;
@@ -351,7 +367,7 @@ public function removeTrait(string $name): self
351367
352368
353369 /**
354- * @param Method|Property|Constant $member
370+ * @param Method|Property|Constant|EnumCase $member
355371 * @return static
356372 */
357373 public function addMember ($ member ): self
@@ -368,8 +384,11 @@ public function addMember($member): self
368384 } elseif ($ member instanceof Constant) {
369385 $ this ->consts [$ member ->getName ()] = $ member ;
370386
387+ } elseif ($ member instanceof EnumCase) {
388+ $ this ->cases [$ member ->getName ()] = $ member ;
389+
371390 } else {
372- throw new Nette \InvalidArgumentException ('Argument must be Method|Property|Constant. ' );
391+ throw new Nette \InvalidArgumentException ('Argument must be Method|Property|Constant|EnumCase . ' );
373392 }
374393
375394 return $ this ;
@@ -414,6 +433,44 @@ public function removeConstant(string $name): self
414433 }
415434
416435
436+ /**
437+ * Sets cases to enum
438+ * @param EnumCase[] $consts
439+ * @return static
440+ */
441+ public function setCases (array $ cases ): self
442+ {
443+ (function (EnumCase ...$ cases ) {})(...$ cases );
444+ $ this ->cases = [];
445+ foreach ($ cases as $ case ) {
446+ $ this ->cases [$ case ->getName ()] = $ case ;
447+ }
448+ return $ this ;
449+ }
450+
451+
452+ /** @return EnumCase[] */
453+ public function getCases (): array
454+ {
455+ return $ this ->cases ;
456+ }
457+
458+
459+ /** Adds case to enum */
460+ public function addCase (string $ name , $ value = null ): EnumCase
461+ {
462+ return $ this ->cases [$ name ] = (new EnumCase ($ name ))->setValue ($ value );
463+ }
464+
465+
466+ /** @return static */
467+ public function removeCase (string $ name ): self
468+ {
469+ unset($ this ->cases [$ name ]);
470+ return $ this ;
471+ }
472+
473+
417474 /**
418475 * @param Property[] $props
419476 * @return static
@@ -540,6 +597,9 @@ public function validate(): void
540597 if ($ this ->abstract && $ this ->final ) {
541598 throw new Nette \InvalidStateException ('Class cannot be abstract and final. ' );
542599
600+ } elseif ($ this ->isEnum () && ($ this ->abstract || $ this ->final || $ this ->extends || $ this ->properties )) {
601+ throw new Nette \InvalidStateException ('Enum cannot be abstract or final or extends class or have properties. ' );
602+
543603 } elseif (!$ this ->name && ($ this ->abstract || $ this ->final )) {
544604 throw new Nette \InvalidStateException ('Anonymous class cannot be abstract or final. ' );
545605 }
@@ -559,6 +619,7 @@ private function validateNames(array $names): void
559619 public function __clone ()
560620 {
561621 $ clone = function ($ item ) { return clone $ item ; };
622+ $ this ->cases = array_map ($ clone , $ this ->cases );
562623 $ this ->consts = array_map ($ clone , $ this ->consts );
563624 $ this ->properties = array_map ($ clone , $ this ->properties );
564625 $ this ->methods = array_map ($ clone , $ this ->methods );
0 commit comments