Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:120446 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 92851 invoked from network); 30 May 2023 02:06:31 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 30 May 2023 02:06:31 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 41F181804D0 for ; Mon, 29 May 2023 19:06:30 -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,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE, T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS15169 209.85.128.0/17 X-Spam-Virus: No X-Envelope-From: Received: from mail-yb1-f172.google.com (mail-yb1-f172.google.com [209.85.219.172]) (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 19:06:29 -0700 (PDT) Received: by mail-yb1-f172.google.com with SMTP id 3f1490d57ef6-ba8374001abso5620185276.2 for ; Mon, 29 May 2023 19:06:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dqxtech-net.20221208.gappssmtp.com; s=20221208; t=1685412389; x=1688004389; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=hG0NrPWQ+oJr8I/8DW/RyUr2A3qqTAPOC7AVvJvrbSo=; b=32o/VyCcmy6QnZcn+o/yeHDkNrA+684EP+RgB369PIvVF6IpXKsOjWk+L0tU9v51YI QvTM4q69DhIRGGYrdFBj3oQ2jkvjmrURA/Q9O+udYiHGPge8E73yF7CeGpESDI4WAvR5 OeEZRGeKLpHE1f/CEf2nfJYptlr6VbaO2SfpZlQkEG0yMu5v8KavQjYf2kQdLuIh+87R HZLsJ/JyrKLxPisf6/ijf3HjKnKuUIdGVqDvGy+L7CIzYKjVeiqYt85Aug7aY1ptwdNa Y65Y1dNQXM2xNpovv7sG++5D/3YgmaXYR0r9aIeQaUXRKE4MaHUrB1pSY+KzMdA09nHF iScw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1685412389; x=1688004389; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=hG0NrPWQ+oJr8I/8DW/RyUr2A3qqTAPOC7AVvJvrbSo=; b=Gwye3y/fVGEvK7sA4itUJb4dl6OFdogcEYvpiM+Pm5XKseKqklPHEwbjOERxAwJRXH BnvIV+WZ3gn7xUGcF8rBDgRk4TP1IobRv+G/nw+faVVfB/SjXqhAZSws5fb7ArE9fTPs +5s3oR/tL38rKiRKea0o2a/4by8FtQdY49aUhybdZtpAGqKDQA5blhgvU1XGwTSLre8u DdVjnqmUgjxn9u/L/I3S+/fcCRvdYLvqeBrmKAZ1SCyC9KjcNs8wAfvrOQkVLci7v7tQ 2H5h9pPg6NEnCzaApPX0scWBCg4flvyGg8YJLJRwlLGqcGBZJ2Q/sslGRY+zzjn/iIVF LH6Q== X-Gm-Message-State: AC+VfDwPPvCW5gey9pnAw46on11e4zGcRIfopoThAVT8fTDr7uo+J9It 9oRyDqUx02esvGh86vxGWITQZsr9t7EuYQ0ZFPWIxw== X-Google-Smtp-Source: ACHHUZ7hbLxFAf7AL1JdzNr7g+6dFEX+rdLhTkzE82zKuHKx+e+nzERUOpSc06M6Q1PjnQ+eih0RM66cOwbWJxu9Jmg= X-Received: by 2002:a25:bd2:0:b0:ba9:b3dd:6b0d with SMTP id 201-20020a250bd2000000b00ba9b3dd6b0dmr993833ybl.64.1685412388746; Mon, 29 May 2023 19:06:28 -0700 (PDT) MIME-Version: 1.0 References: <018AB2D3-6F6C-4B55-877E-489ABA0D8E2A@woofle.net> In-Reply-To: <018AB2D3-6F6C-4B55-877E-489ABA0D8E2A@woofle.net> Date: Tue, 30 May 2023 04:06:17 +0200 Message-ID: To: Dusk Cc: PHP internals Content-Type: text/plain; charset="UTF-8" Subject: Re: [PHP-DEV] Declaration-aware attributes From: andreas@dqxtech.net (Andreas Hennings) Thanks for the feedback! On Tue, 30 May 2023 at 03:43, Dusk wrote: > > 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": Actually, these two options are what is possible with the current version of PHP, but it requires to write php code to solve these problems each time. The actual proposal in terms of "language design" solution was further below in my email :) > > 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; > > public function __construct(?string $name = null) { > $this->name = $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 = null) { > $this->name = $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. This is close to the parameter attribute I proposed. The benefit of the parameter attribute is that a developer can clearly see which parameter will be skipped for regular arguments.