Skip to content

Commit 4964f8d

Browse files
DanielEScherzernikic
authored andcommitted
Add support for attributes on constants
Just merged in php/php-src@3f03f7e, updating this parser is needed to be able to use attributes on constants in the stub files.
1 parent 20b0d55 commit 4964f8d

File tree

15 files changed

+2457
-2120
lines changed

15 files changed

+2457
-2120
lines changed

grammar/php.y

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,10 @@ top_statement:
257257
| T_USE use_declarations semi { $$ = Stmt\Use_[$2, Stmt\Use_::TYPE_NORMAL]; }
258258
| T_USE use_type use_declarations semi { $$ = Stmt\Use_[$3, $2]; }
259259
| group_use_declaration
260-
| T_CONST constant_declaration_list semi { $$ = Stmt\Const_[$2]; }
260+
| T_CONST constant_declaration_list semi { $$ = new Stmt\Const_($2, attributes(), []); }
261+
| attributes T_CONST constant_declaration_list semi
262+
{ $$ = new Stmt\Const_($3, attributes(), $1);
263+
$this->checkConstantAttributes($$); }
261264
;
262265

263266
use_type:

lib/PhpParser/Node/Stmt/Const_.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,28 @@
77
class Const_ extends Node\Stmt {
88
/** @var Node\Const_[] Constant declarations */
99
public array $consts;
10+
/** @var Node\AttributeGroup[] PHP attribute groups */
11+
public array $attrGroups;
1012

1113
/**
1214
* Constructs a const list node.
1315
*
1416
* @param Node\Const_[] $consts Constant declarations
1517
* @param array<string, mixed> $attributes Additional attributes
18+
* @param list<Node\AttributeGroup> $attrGroups PHP attribute groups
1619
*/
17-
public function __construct(array $consts, array $attributes = []) {
20+
public function __construct(
21+
array $consts,
22+
array $attributes = [],
23+
array $attrGroups = []
24+
) {
1825
$this->attributes = $attributes;
26+
$this->attrGroups = $attrGroups;
1927
$this->consts = $consts;
2028
}
2129

2230
public function getSubNodeNames(): array {
23-
return ['consts'];
31+
return ['attrGroups', 'consts'];
2432
}
2533

2634
public function getType(): string {

lib/PhpParser/NodeVisitor/NameResolver.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ public function enterNode(Node $node) {
120120
foreach ($node->consts as $const) {
121121
$this->addNamespacedName($const);
122122
}
123+
$this->resolveAttrGroups($node);
123124
} elseif ($node instanceof Stmt\ClassConst) {
124125
if (null !== $node->type) {
125126
$node->type = $this->resolveType($node->type);

lib/PhpParser/Parser/Php7.php

Lines changed: 1055 additions & 1056 deletions
Large diffs are not rendered by default.

lib/PhpParser/Parser/Php8.php

Lines changed: 1083 additions & 1059 deletions
Large diffs are not rendered by default.

lib/PhpParser/ParserAbstract.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use PhpParser\Node\Stmt\Class_;
2424
use PhpParser\Node\Stmt\ClassConst;
2525
use PhpParser\Node\Stmt\ClassMethod;
26+
use PhpParser\Node\Stmt\Const_;
2627
use PhpParser\Node\Stmt\Else_;
2728
use PhpParser\Node\Stmt\ElseIf_;
2829
use PhpParser\Node\Stmt\Enum_;
@@ -1202,6 +1203,13 @@ protected function checkPropertyHookModifiers(int $a, int $b, int $modifierPos):
12021203
}
12031204
}
12041205

1206+
protected function checkConstantAttributes(Const_ $node): void {
1207+
if ($node->attrGroups !== [] && count($node->consts) > 1) {
1208+
$this->emitError(new Error(
1209+
'Cannot use attributes on multiple constants at once', $node->getAttributes()));
1210+
}
1211+
}
1212+
12051213
/**
12061214
* @param Property|Param $node
12071215
*/

lib/PhpParser/PrettyPrinter/Standard.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -878,7 +878,9 @@ protected function pStmt_Function(Stmt\Function_ $node): string {
878878
}
879879

880880
protected function pStmt_Const(Stmt\Const_ $node): string {
881-
return 'const ' . $this->pCommaSeparated($node->consts) . ';';
881+
return $this->pAttrGroups($node->attrGroups)
882+
. 'const '
883+
. $this->pCommaSeparated($node->consts) . ';';
882884
}
883885

884886
protected function pStmt_Declare(Stmt\Declare_ $node): string {

lib/PhpParser/PrettyPrinterAbstract.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,6 +1634,7 @@ protected function initializeEmptyListInsertionMap(): void {
16341634
Stmt\Trait_::class . '->attrGroups' => [null, '', "\n"],
16351635
Expr\ArrowFunction::class . '->attrGroups' => [null, '', ' '],
16361636
Expr\Closure::class . '->attrGroups' => [null, '', ' '],
1637+
Stmt\Const_::class . '->attrGroups' => [null, '', "\n"],
16371638
PrintableNewAnonClassNode::class . '->attrGroups' => [\T_NEW, ' ', ''],
16381639

16391640
/* These cannot be empty to start with:

test/PhpParser/NodeVisitor/NameResolverTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,9 @@ function(A $a) : A {};
245245
fn(A $a): A => $a;
246246
fn(?A $a): ?A => $a;
247247
248+
#[X]
249+
const EXAMPLE = true;
250+
248251
A::b();
249252
A::$b;
250253
A::B;
@@ -338,6 +341,8 @@ function fn4(?array $a): ?array
338341
#[\NS\X] fn(array $a): array => $a;
339342
fn(\NS\A $a): \NS\A => $a;
340343
fn(?\NS\A $a): ?\NS\A => $a;
344+
#[\NS\X]
345+
const EXAMPLE = true;
341346
\NS\A::b();
342347
\NS\A::$b;
343348
\NS\A::B;
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
Constants
2+
-----
3+
<?php
4+
5+
const FOO = true;
6+
7+
#[A]
8+
const BAR = true;
9+
-----
10+
$attrGroup = new Node\AttributeGroup([
11+
new Node\Attribute(new Node\Name('B'), []),
12+
]);
13+
$stmts[0]->attrGroups[] = $attrGroup;
14+
$stmts[1]->attrGroups[] = $attrGroup;
15+
-----
16+
<?php
17+
18+
#[B]
19+
const FOO = true;
20+
21+
#[A]
22+
#[B]
23+
const BAR = true;
24+
-----
25+
<?php
26+
27+
#[ A, B]
28+
const FOO = true;
29+
30+
#[
31+
A,
32+
B,
33+
]
34+
const BAR = true;
35+
-----
36+
$attr = new Node\Attribute(new Node\Name('C'), []);
37+
$stmts[0]->attrGroups[0]->attrs[] = $attr;
38+
$stmts[1]->attrGroups[0]->attrs[] = $attr;
39+
-----
40+
<?php
41+
42+
#[ A, B, C]
43+
const FOO = true;
44+
45+
#[
46+
A,
47+
B,
48+
C,
49+
]
50+
const BAR = true;

0 commit comments

Comments
 (0)