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

Support eval array notation inside attributes #324

Merged
merged 3 commits into from
Jun 3, 2023

Conversation

thekid
Copy link
Member

@thekid thekid commented Jun 3, 2023

This pull request makes it possible to use array notation inside attributes as follows:

// Currently supported
#[Callback(eval: 'fn() => ...')]
class A { }

(new XPClass(A::class))->getAnnotation('callback'); // Closure{}

// Additionally supported
#[Callback(eval: ['fn() => ...'])]
class B { }

(new XPClass(B::class))->getAnnotation('callback'); // Closure{}

// Using named arguments
#[Callback(eval: ['function' => 'fn() => ...'])]
class C { }

(new XPClass(C::class))->getAnnotation('callback'); // ['function' => Closure{}]

Together with xp-framework/reflection#35, this is a prerequisite for extracting reflection code as proposed by xp-framework/rfc#338.


⚠️ This does not offer full support because the XP Framework core annotation API is built around a single-value paradigm instead of multiple arguments. The following raises an exception:

// Unsupported
#[Callbacks(eval: ['fn() => ...', 'fn() => ...'])]
class A { }

(new XPClass(A::class))->getAnnotation('callbacks'); // *** Parse error

...just like PHP 8 attributes with multiple arguments do.

👉 However, this PR makes it possible to use array notation for single values or multiple named arguments without risking ClassFormatExceptions, ensuring partial compatibility.


It also enables us to emit simpler code in the XP Compiler, where we current have a special-case handling for when exactly one unnamed argument exists. The simplification that can be applied there is along the lines of the following:

- if (1 === sizeof($annotation->arguments) && 0 === key($annotation->arguments)) {
-   // ...
- } else {
-   foreach ($annotation->arguments as $key => $argument) {
-     // ...
-   }
- }
+ foreach ($annotation->arguments as $key => $argument) {
+   // ...
+ }

@thekid thekid merged commit cb48007 into xp-framework:main Jun 3, 2023
@thekid thekid deleted the feature/eval-array-notation branch June 3, 2023 18:40
@thekid
Copy link
Member Author

thekid commented Jun 3, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant