From d20a197ca73fc07d1aa980509b49f4ce268a22a4 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Wed, 11 Dec 2024 11:34:55 +0100 Subject: [PATCH] Emit error - Multiple properties cannot share the same hooks Closes GH-1052. --- grammar/php.y | 1 + lib/PhpParser/Parser/Php8.php | 1 + lib/PhpParser/ParserAbstract.php | 7 ++ .../parser/stmt/class/property_hooks.test | 113 ++++++++++++++++++ 4 files changed, 122 insertions(+) diff --git a/grammar/php.y b/grammar/php.y index e825d038..2545f7d8 100644 --- a/grammar/php.y +++ b/grammar/php.y @@ -840,6 +840,7 @@ class_statement: #if PHP8 | optional_attributes variable_modifiers optional_type_without_static property_declaration_list '{' property_hook_list '}' { $$ = new Stmt\Property($2, $4, attributes(), $3, $1, $6); + $this->checkPropertyHooksForMultiProperty($$, #5); $this->checkEmptyPropertyHookList($6, #5); } #endif | optional_attributes method_modifiers T_CONST class_const_list semi diff --git a/lib/PhpParser/Parser/Php8.php b/lib/PhpParser/Parser/Php8.php index f9cb6338..e97914a5 100644 --- a/lib/PhpParser/Parser/Php8.php +++ b/lib/PhpParser/Parser/Php8.php @@ -1993,6 +1993,7 @@ class Php8 extends \PhpParser\ParserAbstract }, 348 => static function ($self, $stackPos) { $self->semValue = new Stmt\Property($self->semStack[$stackPos-(7-2)], $self->semStack[$stackPos-(7-4)], $self->getAttributes($self->tokenStartStack[$stackPos-(7-1)], $self->tokenEndStack[$stackPos]), $self->semStack[$stackPos-(7-3)], $self->semStack[$stackPos-(7-1)], $self->semStack[$stackPos-(7-6)]); + $self->checkPropertyHooksForMultiProperty($self->semValue, $stackPos-(7-5)); $self->checkEmptyPropertyHookList($self->semStack[$stackPos-(7-6)], $stackPos-(7-5)); }, 349 => static function ($self, $stackPos) { diff --git a/lib/PhpParser/ParserAbstract.php b/lib/PhpParser/ParserAbstract.php index 6921a66f..475b705e 100644 --- a/lib/PhpParser/ParserAbstract.php +++ b/lib/PhpParser/ParserAbstract.php @@ -1158,6 +1158,13 @@ abstract class ParserAbstract implements Parser { } } + protected function checkPropertyHooksForMultiProperty(Property $property, int $hookPos): void { + if (count($property->props) > 1) { + $this->emitError(new Error( + 'Cannot use hooks when declaring multiple properties', $this->getAttributesAt($hookPos))); + } + } + /** @param PropertyHook[] $hooks */ protected function checkEmptyPropertyHookList(array $hooks, int $hookPos): void { if (empty($hooks)) { diff --git a/test/code/parser/stmt/class/property_hooks.test b/test/code/parser/stmt/class/property_hooks.test index f53211c6..c3a6c800 100644 --- a/test/code/parser/stmt/class/property_hooks.test +++ b/test/code/parser/stmt/class/property_hooks.test @@ -523,3 +523,116 @@ array( ) ) ) +----- +