@@ -363,7 +363,7 @@ protected function emitEnum($result, $enum) {
363
363
array_unshift ($ result ->meta , []);
364
364
$ result ->locals = [[], []];
365
365
366
- $ result ->out ->write ('final class ' .$ this ->declaration ($ enum ->name ).' implements \UnitEnum ' );
366
+ $ result ->out ->write ('final class ' .$ this ->declaration ($ enum ->name ).' implements \\' .( $ enum -> base ? ' BackedEnum ' : ' UnitEnum ') );
367
367
$ enum ->implements && $ result ->out ->write (', ' .implode (', ' , $ enum ->implements ));
368
368
$ result ->out ->write ('{ ' );
369
369
@@ -373,8 +373,28 @@ protected function emitEnum($result, $enum) {
373
373
$ this ->emitOne ($ result , $ member );
374
374
}
375
375
376
- // Name and constructor
377
- $ result ->out ->write ('public $name; private function __construct($name) { $this->name= $name; } ' );
376
+ // Constructors
377
+ if ($ enum ->base ) {
378
+ $ result ->out ->write ('public $name, $value; ' );
379
+ $ result ->out ->write ('private static $values= []; ' );
380
+ $ result ->out ->write ('private function __construct($name, $value) {
381
+ $this->name= $name;
382
+ $this->value= $value;
383
+ self::$values[$value]= $this;
384
+ } ' );
385
+ $ result ->out ->write ('public static function tryFrom($value) {
386
+ return self::$values[$value] ?? null;
387
+ } ' );
388
+ $ result ->out ->write ('public static function from($value) {
389
+ if ($r= self::$values[$value] ?? null) return $r;
390
+ throw new \ValueError("Not an enum value: ".\util\Objects::stringOf($value));
391
+ } ' );
392
+ } else {
393
+ $ result ->out ->write ('public $name; ' );
394
+ $ result ->out ->write ('private function __construct($name) {
395
+ $this->name= $name;
396
+ } ' );
397
+ }
378
398
379
399
// Enum cases
380
400
$ result ->out ->write ('public static function cases() { return [ ' );
@@ -385,8 +405,16 @@ protected function emitEnum($result, $enum) {
385
405
386
406
// Initializations
387
407
$ result ->out ->write ('static function __init() { ' );
388
- foreach ($ cases as $ case ) {
389
- $ result ->out ->write ('self::$ ' .$ case ->name .'= new self(" ' .$ case ->name .'"); ' );
408
+ if ($ enum ->base ) {
409
+ foreach ($ cases as $ case ) {
410
+ $ result ->out ->write ('self::$ ' .$ case ->name .'= new self(" ' .$ case ->name .'", ' );
411
+ $ this ->emitOne ($ result , $ case ->expression );
412
+ $ result ->out ->write ('); ' );
413
+ }
414
+ } else {
415
+ foreach ($ cases as $ case ) {
416
+ $ result ->out ->write ('self::$ ' .$ case ->name .'= new self(" ' .$ case ->name .'"); ' );
417
+ }
390
418
}
391
419
$ this ->emitInitializations ($ result , $ result ->locals [0 ]);
392
420
$ this ->emitMeta ($ result , $ enum ->name , $ enum ->annotations , $ enum ->comment );
0 commit comments