diff --git a/src/Util/ClassSourceManipulator.php b/src/Util/ClassSourceManipulator.php index c944503dd..7d48ee63e 100644 --- a/src/Util/ClassSourceManipulator.php +++ b/src/Util/ClassSourceManipulator.php @@ -23,12 +23,11 @@ use Doctrine\ORM\Mapping\OneToOne; use PhpParser\Builder; use PhpParser\BuilderHelpers; -use PhpParser\Lexer; use PhpParser\Node; use PhpParser\NodeTraverser; use PhpParser\NodeVisitor; use PhpParser\Parser; -use PhpParser\PhpVersion; +use PhpParser\ParserFactory; use Symfony\Bundle\MakerBundle\ConsoleStyle; use Symfony\Bundle\MakerBundle\Doctrine\BaseCollectionRelation; use Symfony\Bundle\MakerBundle\Doctrine\BaseRelation; @@ -51,7 +50,6 @@ final class ClassSourceManipulator private const DEFAULT_VALUE_NONE = '__default_value_none'; private Parser $parser; - private Lexer\Emulative $lexer; private PrettyPrinter $printer; private ?ConsoleStyle $io = null; @@ -66,11 +64,7 @@ public function __construct( private bool $overwrite = false, private bool $useAttributesForDoctrineMapping = true, ) { - $this->lexer = new Lexer\Emulative( - PhpVersion::fromString('8.1'), - ); - $this->parser = new Parser\Php7($this->lexer); - + $this->parser = (new ParserFactory())->createForHostVersion(); $this->printer = new PrettyPrinter(); $this->setSourceCode($sourceCode); diff --git a/tests/Util/ClassSourceManipulatorTest.php b/tests/Util/ClassSourceManipulatorTest.php index 421078133..be9a3d5d0 100644 --- a/tests/Util/ClassSourceManipulatorTest.php +++ b/tests/Util/ClassSourceManipulatorTest.php @@ -870,4 +870,33 @@ public function testAddConstructorInClassContainsConstructor() CODE ); } + + /** + * @requires PHP >= 8.4 + */ + #[\PHPUnit\Framework\Attributes\RequiresPhp('>= 8.4')] + public function testParsingPhp84PropertyHooks(): void + { + $source = file_get_contents(__DIR__.'/fixtures/source/User_property_hooks.php'); + + // This should not throw a PhpParser\Error + $manipulator = new ClassSourceManipulator($source); + + // Verify we can still work with the class + $this->assertStringContainsString('class User', $manipulator->getSourceCode()); + } + + /** + * @requires PHP >= 8.4 + */ + #[\PHPUnit\Framework\Attributes\RequiresPhp('>= 8.4')] + public function testAddPropertyToClassWithPropertyHooks(): void + { + $source = file_get_contents(__DIR__.'/fixtures/source/User_property_hooks.php'); + + $manipulator = new ClassSourceManipulator($source); + $manipulator->addProperty(name: 'newProp', propertyType: '?string'); + + $this->assertStringContainsString('private ?string $newProp', $manipulator->getSourceCode()); + } } diff --git a/tests/Util/fixtures/source/User_property_hooks.php b/tests/Util/fixtures/source/User_property_hooks.php new file mode 100644 index 000000000..a1c5fc37c --- /dev/null +++ b/tests/Util/fixtures/source/User_property_hooks.php @@ -0,0 +1,15 @@ + $this->extra ?? []; + set => $value; + } +}