-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
…es on type level
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,8 +4,11 @@ | |
|
||
/** | ||
* @author Tomasz Kowalczyk <[email protected]> | ||
* @psalm-template T | ||
* @psalm-immutable | ||
*/ | ||
abstract class AbstractCallbackEnum implements \JsonSerializable | ||
{ | ||
/** @use CallbackEnumTrait<T> */ | ||
use CallbackEnumTrait; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,8 +4,11 @@ | |
|
||
/** | ||
* @author Tomasz Kowalczyk <[email protected]> | ||
* @psalm-template T | ||
* @psalm-immutable | ||
*/ | ||
abstract class AbstractConstantsEnum implements \JsonSerializable | ||
{ | ||
/** @use ConstantsEnumTrait<T> */ | ||
use ConstantsEnumTrait; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,8 +4,11 @@ | |
|
||
/** | ||
* @author Tomasz Kowalczyk <[email protected]> | ||
* @psalm-template T | ||
* @psalm-immutable | ||
*/ | ||
abstract class AbstractDocblockEnum implements \JsonSerializable | ||
{ | ||
/** @use DocblockEnumTrait<T> */ | ||
use DocblockEnumTrait; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,9 +4,12 @@ | |
|
||
/** | ||
* @author Tomasz Kowalczyk <[email protected]> | ||
* @psalm-template T | ||
* @psalm-immutable | ||
*/ | ||
abstract class AbstractStaticEnum implements \JsonSerializable | ||
{ | ||
/** @use StaticEnumTrait<T> */ | ||
use StaticEnumTrait; | ||
|
||
/** @var array */ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,9 +6,12 @@ | |
|
||
/** | ||
* @author Tomasz Kowalczyk <[email protected]> | ||
* @psalm-template T | ||
* @psalm-immutable | ||
*/ | ||
trait CallbackEnumTrait | ||
{ | ||
/** @use EnumTrait<T> */ | ||
use EnumTrait; | ||
|
||
/** @var non-empty-array<class-string,callable():array<string,int|string>> */ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,9 +4,12 @@ | |
|
||
/** | ||
* @author Tomasz Kowalczyk <[email protected]> | ||
* @psalm-template T | ||
* @psalm-immutable | ||
*/ | ||
trait ConstantsEnumTrait | ||
{ | ||
/** @use EnumTrait<T> */ | ||
use EnumTrait; | ||
|
||
private static function resolve(): array | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,9 +6,12 @@ | |
|
||
/** | ||
* @author Tomasz Kowalczyk <[email protected]> | ||
* @psalm-template T | ||
* @psalm-immutable | ||
*/ | ||
trait DocblockEnumTrait | ||
{ | ||
/** @use EnumTrait<T> */ | ||
use EnumTrait; | ||
|
||
private static function resolve(): array | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,20 +6,22 @@ | |
|
||
/** | ||
* @author Tomasz Kowalczyk <[email protected]> | ||
* @psalm-template T | ||
* @psalm-immutable | ||
*/ | ||
trait EnumTrait | ||
{ | ||
/** @var string */ | ||
private $member; | ||
/** @var int|string */ | ||
/** @psalm-var T */ | ||
Check failure on line 16 in src/Enum/EnumTrait.php GitHub Actions / test (7.4, ubuntu-latest, false)UndefinedDocblockClass
Check failure on line 16 in src/Enum/EnumTrait.php GitHub Actions / test (8.0, ubuntu-latest, false)UndefinedDocblockClass
Check failure on line 16 in src/Enum/EnumTrait.php GitHub Actions / test (8.1, ubuntu-latest, false)UndefinedDocblockClass
Check failure on line 16 in src/Enum/EnumTrait.php GitHub Actions / test (8.2, ubuntu-latest, false)UndefinedDocblockClass
Check failure on line 16 in src/Enum/EnumTrait.php GitHub Actions / test (8.3, ubuntu-latest, false)UndefinedDocblockClass
|
||
private $value; | ||
|
||
/** @var non-empty-array<string,non-empty-array<string,int|string>> */ | ||
/** @psalm-var non-empty-array<string,non-empty-array<string,int|string>> */ | ||
protected static $members = []; | ||
/** @var array<string,array<string,static>> */ | ||
protected static $instances = []; | ||
|
||
/** @param int|string $value */ | ||
/** @psalm-param T $value */ | ||
/* final */ private function __construct(string $member, $value) | ||
{ | ||
$this->member = $member; | ||
|
@@ -51,8 +53,18 @@ final public static function fromMember(string $member): self | |
static::throwDefaultInvalidMemberException($member); | ||
} | ||
|
||
/** @psalm-suppress PropertyTypeCoercion */ | ||
return static::$instances[$class][$member] = static::fromMemberAndValue($member, static::$members[$class][$member]); | ||
} | ||
|
||
/** | ||
* @psalm-param int|string $value | ||
* @psalm-return static | ||
*/ | ||
/* final */ private static function fromMemberAndValue(string $member, $value): self | ||
{ | ||
/** @psalm-suppress UnsafeInstantiation */ | ||
return static::$instances[$class][$member] = new static($member, static::$members[$class][$member]); | ||
return new static($member, $value); | ||
} | ||
|
||
/** | ||
|
@@ -91,12 +103,15 @@ final public static function fromEnum($enum): self | |
} | ||
|
||
/** | ||
* @param static $enum | ||
* @param-out AbstractConstantsEnum|AbstractDocblockEnum|AbstractStaticEnum|AbstractCallbackEnum|AbstractAttributeEnum $enum | ||
* @param self &$enum | ||
* @param-out self $enum | ||
* @psalm-suppress ReferenceConstraintViolation | ||
*/ | ||
final public function fromInstance(&$enum): void | ||
{ | ||
$enum = static::fromEnum($enum); | ||
/** @psalm-suppress ImpureMethodCall,ArgumentTypeCoercion */ | ||
$instance = static::fromEnum($enum); | ||
$enum = $instance; | ||
} | ||
|
||
/** | ||
|
@@ -154,12 +169,13 @@ final public function getMember(): string | |
return $this->member; | ||
} | ||
|
||
/** @return int|string */ | ||
/** @psalm-return T */ | ||
final public function getValue() | ||
{ | ||
return $this->value; | ||
} | ||
|
||
/** @psalm-return T */ | ||
#[\ReturnTypeWillChange] | ||
final public function jsonSerialize() | ||
{ | ||
|
@@ -209,7 +225,7 @@ final public function hasMember(string $members): bool | |
return $members === $this->member; | ||
} | ||
|
||
/** @param int|string $value */ | ||
/** @psalm-param T $value */ | ||
final public function hasValue($value): bool | ||
{ | ||
return $value === $this->value; | ||
|
@@ -293,7 +309,7 @@ private static function resolveMembers(): void | |
// reflection instead of method_exists because of PHP 7.4 bug #78632 | ||
// @see https://bugs.php.net/bug.php?id=78632 | ||
$hasResolve = (new \ReflectionClass($class))->hasMethod('resolve'); | ||
/** @var array<string,int|string> $members */ | ||
/** @psalm-var array<string,T> $members */ | ||
$members = $hasResolve ? static::resolve() : $throwMissingResolve($class); | ||
if(empty($members)) { | ||
throw PlatenumException::fromEmptyMembers($class); | ||
|
@@ -308,6 +324,7 @@ private static function resolveMembers(): void | |
throw PlatenumException::fromNonUniformMemberValues($class, $members); | ||
} | ||
|
||
/** @psalm-suppress MixedPropertyTypeCoercion */ | ||
static::$members[$class] = $members; | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,9 +6,12 @@ | |
|
||
/** | ||
* @author Tomasz Kowalczyk <[email protected]> | ||
* @psalm-template T | ||
* @psalm-immutable | ||
*/ | ||
trait StaticEnumTrait | ||
{ | ||
/** @use EnumTrait<T> */ | ||
use EnumTrait; | ||
|
||
private static function resolve(): array | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?php | ||
declare(strict_types=1); | ||
namespace Thunder\Platenum\Tests\Psalm; | ||
|
||
use Thunder\Platenum\Enum\AbstractConstantsEnum; | ||
|
||
/** | ||
* @method static static FIRST() | ||
* @method static static SECOND() | ||
* @template-extends AbstractConstantsEnum<self::FIRST|self::SECOND> | ||
* @psalm-immutable | ||
* @psalm-suppress PropertyNotSetInConstructor | ||
*/ | ||
final class PsalmConstantsExtendsEnum extends AbstractConstantsEnum | ||
Check failure on line 14 in tests/Psalm/PsalmConstantsExtendsEnum.php GitHub Actions / test (7.4, ubuntu-latest, false)UndefinedDocblockClass
Check failure on line 14 in tests/Psalm/PsalmConstantsExtendsEnum.php GitHub Actions / test (8.0, ubuntu-latest, false)UndefinedDocblockClass
Check failure on line 14 in tests/Psalm/PsalmConstantsExtendsEnum.php GitHub Actions / test (8.1, ubuntu-latest, false)UndefinedDocblockClass
Check failure on line 14 in tests/Psalm/PsalmConstantsExtendsEnum.php GitHub Actions / test (8.2, ubuntu-latest, false)UndefinedDocblockClass
Check failure on line 14 in tests/Psalm/PsalmConstantsExtendsEnum.php GitHub Actions / test (8.3, ubuntu-latest, false)UndefinedDocblockClass
|
||
{ | ||
public const FIRST = 1; | ||
public const SECOND = 2; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
declare(strict_types=1); | ||
namespace Thunder\Platenum\Tests\Psalm; | ||
|
||
use Thunder\Platenum\Enum\ConstantsEnumTrait; | ||
|
||
/** | ||
* @method static static FIRST() | ||
* @method static static SECOND() | ||
* @psalm-template T self::FIRST|self::SECOND | ||
* @psalm-immutable | ||
*/ | ||
final class PsalmConstantsTraitEnum | ||
{ | ||
/** @use ConstantsEnumTrait<T> */ | ||
use ConstantsEnumTrait; | ||
|
||
public const FIRST = 1; | ||
public const SECOND = 2; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?php | ||
declare(strict_types=1); | ||
namespace Thunder\Platenum\Tests\Psalm; | ||
|
||
final class PsalmEnum | ||
{ | ||
} | ||
|
||
PsalmConstantsTraitEnum::FIRST(); | ||
PsalmConstantsTraitEnum::SECOND(); | ||
PsalmConstantsTraitEnum::fromMember('THIRD'); | ||
PsalmConstantsTraitEnum::fromValue(4); | ||
|
||
PsalmConstantsExtendsEnum::FIRST(); | ||
PsalmConstantsExtendsEnum::SECOND(); | ||
PsalmConstantsExtendsEnum::fromMember('THIRD'); | ||
PsalmConstantsExtendsEnum::fromValue(4); |