Skip to content

Commit

Permalink
feat(core) : phpstan check and optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
donaldinou committed Oct 3, 2024
1 parent 2b11c5c commit 0a025f9
Show file tree
Hide file tree
Showing 33 changed files with 589 additions and 199 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
/phpunit.xml
.phpunit.result.cache

# phpcs
.phpcs.cache
.php-cs-fixer.cache

# Composer PHAR
/composer.phar
#/composer.lock
Expand All @@ -27,6 +31,8 @@

# vscode
*.code-workspace
.vscode
.vscode-insiders

# Swap & temp files
*~
Expand Down
18 changes: 13 additions & 5 deletions Reflection/SplReflectionEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
/**
* The ReflectionEnum class reports information about an Enum.
*
* @template T of SplUnitEnum
* @extends \ReflectionClass<\Ducks\Component\SplTypes\SplUnitEnum>
*
* @link https://php.net/manual/en/class.reflectionenum.php
*/
class SplReflectionEnum extends \ReflectionClass
Expand All @@ -38,26 +41,29 @@ class SplReflectionEnum extends \ReflectionClass
*/
private function getProxy(): SplReflectionEnumProxy
{
if (!isset(static::$instances[$this->name])) {
static::$instances[$this->name] = new SplReflectionEnumProxy($this);
if (!isset(self::$instances[$this->name])) {
self::$instances[$this->name] = new SplReflectionEnumProxy($this);
}

return static::$instances[$this->name];
return self::$instances[$this->name];
}

/**
* Instantiates a ReflectionEnum object
*
* @param object|string $objectOrClass
*
* @throws ReflectionException if objectOrClass is not a SplUnitEnum
* @throws \ReflectionException if objectOrClass is not a SplUnitEnum
*
* @phpstan-param SplUnitEnum|class-string<T> $objectOrClass
*
* @link https://www.php.net/manual/en/reflectionenum.construct.php
*/
public function __construct($objectOrClass)
{
// Fast check
if (!\is_a($objectOrClass, SplUnitEnum::class, true)) {
// @phpstan-ignore ternary.elseUnreachable
$classname = \is_object($objectOrClass) ? \get_class($objectOrClass) : $objectOrClass;
throw new \ReflectionException("Class \"$classname\" is not an enum");
}
Expand Down Expand Up @@ -98,11 +104,13 @@ public function getCase(string $name): SplReflectionEnumUnitCase
*
* @return array<int, SplReflectionEnumUnitCase|SplReflectionEnumBackedCase>
*
* @phpstan-return list<SplReflectionEnumUnitCase|SplReflectionEnumBackedCase>
*
* @link https://www.php.net/manual/en/reflectionenum.getcases.php
*/
public function getCases(): array
{
return $this->getProxy()->getCases();
return \array_values($this->getProxy()->getCases());
}

/**
Expand Down
6 changes: 5 additions & 1 deletion Reflection/SplReflectionEnumHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@ private function __construct()
public static function getStringReflectionNamedType(): \ReflectionNamedType
{
if (null === static::$rnts) {
$func = new \ReflectionFunction(static fn(string $param): string => $param);
$func = new \ReflectionFunction(static fn (string $param): string => $param);
// @phpstan-ignore-next-line
static::$rnts = ($func->getParameters()[0])->getType();
}

// @phpstan-ignore-next-line
return static::$rnts;
}

Expand All @@ -51,9 +53,11 @@ public static function getIntReflectionNamedType(): \ReflectionNamedType
{
if (null === static::$rnti) {
$func = new \ReflectionFunction(static fn(int $param): int => $param);
// @phpstan-ignore-next-line
static::$rnti = ($func->getParameters()[0])->getType();
}

// @phpstan-ignore-next-line
return static::$rnti;
}
}
27 changes: 23 additions & 4 deletions Reflection/SplReflectionEnumProxy.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,20 @@

final class SplReflectionEnumProxy
{
/**
* The reflection class used in proxy
*
* @var \ReflectionClass
*
* @phpstan-var \ReflectionClass<object>
*/
private \ReflectionClass $class;

/**
* Is enum is backed
*
* @var boolean|null
*/
private ?bool $backed = null;

/**
Expand All @@ -32,7 +44,7 @@ final class SplReflectionEnumProxy
/**
* Array of constants class, indexed by name, as enum cases.
*
* @var array<string, \ReflectionClassConstant>
* @var array<string,\ReflectionClassConstant>
*/
private array $constantCases = [];

Expand All @@ -45,6 +57,11 @@ final class SplReflectionEnumProxy

public string $name;

/**
* Build a proxy SplReflectionEnum from a ReflectionClass
*
* @param \ReflectionClass<object> $class
*/
public function __construct(\ReflectionClass $class)
{
$this->class = $class;
Expand Down Expand Up @@ -126,7 +143,7 @@ public function addConstantCase(\ReflectionClassConstant ...$constants): void
/**
* Return an array of class constants, indexed by name, that could be use as an enum case.
*
* @return array<string, \ReflectionClassConstant>
* @return array<string,\ReflectionClassConstant>
*/
public function getConstantCases(): array
{
Expand Down Expand Up @@ -249,7 +266,7 @@ public function addCase(\ReflectionClassConstant ...$constants): void
/**
* Returns a list of all cases on an Enum
*
* @return array<int, ReflectionEnumUnitCase|ReflectionEnumBackedCase>
* @return array<string,SplReflectionEnumUnitCase|SplReflectionEnumBackedCase>
*
* @link https://www.php.net/manual/en/reflectionenum.getcases.php
*/
Expand Down Expand Up @@ -341,7 +358,9 @@ public function getBackingType(): ?\ReflectionNamedType
if (null === $this->backingType) {
if ($this->isBacked()) {
if ($this->class->hasProperty('value')) {
$this->backingType = $this->class->getProperty('value')->getType() ?? false;
/** @var \ReflectionNamedType|false $type */
$type = $this->class->getProperty('value')->getType() ?? false;
$this->backingType = $type;
} else {
$constant = $this->getFirstCaseConstant();
if ($constant instanceof \ReflectionClassConstant) {
Expand Down
14 changes: 12 additions & 2 deletions Reflection/SplReflectionEnumUnitCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,16 @@

use Ducks\Component\SplTypes\SplUnitEnum;

/**
* The SplReflectionEnumUnitCase class reports information about an SplEnum unit case, which has no scalar equivalent.
*/
class SplReflectionEnumUnitCase extends \ReflectionClassConstant
{
/**
* Internal instances enum
*
* @var array<string,array<string,SplUnitEnum>>
*/
private static array $instances = [];

/**
Expand All @@ -25,7 +33,7 @@ class SplReflectionEnumUnitCase extends \ReflectionClassConstant
* @param object|string $class An enum instance or a name.
* @param string $constant An enum constant name.
*
* @throws ReflectionException if $class is not a SplReflectionEnumUnitCase
* @throws \ReflectionException if $class is not a SplReflectionEnumUnitCase
*
* @link https://www.php.net/manual/en/reflectionenumunitcase.construct.php
*/
Expand All @@ -43,7 +51,9 @@ public function __construct($class, string $constant)
/**
* Gets the reflection of the enum of this case
*
* @return ReflectionEnum instance describing the Enum this case belongs to.
* @return SplReflectionEnum instance describing the Enum this case belongs to.
*
* @phpstan-return SplReflectionEnum<SplUnitEnum>
*
* @link https://www.php.net/manual/en/reflectionenumunitcase.getenum.php
*/
Expand Down
10 changes: 7 additions & 3 deletions Resources/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@

namespace Ducks\Component\SplTypes;

/** @disregard P1009 Undefined type */
/**
* @disregard P1009 Undefined type
*
* @phpstan-ignore-next-line
*/
if (!\function_exists(spl_enum_exists::class)) {
/**
* Checks if the spl enum has been defined
Expand All @@ -23,8 +27,8 @@
*
* @return boolean Returns true if enum is a defined enum, false otherwise.
*/
function spl_enum_exists(string $class, bool $autoload = true): bool
function spl_enum_exists(string $enum, bool $autoload = true): bool
{
return Util\Tools::isSplEnumExists($class, $autoload);
return Util\Tools::isSplEnumExists($enum, $autoload);
}
}
7 changes: 7 additions & 0 deletions Resources/stubs/SplPureEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,14 @@
use Ducks\Component\SplTypes\SplEnumUnit as DuckSplPureEnum;

/**
* SplEnumUnit alias.
*
* <code>
* \class_alias(DuckSplPureEnum::class, '\\SplPureEnum', true);
* </code>
*
* @template T
* @extends Ducks\Component\SplTypes\SplEnumUnit<T>
*/
// phpcs:ignore PSR1.Classes.ClassDeclaration.MissingNamespace
class SplPureEnum extends DuckSplPureEnum
Expand Down
2 changes: 2 additions & 0 deletions SplBackedEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
/**
* Interface used in order to implements \BackedEnum one.
*
* @template T
*
* @psalm-api
*/
interface SplBackedEnum extends SplUnitEnum
Expand Down
32 changes: 26 additions & 6 deletions SplBackedEnumTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,25 @@

use Ducks\Component\SplTypes\Reflection\SplReflectionEnumBackedCase;

/**
* Simplify SplBackedEnum integration
*
* @template T
*
* @phpstan-require-implements SplBackedEnum
*/
trait SplBackedEnumTrait
{
use SplUnitEnumTrait;

/**
* Maps a scalar to an enum instance
* Maps a scalar to an enum instance.
*
* @param int|string $value The scalar value to map to an enum case.
*
* @return static A case instance of this enumeration.
*
* @throws \ValueError if $value is not a valid backing value for enum
*/
final public static function from($value): self
{
Expand All @@ -40,34 +49,45 @@ final public static function from($value): self
}

/**
* Maps a scalar to an enum instance or null
* Maps a scalar to an enum instance or null.
*
* @param int|string $value e scalar value to map to an enum case.
* @param int|string|mixed $value e scalar value to map to an enum case.
*
* @return static|null A case instance of this enumeration, or null if not found.
*/
final public static function tryFrom($value): ?self
{
foreach (static::cases() as $case) {
/**
* @var SplEnumBacked $case
* @phpstan-var SplEnumBacked<T> $case
*/
if ($case->value === $value) {
$result = $case;

Check failure on line 66 in SplBackedEnumTrait.php

View workflow job for this annotation

GitHub Actions / build

UnusedVariable

SplBackedEnumTrait.php:66:17: UnusedVariable: $result is never referenced or the value is not used (see https://psalm.dev/077)
break;
}
}

/** @var static $result */
return $result ?? null;
}

/**
* Return a new instance of enum
* Return a new instance of enum.
*
* @param string $name
* @param array $arguments
* @param array<int,mixed> $arguments
*
* @return static self keywords not an equivalent
*
* @psalm-suppress UnsafeInstantiation
* @throws \Error if $name is not a valid constant enum
*
* @phpstan-param string $name
* @phpstan-param list<mixed> $arguments
* @phpstan-return static
* @phpstan-ignore-next-line
*
* @psalm-suppress UnsafeInstantiation
*/
#[\ReturnTypeWillChange]
public static function __callStatic(string $name, array $arguments)
Expand Down
8 changes: 8 additions & 0 deletions SplBool.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,19 @@
/**
* The SplBool class is used to enforce strong typing of the bool type.
*
* @extends SplEnum<bool>
* @implements SplBackedEnum<bool>
*
* @psalm-api
* @psalm-suppress MissingDependency
* @psalm-suppress UndefinedClass
*/
class SplBool extends SplEnum implements SplBackedEnum
{
/** @use SplBackedEnumTrait<bool> */
use SplBackedEnumTrait;
/** @use SplEnumBackedTrait<bool> */
use SplEnumBackedTrait;

/**
* @var bool
Expand Down Expand Up @@ -63,7 +69,9 @@ public function __construct(bool $initial_value = self::__default)
{
parent::__construct($initial_value);

/** @psalm-suppress UnsupportedPropertyReferenceUsage */
$this->value = &$this->__default;
$this->name = $this->value ? 'true' : 'false';
}

final public function &__invoke(): bool
Expand Down
Loading

0 comments on commit 0a025f9

Please sign in to comment.