From f15e94ef64ceff012b31f05f7ba22278fc1f1189 Mon Sep 17 00:00:00 2001 From: Larry Garfield Date: Fri, 8 Jul 2022 16:38:47 -0500 Subject: [PATCH 1/7] Add Attributes style guide. --- spec.md | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/spec.md b/spec.md index 5273245..b7bd573 100644 --- a/spec.md +++ b/spec.md @@ -1276,6 +1276,87 @@ function allowed() compliant nowdoc COMPLIANT; +``` + +## 11. Attributes + +### 12.1 Basics + +Attribute names must immediately follow the opening attribute block indicator `#[` with no space. + +If an attribute has no arguments, the `()` MUST be omitted. + +The closing attribute block indicator `]` MUST follow the last character of the attribute name or the closing `)` of +its argument list, with no preceding space. + +### 12.2 Placement + +Attributes on classes, methods, functions, constants and properties MUST +be placed on their own line, immediately prior to the structure being described. + +For attributes on parameters, if the parameter list is presented on a single line, +the attribute MUST be placed inline with the parameter it describes, separated by a single space. +If the parameter list is split into multiple lines for any reason, the attribute MUST be placed on +its own line prior to the parameter, indented the same as the parameter. + +If a comment docblock is present on a structure that also includes an attribute, the comment block MUST +come first, followed by any attributes, followed by the structure itself. There MUST NOT be any blank lines +between the docblock and attributes, or the attributes and the structure. + +If two separate attribute blocks (denoted by separate `#[]` markers) are used in a multi-line context, +they MUST be on separate lines with no blank lines between them. + +### 12.3 Compound attributes + +Multiple attributes MAY be placed in the same attribute block (`#[]`) if and only if the entire block is listed on a +single line. They must be separated by a comma with a space following but no space preceding. If the attribute list +is split into multiple lines for any reason, then the attributes MUST be placed in separate attribute blocks. +Those blocks may themselves contain multiple attributes provided this rule is respected. + +If an attribute's argument list is split into multiple lines for any reason, then: + +* The attribute MUST be the only one in its attribute block. +* The attribute arguments MUST follow the same rules as defined for multiline function calls. + +### 12.4 Example + +The following is an example of valid attribute usage. + +```php +#[Foo] +#[Bar('baz')] +class Demo +{ + #[Beep] + private Foo $foo; + + /** + * Sets the foo. + */ + #[Poink('narf'), Narf('poink')] + public function setFoo(#[Beep] Foo $new): void + { + // ... + } + + #[Complex( + prop: 'val', + other: 5, + )] + #[Other, Stuff, Here] + public function complicated( + string $a, + #[Decl] + string $b, + #[Complex( + prop: 'val', + other: 5, + )] + string $c, + int $d, + ): string { + // ... + } } ``` From b7ab5ab7225e17496b3f4a074591679d091311a2 Mon Sep 17 00:00:00 2001 From: Larry Garfield Date: Fri, 8 Jul 2022 17:01:20 -0500 Subject: [PATCH 2/7] Whitespace fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tim Düsterhus --- spec.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec.md b/spec.md index b7bd573..954c3ff 100644 --- a/spec.md +++ b/spec.md @@ -1310,7 +1310,7 @@ they MUST be on separate lines with no blank lines between them. Multiple attributes MAY be placed in the same attribute block (`#[]`) if and only if the entire block is listed on a single line. They must be separated by a comma with a space following but no space preceding. If the attribute list -is split into multiple lines for any reason, then the attributes MUST be placed in separate attribute blocks. +is split into multiple lines for any reason, then the attributes MUST be placed in separate attribute blocks. Those blocks may themselves contain multiple attributes provided this rule is respected. If an attribute's argument list is split into multiple lines for any reason, then: @@ -1333,7 +1333,7 @@ class Demo /** * Sets the foo. */ - #[Poink('narf'), Narf('poink')] + #[Poink('narf'), Narf('poink')] public function setFoo(#[Beep] Foo $new): void { // ... From c5d60e6f3f6a89908f8eba9371180831cc40904e Mon Sep 17 00:00:00 2001 From: Larry Garfield Date: Tue, 19 Jul 2022 12:01:51 -0500 Subject: [PATCH 3/7] Tweak language around compound attributes. --- spec.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/spec.md b/spec.md index 954c3ff..40e0cb2 100644 --- a/spec.md +++ b/spec.md @@ -1276,11 +1276,12 @@ function allowed() compliant nowdoc COMPLIANT; +} ``` ## 11. Attributes -### 12.1 Basics +### 11.1 Basics Attribute names must immediately follow the opening attribute block indicator `#[` with no space. @@ -1289,7 +1290,7 @@ If an attribute has no arguments, the `()` MUST be omitted. The closing attribute block indicator `]` MUST follow the last character of the attribute name or the closing `)` of its argument list, with no preceding space. -### 12.2 Placement +### 11.2 Placement Attributes on classes, methods, functions, constants and properties MUST be placed on their own line, immediately prior to the structure being described. @@ -1306,10 +1307,10 @@ between the docblock and attributes, or the attributes and the structure. If two separate attribute blocks (denoted by separate `#[]` markers) are used in a multi-line context, they MUST be on separate lines with no blank lines between them. -### 12.3 Compound attributes +### 11.3 Compound attributes Multiple attributes MAY be placed in the same attribute block (`#[]`) if and only if the entire block is listed on a -single line. They must be separated by a comma with a space following but no space preceding. If the attribute list +single line and each attribute is reasonably short. They MUST be separated by a comma with a space following but no space preceding. If the attribute list is split into multiple lines for any reason, then the attributes MUST be placed in separate attribute blocks. Those blocks may themselves contain multiple attributes provided this rule is respected. @@ -1318,7 +1319,7 @@ If an attribute's argument list is split into multiple lines for any reason, the * The attribute MUST be the only one in its attribute block. * The attribute arguments MUST follow the same rules as defined for multiline function calls. -### 12.4 Example +### 11.4 Example The following is an example of valid attribute usage. From d59aae4784a46689b3c5b6914e3b67c1fa4ac863 Mon Sep 17 00:00:00 2001 From: Larry Garfield Date: Tue, 2 Aug 2022 09:00:34 -0500 Subject: [PATCH 4/7] Add a constructor example for attributes, including blank lines. --- spec.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/spec.md b/spec.md index 40e0cb2..29abe66 100644 --- a/spec.md +++ b/spec.md @@ -1298,7 +1298,9 @@ be placed on their own line, immediately prior to the structure being described. For attributes on parameters, if the parameter list is presented on a single line, the attribute MUST be placed inline with the parameter it describes, separated by a single space. If the parameter list is split into multiple lines for any reason, the attribute MUST be placed on -its own line prior to the parameter, indented the same as the parameter. +its own line prior to the parameter, indented the same as the parameter. If the parameter list +is split into multiple lines, a blank line MAY be included between one parameter and the attributes +of the following parameter in order to aid readability. If a comment docblock is present on a structure that also includes an attribute, the comment block MUST come first, followed by any attributes, followed by the structure itself. There MUST NOT be any blank lines @@ -1331,6 +1333,14 @@ class Demo #[Beep] private Foo $foo; + public function __construct( + #[Load(context: 'foo', bar: true)] + private readonly FooService $fooService, + + #[LoadProxy(context: 'bar')] + private readonly BarService $barService, + ) {} + /** * Sets the foo. */ From 0fc022d341301fb24aeade0f6413d94d89c6ecc4 Mon Sep 17 00:00:00 2001 From: Larry Garfield Date: Tue, 2 Aug 2022 09:01:07 -0500 Subject: [PATCH 5/7] Add more blank lines. --- spec.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec.md b/spec.md index 29abe66..80c1ba8 100644 --- a/spec.md +++ b/spec.md @@ -1357,13 +1357,16 @@ class Demo #[Other, Stuff, Here] public function complicated( string $a, + #[Decl] string $b, + #[Complex( prop: 'val', other: 5, )] string $c, + int $d, ): string { // ... From b96975237a2e4743b0f16b249add68a5e65567e0 Mon Sep 17 00:00:00 2001 From: Larry Garfield Date: Tue, 2 Aug 2022 14:31:09 -0500 Subject: [PATCH 6/7] Fix whitespace alignment. --- spec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.md b/spec.md index 80c1ba8..d2c7123 100644 --- a/spec.md +++ b/spec.md @@ -1333,7 +1333,7 @@ class Demo #[Beep] private Foo $foo; - public function __construct( + public function __construct( #[Load(context: 'foo', bar: true)] private readonly FooService $fooService, From a774903c8b507e532517aac4d47ade647bae18d7 Mon Sep 17 00:00:00 2001 From: Larry Garfield Date: Mon, 8 Aug 2022 15:59:34 -0500 Subject: [PATCH 7/7] Revise compound section. --- spec.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/spec.md b/spec.md index d2c7123..1fa5fd7 100644 --- a/spec.md +++ b/spec.md @@ -1283,13 +1283,15 @@ function allowed() ### 11.1 Basics -Attribute names must immediately follow the opening attribute block indicator `#[` with no space. +Attribute names MUST immediately follow the opening attribute block indicator `#[` with no space. If an attribute has no arguments, the `()` MUST be omitted. The closing attribute block indicator `]` MUST follow the last character of the attribute name or the closing `)` of its argument list, with no preceding space. +The construct `#[...]` is referred to as an "attribute block" in this document. + ### 11.2 Placement Attributes on classes, methods, functions, constants and properties MUST @@ -1306,15 +1308,15 @@ If a comment docblock is present on a structure that also includes an attribute, come first, followed by any attributes, followed by the structure itself. There MUST NOT be any blank lines between the docblock and attributes, or the attributes and the structure. -If two separate attribute blocks (denoted by separate `#[]` markers) are used in a multi-line context, -they MUST be on separate lines with no blank lines between them. +If two separate attribute blocks are used in a multi-line context, they MUST be on separate lines with no blank +lines between them. ### 11.3 Compound attributes -Multiple attributes MAY be placed in the same attribute block (`#[]`) if and only if the entire block is listed on a -single line and each attribute is reasonably short. They MUST be separated by a comma with a space following but no space preceding. If the attribute list -is split into multiple lines for any reason, then the attributes MUST be placed in separate attribute blocks. -Those blocks may themselves contain multiple attributes provided this rule is respected. +If multiple attributes are placed in the same attribute block, they MUST be separated by a comma with a space +following but no space preceding. If the attribute list is split into multiple lines for any reason, then the +attributes MUST be placed in separate attribute blocks. Those blocks may themselves contain multiple +attributes provided this rule is respected. If an attribute's argument list is split into multiple lines for any reason, then: @@ -1354,7 +1356,8 @@ class Demo prop: 'val', other: 5, )] - #[Other, Stuff, Here] + #[Other, Stuff] + #[Here] public function complicated( string $a,