Skip to content

Allow class inheritance determination for enums#16

Open
agustingomes wants to merge 1 commit intoCrell:masterfrom
agustingomes:enum-implementing-interface
Open

Allow class inheritance determination for enums#16
agustingomes wants to merge 1 commit intoCrell:masterfrom
agustingomes:enum-implementing-interface

Conversation

@agustingomes
Copy link

@agustingomes agustingomes commented Mar 1, 2026

Description

Read enum implemented interfaces and its attributes

Motivation and context

In the scope of a downstream project issue, It was noticed that in cases where an enum implemented an interface, the interface attributes could not be read.

This change allows ReflectionEnum to retrieve such information if it exists.

How has this been tested?

Unit test case has been added to existing test

Types of changes

What types of changes does your code introduce? Put an x in all the boxes that apply:

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

Go over all the following points, and put an x in all the boxes that apply.

Please, please, please, don't send your pull request until all of the boxes are ticked. Once your pull request is created, it will trigger a build on our continuous integration server to make sure your tests and code style pass.

  • I have read the CONTRIBUTING document.
  • My pull request addresses exactly one patch/feature.
  • I have created a branch for this patch/feature.
  • Each individual commit in the pull request is meaningful.
  • I have added tests to cover my changes.
  • If my change requires a change to the documentation, I have updated it accordingly.

@agustingomes agustingomes force-pushed the enum-implementing-interface branch from e949de1 to 93f1875 Compare March 2, 2026 16:11
@agustingomes
Copy link
Author

@Crell Thank you for the review and the suggestions. I applied them.

README.md Outdated
use Crell\AttributeUtils\Inheritable;

#[Attribute(Attribute::TARGET_CLASS)]
final readonly class TypeMap implements Inheritable
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Serde TypeMaps were the reason I added this feature, but I don't think they make a particularly good example. It requires a lot of context to understand why you'd want to do it. For the README, we should have a much simpler and more understandable example. Remember, not everyone using AU is using Serde. (I hope... 😄 )

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, that is a reasonable take. I used the Serde TypeMaps since that is what I'm using as reference for these changes.

The TypeMap also helped me learn that if an attribute does not implement Inheritable the result is different than expected, which is something I believe the Readme needs to account for.

With that said, I will try to write an example that is not tied to the TypeMaps.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hopefully the new example I pushed makes more sense and requires less context.

* @return iterable<\ReflectionClass<object>>
* @throws \ReflectionException
*/
protected function enumInheritanceTree(\ReflectionEnum $subject): iterable
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am I missing something, or is this identical to classInheritanceTree()? If they're the same, there's no reason to duplicate it. It's fine to have attributeInheritanceTree() call the same method for classes and enums, since enums are classes.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is indeed identical.

In my first iteration, I did use classInheritanceTree method instead, but when resolving the PHPStan issues it raised, it felt like a better approach to implement a specific method for ReflectionEnum.

I will take a second look at the PHPStan issues and see if I can figure them out, because the enum are classes under the hood, so it definitely makes sense to re-use the existing classInheritanceTree.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. The annotation change ended up being simpler. Although I'd have expected ReflectionEnum to be accepted as ReflectionObject is, but maybe because of the UnitEnum, it was not accepted the same way.

### Motivation

In the scope of [a downstream project issue](Crell/Serde#10), It was noticed that in cases where an enum implemented an interface, the interface attributes could not be read.

This change allows `ReflectionEnum` to retrieve such information if it exists
@agustingomes agustingomes force-pushed the enum-implementing-interface branch from 93f1875 to 829d9cc Compare March 2, 2026 18:15
@agustingomes agustingomes requested a review from Crell March 2, 2026 18:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants