Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP Psalm templates #24

Merged
merged 1 commit into from
Feb 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

<projectFiles>
<directory name="src" />
<directory name="tests/Psalm" />
<ignoreFiles>
<directory name="vendor" />
</ignoreFiles>
Expand All @@ -30,6 +31,11 @@
<file name="src/Doctrine/PlatenumDoctrineType.php" />
</errorLevel>
</DeprecatedMethod>
<DocblockTypeContradiction errorLevel="error">
<errorLevel type="suppress">
<file name="src/Enum/EnumTrait.php" /> <!-- PHP 7.2 only? -->
</errorLevel>
</DocblockTypeContradiction>
</issueHandlers>

</psalm>
4 changes: 4 additions & 0 deletions src/Enum/AbstractAttributeEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
namespace Thunder\Platenum\Enum;

/**
* @template TMember
* @template TValue
*
* @author Tomasz Kowalczyk <[email protected]>
*/
abstract class AbstractAttributeEnum implements \JsonSerializable
{
/** @use AttributeEnumTrait<TMember,TValue> */
use AttributeEnumTrait;
}
4 changes: 4 additions & 0 deletions src/Enum/AbstractCallbackEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
namespace Thunder\Platenum\Enum;

/**
* @template TMember
* @template TValue
*
* @author Tomasz Kowalczyk <[email protected]>
*/
abstract class AbstractCallbackEnum implements \JsonSerializable
{
/** @use CallbackEnumTrait<TMember,TValue> */
use CallbackEnumTrait;
}
4 changes: 4 additions & 0 deletions src/Enum/AbstractConstantsEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
namespace Thunder\Platenum\Enum;

/**
* @template TMember
* @template TValue
*
* @author Tomasz Kowalczyk <[email protected]>
*/
abstract class AbstractConstantsEnum implements \JsonSerializable
{
/** @use ConstantsEnumTrait<TMember,TValue> */
use ConstantsEnumTrait;
}
4 changes: 4 additions & 0 deletions src/Enum/AbstractDocblockEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
namespace Thunder\Platenum\Enum;

/**
* @template TMember
* @template TValue
*
* @author Tomasz Kowalczyk <[email protected]>
*/
abstract class AbstractDocblockEnum implements \JsonSerializable
{
/** @use DocblockEnumTrait<TMember,TValue> */
use DocblockEnumTrait;
}
4 changes: 4 additions & 0 deletions src/Enum/AbstractStaticEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
namespace Thunder\Platenum\Enum;

