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:
This pull request makes it possible to use array notation inside attributes as follows:
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:
...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
ClassFormatException
s, 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: