Skip to content

Commit 6b30aff

Browse files
authored
Merge pull request #152 from romm/fix/anonymous-class-attribute
Handle anonymous class attribute
2 parents 16a1ab8 + bc7d1c8 commit 6b30aff

5 files changed

Lines changed: 68 additions & 4 deletions

File tree

src/CodeManipulation/Actions/Generic.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
const RIGHT_SQUARE = ']';
2121
const SEMICOLON = ';';
2222

23-
foreach (['NAME_FULLY_QUALIFIED', 'NAME_QUALIFIED', 'NAME_RELATIVE', 'ELLIPSIS', 'ATTRIBUTE'] as $constant) {
23+
foreach (['NAME_FULLY_QUALIFIED', 'NAME_QUALIFIED', 'NAME_RELATIVE', 'ELLIPSIS', 'ATTRIBUTE', 'READONLY'] as $constant) {
2424
if (defined('T_' . $constant)) {
2525
define(__NAMESPACE__ . '\\' . $constant, constant('T_' . $constant));
2626
} else {
@@ -137,8 +137,12 @@ function injectCodeAfterClassDefinitions($code)
137137
{
138138
return function(Source $s) use ($code) {
139139
foreach ($s->all(T_CLASS) as $match) {
140-
if ($s->is([T_DOUBLE_COLON, T_NEW], $s->skipBack(Source::junk(), $match))) {
141-
# Not a proper class definition: either ::class syntax or anonymous class
140+
if ($s->is([LEFT_ROUND, LEFT_CURLY, T_EXTENDS, T_IMPLEMENTS], $s->skip(Source::junk(), $match))) {
141+
# Not a proper class definition: anonymous class (with or without attribute)
142+
continue;
143+
}
144+
if ($s->is(T_DOUBLE_COLON, $s->skipBack(Source::junk(), $match))) {
145+
# Not a proper class definition: ::class syntax
142146
continue;
143147
}
144148
$leftBracket = $s->next(LEFT_CURLY, $match);

src/CodeManipulation/Actions/RedefinitionOfNew.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ function spliceAllInstantiations(Source $s)
3030
}
3131
foreach ($s->all(T_NEW) as $new) {
3232
$begin = $s->skip(Source::junk(), $new);
33-
if ($s->is(T_CLASS, $begin)) {
33+
if ($s->is([T_CLASS, Generic\READONLY, Generic\ATTRIBUTE], $begin)) {
3434
# Anonymous class
3535
continue;
3636
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
Attribute declared in anonymous class
3+
4+
--SKIPIF--
5+
<?php version_compare(PHP_VERSION, "8.0", ">=")
6+
or die("skip because attributes are only available since PHP 8.0") ?>
7+
8+
--FILE--
9+
<?php
10+
11+
error_reporting(E_ALL | E_STRICT);
12+
13+
require __DIR__ . "/../Patchwork.php";
14+
require __DIR__ . "/includes/AnonymousClassAttribute.php";
15+
16+
?>
17+
===DONE===
18+
19+
--EXPECT--
20+
===DONE===
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
#[\Attribute]
4+
class SomeAttribute {
5+
public function __construct($value) {}
6+
}
7+
8+
// Simple attribute
9+
new #[SomeAttribute('foo')] class {};
10+
11+
// Several attributes
12+
new #[SomeAttribute('foo')] #[SomeAttribute('bar')] class {};
13+
14+
// Attribute with argument on several lines
15+
new #[SomeAttribute([
16+
'foo',
17+
'bar',
18+
])] class {};
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
Redefinition of new in anonymous class with attribute
3+
4+
--SKIPIF--
5+
<?php version_compare(PHP_VERSION, "8.0", ">=")
6+
or die("skip because attributes are only available since PHP 8.0") ?>
7+
8+
--FILE--
9+
<?php
10+
11+
error_reporting(E_ALL | E_STRICT);
12+
13+
$_SERVER['PHP_SELF'] = __FILE__;
14+
15+
require __DIR__ . "/../Patchwork.php";
16+
require __DIR__ . "/includes/AnonymousClassAttribute.php";
17+
18+
?>
19+
===DONE===
20+
21+
--EXPECT--
22+
===DONE===

0 commit comments

Comments
 (0)