Re: [Vote] New in initializers

From: Date: Tue, 06 Jul 2021 13:38:08 +0000
Subject: Re: [Vote] New in initializers
References: 1 2 3 4 5 6  Groups: php.internals 
Request: Send a blank email to internals+get-115322@lists.php.net to get a copy of this message
On Tue, Jul 6, 2021 at 2:30 PM Nicolas Grekas <nicolas.grekas+php@gmail.com> wrote: > > > > This is not 100% correct, you can have an attribte #[Foo(Foo::class)] >> and >> > > then calling ReflectionAttribute::getArguments would also require to >> > > resolve the type Foo. So this is not different than what could happen >> > right >> > > now already. >> > >> > >> > Despite its name, "::class" doesn't care about class definitions, it >> > just performs a string substitution based on the "namespace" and >> > "use" >> > statements in the current file. >> > >> > In most cases, that happens entirely at compile time, so the following >> > two source files compile identically: >> > >> >> Hah, I realized after sending the example was bad :) I should have used an >> example using actual constants (vs magic ones): >> >> #[Foo(Foo::BAR)] >> >> This would trigger autoloading and resolving during getArguments() >> > > > Right! > > Extending on my proposal, getUninitializedArguments() could return a > ReflectionConstant in place of such values. > This doesn't extend to any more complex scenario: It's not just #[Foo(A::B)], it could also be #[Foo(A::FLAG_1 | A::FLAG_2)] and so on. The only way to do this is to go all the way back to Dmitry's attribute proposal (https://wiki.php.net/rfc/attributes) which allows fetching the AST of attribute arguments. That could represent arbitrary arguments without evaluating them. (In fact, that proposal also allowed attribute arguments that PHP cannot constant-evaluate at all.) I also think that viewing this as "nested attributes" is not quite the right way to think about it. Yes, the Assert\All use case is nested attributes, but that's just a special case. More generally this just allows you to use an object as an attribute argument, and that object does not necessarily have to be an attribute itself. To give a silly example, if we were to write argument and return types as attributes, you could have something like #[ReturnType(new IntersectionType(Foo::class, Bar::class))], where IntersectionType is just the representation of a particular type, but is not (and shouldn't be) an attribute itself. Regards, Nikita

« previous php.internals (#115322) next »