Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:120445 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 90905 invoked from network); 30 May 2023 01:43:57 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 30 May 2023 01:43:57 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 2EBF61804F8 for ; Mon, 29 May 2023 18:43:57 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS63949 74.207.240.0/20 X-Spam-Virus: No X-Envelope-From: Received: from malamute.woofle.net (woofle.net [74.207.252.100]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Mon, 29 May 2023 18:43:56 -0700 (PDT) Received: by malamute.woofle.net (Postfix) with ESMTPSA id 6897F1EF2E; Mon, 29 May 2023 18:43:55 -0700 (PDT) Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3731.600.7\)) In-Reply-To: Date: Mon, 29 May 2023 18:43:44 -0700 Cc: PHP internals Content-Transfer-Encoding: quoted-printable Message-ID: <018AB2D3-6F6C-4B55-877E-489ABA0D8E2A@woofle.net> References: To: Andreas Hennings X-Mailer: Apple Mail (2.3731.600.7) Subject: Re: [PHP-DEV] Declaration-aware attributes From: dusk@woofle.net (Dusk) On May 29, 2023, at 17:48, Andreas Hennings wrote: > Quite often I found myself writing attribute classes that need to fill > some default values or do some validation based on the symbol the > attribute is attached to. > E.g. a parameter attribute might require a specific type on that > parameter, or it might fill a default value based on the parameter > name. +1. This is a substantial limitation in the attribute system. > Currently I see two ways to do this: > 1. Do the logic in the code that reads the attribute, instead of the > attribute class. This works ok for one-off attribute classes, but it > becomes quite unflexible with attribute interfaces, where 3rd parties > can provide their own attribute class implementations. > 2. Add additional methods to the attribute class that take the symbol > reflector as a parameter, like "setReflectionMethod()", or > "setReflectionClass()". Or the method in the attribute class that > returns the values can have a reflector as a parameter. I see a third way which introduces less "magic": 3.a. Add a method to ReflectionAttribute which retrieves the target of = the attribute as an appropriate reflection object. (Sadly, the obvious = name "getTarget" is already taken; I'll call it "getReflectionTarget" = for now.) 3.b. Add a static method to ReflectionAttribute which, when called = within an Attribute constructor which is being called by = ReflectionAttribute::newInstance(), returns the ReflectionAttribute = object which is being instantiated. These features could be used together to set a default property on an = attribute based on its target, e.g. #[Attribute(Attribute::TARGET_PROPERTY)] class PropertyAnnotation { public string $name; =20 public function __construct(?string $name =3D null) { $this->name =3D $name ?? = ReflectionAttribute::underConstruction()->getReflectionTarget()->getName()= ; } } Another variant that comes to mind is: 3.b. Add a new flag to attributes which causes the ReflectionAttribute = object to be passed to the constructor as the first argument, e.g. #[Attribute(Attribute::TARGET_PROPERTY | Attribute::WHO_MADE_ME)] class PropertyAnnotation { public string $name; public function __construct(ReflectionAttribute $attr, ?string = $name =3D null) { $this->name =3D $name ?? = $attr->getReflectionTarget()->getName(); } } This is a little messier because it can't be used "under the covers" by = an attribute base class, but it accomplishes the same goals.=