diff --git a/lib/PhpParser/Node/Param.php b/lib/PhpParser/Node/Param.php index a277ca0a..57d15b7b 100644 --- a/lib/PhpParser/Node/Param.php +++ b/lib/PhpParser/Node/Param.php @@ -68,11 +68,20 @@ class Param extends NodeAbstract { * Whether this parameter uses constructor property promotion. */ public function isPromoted(): bool { - return $this->flags !== 0; + return $this->flags !== 0 || $this->hooks !== []; } public function isPublic(): bool { - return (bool) ($this->flags & Modifiers::PUBLIC); + $public = (bool) ($this->flags & Modifiers::PUBLIC); + if ($public) { + return true; + } + + if ($this->hooks === []) { + return false; + } + + return ($this->flags & Modifiers::VISIBILITY_MASK) === 0; } public function isProtected(): bool { diff --git a/test/PhpParser/Node/ParamTest.php b/test/PhpParser/Node/ParamTest.php index 93bbf92c..c488b659 100644 --- a/test/PhpParser/Node/ParamTest.php +++ b/test/PhpParser/Node/ParamTest.php @@ -47,4 +47,18 @@ class ParamTest extends \PHPUnit\Framework\TestCase { $node->flags = Modifiers::PUBLIC_SET; $this->assertTrue($node->isPublicSet()); } + + public function testPromotedPropertyWithoutVisibilityModifier(): void { + $node = new Param(new Variable('foo')); + $get = new PropertyHook('get', null); + $node->hooks[] = $get; + + $this->assertTrue($node->isPromoted()); + $this->assertTrue($node->isPublic()); + } + + public function testNonPromotedPropertyIsNotPublic(): void { + $node = new Param(new Variable('foo')); + $this->assertFalse($node->isPublic()); + } }