Skip to content

Commit

Permalink
Support defining #[Meta] on traits (resolve #9)
Browse files Browse the repository at this point in the history
  • Loading branch information
stancl committed Jan 12, 2024
1 parent f0ea4c3 commit 365b344
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 5 deletions.
21 changes: 16 additions & 5 deletions src/Meta/Reflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace ArchTech\Enums\Meta;

use ReflectionAttribute;
use ReflectionClass;
use ReflectionEnumUnitCase;
use ReflectionObject;

Expand All @@ -19,12 +20,22 @@ class Reflection
public static function metaProperties(mixed $enum): array
{
$reflection = new ReflectionObject($enum);
$metaProperties = static::parseMetaProperties($reflection);

// Attributes of the `Meta` type
$attributes = array_values(array_filter(
$reflection->getAttributes(),
fn (ReflectionAttribute $attr) => $attr->getName() === Meta::class,
));
// Traits except the `Metadata` trait
$traits = array_values(array_filter($reflection->getTraits(), fn (ReflectionClass $class) => $class->getName() !== 'ArchTech\Enums\Metadata'));

foreach ($traits as $trait) {
$metaProperties = array_merge($metaProperties, static::parseMetaProperties($trait));
}

return $metaProperties;
}

protected static function parseMetaProperties(ReflectionClass $reflection): array

Check failure on line 35 in src/Meta/Reflection.php

View workflow job for this annotation

GitHub Actions / Static analysis (PHPStan)

Method ArchTech\Enums\Meta\Reflection::parseMetaProperties() has parameter $reflection with generic class ReflectionClass but does not specify its types: T
{
// Only the `Meta` attribute
$attributes = $reflection->getAttributes(Meta::class);

if ($attributes) {
/** @var Meta $meta */
Expand Down
37 changes: 37 additions & 0 deletions tests/Pest/TraitTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

use ArchTech\Enums\Meta\Meta;
use ArchTech\Enums\Meta\MetaProperty;
use ArchTech\Enums\Metadata;

test('enums can use traits which define meta properties on themselves', function () {
expect(MyEnum::FOO->description())->toBe('Foo!');
expect(MyEnum::BAR->description())->toBe('Bar!');
expect(MyEnum::BAZ->description())->toBe(null);
});

enum MyEnum
{
use Metadata;
use HasDescription;

#[Description('Foo!')]
case FOO;

#[Description('Bar!')]
case BAR;

case BAZ;
}

#[Attribute]
class Description extends MetaProperty
{}

/**
* @method string|null description()
*/
#[Meta(Description::class)]
trait HasDescription
{
}

0 comments on commit 365b344

Please sign in to comment.