/**
* @template TMember
* @template TValue
*
* @author Tomasz Kowalczyk <[email protected]>
*/
abstract class AbstractStaticEnum implements \JsonSerializable
{
/** @use StaticEnumTrait<TMember,TValue> */
use StaticEnumTrait;

/** @var array */
Expand Down
4 changes: 4 additions & 0 deletions src/Enum/AttributeEnumTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
namespace Thunder\Platenum\Enum;

/**
* @template TMember
* @template TValue
*
* @author Tomasz Kowalczyk <[email protected]>
*/
trait AttributeEnumTrait
{
/** @use EnumTrait<TMember,TValue> */
use EnumTrait;

/** @psalm-suppress UndefinedDocblockClass, UndefinedMethod because there is no ReflectionAttribute on PHP <8.0 */
Expand Down
4 changes: 4 additions & 0 deletions src/Enum/CallbackEnumTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@
use Thunder\Platenum\Exception\PlatenumException;

/**
* @template TMember
* @template TValue
*
* @author Tomasz Kowalczyk <[email protected]>
*/
trait CallbackEnumTrait
{
/** @use EnumTrait<TMember,TValue> */
use EnumTrait;

/** @var non-empty-array<class-string,callable():array<string,int|string>> */
Expand Down
4 changes: 4 additions & 0 deletions src/Enum/ConstantsEnumTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
namespace Thunder\Platenum\Enum;

/**
* @template TMember
* @template TValue
*
* @author Tomasz Kowalczyk <[email protected]>
*/
trait ConstantsEnumTrait
{
/** @use EnumTrait<TMember,TValue> */
use EnumTrait;

private static function resolve(): array
Expand Down
4 changes: 4 additions & 0 deletions src/Enum/DocblockEnumTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@
use Thunder\Platenum\Exception\PlatenumException;

/**
* @template TMember
* @template TValue
*
* @author Tomasz Kowalczyk <[email protected]>
*/
trait DocblockEnumTrait
{
/** @use EnumTrait<TMember,TValue> */
use EnumTrait;

private static function resolve(): array
Expand Down
31 changes: 21 additions & 10 deletions src/Enum/EnumTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,28 @@
use Thunder\Platenum\Exception\PlatenumException;

/**
* @template TMember
* @template TValue
*
* @author Tomasz Kowalczyk <[email protected]>
*/
trait EnumTrait
{
/** @var string */
/** @var TMember */
private $member;
/** @var int|string */
/** @var TValue */
private $value;

/** @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 */

/**
* @param TMember $member
* @param TValue $value
*/
/* final */ private function __construct(string $member, $value)
{
$this->member = $member;
Expand Down Expand Up @@ -51,7 +58,7 @@
static::throwDefaultInvalidMemberException($member);
}

/** @psalm-suppress UnsafeInstantiation */
/** @psalm-suppress UnsafeInstantiation,ArgumentTypeCoercion,PropertyTypeCoercion */
return static::$instances[$class][$member] = new static($member, static::$members[$class][$member]);
}

Expand Down Expand Up @@ -91,6 +98,7 @@
}

/**
* @psalm-suppress ReferenceConstraintViolation
* @param static $enum
* @param-out AbstractConstantsEnum|AbstractDocblockEnum|AbstractStaticEnum|AbstractCallbackEnum|AbstractAttributeEnum $enum
*/
Expand All @@ -105,9 +113,9 @@
*/
final public static function getInstances(): array
{
static::resolveMembers();

Check warning on line 116 in src/Enum/EnumTrait.php

View workflow job for this annotation

GitHub Actions / test (8.0, ubuntu-latest, false)

Escaped Mutant for Mutator "MethodCallRemoval": --- Original +++ New @@ @@ */ public static final function getInstances() : array { - static::resolveMembers(); + foreach (static::$members[static::class] as $member => $value) { static::fromMember($member); }

Check warning on line 116 in src/Enum/EnumTrait.php

View workflow job for this annotation

GitHub Actions / test (8.1, ubuntu-latest, false)

Escaped Mutant for Mutator "MethodCallRemoval": --- Original +++ New @@ @@ */ public static final function getInstances() : array { - static::resolveMembers(); + foreach (static::$members[static::class] as $member => $value) { static::fromMember($member); }

Check warning on line 116 in src/Enum/EnumTrait.php

View workflow job for this annotation

GitHub Actions / test (8.2, ubuntu-latest, false)

Escaped Mutant for Mutator "MethodCallRemoval": --- Original +++ New @@ @@ */ public static final function getInstances() : array { - static::resolveMembers(); + foreach (static::$members[static::class] as $member => $value) { static::fromMember($member); }

Check warning on line 116 in src/Enum/EnumTrait.php

View workflow job for this annotation

GitHub Actions / test (8.3, ubuntu-latest, false)

Escaped Mutant for Mutator "MethodCallRemoval": --- Original +++ New @@ @@ */ public static final function getInstances() : array { - static::resolveMembers(); + foreach (static::$members[static::class] as $member => $value) { static::fromMember($member); }

Check warning on line 116 in src/Enum/EnumTrait.php

View workflow job for this annotation

GitHub Actions / test (nightly, ubuntu-latest, true)

Escaped Mutant for Mutator "MethodCallRemoval": --- Original +++ New @@ @@ */ public static final function getInstances() : array { - static::resolveMembers(); + foreach (static::$members[static::class] as $member => $value) { static::fromMember($member); }
foreach(static::$members[static::class] as $member => $value) {

Check warning on line 117 in src/Enum/EnumTrait.php

View workflow job for this annotation

GitHub Actions / test (8.0, ubuntu-latest, false)

Escaped Mutant for Mutator "Foreach_": --- Original +++ New @@ @@ public static final function getInstances() : array { static::resolveMembers(); - foreach (static::$members[static::class] as $member => $value) { + foreach (array() as $member => $value) { static::fromMember($member); } return array_values(static::$instances[static::class]);

Check warning on line 117 in src/Enum/EnumTrait.php

View workflow job for this annotation

GitHub Actions / test (8.1, ubuntu-latest, false)

Escaped Mutant for Mutator "Foreach_": --- Original +++ New @@ @@ public static final function getInstances() : array { static::resolveMembers(); - foreach (static::$members[static::class] as $member => $value) { + foreach (array() as $member => $value) { static::fromMember($member); } return array_values(static::$instances[static::class]);

Check warning on line 117 in src/Enum/EnumTrait.php

View workflow job for this annotation

GitHub Actions / test (8.2, ubuntu-latest, false)

Escaped Mutant for Mutator "Foreach_": --- Original +++ New @@ @@ public static final function getInstances() : array { static::resolveMembers(); - foreach (static::$members[static::class] as $member => $value) { + foreach (array() as $member => $value) { static::fromMember($member); } return array_values(static::$instances[static::class]);

Check warning on line 117 in src/Enum/EnumTrait.php

View workflow job for this annotation

GitHub Actions / test (8.3, ubuntu-latest, false)

Escaped Mutant for Mutator "Foreach_": --- Original +++ New @@ @@ public static final function getInstances() : array { static::resolveMembers(); - foreach (static::$members[static::class] as $member => $value) { + foreach (array() as $member => $value) { static::fromMember($member); } return array_values(static::$instances[static::class]);

Check warning on line 117 in src/Enum/EnumTrait.php

View workflow job for this annotation

GitHub Actions / test (nightly, ubuntu-latest, true)

Escaped Mutant for Mutator "Foreach_": --- Original +++ New @@ @@ public static final function getInstances() : array { static::resolveMembers(); - foreach (static::$members[static::class] as $member => $value) { + foreach (array() as $member => $value) { static::fromMember($member); } return array_values(static::$instances[static::class]);
static::fromMember($member);

Check warning on line 118 in src/Enum/EnumTrait.php

View workflow job for this annotation

GitHub Actions / test (8.0, ubuntu-latest, false)

Escaped Mutant for Mutator "MethodCallRemoval": --- Original +++ New @@ @@ { static::resolveMembers(); foreach (static::$members[static::class] as $member => $value) { - static::fromMember($member); + } return array_values(static::$instances[static::class]); }

Check warning on line 118 in src/Enum/EnumTrait.php

View workflow job for this annotation

GitHub Actions / test (8.1, ubuntu-latest, false)

Escaped Mutant for Mutator "MethodCallRemoval": --- Original +++ New @@ @@ { static::resolveMembers(); foreach (static::$members[static::class] as $member => $value) { - static::fromMember($member); + } return array_values(static::$instances[static::class]); }

Check warning on line 118 in src/Enum/EnumTrait.php

View workflow job for this annotation

GitHub Actions / test (8.2, ubuntu-latest, false)

Escaped Mutant for Mutator "MethodCallRemoval": --- Original +++ New @@ @@ { static::resolveMembers(); foreach (static::$members[static::class] as $member => $value) { - static::fromMember($member); + } return array_values(static::$instances[static::class]); }

Check warning on line 118 in src/Enum/EnumTrait.php

View workflow job for this annotation

GitHub Actions / test (8.3, ubuntu-latest, false)

Escaped Mutant for Mutator "MethodCallRemoval": --- Original +++ New @@ @@ { static::resolveMembers(); foreach (static::$members[static::class] as $member => $value) { - static::fromMember($member); + } return array_values(static::$instances[static::class]); }

Check warning on line 118 in src/Enum/EnumTrait.php

View workflow job for this annotation

GitHub Actions / test (nightly, ubuntu-latest, true)

Escaped Mutant for Mutator "MethodCallRemoval": --- Original +++ New @@ @@ { static::resolveMembers(); foreach (static::$members[static::class] as $member => $value) { - static::fromMember($member); + } return array_values(static::$instances[static::class]); }
}

return array_values(static::$instances[static::class]);
Expand Down Expand Up @@ -149,17 +157,19 @@

/* --- TRANSFORM --- */

/** @return TMember */
final public function getMember(): string
{
return $this->member;
}

/** @return int|string */
/** @return TValue */
final public function getValue()
{
return $this->value;
}

/** @psalm-suppress MissingReturnType */
#[\ReturnTypeWillChange]
final public function jsonSerialize()
{
Expand Down Expand Up @@ -204,24 +214,25 @@
return [] !== array_intersect(static::$members[static::class], $values);
}

final public function hasMember(string $members): bool
/** @param TMember $member */
final public function hasMember(string $member): bool
{
return $members === $this->member;
return $member === $this->member;
}

/** @param int|string $value */
/** @param TValue $value */
final public function hasValue($value): bool
{
return $value === $this->value;
}

/** @param list<string> $members */
/** @param list<TMember> $members */
final public function hasMemberIn(array $members): bool
{
return in_array($this->member, $members, true);
}

/** @param list<int|string> $values */
/** @param list<TValue> $values */
final public function hasValueIn(array $values): bool
{
return in_array($this->value, $values, true);
Expand Down
4 changes: 4 additions & 0 deletions src/Enum/StaticEnumTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@
use Thunder\Platenum\Exception\PlatenumException;

/**
* @template TMember
* @template TValue
*
* @author Tomasz Kowalczyk <[email protected]>
*/
trait StaticEnumTrait
{
/** @use EnumTrait<TMember,TValue> */
use EnumTrait;

private static function resolve(): array
Expand Down
28 changes: 28 additions & 0 deletions tests/Psalm/SeasonsExtend.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace Thunder\Platenum\Tests\Psalm;

use Thunder\Platenum\Enum\AbstractConstantsEnum;

/**
* @method static static SPRING()
* @method static static SUMMER()
* @method static static AUTUMN()
* @method static static WINTER()
*
* @extends AbstractConstantsEnum<'SPRING'|'SUMMER'|'AUTUMN'|'WINTER',SeasonsExtend::*>
* @psalm-suppress PropertyNotSetInConstructor
*/
final class SeasonsExtend extends AbstractConstantsEnum
{
private const SPRING = 1;
private const SUMMER = 2;
private const AUTUMN = 3;
private const WINTER = 4;
}

$spring = SeasonsExtend::SPRING();
/** @psalm-suppress InvalidArgument */
$spring->hasMember('INVALID');
/** @psalm-suppress InvalidArgument */
$spring->hasValue(9);
28 changes: 28 additions & 0 deletions tests/Psalm/SeasonsTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace Thunder\Platenum\Tests\Psalm;

use Thunder\Platenum\Enum\ConstantsEnumTrait;

/**
* @method static static SPRING()
* @method static static SUMMER()
* @method static static AUTUMN()
* @method static static WINTER()
*/
final class SeasonsTrait
{
private const SPRING = 1;
private const SUMMER = 2;
private const AUTUMN = 3;
private const WINTER = 4;

/** @use ConstantsEnumTrait<'SPRING'|'SUMMER'|'AUTUMN'|'WINTER',SeasonsTrait::*> */
use ConstantsEnumTrait;
}

$spring = SeasonsTrait::SPRING();
/** @psalm-suppress InvalidArgument */
$spring->hasMember('INVALID');
/** @psalm-suppress InvalidArgument */
$spring->hasValue(9);
Loading