Skip to content

Commit ebfdbd1

Browse files
committed
bug #1793 [make:entity] Fix PHP 8.4 property hooks support (Amoifr)
This PR was squashed before being merged into the 1.x branch. Discussion ---------- [make:entity] Fix PHP 8.4 property hooks support ## Summary This PR fixes the `PhpParser\Error` that occurs when using `make:entity` on classes that contain PHP 8.4 property hooks (e.g., `private(set)`, get/set hooks). - Uses `ParserFactory::createForHostVersion()` instead of hardcoded PHP 8.1 parser - Automatically detects and uses the appropriate PHP version for parsing - Adds tests for PHP 8.4 property hooks ## Test plan - [x] Existing tests pass (59 tests) - [x] New tests for PHP 8.4 property hooks pass - [ ] Manual testing with entity using property hooks Fixes #1716 Commits ------- a29f35c [make:entity] Fix PHP 8.4 property hooks support
2 parents d6f2168 + a29f35c commit ebfdbd1

3 files changed

Lines changed: 46 additions & 8 deletions

File tree

src/Util/ClassSourceManipulator.php

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,11 @@
2323
use Doctrine\ORM\Mapping\OneToOne;
2424
use PhpParser\Builder;
2525
use PhpParser\BuilderHelpers;
26-
use PhpParser\Lexer;
2726
use PhpParser\Node;
2827
use PhpParser\NodeTraverser;
2928
use PhpParser\NodeVisitor;
3029
use PhpParser\Parser;
31-
use PhpParser\PhpVersion;
30+
use PhpParser\ParserFactory;
3231
use Symfony\Bundle\MakerBundle\ConsoleStyle;
3332
use Symfony\Bundle\MakerBundle\Doctrine\BaseCollectionRelation;
3433
use Symfony\Bundle\MakerBundle\Doctrine\BaseRelation;
@@ -51,7 +50,6 @@ final class ClassSourceManipulator
5150
private const DEFAULT_VALUE_NONE = '__default_value_none';
5251

5352
private Parser $parser;
54-
private Lexer\Emulative $lexer;
5553
private PrettyPrinter $printer;
5654
private ?ConsoleStyle $io = null;
5755

@@ -66,11 +64,7 @@ public function __construct(
6664
private bool $overwrite = false,
6765
private bool $useAttributesForDoctrineMapping = true,
6866
) {
69-
$this->lexer = new Lexer\Emulative(
70-
PhpVersion::fromString('8.1'),
71-
);
72-
$this->parser = new Parser\Php7($this->lexer);
73-
67+
$this->parser = (new ParserFactory())->createForHostVersion();
7468
$this->printer = new PrettyPrinter();
7569

7670
$this->setSourceCode($sourceCode);

tests/Util/ClassSourceManipulatorTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -870,4 +870,33 @@ public function testAddConstructorInClassContainsConstructor()
870870
CODE
871871
);
872872
}
873+
874+
/**
875+
* @requires PHP >= 8.4
876+
*/
877+
#[\PHPUnit\Framework\Attributes\RequiresPhp('>= 8.4')]
878+
public function testParsingPhp84PropertyHooks(): void
879+
{
880+
$source = file_get_contents(__DIR__.'/fixtures/source/User_property_hooks.php');
881+
882+
// This should not throw a PhpParser\Error
883+
$manipulator = new ClassSourceManipulator($source);
884+
885+
// Verify we can still work with the class
886+
$this->assertStringContainsString('class User', $manipulator->getSourceCode());
887+
}
888+
889+
/**
890+
* @requires PHP >= 8.4
891+
*/
892+
#[\PHPUnit\Framework\Attributes\RequiresPhp('>= 8.4')]
893+
public function testAddPropertyToClassWithPropertyHooks(): void
894+
{
895+
$source = file_get_contents(__DIR__.'/fixtures/source/User_property_hooks.php');
896+
897+
$manipulator = new ClassSourceManipulator($source);
898+
$manipulator->addProperty(name: 'newProp', propertyType: '?string');
899+
900+
$this->assertStringContainsString('private ?string $newProp', $manipulator->getSourceCode());
901+
}
873902
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace App\Entity;
4+
5+
class User
6+
{
7+
private ?int $id = null;
8+
9+
private(set) ?string $name = null;
10+
11+
public ?array $extra {
12+
get => $this->extra ?? [];
13+
set => $value;
14+
}
15+
}

0 commit comments

Comments
 (0)