Skip to content

Commit

Permalink
Merge pull request #152 from romm/fix/anonymous-class-attribute
Browse files Browse the repository at this point in the history
Handle anonymous class attribute
  • Loading branch information
antecedent committed Feb 6, 2024
2 parents 16a1ab8 + bc7d1c8 commit 6b30aff
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 4 deletions.
10 changes: 7 additions & 3 deletions src/CodeManipulation/Actions/Generic.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
const RIGHT_SQUARE = ']';
const SEMICOLON = ';';

foreach (['NAME_FULLY_QUALIFIED', 'NAME_QUALIFIED', 'NAME_RELATIVE', 'ELLIPSIS', 'ATTRIBUTE'] as $constant) {
foreach (['NAME_FULLY_QUALIFIED', 'NAME_QUALIFIED', 'NAME_RELATIVE', 'ELLIPSIS', 'ATTRIBUTE', 'READONLY'] as $constant) {
if (defined('T_' . $constant)) {
define(__NAMESPACE__ . '\\' . $constant, constant('T_' . $constant));
} else {
Expand Down Expand Up @@ -137,8 +137,12 @@ function injectCodeAfterClassDefinitions($code)
{
return function(Source $s) use ($code) {
foreach ($s->all(T_CLASS) as $match) {
if ($s->is([T_DOUBLE_COLON, T_NEW], $s->skipBack(Source::junk(), $match))) {
# Not a proper class definition: either ::class syntax or anonymous class
if ($s->is([LEFT_ROUND, LEFT_CURLY, T_EXTENDS, T_IMPLEMENTS], $s->skip(Source::junk(), $match))) {
# Not a proper class definition: anonymous class (with or without attribute)
continue;
}
if ($s->is(T_DOUBLE_COLON, $s->skipBack(Source::junk(), $match))) {
# Not a proper class definition: ::class syntax
continue;
}
$leftBracket = $s->next(LEFT_CURLY, $match);
Expand Down
2 changes: 1 addition & 1 deletion src/CodeManipulation/Actions/RedefinitionOfNew.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ function spliceAllInstantiations(Source $s)
}
foreach ($s->all(T_NEW) as $new) {
$begin = $s->skip(Source::junk(), $new);
if ($s->is(T_CLASS, $begin)) {
if ($s->is([T_CLASS, Generic\READONLY, Generic\ATTRIBUTE], $begin)) {
# Anonymous class
continue;
}
Expand Down
20 changes: 20 additions & 0 deletions tests/anonymous-class-attribute.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
--TEST--
Attribute declared in anonymous class

--SKIPIF--
<?php version_compare(PHP_VERSION, "8.0", ">=")
or die("skip because attributes are only available since PHP 8.0") ?>

--FILE--
<?php

error_reporting(E_ALL | E_STRICT);

require __DIR__ . "/../Patchwork.php";
require __DIR__ . "/includes/AnonymousClassAttribute.php";

?>
===DONE===

--EXPECT--
===DONE===
18 changes: 18 additions & 0 deletions tests/includes/AnonymousClassAttribute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

#[\Attribute]
class SomeAttribute {
public function __construct($value) {}
}

// Simple attribute
new #[SomeAttribute('foo')] class {};

// Several attributes
new #[SomeAttribute('foo')] #[SomeAttribute('bar')] class {};

// Attribute with argument on several lines
new #[SomeAttribute([
'foo',
'bar',
])] class {};
22 changes: 22 additions & 0 deletions tests/redefinition-new-anonymous-class-with-attribute.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
--TEST--
Redefinition of new in anonymous class with attribute

--SKIPIF--
<?php version_compare(PHP_VERSION, "8.0", ">=")
or die("skip because attributes are only available since PHP 8.0") ?>

--FILE--
<?php

error_reporting(E_ALL | E_STRICT);

$_SERVER['PHP_SELF'] = __FILE__;

require __DIR__ . "/../Patchwork.php";
require __DIR__ . "/includes/AnonymousClassAttribute.php";

?>
===DONE===

--EXPECT--
===DONE===

0 comments on commit 6b30aff

Please sign in to comment.